diff --git a/APP_Framework/Framework/security/Kconfig b/APP_Framework/Framework/security/Kconfig index a67663056..13e900272 100755 --- a/APP_Framework/Framework/security/Kconfig +++ b/APP_Framework/Framework/security/Kconfig @@ -24,5 +24,11 @@ endif menuconfig MBEDTLS bool "using mbedtls" default n + select MBEDTLS_ENABLE +if MBEDTLS + menuconfig ENABLE_MBEDTLS_TEST + bool "enable test" + default n +endif endmenu diff --git a/APP_Framework/Framework/security/mbedtls/Makefile b/APP_Framework/Framework/security/mbedtls/Makefile index f15779dad..34e33f70c 100644 --- a/APP_Framework/Framework/security/mbedtls/Makefile +++ b/APP_Framework/Framework/security/mbedtls/Makefile @@ -1,5 +1,14 @@ -SRC_FILES := aes.c aria.c asn1parse.c asn1write.c base64.c bignum.c certs.c cipher.c cmac.c ctr_drbg.c dhm.c ecp.c \ -entropy.c files.txt md5.c md.c oid.c pem.c pk.c pkcs12.c pkcs5.c pkparse.c rsa.c rsa_internal.c sha1.c \ -sha256.c ssl_cli.c ssl_srv.c ssl_tls.c +SRC_FILES := aes.c aesni.c arc4.c asn1parse.c asn1write.c base64.c bignum.c blowfish.c camellia.c \ +ccm.c certs.c cipher.c cipher_wrap.c cmac.c ctr_drbg.c debug.c des.c dhm.c ecdh.c ecdsa.c ecjpake.c \ +ecp.c ecp_curves.c entropy.c entropy_poll.c error.c gcm.c havege.c hmac_drbg.c md2.c md4.c md5.c md.c \ +md_wrap.c memory_buffer_alloc.c net_sockets.c oid.c padlock.c pem.c pk.c pkcs11.c pkcs12.c pkcs5.c \ +pkparse.c pk_wrap.c pkwrite.c platform.c ripemd160.c rsa.c rsa_internal.c sha1.c sha256.c sha512.c \ +ssl_cache.c ssl_ciphersuites.c ssl_cli.c ssl_cookie.c ssl_srv.c ssl_ticket.c ssl_tls.c threading.c \ +version.c version_features.c x509.c x509_create.c x509_crl.c x509_csr.c \ +x509write_crt.c x509write_csr.c xtea.c # timing_alt.c tls_hardware.c + +ifeq ($(CONFIG_ENABLE_MBEDTLS_TEST), y) + SRC_FILES += test.c +endif include $(KERNEL_ROOT)/compiler.mk \ No newline at end of file diff --git a/APP_Framework/Framework/security/mbedtls/aes.c b/APP_Framework/Framework/security/mbedtls/aes.c index 3c2c56626..84bd91ce0 100644 --- a/APP_Framework/Framework/security/mbedtls/aes.c +++ b/APP_Framework/Framework/security/mbedtls/aes.c @@ -36,8 +36,6 @@ #include #include "aes.h" -#include "platform.h" -#include "platform_util.h" #if defined(MBEDTLS_PADLOCK_C) #include "padlock.h" #endif @@ -56,11 +54,10 @@ #if !defined(MBEDTLS_AES_ALT) -/* Parameter validation macros based on platform_util.h */ -#define AES_VALIDATE_RET( cond ) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_AES_BAD_INPUT_DATA ) -#define AES_VALIDATE( cond ) \ - MBEDTLS_INTERNAL_VALIDATE( cond ) +/* 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; +} /* * 32-bit integer manipulation macros (little endian) @@ -85,33 +82,6 @@ } #endif -/* - * Data structure for AES round data - */ -typedef struct { - uint32_t *rk_ptr; /* Round Key */ - uint32_t xy_values[8]; /* X0, X1, X2, X3, Y0, Y1, Y2, Y3 */ -#if defined(MBEDTLS_AES_128_BIT_MASKED) - uint32_t round; -#endif -} aes_r_data_t; - -#if defined(MBEDTLS_AES_SCA_COUNTERMEASURES) -/* Number of additional AES dummy rounds added for SCA countermeasures */ -#define AES_SCA_CM_ROUNDS 5 - -#if defined (MBEDTLS_AES_128_BIT_MASKED) - -#define Nb (4) /* number of columns (32-bit words) comprising the state */ -#define Nk (4) /* number of 32-bit words comprising the key */ -#define Nr (10) /* number of rounds */ - -// state - array holding the intermediate results during aes operation. -typedef uint8_t masked_state_t[4][4]; - -#endif -#endif /* MBEDTLS_AES_SCA_COUNTERMEASURES */ - #if defined(MBEDTLS_PADLOCK_C) && \ ( defined(MBEDTLS_HAVE_X86) || defined(MBEDTLS_PADLOCK_ALIGN16) ) static int aes_padlock_ace = -1; @@ -157,8 +127,6 @@ static const unsigned char FSb[256] = 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16 }; - -#if !defined(MBEDTLS_AES_128_BIT_MASKED) /* * Forward tables */ @@ -233,8 +201,6 @@ static const unsigned char FSb[256] = static const uint32_t FT0[256] = { FT }; #undef V -#if !defined(MBEDTLS_AES_FEWER_TABLES) - #define V(a,b,c,d) 0x##b##c##d##a static const uint32_t FT1[256] = { FT }; #undef V @@ -247,13 +213,8 @@ static const uint32_t FT2[256] = { FT }; static const uint32_t FT3[256] = { FT }; #undef V -#endif /* !MBEDTLS_AES_FEWER_TABLES */ - #undef FT -#endif //ifndef MBEDTLS_AES_128_BIT_MASKED - -#if !defined(MBEDTLS_AES_ONLY_ENCRYPT) /* * Reverse S-box */ @@ -293,8 +254,6 @@ static const unsigned char RSb[256] = 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D }; -#endif /* !MBEDTLS_AES_ONLY_ENCRYPT */ - /* * Reverse tables */ @@ -365,13 +324,10 @@ static const unsigned char RSb[256] = V(71,01,A8,39), V(DE,B3,0C,08), V(9C,E4,B4,D8), V(90,C1,56,64), \ V(61,84,CB,7B), V(70,B6,32,D5), V(74,5C,6C,48), V(42,57,B8,D0) -#if !defined(MBEDTLS_AES_ONLY_ENCRYPT) #define V(a,b,c,d) 0x##a##b##c##d static const uint32_t RT0[256] = { RT }; #undef V -#if !defined(MBEDTLS_AES_FEWER_TABLES) - #define V(a,b,c,d) 0x##b##c##d##a static const uint32_t RT1[256] = { RT }; #undef V @@ -384,9 +340,6 @@ static const uint32_t RT2[256] = { RT }; static const uint32_t RT3[256] = { RT }; #undef V -#endif /* !MBEDTLS_AES_FEWER_TABLES */ -#endif /* !MBEDTLS_AES_ONLY_ENCRYPT */ - #undef RT /* @@ -405,28 +358,19 @@ static const uint32_t RCON[10] = * Forward S-box & tables */ static unsigned char FSb[256]; -#if !defined(MBEDTLS_AES_128_BIT_MASKED) static uint32_t FT0[256]; -#endif -#if !defined(MBEDTLS_AES_FEWER_TABLES) static uint32_t FT1[256]; static uint32_t FT2[256]; static uint32_t FT3[256]; -#endif /* !MBEDTLS_AES_FEWER_TABLES */ /* * Reverse S-box & tables */ -#if !defined(MBEDTLS_AES_ONLY_ENCRYPT) static unsigned char RSb[256]; - static uint32_t RT0[256]; -#if !defined(MBEDTLS_AES_FEWER_TABLES) static uint32_t RT1[256]; static uint32_t RT2[256]; static uint32_t RT3[256]; -#endif /* !MBEDTLS_AES_FEWER_TABLES */ -#endif /* !MBEDTLS_AES_ONLY_ENCRYPT */ /* * Round constants @@ -436,20 +380,15 @@ static uint32_t RCON[10]; /* * Tables generation code */ -#define XTIME(x) ( ( (x) << 1 ) ^ ( ( (x) & 0x80 ) ? 0x1B : 0x00 ) ) -#if !defined(MBEDTLS_AES_128_BIT_MASKED) -#define ROTL8(x) ( ( (x) << 8 ) & 0xFFFFFFFF ) | ( (x) >> 24 ) -#define MUL(x,y) ( ( (x) && (y) ) ? pow[(log[(x)]+log[(y)]) % 255] : 0 ) -#endif +#define ROTL8(x) ( ( x << 8 ) & 0xFFFFFFFF ) | ( x >> 24 ) +#define XTIME(x) ( ( x << 1 ) ^ ( ( x & 0x80 ) ? 0x1B : 0x00 ) ) +#define MUL(x,y) ( ( x && y ) ? pow[(log[x]+log[y]) % 255] : 0 ) static int aes_init_done = 0; static void aes_gen_tables( void ) { - int i, x, y; -#if !defined(MBEDTLS_AES_128_BIT_MASKED) - int z; -#endif + int i, x, y, z; int pow[256]; int log[256]; @@ -476,9 +415,7 @@ static void aes_gen_tables( void ) * generate the forward and reverse S-boxes */ FSb[0x00] = 0x63; -#if !defined(MBEDTLS_AES_ONLY_ENCRYPT) RSb[0x63] = 0x00; -#endif for( i = 1; i < 256; i++ ) { @@ -491,11 +428,9 @@ static void aes_gen_tables( void ) x ^= y ^ 0x63; FSb[i] = (unsigned char) x; -#if !defined(MBEDTLS_AES_ONLY_ENCRYPT) RSb[x] = (unsigned char) i; -#endif } -#if !defined(MBEDTLS_AES_128_BIT_MASKED) + /* * generate the forward and reverse tables */ @@ -510,13 +445,10 @@ static void aes_gen_tables( void ) ( (uint32_t) x << 16 ) ^ ( (uint32_t) z << 24 ); -#if !defined(MBEDTLS_AES_FEWER_TABLES) FT1[i] = ROTL8( FT0[i] ); FT2[i] = ROTL8( FT1[i] ); FT3[i] = ROTL8( FT2[i] ); -#endif /* !MBEDTLS_AES_FEWER_TABLES */ -#if !defined(MBEDTLS_AES_ONLY_ENCRYPT) x = RSb[i]; RT0[i] = ( (uint32_t) MUL( 0x0E, x ) ) ^ @@ -524,158 +456,16 @@ static void aes_gen_tables( void ) ( (uint32_t) MUL( 0x0D, x ) << 16 ) ^ ( (uint32_t) MUL( 0x0B, x ) << 24 ); -#if !defined(MBEDTLS_AES_FEWER_TABLES) RT1[i] = ROTL8( RT0[i] ); RT2[i] = ROTL8( RT1[i] ); RT3[i] = ROTL8( RT2[i] ); -#endif /* !MBEDTLS_AES_FEWER_TABLES */ -#endif /* !MBEDTLS_AES_ONLY_ENCRYPT */ } - -#endif //MBEDTLS_AES_128_BIT_MASKED } -#undef ROTL8 - #endif /* MBEDTLS_AES_ROM_TABLES */ -/** - * Randomize positions for AES SCA countermeasures if AES countermeasures are - * enabled. If the countermeasures are not enabled then we fill the given table - * with only real AES rounds to be executed. - * - * Dummy rounds are added as follows: - * 1. One dummy round added to the initial round key addition (executed in - * random order). - * 2. Random number of dummy rounds added as first and/or last AES calculation - * round. Total number of dummy rounds is AES_SCA_CM_ROUNDS. - * - * Description of the bytes in the table are as follows: - * - 2 bytes for initial round key addition - * - remaining bytes for AES calculation with real or dummy data - * - * Each byte indicates one AES calculation round: - * -4 high bit = table to use 0x10 for dummy data, 0x00 real data - * -bit 2 = offset for even/odd rounds - * -bit 0-1: stop mark (0x03) to indicate calculation end - * - * Return Number of additional AES rounds - * - * Example of the control bytes: - * R = real data in actual AES calculation round - * Ri = Real data in initial round key addition phase - * F = fake data in actual AES calculation round - * Fi = fake data in initial round key addition phase - * - * 1. No countermeasures enabled and AES-128, only real data (R) used: - * | Ri | R | R | R | R | R | R | R | R | R | R | - * |0x03|0x04|0x00|0x04|0x00|0x04|0x00|0x04|0x00|0x07|0x03| - * - * 2. Countermeasures enabled, 3 (F) dummy rounds in start and 1 at end: - * | Fi | Ri | F | F | F | R | R | ... | R | R | R | R | F | - * |0x10|0x03|0x10|0x10|0x10|0x04|0x00| ... |0x04|0x00|0x04|0x03|0x07| - */ -#if defined(MBEDTLS_AES_SCA_COUNTERMEASURES) -static int aes_sca_cm_data_randomize( uint8_t *tbl, int tbl_len ) -{ - int i = 0, j, is_even_pos, dummy_rounds, num; - - mbedtls_platform_memset( tbl, 0, tbl_len ); - // get random from 0x0fff - num = mbedtls_platform_random_in_range( 0x1000 ); - - // Randomize execution order of initial round key addition - if ( ( num & 0x0100 ) == 0 ) - { - tbl[i++] = 0x10; // dummy data - tbl[i++] = 0x00 | 0x03; // real data + stop marker - } else { - tbl[i++] = 0x00; // real data - tbl[i++] = 0x10 | 0x03; // dummy data + stop marker - } - - // Randomize number of dummy AES rounds - dummy_rounds = AES_SCA_CM_ROUNDS - ( ( num & 0x0010 ) >> 4 ); - tbl_len = tbl_len - (AES_SCA_CM_ROUNDS - dummy_rounds); - - // randomize positions for the dummy rounds - num = ( num & 0x0fff ) % ( dummy_rounds + 1 ); - - // add dummy rounds after initial round key addition (if needed) - for ( ; i < num + 2; i++ ) - { - tbl[i] = 0x10; // dummy data - } - - // add dummy rounds to the end, (AES_SCA_CM_ROUNDS - num) rounds if needed - for ( j = tbl_len - dummy_rounds + num; j < tbl_len; j++ ) - { - tbl[j] = 0x10; // dummy data - } - - // Fill real AES data to the remaining places - is_even_pos = 1; - for( ; i < tbl_len; i++ ) - { - if( tbl[i] == 0 ) - { - if( is_even_pos == 1 ) - { - tbl[i] = 0x04; // real data, offset for rounds 1,3,5, etc... - is_even_pos = 0; - } - else - { - tbl[i] = 0x00; // real data, offset for rounds 2,4,6,... - is_even_pos = 1; - } - j = i; // remember the final round position in table - } - } - - tbl[( tbl_len - 1)] |= 0x03; // Stop marker for the last item in tbl - tbl[( j - 1 )] |= 0x03; // stop marker for final - 1 real data - - return( dummy_rounds ); -} -#endif /* MBEDTLS_AES_SCA_COUNTERMEASURES */ - -#if !defined(MBEDTLS_AES_128_BIT_MASKED) -#if defined(MBEDTLS_AES_FEWER_TABLES) - -#define ROTL8(x) ( (uint32_t)( ( x ) << 8 ) + (uint32_t)( ( x ) >> 24 ) ) -#define ROTL16(x) ( (uint32_t)( ( x ) << 16 ) + (uint32_t)( ( x ) >> 16 ) ) -#define ROTL24(x) ( (uint32_t)( ( x ) << 24 ) + (uint32_t)( ( x ) >> 8 ) ) - -#define AES_RT0(idx) RT0[idx] -#define AES_RT1(idx) ROTL8( RT0[idx] ) -#define AES_RT2(idx) ROTL16( RT0[idx] ) -#define AES_RT3(idx) ROTL24( RT0[idx] ) - -#define AES_FT0(idx) FT0[idx] -#define AES_FT1(idx) ROTL8( FT0[idx] ) -#define AES_FT2(idx) ROTL16( FT0[idx] ) -#define AES_FT3(idx) ROTL24( FT0[idx] ) - -#else /* MBEDTLS_AES_FEWER_TABLES */ - -#define AES_RT0(idx) RT0[idx] -#define AES_RT1(idx) RT1[idx] -#define AES_RT2(idx) RT2[idx] -#define AES_RT3(idx) RT3[idx] - -#define AES_FT0(idx) FT0[idx] -#define AES_FT1(idx) FT1[idx] -#define AES_FT2(idx) FT2[idx] -#define AES_FT3(idx) FT3[idx] - -#endif /* MBEDTLS_AES_FEWER_TABLES */ -#endif - void mbedtls_aes_init( mbedtls_aes_context *ctx ) { - AES_VALIDATE( ctx != NULL ); - memset( ctx, 0, sizeof( mbedtls_aes_context ) ); } @@ -684,40 +474,9 @@ void mbedtls_aes_free( mbedtls_aes_context *ctx ) if( ctx == NULL ) return; - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_aes_context ) ); + mbedtls_zeroize( ctx, sizeof( mbedtls_aes_context ) ); } -#if defined(MBEDTLS_CIPHER_MODE_XTS) -void mbedtls_aes_xts_init( mbedtls_aes_xts_context *ctx ) -{ - AES_VALIDATE( ctx != NULL ); - - mbedtls_aes_init( &ctx->crypt ); - mbedtls_aes_init( &ctx->tweak ); -} - -void mbedtls_aes_xts_free( mbedtls_aes_xts_context *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_aes_free( &ctx->crypt ); - mbedtls_aes_free( &ctx->tweak ); -} -#endif /* MBEDTLS_CIPHER_MODE_XTS */ - -#if defined(MBEDTLS_AES_SCA_COUNTERMEASURES) -static void mbedtls_generate_fake_key( unsigned int keybits, mbedtls_aes_context *ctx ) -{ - unsigned int qword; - - for( qword = keybits >> 5; qword > 0; qword-- ) - { - ctx->frk[ qword - 1 ] = mbedtls_platform_random_uint32(); - } -} -#endif /* MBEDTLS_AES_SCA_COUNTERMEASURES */ - /* * AES key schedule (encryption) */ @@ -725,34 +484,26 @@ static void mbedtls_generate_fake_key( unsigned int keybits, mbedtls_aes_context int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key, unsigned int keybits ) { - unsigned int j = 0; - unsigned int flow_ctrl = 0; - volatile unsigned int i = 0; - volatile int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; + unsigned int i; uint32_t *RK; - uint32_t offset = 0; - AES_VALIDATE_RET( ctx != NULL ); - AES_VALIDATE_RET( key != NULL ); - (void) ret; - - switch( keybits ) - { - case 128: ctx->nr = 10; break; -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) - case 192: ctx->nr = 12; break; - case 256: ctx->nr = 14; break; -#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */ - default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH ); - } #if !defined(MBEDTLS_AES_ROM_TABLES) if( aes_init_done == 0 ) { aes_gen_tables(); aes_init_done = 1; + } #endif + switch( keybits ) + { + case 128: ctx->nr = 10; break; + case 192: ctx->nr = 12; break; + case 256: ctx->nr = 14; break; + default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH ); + } + #if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16) if( aes_padlock_ace == -1 ) aes_padlock_ace = mbedtls_padlock_has_support( MBEDTLS_PADLOCK_ACE ); @@ -761,37 +512,22 @@ int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key, ctx->rk = RK = MBEDTLS_PADLOCK_ALIGN16( ctx->buf ); else #endif - ctx->rk = RK = ctx->buf; -#if defined(MBEDTLS_AES_SCA_COUNTERMEASURES) - mbedtls_generate_fake_key( keybits, ctx ); -#endif #if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64) if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) ) return( mbedtls_aesni_setkey_enc( (unsigned char *) ctx->rk, key, keybits ) ); #endif - /* Three least significant bits are truncated from keybits, which is - * expected to be a multiple of 8. */ - mbedtls_platform_memset( RK, 0, keybits >> 3 ); - offset = mbedtls_platform_random_in_range( keybits >> 5 ); - - for( j = offset; j < ( keybits >> 5 ); j++ ) + for( i = 0; i < ( keybits >> 5 ); i++ ) { - GET_UINT32_LE( RK[j], key, j << 2 ); - flow_ctrl++; - } - - for( j = 0; j < offset; j++ ) - { - GET_UINT32_LE( RK[j], key, j << 2 ); - flow_ctrl++; + GET_UINT32_LE( RK[i], key, i << 2 ); } switch( ctx->nr ) { case 10: + for( i = 0; i < 10; i++, RK += 4 ) { RK[4] = RK[0] ^ RCON[i] ^ @@ -805,7 +541,7 @@ int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key, RK[7] = RK[3] ^ RK[6]; } break; -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) + case 12: for( i = 0; i < 8; i++, RK += 6 ) @@ -849,25 +585,9 @@ int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key, RK[15] = RK[7] ^ RK[14]; } break; -#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */ } - /* Validate execution path */ - if( ( flow_ctrl == keybits >> 5 ) && ( ( ctx->nr == 10 && i == 10 ) -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) - || ( ctx->nr == 12 && i == 8 ) - || ( ctx->nr == 14 && i == 7 ) -#endif - ) ) - { -#if defined(MBEDTLS_VALIDATE_AES_KEYS_INTEGRITY) - ctx->hash = mbedtls_hash( ctx->rk, keybits >> 3 ); -#endif - return 0; - } - - mbedtls_platform_memset( RK, 0, ( keybits >> 5 ) * 4 ); - return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); + return( 0 ); } #endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */ @@ -878,22 +598,11 @@ int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key, int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key, unsigned int keybits ) { -#if defined(MBEDTLS_AES_ONLY_ENCRYPT) - (void) ctx; - (void) key; - (void) keybits; - - return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH; -#else /* */ - volatile unsigned int i = 0, j = 0; - volatile int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; + int i, j, ret; mbedtls_aes_context cty; uint32_t *RK; uint32_t *SK; - AES_VALIDATE_RET( ctx != NULL ); - AES_VALIDATE_RET( key != NULL ); - mbedtls_aes_init( &cty ); #if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16) @@ -905,9 +614,6 @@ int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key, else #endif ctx->rk = RK = ctx->buf; -#if defined(MBEDTLS_AES_SCA_COUNTERMEASURES) - mbedtls_generate_fake_key( keybits, ctx ); -#endif /* Also checks keybits */ if( ( ret = mbedtls_aes_setkey_enc( &cty, key, keybits ) ) != 0 ) @@ -920,8 +626,6 @@ int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key, { mbedtls_aesni_inverse_key( (unsigned char *) ctx->rk, (const unsigned char *) cty.rk, ctx->nr ); - i = 0; - j = 4; goto exit; } #endif @@ -937,10 +641,10 @@ int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key, { for( j = 0; j < 4; j++, SK++ ) { - *RK++ = AES_RT0( FSb[ ( *SK ) & 0xFF ] ) ^ - AES_RT1( FSb[ ( *SK >> 8 ) & 0xFF ] ) ^ - AES_RT2( FSb[ ( *SK >> 16 ) & 0xFF ] ) ^ - AES_RT3( FSb[ ( *SK >> 24 ) & 0xFF ] ); + *RK++ = RT0[ FSb[ ( *SK ) & 0xFF ] ] ^ + RT1[ FSb[ ( *SK >> 8 ) & 0xFF ] ] ^ + RT2[ FSb[ ( *SK >> 16 ) & 0xFF ] ] ^ + RT3[ FSb[ ( *SK >> 24 ) & 0xFF ] ]; } } @@ -952,701 +656,60 @@ int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key, exit: mbedtls_aes_free( &cty ); - if( ret != 0 ) - { - return( ret ); - } - else if( ( i == 0 ) && ( j == 4 ) ) - { -#if defined(MBEDTLS_VALIDATE_AES_KEYS_INTEGRITY) - ctx->hash = mbedtls_hash( ctx->rk, keybits >> 3 ); -#endif - return( ret ); - } - else - { - return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); - } - -#endif /* MBEDTLS_AES_ONLY_ENCRYPT */ + return( ret ); } - -#if defined(MBEDTLS_CIPHER_MODE_XTS) -static int mbedtls_aes_xts_decode_keys( const unsigned char *key, - unsigned int keybits, - const unsigned char **key1, - unsigned int *key1bits, - const unsigned char **key2, - unsigned int *key2bits ) -{ - const unsigned int half_keybits = keybits / 2; - const unsigned int half_keybytes = half_keybits / 8; - - switch( keybits ) - { - case 256: break; - case 512: break; - default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH ); - } - - *key1bits = half_keybits; - *key2bits = half_keybits; - *key1 = &key[0]; - *key2 = &key[half_keybytes]; - - return 0; -} - -int mbedtls_aes_xts_setkey_enc( mbedtls_aes_xts_context *ctx, - const unsigned char *key, - unsigned int keybits) -{ - int ret; - const unsigned char *key1, *key2; - unsigned int key1bits, key2bits; - - AES_VALIDATE_RET( ctx != NULL ); - AES_VALIDATE_RET( key != NULL ); - - ret = mbedtls_aes_xts_decode_keys( key, keybits, &key1, &key1bits, - &key2, &key2bits ); - if( ret != 0 ) - return( ret ); - - /* Set the tweak key. Always set tweak key for the encryption mode. */ - ret = mbedtls_aes_setkey_enc( &ctx->tweak, key2, key2bits ); - if( ret != 0 ) - return( ret ); - - /* Set crypt key for encryption. */ - return mbedtls_aes_setkey_enc( &ctx->crypt, key1, key1bits ); -} - -int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx, - const unsigned char *key, - unsigned int keybits) -{ - int ret; - const unsigned char *key1, *key2; - unsigned int key1bits, key2bits; - - AES_VALIDATE_RET( ctx != NULL ); - AES_VALIDATE_RET( key != NULL ); - - ret = mbedtls_aes_xts_decode_keys( key, keybits, &key1, &key1bits, - &key2, &key2bits ); - if( ret != 0 ) - return( ret ); - - /* Set the tweak key. Always set tweak key for encryption. */ - ret = mbedtls_aes_setkey_enc( &ctx->tweak, key2, key2bits ); - if( ret != 0 ) - return( ret ); - - /* Set crypt key for decryption. */ - return mbedtls_aes_setkey_dec( &ctx->crypt, key1, key1bits ); -} -#endif /* MBEDTLS_CIPHER_MODE_XTS */ - #endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */ +#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ +{ \ + X0 = *RK++ ^ FT0[ ( Y0 ) & 0xFF ] ^ \ + FT1[ ( Y1 >> 8 ) & 0xFF ] ^ \ + FT2[ ( Y2 >> 16 ) & 0xFF ] ^ \ + FT3[ ( Y3 >> 24 ) & 0xFF ]; \ + \ + X1 = *RK++ ^ FT0[ ( Y1 ) & 0xFF ] ^ \ + FT1[ ( Y2 >> 8 ) & 0xFF ] ^ \ + FT2[ ( Y3 >> 16 ) & 0xFF ] ^ \ + FT3[ ( Y0 >> 24 ) & 0xFF ]; \ + \ + X2 = *RK++ ^ FT0[ ( Y2 ) & 0xFF ] ^ \ + FT1[ ( Y3 >> 8 ) & 0xFF ] ^ \ + FT2[ ( Y0 >> 16 ) & 0xFF ] ^ \ + FT3[ ( Y1 >> 24 ) & 0xFF ]; \ + \ + X3 = *RK++ ^ FT0[ ( Y3 ) & 0xFF ] ^ \ + FT1[ ( Y0 >> 8 ) & 0xFF ] ^ \ + FT2[ ( Y1 >> 16 ) & 0xFF ] ^ \ + FT3[ ( Y2 >> 24 ) & 0xFF ]; \ +} + +#define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ +{ \ + X0 = *RK++ ^ RT0[ ( Y0 ) & 0xFF ] ^ \ + RT1[ ( Y3 >> 8 ) & 0xFF ] ^ \ + RT2[ ( Y2 >> 16 ) & 0xFF ] ^ \ + RT3[ ( Y1 >> 24 ) & 0xFF ]; \ + \ + X1 = *RK++ ^ RT0[ ( Y1 ) & 0xFF ] ^ \ + RT1[ ( Y0 >> 8 ) & 0xFF ] ^ \ + RT2[ ( Y3 >> 16 ) & 0xFF ] ^ \ + RT3[ ( Y2 >> 24 ) & 0xFF ]; \ + \ + X2 = *RK++ ^ RT0[ ( Y2 ) & 0xFF ] ^ \ + RT1[ ( Y1 >> 8 ) & 0xFF ] ^ \ + RT2[ ( Y0 >> 16 ) & 0xFF ] ^ \ + RT3[ ( Y3 >> 24 ) & 0xFF ]; \ + \ + X3 = *RK++ ^ RT0[ ( Y3 ) & 0xFF ] ^ \ + RT1[ ( Y2 >> 8 ) & 0xFF ] ^ \ + RT2[ ( Y1 >> 16 ) & 0xFF ] ^ \ + RT3[ ( Y0 >> 24 ) & 0xFF ]; \ +} + /* * AES-ECB block encryption */ #if !defined(MBEDTLS_AES_ENCRYPT_ALT) - -#if defined(MBEDTLS_AES_SCA_COUNTERMEASURES) - -#if defined(MBEDTLS_AES_128_BIT_MASKED) - -static uint8_t xtime( uint8_t x ) -{ - return ( ( x << 1 ) ^ ( ( ( x >> 7 ) & 1 ) * 0x1b ) ); -} - -static int sub_bytes_masked( uint32_t *data, uint8_t sbox_masked[256] ) -{ - volatile unsigned int i; - - for ( i = 0; i < 4; i++ ) - { - data[i] = ( (uint32_t)sbox_masked[(data[i]) & 0xFF] ) ^ - ( (uint32_t)sbox_masked[(data[i] >> 8 ) & 0xFF] << 8 ) ^ - ( (uint32_t)sbox_masked[(data[i] >> 16 ) & 0xFF] << 16 ) ^ - ( (uint32_t)sbox_masked[(data[i] >> 24 ) & 0xFF] << 24 ); - } - - if ( i == 4 ) - { - return 0; - } - - return ( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); -} - -static int mix_columns( uint8_t *s ) -{ - masked_state_t *state = (masked_state_t *)s; - volatile unsigned int i = 0; - uint8_t Tmp, Tm, t; - - for ( i = 0; i < 4; ++i ) - { - t = (*state)[i][0]; - Tmp = (*state)[i][0] ^ (*state)[i][1] ^ (*state)[i][2] ^ (*state)[i][3]; - Tm = (*state)[i][0] ^ (*state)[i][1]; - Tm = xtime(Tm); - (*state)[i][0] ^= Tm ^ Tmp; - Tm = (*state)[i][1] ^ (*state)[i][2]; - Tm = xtime(Tm); - (*state)[i][1] ^= Tm ^ Tmp; - Tm = (*state)[i][2] ^ (*state)[i][3]; - Tm = xtime(Tm); - (*state)[i][2] ^= Tm ^ Tmp; - Tm = (*state)[i][3] ^ t; - Tm = xtime(Tm); - (*state)[i][3] ^= Tm ^ Tmp; - } - - if ( i == 4 ) - { - return 0; - } - - return ( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); -} - -static void shift_rows( uint8_t *s ) -{ - uint8_t temp; - masked_state_t *state = (masked_state_t *)s; - // Rotate first row 1 columns to left - temp = (*state)[0][1]; - (*state)[0][1] = (*state)[1][1]; - (*state)[1][1] = (*state)[2][1]; - (*state)[2][1] = (*state)[3][1]; - (*state)[3][1] = temp; - - // Rotate second row 2 columns to left - temp = (*state)[0][2]; - (*state)[0][2] = (*state)[2][2]; - (*state)[2][2] = temp; - - temp = (*state)[1][2]; - (*state)[1][2] = (*state)[3][2]; - (*state)[3][2] = temp; - - // Rotate third row 3 columns to left - temp = (*state)[0][3]; - (*state)[0][3] = (*state)[3][3]; - (*state)[3][3] = (*state)[2][3]; - (*state)[2][3] = (*state)[1][3]; - (*state)[1][3] = temp; -} - -#define mul_02( num ) ( ( num << 1 ) ^ ( 0x11b & - ( num >> 7 ) ) ) -#define mul_03( num ) ( mul_02( num ) ^ num ) - -static void calc_mix_colmn_mask( uint32_t mask[10] ) -{ - mask[6] = mul_02( mask[0] ) ^ mul_03( mask[1] ) ^ mask[2] ^ mask[3]; - mask[7] = mask[0] ^ mul_02( mask[1] ) ^ mul_03( mask[2] ) ^ mask[3]; - mask[8] = mask[0] ^ mask[1] ^ mul_02( mask[2] ) ^ mul_03( mask[3] ); - mask[9] = mul_03( mask[0] ) ^ mask[1] ^ mask[2] ^ mul_02( mask[3] ); -} - -//Calculate the the invSbox to change from Mask m to Mask m' -static int calc_sbox_masked( uint32_t mask[10], uint8_t sbox_masked[256] ) -{ - volatile unsigned int i = 0; - - for ( i = 0; i < 256; i++ ) - { - sbox_masked[i ^ mask[4]] = FSb[i] ^ mask[5]; - } - if ( i == 256 ) - { - return 0; - } - - return ( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); -} - -static int remask( uint32_t *data, uint32_t m1, uint32_t m2, - uint32_t m3, uint32_t m4, uint32_t m5, - uint32_t m6, uint32_t m7, uint32_t m8 ) -{ - volatile unsigned int i = 0; - - for ( i = 0; i < 4; i++ ) - { - data[i] = data[i] ^ ( ( m1 ^ m5 ) ); - data[i] = data[i] ^ ( ( m2 ^ m6 ) << 8 ); - data[i] = data[i] ^ ( ( m3 ^ m7 ) << 16 ); - data[i] = data[i] ^ ( ( m4 ^ m8 ) << 24 ); - } - - if ( i == 4 ) - { - return 0; - } - - return ( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); -} - -#define MASK_INIT_CONTROL 19 - -static int init_masking_encrypt( const uint8_t *rk, uint8_t *rk_masked, - uint32_t mask[10], uint8_t sbox_masked[256] ) -{ - volatile int flow_control = 0; - unsigned int i = 0; - - mbedtls_platform_memcpy( rk_masked, rk, - MBEDTLS_AES_128_EXPANDED_KEY_SIZE_IN_WORDS * 4 ); - - //Randomly generate the masks: m1 m2 m3 m4 m m' - for ( i = 0; i < 6; i++ ) - { - mask[i] = mbedtls_platform_random_in_range( 0xFF ); - flow_control++; - } - - //Calculate m1',m2',m3',m4' - calc_mix_colmn_mask( mask ); - flow_control++; - - //Calculate the masked Sbox - if ( calc_sbox_masked( mask, sbox_masked ) == 0 ) - { - flow_control++; - } - - //Init masked key - if ( remask( (uint32_t *)&rk_masked[(Nr * Nb * 4)], 0, 0, 0, 0, - mask[5], mask[5], mask[5], mask[5]) == 0 ) - { - flow_control++; - } - - // Mask change from M1',M2',M3',M4' to M - for ( i = 0; i < Nr; i++ ) - { - if ( remask( (uint32_t *)&rk_masked[( i * Nb * 4 )], mask[6], - mask[7], mask[8], mask[9], mask[4], mask[4], mask[4], mask[4]) == 0 ) - { - flow_control++; - } - } - - if ( flow_control == MASK_INIT_CONTROL ) - { - mbedtls_platform_random_delay(); - if (flow_control == MASK_INIT_CONTROL) - { - return MASK_INIT_CONTROL; - } - } - - return ( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); -} - -static int add_rk_masked( uint32_t round, uint32_t *data, - const uint32_t * rk_masked ) -{ - volatile unsigned int i; - unsigned int offset = round * 4; - - for ( i = 0; i < 4; i++ ) - { - data[i] ^= rk_masked[offset + i]; - } - - if ( i == 4 ) - { - return 0; - } - return ( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); -} - -static int aes_masked_round( uint32_t *data, uint32_t *key, uint32_t round, - uint32_t mask[10], uint8_t sbox_masked[256] ) -{ - volatile uint32_t flow_control = 0; - -// Mask changes from M to M' - if ( sub_bytes_masked( data, sbox_masked ) == 0 ) - { - flow_control++; - } - - //No impact on mask - shift_rows((uint8_t *)data); - - //Change mask from M' to - // M1 for first row - // M2 for second row - // M3 for third row - // M4 for fourth row - if ( remask( data, mask[0], mask[1], mask[2], mask[3], - mask[5], mask[5], mask[5], mask[5]) == 0 ) - { - flow_control++; - } - - // Masks change from M1,M2,M3,M4 to M1',M2',M3',M4' - if ( mix_columns( (uint8_t *)data ) == 0 ) - { - flow_control++; - } - - // Add the First round key to the state before starting the rounds. - // Masks change from M1',M2',M3',M4' to M - if ( add_rk_masked( round, data, key ) == 0 ) - { - flow_control++; - } - - if ( flow_control == 4 ) - { - return 0; - } - - return ( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); -} - -static int aes_masked_round_final( uint32_t *data, uint32_t *key, - uint8_t sbox_masked[256] ) -{ - volatile uint32_t flow_control = 0; - - if ( sub_bytes_masked(data, sbox_masked) == 0 ) - { - flow_control++; - } - - shift_rows( (uint8_t *)data ); - - // Mask are removed by the last addroundkey - // From M' to 0 - if( add_rk_masked( Nr, data, key ) == 0 ) - { - flow_control++; - } - - if ( flow_control == 2 ) - { - return 0; - } - - return ( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); -} - -//2 comes from initial data remask of real and fake data -#define MASKING_FLOW_CONTORL ( MASK_INIT_CONTROL + 2 ) - -#else // end of MBEDTLS_AES_128_BIT_MASKED - -#define MASKING_FLOW_CONTORL 0 - -static uint32_t *aes_fround( uint32_t *R, - uint32_t *X0, uint32_t *X1, uint32_t *X2, uint32_t *X3, - uint32_t Y0, uint32_t Y1, uint32_t Y2, uint32_t Y3 ) -{ - *X0 = *R++ ^ AES_FT0( ( Y0 ) & 0xFF ) ^ - AES_FT1( ( Y1 >> 8 ) & 0xFF ) ^ - AES_FT2( ( Y2 >> 16 ) & 0xFF ) ^ - AES_FT3( ( Y3 >> 24 ) & 0xFF ); - - *X1 = *R++ ^ AES_FT0( ( Y1 ) & 0xFF ) ^ - AES_FT1( ( Y2 >> 8 ) & 0xFF ) ^ - AES_FT2( ( Y3 >> 16 ) & 0xFF ) ^ - AES_FT3( ( Y0 >> 24 ) & 0xFF ); - - *X2 = *R++ ^ AES_FT0( ( Y2 ) & 0xFF ) ^ - AES_FT1( ( Y3 >> 8 ) & 0xFF ) ^ - AES_FT2( ( Y0 >> 16 ) & 0xFF ) ^ - AES_FT3( ( Y1 >> 24 ) & 0xFF ); - - *X3 = *R++ ^ AES_FT0( ( Y3 ) & 0xFF ) ^ - AES_FT1( ( Y0 >> 8 ) & 0xFF ) ^ - AES_FT2( ( Y1 >> 16 ) & 0xFF ) ^ - AES_FT3( ( Y2 >> 24 ) & 0xFF ); - - return R; -} - - -static void aes_fround_final( uint32_t *R, - uint32_t *X0, uint32_t *X1, uint32_t *X2, uint32_t *X3, - uint32_t Y0, uint32_t Y1, uint32_t Y2, uint32_t Y3 ) -{ - - *X0 = *R++ ^ ( (uint32_t) FSb[ ( (Y0) ) & 0xFF ] ) ^ - ( (uint32_t) FSb[ ( (Y1) >> 8 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) FSb[ ( (Y2) >> 16 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) FSb[ ( (Y3) >> 24 ) & 0xFF ] << 24 ); - - *X1 = *R++ ^ ( (uint32_t) FSb[ ( (Y1) ) & 0xFF ] ) ^ - ( (uint32_t) FSb[ ( (Y2) >> 8 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) FSb[ ( (Y3) >> 16 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) FSb[ ( (Y0) >> 24 ) & 0xFF ] << 24 ); - - *X2 = *R++ ^ ( (uint32_t) FSb[ ( (Y2) ) & 0xFF ] ) ^ - ( (uint32_t) FSb[ ( (Y3) >> 8 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) FSb[ ( (Y0) >> 16 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) FSb[ ( (Y1) >> 24 ) & 0xFF ] << 24 ); - - *X3 = *R++ ^ ( (uint32_t) FSb[ ( (Y3) ) & 0xFF ] ) ^ - ( (uint32_t) FSb[ ( (Y0) >> 8 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) FSb[ ( (Y1) >> 16 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) FSb[ ( (Y2) >> 24 ) & 0xFF ] << 24 ); -} -#endif // MBEDTLS_AES_128_BIT_MASKED - - -int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx, - const unsigned char input[16], - unsigned char output[16] ) -{ - int i, tindex, offset, stop_mark, dummy_rounds; - aes_r_data_t aes_data_real; // real data - aes_r_data_t aes_data_fake; // fake data - aes_r_data_t *aes_data_ptr; // pointer to real or fake data - aes_r_data_t *aes_data_table[2] = {0}; // pointers to real and fake data - int round_ctrl_table_len = ctx->nr + 2 + AES_SCA_CM_ROUNDS; - volatile int flow_control = 0; - // control bytes for AES calculation rounds, - // reserve based on max rounds + dummy rounds + 2 (for initial key addition) - uint8_t round_ctrl_table[( 14 + AES_SCA_CM_ROUNDS + 2 )]; - -#if defined MBEDTLS_AES_128_BIT_MASKED - uint32_t rk_masked[MBEDTLS_AES_128_EXPANDED_KEY_SIZE_IN_WORDS]; - uint8_t sbox_masked[256]; - uint32_t mask[10]; -#endif - -#if defined(MBEDTLS_VALIDATE_AES_KEYS_INTEGRITY) - unsigned key_bytes = 0; - uint32_t check_hash = 0; - switch( ctx->nr ) - { - case 10: key_bytes = 16; break; -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) - case 12: key_bytes = 24; break; - case 14: key_bytes = 32; break; -#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */ - default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH ); - } - check_hash = mbedtls_hash( ctx->rk, key_bytes ); -#endif - -#if defined (MBEDTLS_AES_128_BIT_MASKED) - /* Flow control should be MASK_INIT_CONTROL and it will be checked as - a part last flow control verification */ - flow_control = init_masking_encrypt( (uint8_t *)ctx->rk, - (uint8_t *)rk_masked, mask, sbox_masked ); - - aes_data_real.rk_ptr = &rk_masked[0]; -#else - aes_data_real.rk_ptr = ctx->rk; -#endif - - aes_data_fake.rk_ptr = ctx->frk; - - aes_data_table[0] = &aes_data_real; - aes_data_table[1] = &aes_data_fake; - - // Get AES calculation control bytes - dummy_rounds = aes_sca_cm_data_randomize( round_ctrl_table, - round_ctrl_table_len ); - flow_control += dummy_rounds; - - // SCA countermeasure, safely clear the aes_data_real.xy_values - mbedtls_platform_memset( aes_data_real.xy_values, 0, 16 ); - - // SCA countermeasure, randomize secret data location by initializing it in - // a random order and writing randomized fake data between the real data - // writes. - offset = mbedtls_platform_random_in_range( 4 ); - i = offset; - do - { - GET_UINT32_LE( aes_data_real.xy_values[i], input, ( i * 4 ) ); - aes_data_fake.xy_values[i] = mbedtls_platform_random_uint32(); - flow_control++; - } while( ( i = ( i + 1 ) % 4 ) != offset ); - -#if defined (MBEDTLS_AES_128_BIT_MASKED) - //Plain text masked with m1',m2',m3',m4' - if (remask( &aes_data_real.xy_values[0], mask[6], - mask[7], mask[8], mask[9], 0, 0, 0, 0) == 0 ) - { - flow_control++; - } - - if (remask( &aes_data_fake.xy_values[0], mask[6], - mask[7], mask[8], mask[9], 0, 0, 0, 0) == 0 ) - { - flow_control++; - } -#endif - - tindex = 0; - do - { - // Get pointer to the real or fake data - aes_data_ptr = aes_data_table[round_ctrl_table[tindex] >> 4]; - stop_mark = round_ctrl_table[tindex] & 0x03; - - // initial round key addition -#if defined (MBEDTLS_AES_128_BIT_MASKED) - if ( add_rk_masked( 0, &aes_data_ptr->xy_values[0], - aes_data_ptr->rk_ptr ) == 0 ) - { - flow_control++; - } - aes_data_ptr->round = 1; -#else - for( i = 0; i < 4; i++ ) - { - aes_data_ptr->xy_values[i] ^= *aes_data_ptr->rk_ptr++; - } - flow_control++; -#endif - - tindex++; - } while( stop_mark == 0 ); - - // Calculate AES rounds (9, 11 or 13 rounds) + dummy rounds - do - { - // Get pointer to the real or fake data - aes_data_ptr = aes_data_table[round_ctrl_table[tindex] >> 4]; - offset = round_ctrl_table[tindex] & 0x04; - stop_mark = round_ctrl_table[tindex] & 0x03; -#if defined (MBEDTLS_AES_128_BIT_MASKED) - if ( aes_masked_round( &aes_data_ptr->xy_values[0], - aes_data_ptr->rk_ptr, - aes_data_ptr->round, mask, sbox_masked ) == 0 ) - { - flow_control++; - } - aes_data_ptr->round ++; -#else - aes_data_ptr->rk_ptr = aes_fround( aes_data_ptr->rk_ptr, - &aes_data_ptr->xy_values[0 + offset], - &aes_data_ptr->xy_values[1 + offset], - &aes_data_ptr->xy_values[2 + offset], - &aes_data_ptr->xy_values[3 + offset], - aes_data_ptr->xy_values[4 - offset], - aes_data_ptr->xy_values[5 - offset], - aes_data_ptr->xy_values[6 - offset], - aes_data_ptr->xy_values[7 - offset] ); - flow_control++; -#endif - tindex++; - - } while( stop_mark == 0 ); - - // Calculate final AES round + dummy rounds - do - { - aes_data_ptr = aes_data_table[round_ctrl_table[tindex] >> 4]; - stop_mark = round_ctrl_table[tindex] & 0x03; -#if defined (MBEDTLS_AES_128_BIT_MASKED) - if ( aes_masked_round_final( &aes_data_ptr->xy_values[0], - aes_data_ptr->rk_ptr, sbox_masked ) == 0 ) - { - flow_control++; - } -#else - aes_fround_final( aes_data_ptr->rk_ptr, - &aes_data_ptr->xy_values[0], - &aes_data_ptr->xy_values[1], - &aes_data_ptr->xy_values[2], - &aes_data_ptr->xy_values[3], - aes_data_ptr->xy_values[4], - aes_data_ptr->xy_values[5], - aes_data_ptr->xy_values[6], - aes_data_ptr->xy_values[7] ); - flow_control++; -#endif - tindex++; - } while( stop_mark == 0 ); - - // SCA countermeasure, safely clear the output - mbedtls_platform_memset( output, 0, 16 ); - - // SCA countermeasure, randomize secret data location by writing to it in - // a random order. - offset = mbedtls_platform_random_in_range( 4 ); - i = offset; - do - { - PUT_UINT32_LE( aes_data_real.xy_values[i], output, ( i * 4 ) ); - flow_control++; - } while( ( i = ( i + 1 ) % 4 ) != offset ); - -#if defined (MBEDTLS_AES_128_BIT_MASKED) - mbedtls_platform_memset( rk_masked, 0, sizeof(rk_masked) ); -#endif - /* Double negation is used to silence an "extraneous parentheses" warning */ - if( ! ( flow_control != tindex + dummy_rounds + MASKING_FLOW_CONTORL + 8 ) -#if defined(MBEDTLS_VALIDATE_AES_KEYS_INTEGRITY) - && check_hash == ctx->hash -#endif - ) - { -#if defined(MBEDTLS_VALIDATE_AES_KEYS_INTEGRITY) - mbedtls_platform_random_delay(); - if( mbedtls_hash( ctx->rk, key_bytes ) == ctx->hash ) -#endif - { - return 0; - } - } - - // Clear the output in case of a FI - mbedtls_platform_memset( output, 0, 16 ); - mbedtls_platform_memset( (uint8_t*)&aes_data_real, 0, - sizeof(aes_data_real) ); - mbedtls_platform_memset ( aes_data_table, 0, sizeof(aes_data_table) ); -#if defined (MBEDTLS_AES_128_BIT_MASKED) - //Clear masked key, masked sbox and mask in case of a FI - mbedtls_platform_memset( rk_masked, 0, sizeof(rk_masked) ); - mbedtls_platform_memset( mask, 0, sizeof(mask) ); - mbedtls_platform_memset( sbox_masked, 0, sizeof(sbox_masked) ); -#endif - return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); -} - -#else /* MBEDTLS_AES_SCA_COUNTERMEASURES */ - -#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ - do \ - { \ - (X0) = *RK++ ^ AES_FT0( ( (Y0) ) & 0xFF ) ^ \ - AES_FT1( ( (Y1) >> 8 ) & 0xFF ) ^ \ - AES_FT2( ( (Y2) >> 16 ) & 0xFF ) ^ \ - AES_FT3( ( (Y3) >> 24 ) & 0xFF ); \ - \ - (X1) = *RK++ ^ AES_FT0( ( (Y1) ) & 0xFF ) ^ \ - AES_FT1( ( (Y2) >> 8 ) & 0xFF ) ^ \ - AES_FT2( ( (Y3) >> 16 ) & 0xFF ) ^ \ - AES_FT3( ( (Y0) >> 24 ) & 0xFF ); \ - \ - (X2) = *RK++ ^ AES_FT0( ( (Y2) ) & 0xFF ) ^ \ - AES_FT1( ( (Y3) >> 8 ) & 0xFF ) ^ \ - AES_FT2( ( (Y0) >> 16 ) & 0xFF ) ^ \ - AES_FT3( ( (Y1) >> 24 ) & 0xFF ); \ - \ - (X3) = *RK++ ^ AES_FT0( ( (Y3) ) & 0xFF ) ^ \ - AES_FT1( ( (Y0) >> 8 ) & 0xFF ) ^ \ - AES_FT2( ( (Y1) >> 16 ) & 0xFF ) ^ \ - AES_FT3( ( (Y2) >> 24 ) & 0xFF ); \ - } while( 0 ) - int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx, const unsigned char input[16], unsigned char output[16] ) @@ -1698,21 +761,8 @@ int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx, PUT_UINT32_LE( X2, output, 8 ); PUT_UINT32_LE( X3, output, 12 ); - mbedtls_platform_zeroize( &X0, sizeof( X0 ) ); - mbedtls_platform_zeroize( &X1, sizeof( X1 ) ); - mbedtls_platform_zeroize( &X2, sizeof( X2 ) ); - mbedtls_platform_zeroize( &X3, sizeof( X3 ) ); - - mbedtls_platform_zeroize( &Y0, sizeof( Y0 ) ); - mbedtls_platform_zeroize( &Y1, sizeof( Y1 ) ); - mbedtls_platform_zeroize( &Y2, sizeof( Y2 ) ); - mbedtls_platform_zeroize( &Y3, sizeof( Y3 ) ); - - mbedtls_platform_zeroize( &RK, sizeof( RK ) ); - return( 0 ); } -#endif /* MBEDTLS_AES_SCA_COUNTERMEASURES */ #endif /* !MBEDTLS_AES_ENCRYPT_ALT */ #if !defined(MBEDTLS_DEPRECATED_REMOVED) @@ -1727,233 +777,7 @@ void mbedtls_aes_encrypt( mbedtls_aes_context *ctx, /* * AES-ECB block decryption */ - #if !defined(MBEDTLS_AES_DECRYPT_ALT) -#if !defined(MBEDTLS_AES_ONLY_ENCRYPT) - -#if defined(MBEDTLS_AES_SCA_COUNTERMEASURES) -static uint32_t *aes_rround( uint32_t *R, - uint32_t *X0, uint32_t *X1, uint32_t *X2, uint32_t *X3, - uint32_t Y0, uint32_t Y1, uint32_t Y2, uint32_t Y3 ) -{ - *X0 = *R++ ^ AES_RT0( ( Y0 ) & 0xFF ) ^ - AES_RT1( ( Y3 >> 8 ) & 0xFF ) ^ - AES_RT2( ( Y2 >> 16 ) & 0xFF ) ^ - AES_RT3( ( Y1 >> 24 ) & 0xFF ); - - *X1 = *R++ ^ AES_RT0( ( Y1 ) & 0xFF ) ^ - AES_RT1( ( Y0 >> 8 ) & 0xFF ) ^ - AES_RT2( ( Y3 >> 16 ) & 0xFF ) ^ - AES_RT3( ( Y2 >> 24 ) & 0xFF ); - - *X2 = *R++ ^ AES_RT0( ( Y2 ) & 0xFF ) ^ - AES_RT1( ( Y1 >> 8 ) & 0xFF ) ^ - AES_RT2( ( Y0 >> 16 ) & 0xFF ) ^ - AES_RT3( ( Y3 >> 24 ) & 0xFF ); - - *X3 = *R++ ^ AES_RT0( ( Y3 ) & 0xFF ) ^ - AES_RT1( ( Y2 >> 8 ) & 0xFF ) ^ - AES_RT2( ( Y1 >> 16 ) & 0xFF ) ^ - AES_RT3( ( Y0 >> 24 ) & 0xFF ); - return R; -} - -static void aes_rround_final( uint32_t *R, - uint32_t *X0, uint32_t *X1, uint32_t *X2, uint32_t *X3, - uint32_t Y0, uint32_t Y1, uint32_t Y2, uint32_t Y3 ) -{ - *X0 = *R++ ^ ( (uint32_t) RSb[ ( (Y0) ) & 0xFF ] ) ^ - ( (uint32_t) RSb[ ( (Y3) >> 8 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) RSb[ ( (Y2) >> 16 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) RSb[ ( (Y1) >> 24 ) & 0xFF ] << 24 ); - - *X1 = *R++ ^ ( (uint32_t) RSb[ ( (Y1) ) & 0xFF ] ) ^ - ( (uint32_t) RSb[ ( (Y0) >> 8 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) RSb[ ( (Y3) >> 16 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) RSb[ ( (Y2) >> 24 ) & 0xFF ] << 24 ); - - *X2 = *R++ ^ ( (uint32_t) RSb[ ( (Y2) ) & 0xFF ] ) ^ - ( (uint32_t) RSb[ ( (Y1) >> 8 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) RSb[ ( (Y0) >> 16 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) RSb[ ( (Y3) >> 24 ) & 0xFF ] << 24 ); - - *X3 = *R++ ^ ( (uint32_t) RSb[ ( (Y3) ) & 0xFF ] ) ^ - ( (uint32_t) RSb[ ( (Y2) >> 8 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) RSb[ ( (Y1) >> 16 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) RSb[ ( (Y0) >> 24 ) & 0xFF ] << 24 ); -} - -int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx, - const unsigned char input[16], - unsigned char output[16] ) -{ - int i, tindex, offset, stop_mark, dummy_rounds; - aes_r_data_t aes_data_real; // real data - aes_r_data_t aes_data_fake; // fake data - aes_r_data_t *aes_data_ptr; // pointer to real or fake data - aes_r_data_t *aes_data_table[2]; // pointers to real and fake data - int round_ctrl_table_len = ctx->nr + 2 + AES_SCA_CM_ROUNDS; - volatile int flow_control; - // control bytes for AES calculation rounds, - // reserve based on max rounds + dummy rounds + 2 (for initial key addition) - uint8_t round_ctrl_table[( 14 + AES_SCA_CM_ROUNDS + 2 )]; - -#if defined(MBEDTLS_VALIDATE_AES_KEYS_INTEGRITY) - unsigned key_bytes = 0; - uint32_t check_hash = 0; - switch( ctx->nr ) - { - case 10: key_bytes = 16; break; -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) - case 12: key_bytes = 24; break; - case 14: key_bytes = 32; break; -#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */ - default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH ); - } - check_hash = mbedtls_hash( ctx->rk, key_bytes ); -#endif - - aes_data_real.rk_ptr = ctx->rk; - aes_data_fake.rk_ptr = ctx->frk; - - aes_data_table[0] = &aes_data_real; - aes_data_table[1] = &aes_data_fake; - - // Get AES calculation control bytes - dummy_rounds = aes_sca_cm_data_randomize( round_ctrl_table, - round_ctrl_table_len ); - flow_control = dummy_rounds; - - // SCA countermeasure, safely clear the aes_data_real.xy_values - mbedtls_platform_memset( aes_data_real.xy_values, 0, 16 ); - - // SCA countermeasure, randomize secret data location by initializing it in - // a random order and writing randomized fake data between the real data - // writes. - offset = mbedtls_platform_random_in_range( 4 ); - i = offset; - do - { - GET_UINT32_LE( aes_data_real.xy_values[i], input, ( i * 4 ) ); - aes_data_fake.xy_values[i] = mbedtls_platform_random_in_range( 0xffffffff ); - flow_control++; - } while( ( i = ( i + 1 ) % 4 ) != offset ); - - tindex = 0; - do - { - // Get pointer to the real or fake data - aes_data_ptr = aes_data_table[round_ctrl_table[tindex] >> 4]; - stop_mark = round_ctrl_table[tindex] & 0x03; - - // initial round key addition - for( i = 0; i < 4; i++ ) - { - aes_data_ptr->xy_values[i] ^= *aes_data_ptr->rk_ptr++; - } - tindex++; - flow_control++; - } while( stop_mark == 0 ); - - // Calculate AES rounds (9, 11 or 13 rounds) + dummy rounds - do - { - // Get pointer to the real or fake data - aes_data_ptr = aes_data_table[round_ctrl_table[tindex] >> 4]; - offset = round_ctrl_table[tindex] & 0x04; - stop_mark = round_ctrl_table[tindex] & 0x03; - - aes_data_ptr->rk_ptr = aes_rround( aes_data_ptr->rk_ptr, - &aes_data_ptr->xy_values[0 + offset], - &aes_data_ptr->xy_values[1 + offset], - &aes_data_ptr->xy_values[2 + offset], - &aes_data_ptr->xy_values[3 + offset], - aes_data_ptr->xy_values[4 - offset], - aes_data_ptr->xy_values[5 - offset], - aes_data_ptr->xy_values[6 - offset], - aes_data_ptr->xy_values[7 - offset] ); - tindex++; - flow_control++; - } while( stop_mark == 0 ); - - // Calculate final AES round + dummy rounds - do - { - aes_data_ptr = aes_data_table[round_ctrl_table[tindex] >> 4]; - stop_mark = round_ctrl_table[tindex] & 0x03; - aes_rround_final( aes_data_ptr->rk_ptr, - &aes_data_ptr->xy_values[0], - &aes_data_ptr->xy_values[1], - &aes_data_ptr->xy_values[2], - &aes_data_ptr->xy_values[3], - aes_data_ptr->xy_values[4], - aes_data_ptr->xy_values[5], - aes_data_ptr->xy_values[6], - aes_data_ptr->xy_values[7] ); - flow_control++; - tindex++; - } while( stop_mark == 0 ); - - // SCA countermeasure, safely clear the output - mbedtls_platform_memset( output, 0, 16 ); - - // SCA countermeasure, randomize secret data location by writing to it in - // a random order. - offset = mbedtls_platform_random_in_range( 4 ); - i = offset; - do - { - PUT_UINT32_LE( aes_data_real.xy_values[i], output, ( i * 4 ) ); - flow_control++; - } while( ( i = ( i + 1 ) % 4 ) != offset ); - - /* Double negation is used to silence an "extraneous parentheses" warning */ - if( ! ( flow_control != tindex + dummy_rounds + 8 ) -#if defined(MBEDTLS_VALIDATE_AES_KEYS_INTEGRITY) - && check_hash == ctx->hash -#endif - ) - { -#if defined(MBEDTLS_VALIDATE_AES_KEYS_INTEGRITY) - mbedtls_platform_random_delay(); - if( mbedtls_hash( ctx->rk, key_bytes ) == ctx->hash ) -#endif - { - return 0; - } - } - - // Clear the output in case of a FI - mbedtls_platform_memset( output, 0, 16 ); - return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); -} - -#else /* MBEDTLS_AES_SCA_COUNTERMEASURES */ - -#define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ - do \ - { \ - (X0) = *RK++ ^ AES_RT0( ( (Y0) ) & 0xFF ) ^ \ - AES_RT1( ( (Y3) >> 8 ) & 0xFF ) ^ \ - AES_RT2( ( (Y2) >> 16 ) & 0xFF ) ^ \ - AES_RT3( ( (Y1) >> 24 ) & 0xFF ); \ - \ - (X1) = *RK++ ^ AES_RT0( ( (Y1) ) & 0xFF ) ^ \ - AES_RT1( ( (Y0) >> 8 ) & 0xFF ) ^ \ - AES_RT2( ( (Y3) >> 16 ) & 0xFF ) ^ \ - AES_RT3( ( (Y2) >> 24 ) & 0xFF ); \ - \ - (X2) = *RK++ ^ AES_RT0( ( (Y2) ) & 0xFF ) ^ \ - AES_RT1( ( (Y1) >> 8 ) & 0xFF ) ^ \ - AES_RT2( ( (Y0) >> 16 ) & 0xFF ) ^ \ - AES_RT3( ( (Y3) >> 24 ) & 0xFF ); \ - \ - (X3) = *RK++ ^ AES_RT0( ( (Y3) ) & 0xFF ) ^ \ - AES_RT1( ( (Y2) >> 8 ) & 0xFF ) ^ \ - AES_RT2( ( (Y1) >> 16 ) & 0xFF ) ^ \ - AES_RT3( ( (Y0) >> 24 ) & 0xFF ); \ - } while( 0 ) - int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx, const unsigned char input[16], unsigned char output[16] ) @@ -2005,23 +829,8 @@ int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx, PUT_UINT32_LE( X2, output, 8 ); PUT_UINT32_LE( X3, output, 12 ); - mbedtls_platform_zeroize( &X0, sizeof( X0 ) ); - mbedtls_platform_zeroize( &X1, sizeof( X1 ) ); - mbedtls_platform_zeroize( &X2, sizeof( X2 ) ); - mbedtls_platform_zeroize( &X3, sizeof( X3 ) ); - - mbedtls_platform_zeroize( &Y0, sizeof( Y0 ) ); - mbedtls_platform_zeroize( &Y1, sizeof( Y1 ) ); - mbedtls_platform_zeroize( &Y2, sizeof( Y2 ) ); - mbedtls_platform_zeroize( &Y3, sizeof( Y3 ) ); - - mbedtls_platform_zeroize( &RK, sizeof( RK ) ); - return( 0 ); } -#endif /* !MBEDTLS_AES_ONLY_ENCRYPT */ -#endif /* MBEDTLS_AES_SCA_COUNTERMEASURES */ - #endif /* !MBEDTLS_AES_DECRYPT_ALT */ #if !defined(MBEDTLS_DEPRECATED_REMOVED) @@ -2029,13 +838,7 @@ void mbedtls_aes_decrypt( mbedtls_aes_context *ctx, const unsigned char input[16], unsigned char output[16] ) { -#if defined(MBEDTLS_AES_ONLY_ENCRYPT) - (void) ctx; - (void) input; - (void) output; -#else /* MBEDTLS_AES_ONLY_ENCRYPT */ mbedtls_internal_aes_decrypt( ctx, input, output ); -#endif /* MBEDTLS_AES_ONLY_ENCRYPT */ } #endif /* !MBEDTLS_DEPRECATED_REMOVED */ @@ -2043,17 +846,10 @@ void mbedtls_aes_decrypt( mbedtls_aes_context *ctx, * AES-ECB block encryption/decryption */ int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx, - int mode, - const unsigned char input[16], - unsigned char output[16] ) + int mode, + const unsigned char input[16], + unsigned char output[16] ) { - AES_VALIDATE_RET( ctx != NULL ); - AES_VALIDATE_RET( input != NULL ); - AES_VALIDATE_RET( output != NULL ); - AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT || - mode == MBEDTLS_AES_DECRYPT ); - (void) mode; - #if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64) if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) ) return( mbedtls_aesni_crypt_ecb( ctx, mode, input, output ) ); @@ -2071,15 +867,10 @@ int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx, } #endif -#if defined(MBEDTLS_AES_ONLY_ENCRYPT) - return( mbedtls_internal_aes_encrypt( ctx, input, output ) ); -#else /* MBEDTLS_AES_ONLY_ENCRYPT */ - if( mode == MBEDTLS_AES_ENCRYPT ) return( mbedtls_internal_aes_encrypt( ctx, input, output ) ); else return( mbedtls_internal_aes_decrypt( ctx, input, output ) ); -#endif /* MBEDTLS_AES_ONLY_ENCRYPT */ } #if defined(MBEDTLS_CIPHER_MODE_CBC) @@ -2096,13 +887,6 @@ int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx, int i; unsigned char temp[16]; - AES_VALIDATE_RET( ctx != NULL ); - AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT || - mode == MBEDTLS_AES_DECRYPT ); - AES_VALIDATE_RET( iv != NULL ); - AES_VALIDATE_RET( input != NULL ); - AES_VALIDATE_RET( output != NULL ); - if( length % 16 ) return( MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH ); @@ -2122,13 +906,13 @@ int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx, { while( length > 0 ) { - mbedtls_platform_memcpy( temp, input, 16 ); + memcpy( temp, input, 16 ); mbedtls_aes_crypt_ecb( ctx, mode, input, output ); for( i = 0; i < 16; i++ ) output[i] = (unsigned char)( output[i] ^ iv[i] ); - mbedtls_platform_memcpy( iv, temp, 16 ); + memcpy( iv, temp, 16 ); input += 16; output += 16; @@ -2143,7 +927,7 @@ int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx, output[i] = (unsigned char)( input[i] ^ iv[i] ); mbedtls_aes_crypt_ecb( ctx, mode, output, output ); - mbedtls_platform_memcpy( iv, output, 16 ); + memcpy( iv, output, 16 ); input += 16; output += 16; @@ -2155,172 +939,6 @@ int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx, } #endif /* MBEDTLS_CIPHER_MODE_CBC */ -#if defined(MBEDTLS_CIPHER_MODE_XTS) - -/* Endianess with 64 bits values */ -#ifndef GET_UINT64_LE -#define GET_UINT64_LE(n,b,i) \ -{ \ - (n) = ( (uint64_t) (b)[(i) + 7] << 56 ) \ - | ( (uint64_t) (b)[(i) + 6] << 48 ) \ - | ( (uint64_t) (b)[(i) + 5] << 40 ) \ - | ( (uint64_t) (b)[(i) + 4] << 32 ) \ - | ( (uint64_t) (b)[(i) + 3] << 24 ) \ - | ( (uint64_t) (b)[(i) + 2] << 16 ) \ - | ( (uint64_t) (b)[(i) + 1] << 8 ) \ - | ( (uint64_t) (b)[(i) ] ); \ -} -#endif - -#ifndef PUT_UINT64_LE -#define PUT_UINT64_LE(n,b,i) \ -{ \ - (b)[(i) + 7] = (unsigned char) ( (n) >> 56 ); \ - (b)[(i) + 6] = (unsigned char) ( (n) >> 48 ); \ - (b)[(i) + 5] = (unsigned char) ( (n) >> 40 ); \ - (b)[(i) + 4] = (unsigned char) ( (n) >> 32 ); \ - (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \ - (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \ - (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \ - (b)[(i) ] = (unsigned char) ( (n) ); \ -} -#endif - -typedef unsigned char mbedtls_be128[16]; - -/* - * GF(2^128) multiplication function - * - * This function multiplies a field element by x in the polynomial field - * representation. It uses 64-bit word operations to gain speed but compensates - * for machine endianess and hence works correctly on both big and little - * endian machines. - */ -static void mbedtls_gf128mul_x_ble( unsigned char r[16], - const unsigned char x[16] ) -{ - uint64_t a, b, ra, rb; - - GET_UINT64_LE( a, x, 0 ); - GET_UINT64_LE( b, x, 8 ); - - ra = ( a << 1 ) ^ 0x0087 >> ( 8 - ( ( b >> 63 ) << 3 ) ); - rb = ( a >> 63 ) | ( b << 1 ); - - PUT_UINT64_LE( ra, r, 0 ); - PUT_UINT64_LE( rb, r, 8 ); -} - -/* - * AES-XTS buffer encryption/decryption - */ -int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx, - int mode, - size_t length, - const unsigned char data_unit[16], - const unsigned char *input, - unsigned char *output ) -{ - int ret; - size_t blocks = length / 16; - size_t leftover = length % 16; - unsigned char tweak[16]; - unsigned char prev_tweak[16]; - unsigned char tmp[16]; - - AES_VALIDATE_RET( ctx != NULL ); - AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT || - mode == MBEDTLS_AES_DECRYPT ); - AES_VALIDATE_RET( data_unit != NULL ); - AES_VALIDATE_RET( input != NULL ); - AES_VALIDATE_RET( output != NULL ); - - /* Data units must be at least 16 bytes long. */ - if( length < 16 ) - return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH; - - /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */ - if( length > ( 1 << 20 ) * 16 ) - return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH; - - /* Compute the tweak. */ - ret = mbedtls_aes_crypt_ecb( &ctx->tweak, MBEDTLS_AES_ENCRYPT, - data_unit, tweak ); - if( ret != 0 ) - return( ret ); - - while( blocks-- ) - { - size_t i; - - if( leftover && ( mode == MBEDTLS_AES_DECRYPT ) && blocks == 0 ) - { - /* We are on the last block in a decrypt operation that has - * leftover bytes, so we need to use the next tweak for this block, - * and this tweak for the lefover bytes. Save the current tweak for - * the leftovers and then update the current tweak for use on this, - * the last full block. */ - mbedtls_platform_memcpy( prev_tweak, tweak, sizeof( tweak ) ); - mbedtls_gf128mul_x_ble( tweak, tweak ); - } - - for( i = 0; i < 16; i++ ) - tmp[i] = input[i] ^ tweak[i]; - - ret = mbedtls_aes_crypt_ecb( &ctx->crypt, mode, tmp, tmp ); - if( ret != 0 ) - return( ret ); - - for( i = 0; i < 16; i++ ) - output[i] = tmp[i] ^ tweak[i]; - - /* Update the tweak for the next block. */ - mbedtls_gf128mul_x_ble( tweak, tweak ); - - output += 16; - input += 16; - } - - if( leftover ) - { - /* If we are on the leftover bytes in a decrypt operation, we need to - * use the previous tweak for these bytes (as saved in prev_tweak). */ - unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak; - - /* We are now on the final part of the data unit, which doesn't divide - * evenly by 16. It's time for ciphertext stealing. */ - size_t i; - unsigned char *prev_output = output - 16; - - /* Copy ciphertext bytes from the previous block to our output for each - * byte of cyphertext we won't steal. At the same time, copy the - * remainder of the input for this final round (since the loop bounds - * are the same). */ - for( i = 0; i < leftover; i++ ) - { - output[i] = prev_output[i]; - tmp[i] = input[i] ^ t[i]; - } - - /* Copy ciphertext bytes from the previous block for input in this - * round. */ - for( ; i < 16; i++ ) - tmp[i] = prev_output[i] ^ t[i]; - - ret = mbedtls_aes_crypt_ecb( &ctx->crypt, mode, tmp, tmp ); - if( ret != 0 ) - return ret; - - /* Write the result back to the previous block, overriding the previous - * output we copied. */ - for( i = 0; i < 16; i++ ) - prev_output[i] = tmp[i] ^ t[i]; - } - - return( 0 ); -} -#endif /* MBEDTLS_CIPHER_MODE_XTS */ - #if defined(MBEDTLS_CIPHER_MODE_CFB) /* * AES-CFB128 buffer encryption/decryption @@ -2334,20 +952,7 @@ int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx, unsigned char *output ) { int c; - size_t n; - - AES_VALIDATE_RET( ctx != NULL ); - AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT || - mode == MBEDTLS_AES_DECRYPT ); - AES_VALIDATE_RET( iv_off != NULL ); - AES_VALIDATE_RET( iv != NULL ); - AES_VALIDATE_RET( input != NULL ); - AES_VALIDATE_RET( output != NULL ); - - n = *iv_off; - - if( n > 15 ) - return( MBEDTLS_ERR_AES_BAD_INPUT_DATA ); + size_t n = *iv_off; if( mode == MBEDTLS_AES_DECRYPT ) { @@ -2385,24 +990,18 @@ int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx, * AES-CFB8 buffer encryption/decryption */ int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx, - int mode, - size_t length, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output ) + int mode, + size_t length, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ) { unsigned char c; unsigned char ov[17]; - AES_VALIDATE_RET( ctx != NULL ); - AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT || - mode == MBEDTLS_AES_DECRYPT ); - AES_VALIDATE_RET( iv != NULL ); - AES_VALIDATE_RET( input != NULL ); - AES_VALIDATE_RET( output != NULL ); while( length-- ) { - mbedtls_platform_memcpy( ov, iv, 16 ); + memcpy( ov, iv, 16 ); mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv ); if( mode == MBEDTLS_AES_DECRYPT ) @@ -2413,57 +1012,12 @@ int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx, if( mode == MBEDTLS_AES_ENCRYPT ) ov[16] = c; - mbedtls_platform_memcpy( iv, ov + 1, 16 ); + memcpy( iv, ov + 1, 16 ); } return( 0 ); } -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_OFB) -/* - * AES-OFB (Output Feedback Mode) buffer encryption/decryption - */ -int mbedtls_aes_crypt_ofb( mbedtls_aes_context *ctx, - size_t length, - size_t *iv_off, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output ) -{ - int ret = 0; - size_t n; - - AES_VALIDATE_RET( ctx != NULL ); - AES_VALIDATE_RET( iv_off != NULL ); - AES_VALIDATE_RET( iv != NULL ); - AES_VALIDATE_RET( input != NULL ); - AES_VALIDATE_RET( output != NULL ); - - n = *iv_off; - - if( n > 15 ) - return( MBEDTLS_ERR_AES_BAD_INPUT_DATA ); - - while( length-- ) - { - if( n == 0 ) - { - ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv ); - if( ret != 0 ) - goto exit; - } - *output++ = *input++ ^ iv[n]; - - n = ( n + 1 ) & 0x0F; - } - - *iv_off = n; - -exit: - return( ret ); -} -#endif /* MBEDTLS_CIPHER_MODE_OFB */ +#endif /*MBEDTLS_CIPHER_MODE_CFB */ #if defined(MBEDTLS_CIPHER_MODE_CTR) /* @@ -2478,19 +1032,7 @@ int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx, unsigned char *output ) { int c, i; - size_t n; - - AES_VALIDATE_RET( ctx != NULL ); - AES_VALIDATE_RET( nc_off != NULL ); - AES_VALIDATE_RET( nonce_counter != NULL ); - AES_VALIDATE_RET( stream_block != NULL ); - AES_VALIDATE_RET( input != NULL ); - AES_VALIDATE_RET( output != NULL ); - - n = *nc_off; - - if( n > 0x0F ) - return( MBEDTLS_ERR_AES_BAD_INPUT_DATA ); + size_t n = *nc_off; while( length-- ) { @@ -2629,72 +1171,6 @@ static const unsigned char aes_test_cfb128_ct[3][64] = }; #endif /* MBEDTLS_CIPHER_MODE_CFB */ -#if defined(MBEDTLS_CIPHER_MODE_OFB) -/* - * AES-OFB test vectors from: - * - * https://csrc.nist.gov/publications/detail/sp/800-38a/final - */ -static const unsigned char aes_test_ofb_key[3][32] = -{ - { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, - 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }, - { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52, - 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5, - 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B }, - { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, - 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81, - 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, - 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 } -}; - -static const unsigned char aes_test_ofb_iv[16] = -{ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F -}; - -static const unsigned char aes_test_ofb_pt[64] = -{ - 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, - 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A, - 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C, - 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51, - 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11, - 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF, - 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17, - 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10 -}; - -static const unsigned char aes_test_ofb_ct[3][64] = -{ - { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20, - 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A, - 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03, - 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25, - 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6, - 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc, - 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78, - 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e }, - { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB, - 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74, - 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c, - 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01, - 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f, - 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2, - 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e, - 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a }, - { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B, - 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60, - 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a, - 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d, - 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed, - 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08, - 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8, - 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 } -}; -#endif /* MBEDTLS_CIPHER_MODE_OFB */ - #if defined(MBEDTLS_CIPHER_MODE_CTR) /* * AES-CTR test vectors from: @@ -2758,74 +1234,6 @@ static const int aes_test_ctr_len[3] = { 16, 32, 36 }; #endif /* MBEDTLS_CIPHER_MODE_CTR */ -#if defined(MBEDTLS_CIPHER_MODE_XTS) -/* - * AES-XTS test vectors from: - * - * IEEE P1619/D16 Annex B - * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf - * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf) - */ -static const unsigned char aes_test_xts_key[][32] = -{ - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, - 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 }, - { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, - 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0, - 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, - 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 }, -}; - -static const unsigned char aes_test_xts_pt32[][32] = -{ - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, - 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, - 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, - 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 }, - { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, - 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, - 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, - 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 }, -}; - -static const unsigned char aes_test_xts_ct32[][32] = -{ - { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec, - 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92, - 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85, - 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e }, - { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e, - 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b, - 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4, - 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 }, - { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a, - 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2, - 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53, - 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 }, -}; - -static const unsigned char aes_test_xts_data_unit[][16] = -{ - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, -}; - -#endif /* MBEDTLS_CIPHER_MODE_XTS */ - /* * Checkup routine */ @@ -2842,14 +1250,11 @@ int mbedtls_aes_self_test( int verbose ) #if defined(MBEDTLS_CIPHER_MODE_CBC) unsigned char prv[16]; #endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \ - defined(MBEDTLS_CIPHER_MODE_OFB) +#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) size_t offset; #endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS) - int len; -#endif #if defined(MBEDTLS_CIPHER_MODE_CTR) + int len; unsigned char nonce_counter[16]; unsigned char stream_block[16]; #endif @@ -2871,22 +1276,6 @@ int mbedtls_aes_self_test( int verbose ) mbedtls_printf( " AES-ECB-%3d (%s): ", keybits, ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); -#if defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) - if( keybits > 128 ) - { - mbedtls_printf( "skipped\n" ); - continue; - } -#endif /* MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */ - -#if defined(MBEDTLS_AES_ONLY_ENCRYPT) - if( mode == MBEDTLS_AES_DECRYPT ) - { - mbedtls_printf( "skipped\n" ); - continue; - } -#endif /* MBEDTLS_AES_ONLY_ENCRYPT */ - memset( buf, 0, 16 ); if( mode == MBEDTLS_AES_DECRYPT ) @@ -2905,7 +1294,7 @@ int mbedtls_aes_self_test( int verbose ) * there is an alternative underlying implementation i.e. when * MBEDTLS_AES_ALT is defined. */ - if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 ) + if( ret == MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE && keybits == 192 ) { mbedtls_printf( "skipped\n" ); continue; @@ -2949,22 +1338,6 @@ int mbedtls_aes_self_test( int verbose ) mbedtls_printf( " AES-CBC-%3d (%s): ", keybits, ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); -#if defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) - if( keybits > 128 ) - { - mbedtls_printf( "skipped\n" ); - continue; - } -#endif - -#if defined(MBEDTLS_AES_ONLY_ENCRYPT) - if( mode == MBEDTLS_AES_DECRYPT ) - { - mbedtls_printf( "skipped\n" ); - continue; - } -#endif /* MBEDTLS_AES_ONLY_ENCRYPT */ - memset( iv , 0, 16 ); memset( prv, 0, 16 ); memset( buf, 0, 16 ); @@ -2985,7 +1358,7 @@ int mbedtls_aes_self_test( int verbose ) * there is an alternative underlying implementation i.e. when * MBEDTLS_AES_ALT is defined. */ - if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 ) + if( ret == MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE && keybits == 192 ) { mbedtls_printf( "skipped\n" ); continue; @@ -3040,22 +1413,6 @@ int mbedtls_aes_self_test( int verbose ) mbedtls_printf( " AES-CFB128-%3d (%s): ", keybits, ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); -#if defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) - if( keybits > 128 ) - { - mbedtls_printf( "skipped\n" ); - continue; - } -#endif - -#if defined(MBEDTLS_AES_ONLY_ENCRYPT) - if( mode == MBEDTLS_AES_DECRYPT ) - { - mbedtls_printf( "skipped\n" ); - continue; - } -#endif /* MBEDTLS_AES_ONLY_ENCRYPT */ - memcpy( iv, aes_test_cfb128_iv, 16 ); memcpy( key, aes_test_cfb128_key[u], keybits / 8 ); @@ -3066,7 +1423,7 @@ int mbedtls_aes_self_test( int verbose ) * there is an alternative underlying implementation i.e. when * MBEDTLS_AES_ALT is defined. */ - if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 ) + if( ret == MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE && keybits == 192 ) { mbedtls_printf( "skipped\n" ); continue; @@ -3105,85 +1462,6 @@ int mbedtls_aes_self_test( int verbose ) mbedtls_printf( "\n" ); #endif /* MBEDTLS_CIPHER_MODE_CFB */ -#if defined(MBEDTLS_CIPHER_MODE_OFB) - /* - * OFB mode - */ - for( i = 0; i < 6; i++ ) - { - u = i >> 1; - keybits = 128 + u * 64; - mode = i & 1; - - if( verbose != 0 ) - mbedtls_printf( " AES-OFB-%3d (%s): ", keybits, - ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); - -#if defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) - if( keybits > 128 ) - { - mbedtls_printf( "skipped\n" ); - continue; - } -#endif - -#if defined(MBEDTLS_AES_ONLY_ENCRYPT) - if( mode == MBEDTLS_AES_DECRYPT ) - { - mbedtls_printf( "skipped\n" ); - continue; - } -#endif /* MBEDTLS_AES_ONLY_ENCRYPT */ - - memcpy( iv, aes_test_ofb_iv, 16 ); - memcpy( key, aes_test_ofb_key[u], keybits / 8 ); - - offset = 0; - ret = mbedtls_aes_setkey_enc( &ctx, key, keybits ); - /* - * AES-192 is an optional feature that may be unavailable when - * there is an alternative underlying implementation i.e. when - * MBEDTLS_AES_ALT is defined. - */ - if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 ) - { - mbedtls_printf( "skipped\n" ); - continue; - } - else if( ret != 0 ) - { - goto exit; - } - - if( mode == MBEDTLS_AES_DECRYPT ) - { - memcpy( buf, aes_test_ofb_ct[u], 64 ); - aes_tests = aes_test_ofb_pt; - } - else - { - memcpy( buf, aes_test_ofb_pt, 64 ); - aes_tests = aes_test_ofb_ct[u]; - } - - ret = mbedtls_aes_crypt_ofb( &ctx, 64, &offset, iv, buf, buf ); - if( ret != 0 ) - goto exit; - - if( memcmp( buf, aes_tests, 64 ) != 0 ) - { - ret = 1; - goto exit; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); -#endif /* MBEDTLS_CIPHER_MODE_OFB */ - #if defined(MBEDTLS_CIPHER_MODE_CTR) /* * CTR mode @@ -3197,22 +1475,6 @@ int mbedtls_aes_self_test( int verbose ) mbedtls_printf( " AES-CTR-128 (%s): ", ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); -#if defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) - if( keybits > 128 ) - { - mbedtls_printf( "skipped\n" ); - continue; - } -#endif - -#if defined(MBEDTLS_AES_ONLY_ENCRYPT) - if( mode == MBEDTLS_AES_DECRYPT ) - { - mbedtls_printf( "skipped\n" ); - continue; - } -#endif /* MBEDTLS_AES_ONLY_ENCRYPT */ - memcpy( nonce_counter, aes_test_ctr_nonce_counter[u], 16 ); memcpy( key, aes_test_ctr_key[u], 16 ); @@ -3252,81 +1514,6 @@ int mbedtls_aes_self_test( int verbose ) mbedtls_printf( "\n" ); #endif /* MBEDTLS_CIPHER_MODE_CTR */ -#if defined(MBEDTLS_CIPHER_MODE_XTS) - { - static const int num_tests = - sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key); - mbedtls_aes_xts_context ctx_xts; - - /* - * XTS mode - */ - mbedtls_aes_xts_init( &ctx_xts ); - - for( i = 0; i < num_tests << 1; i++ ) - { - const unsigned char *data_unit; - u = i >> 1; - mode = i & 1; - - if( verbose != 0 ) - mbedtls_printf( " AES-XTS-128 (%s): ", - ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); - -#if defined(MBEDTLS_AES_ONLY_ENCRYPT) - if( mode == MBEDTLS_AES_DECRYPT ) - { - mbedtls_printf( "skipped\n" ); - continue; - } -#endif /* MBEDTLS_AES_ONLY_ENCRYPT */ - - memset( key, 0, sizeof( key ) ); - memcpy( key, aes_test_xts_key[u], 32 ); - data_unit = aes_test_xts_data_unit[u]; - - len = sizeof( *aes_test_xts_ct32 ); - - if( mode == MBEDTLS_AES_DECRYPT ) - { - ret = mbedtls_aes_xts_setkey_dec( &ctx_xts, key, 256 ); - if( ret != 0) - goto exit; - memcpy( buf, aes_test_xts_ct32[u], len ); - aes_tests = aes_test_xts_pt32[u]; - } - else - { - ret = mbedtls_aes_xts_setkey_enc( &ctx_xts, key, 256 ); - if( ret != 0) - goto exit; - memcpy( buf, aes_test_xts_pt32[u], len ); - aes_tests = aes_test_xts_ct32[u]; - } - - - ret = mbedtls_aes_crypt_xts( &ctx_xts, mode, len, data_unit, - buf, buf ); - if( ret != 0 ) - goto exit; - - if( memcmp( buf, aes_tests, len ) != 0 ) - { - ret = 1; - goto exit; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - - mbedtls_aes_xts_free( &ctx_xts ); - } -#endif /* MBEDTLS_CIPHER_MODE_XTS */ - ret = 0; exit: diff --git a/APP_Framework/Framework/security/mbedtls/aes.h b/APP_Framework/Framework/security/mbedtls/aes.h index 0a02642ee..46016dcb7 100644 --- a/APP_Framework/Framework/security/mbedtls/aes.h +++ b/APP_Framework/Framework/security/mbedtls/aes.h @@ -1,9 +1,7 @@ /** * \file aes.h * - * \brief This file contains AES definitions and functions. - * - * The Advanced Encryption Standard (AES) specifies a FIPS-approved + * \brief The Advanced Encryption Standard (AES) specifies a FIPS-approved * cryptographic algorithm that can be used to protect electronic * data. * @@ -13,13 +11,7 @@ * ISO/IEC 18033-2:2006: Information technology -- Security * techniques -- Encryption algorithms -- Part 2: Asymmetric * ciphers. - * - * The AES-XTS block mode is standardized by NIST SP 800-38E - * - * and described in detail by IEEE P1619 - * . */ - /* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved. * SPDX-License-Identifier: Apache-2.0 * @@ -58,13 +50,8 @@ #define MBEDTLS_ERR_AES_INVALID_KEY_LENGTH -0x0020 /**< Invalid key length. */ #define MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH -0x0022 /**< Invalid data input length. */ -/* Error codes in range 0x0021-0x0025 */ -#define MBEDTLS_ERR_AES_BAD_INPUT_DATA -0x0021 /**< Invalid input data. */ - -/* MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE is deprecated and should not be used. */ +/* Error codes in range 0x0023-0x0025 */ #define MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE -0x0023 /**< Feature not available. For example, an unsupported AES key size. */ - -/* MBEDTLS_ERR_AES_HW_ACCEL_FAILED is deprecated and should not be used. */ #define MBEDTLS_ERR_AES_HW_ACCEL_FAILED -0x0025 /**< AES hardware accelerator failed. */ #if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ @@ -72,34 +59,21 @@ #define inline __inline #endif -#ifdef __cplusplus -extern "C" { -#endif - #if !defined(MBEDTLS_AES_ALT) // Regular implementation // +#ifdef __cplusplus +extern "C" { +#endif + /** * \brief The AES context-type definition. */ - -#if defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) -#define MBEDTLS_AES_128_EXPANDED_KEY_SIZE_IN_WORDS 44 -#endif -typedef struct mbedtls_aes_context +typedef struct { int nr; /*!< The number of rounds. */ uint32_t *rk; /*!< AES round keys. */ -#if defined(MBEDTLS_AES_SCA_COUNTERMEASURES) - uint32_t frk[8]; /*!< Fake AES round keys. */ -#endif -#if defined(MBEDTLS_VALIDATE_AES_KEYS_INTEGRITY) - uint32_t hash; /*!< hash of the set key */ -#endif -#if defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) && !defined(MBEDTLS_PADLOCK_C) - uint32_t buf[MBEDTLS_AES_128_EXPANDED_KEY_SIZE_IN_WORDS]; /*!< Unaligned data buffer for expanded key only */ -#else /* MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */ uint32_t buf[68]; /*!< Unaligned data buffer. This buffer can hold 32 extra Bytes, which can be used for one of the following purposes: @@ -108,34 +82,16 @@ typedef struct mbedtls_aes_context
  • Simplifying key expansion in the 256-bit case by generating an extra round key.
  • */ -#endif /* MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */ } mbedtls_aes_context; -#if defined(MBEDTLS_CIPHER_MODE_XTS) -/** - * \brief The AES XTS context-type definition. - */ -typedef struct mbedtls_aes_xts_context -{ - mbedtls_aes_context crypt; /*!< The AES context to use for AES block - encryption or decryption. */ - mbedtls_aes_context tweak; /*!< The AES context used for tweak - computation. */ -} mbedtls_aes_xts_context; -#endif /* MBEDTLS_CIPHER_MODE_XTS */ - -#else /* MBEDTLS_AES_ALT */ -#include "aes_alt.h" -#endif /* MBEDTLS_AES_ALT */ - /** * \brief This function initializes the specified AES context. * * It must be the first API called before using * the context. * - * \param ctx The AES context to initialize. This must not be \c NULL. + * \param ctx The AES context to initialize. */ void mbedtls_aes_init( mbedtls_aes_context *ctx ); @@ -143,47 +99,21 @@ void mbedtls_aes_init( mbedtls_aes_context *ctx ); * \brief This function releases and clears the specified AES context. * * \param ctx The AES context to clear. - * If this is \c NULL, this function does nothing. - * Otherwise, the context must have been at least initialized. */ void mbedtls_aes_free( mbedtls_aes_context *ctx ); -#if defined(MBEDTLS_CIPHER_MODE_XTS) -/** - * \brief This function initializes the specified AES XTS context. - * - * It must be the first API called before using - * the context. - * - * \param ctx The AES XTS context to initialize. This must not be \c NULL. - */ -void mbedtls_aes_xts_init( mbedtls_aes_xts_context *ctx ); - -/** - * \brief This function releases and clears the specified AES XTS context. - * - * \param ctx The AES XTS context to clear. - * If this is \c NULL, this function does nothing. - * Otherwise, the context must have been at least initialized. - */ -void mbedtls_aes_xts_free( mbedtls_aes_xts_context *ctx ); -#endif /* MBEDTLS_CIPHER_MODE_XTS */ - /** * \brief This function sets the encryption key. * * \param ctx The AES context to which the key should be bound. - * It must be initialized. * \param key The encryption key. - * This must be a readable buffer of size \p keybits bits. * \param keybits The size of data passed in bits. Valid options are: *
    • 128 bits
    • *
    • 192 bits
    • *
    • 256 bits
    * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH or - * #MBEDTLS_ERR_PLATFORM_FAULT_DETECTED on failure. + * \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, unsigned int keybits ); @@ -192,63 +122,17 @@ int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key, * \brief This function sets the decryption key. * * \param ctx The AES context to which the key should be bound. - * It must be initialized. * \param key The decryption key. - * This must be a readable buffer of size \p keybits bits. * \param keybits The size of data passed. Valid options are: *
    • 128 bits
    • *
    • 192 bits
    • *
    • 256 bits
    * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH or - * #MBEDTLS_ERR_PLATFORM_FAULT_DETECTED on failure. + * \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, unsigned int keybits ); -#if defined(MBEDTLS_CIPHER_MODE_XTS) -/** - * \brief This function prepares an XTS context for encryption and - * sets the encryption key. - * - * \param ctx The AES XTS context to which the key should be bound. - * It must be initialized. - * \param key The encryption key. This is comprised of the XTS key1 - * concatenated with the XTS key2. - * This must be a readable buffer of size \p keybits bits. - * \param keybits The size of \p key passed in bits. Valid options are: - *
    • 256 bits (each of key1 and key2 is a 128-bit key)
    • - *
    • 512 bits (each of key1 and key2 is a 256-bit key)
    - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure. - */ -int mbedtls_aes_xts_setkey_enc( mbedtls_aes_xts_context *ctx, - const unsigned char *key, - unsigned int keybits ); - -/** - * \brief This function prepares an XTS context for decryption and - * sets the decryption key. - * - * \param ctx The AES XTS context to which the key should be bound. - * It must be initialized. - * \param key The decryption key. This is comprised of the XTS key1 - * concatenated with the XTS key2. - * This must be a readable buffer of size \p keybits bits. - * \param keybits The size of \p key passed in bits. Valid options are: - *
    • 256 bits (each of key1 and key2 is a 128-bit key)
    • - *
    • 512 bits (each of key1 and key2 is a 256-bit key)
    - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure. - */ -int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx, - const unsigned char *key, - unsigned int keybits ); -#endif /* MBEDTLS_CIPHER_MODE_XTS */ - /** * \brief This function performs an AES single-block encryption or * decryption operation. @@ -262,13 +146,10 @@ int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx, * call to this API with the same context. * * \param ctx The AES context to use for encryption or decryption. - * It must be initialized and bound to a key. * \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or * #MBEDTLS_AES_DECRYPT. - * \param input The buffer holding the input data. - * It must be readable and at least \c 16 Bytes long. - * \param output The buffer where the output data will be written. - * It must be writeable and at least \c 16 Bytes long. + * \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. */ @@ -291,8 +172,8 @@ int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx, * 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 full blocks, that is, the input size - * must be a multiple of the AES block size of \c 16 Bytes. + * \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 * call the same function again on the next @@ -303,20 +184,15 @@ int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx, * * * \param ctx The AES context to use for encryption or decryption. - * It must be initialized and bound to a key. * \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 (\c 16 Bytes). + * multiple of the block size (16 Bytes). * \param iv Initialization vector (updated after use). - * It must be a readable and writeable buffer of \c 16 Bytes. * \param input The buffer holding the input data. - * It must be readable and of size \p length Bytes. * \param output The buffer holding the output data. - * It must be writeable and of size \p length Bytes. * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH + * \return \c 0 on success, or #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH * on failure. */ int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx, @@ -327,50 +203,6 @@ int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx, unsigned char *output ); #endif /* MBEDTLS_CIPHER_MODE_CBC */ -#if defined(MBEDTLS_CIPHER_MODE_XTS) -/** - * \brief This function performs an AES-XTS encryption or decryption - * operation for an entire XTS data unit. - * - * AES-XTS encrypts or decrypts blocks based on their location as - * defined by a data unit number. The data unit number must be - * provided by \p data_unit. - * - * NIST SP 800-38E limits the maximum size of a data unit to 2^20 - * AES blocks. If the data unit is larger than this, this function - * returns #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH. - * - * \param ctx The AES XTS context to use for AES XTS operations. - * It must be initialized and bound to a key. - * \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or - * #MBEDTLS_AES_DECRYPT. - * \param length The length of a data unit in Bytes. This can be any - * length between 16 bytes and 2^24 bytes inclusive - * (between 1 and 2^20 block cipher blocks). - * \param data_unit The address of the data unit encoded as an array of 16 - * bytes in little-endian format. For disk encryption, this - * is typically the index of the block device sector that - * contains the data. - * \param input The buffer holding the input data (which is an entire - * data unit). This function reads \p length Bytes from \p - * input. - * \param output The buffer holding the output data (which is an entire - * data unit). This function writes \p length Bytes to \p - * output. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH if \p length is - * smaller than an AES block in size (16 Bytes) or if \p - * length is larger than 2^20 blocks (16 MiB). - */ -int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx, - int mode, - size_t length, - const unsigned char data_unit[16], - const unsigned char *input, - unsigned char *output ); -#endif /* MBEDTLS_CIPHER_MODE_XTS */ - #if defined(MBEDTLS_CIPHER_MODE_CFB) /** * \brief This function performs an AES-CFB128 encryption or decryption @@ -396,18 +228,13 @@ int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx, * * * \param ctx The AES context to use for encryption or decryption. - * It must be initialized and bound to a key. * \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or * #MBEDTLS_AES_DECRYPT. - * \param length The length of the input data in Bytes. + * \param length The length of the input data. * \param iv_off The offset in IV (updated after use). - * It must point to a valid \c size_t. * \param iv The initialization vector (updated after use). - * It must be a readable and writeable buffer of \c 16 Bytes. * \param input The buffer holding the input data. - * It must be readable and of size \p length Bytes. * \param output The buffer holding the output data. - * It must be writeable and of size \p length Bytes. * * \return \c 0 on success. */ @@ -442,16 +269,12 @@ int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx, * * * \param ctx The AES context to use for encryption or decryption. - * It must be initialized and bound to a key. * \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). - * It must be a readable and writeable buffer of \c 16 Bytes. * \param input The buffer holding the input data. - * It must be readable and of size \p length Bytes. * \param output The buffer holding the output data. - * It must be writeable and of size \p length Bytes. * * \return \c 0 on success. */ @@ -463,61 +286,6 @@ int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx, unsigned char *output ); #endif /*MBEDTLS_CIPHER_MODE_CFB */ -#if defined(MBEDTLS_CIPHER_MODE_OFB) -/** - * \brief This function performs an AES-OFB (Output Feedback Mode) - * encryption or decryption operation. - * - * For OFB, you must set up the context with - * mbedtls_aes_setkey_enc(), regardless of whether you are - * performing an encryption or decryption operation. This is - * because OFB mode uses the same key schedule for encryption and - * decryption. - * - * The OFB operation is identical for encryption or decryption, - * therefore no operation mode needs to be specified. - * - * \note Upon exit, the content of iv, the Initialisation Vector, is - * updated so that you can call the same function again on the next - * block(s) of data and get the same result as if it was encrypted - * in one call. This allows a "streaming" usage, by initialising - * iv_off to 0 before the first call, and preserving its value - * between calls. - * - * For non-streaming use, the iv should be initialised on each call - * to a unique value, and iv_off set to 0 on each call. - * - * If you need to retain the contents of the initialisation vector, - * you must either save it manually or use the cipher module - * instead. - * - * \warning For the OFB mode, the initialisation vector must be unique - * every encryption operation. Reuse of an initialisation vector - * will compromise security. - * - * \param ctx The AES context to use for encryption or decryption. - * It must be initialized and bound to a key. - * \param length The length of the input data. - * \param iv_off The offset in IV (updated after use). - * It must point to a valid \c size_t. - * \param iv The initialization vector (updated after use). - * It must be a readable and writeable buffer of \c 16 Bytes. - * \param input The buffer holding the input data. - * It must be readable and of size \p length Bytes. - * \param output The buffer holding the output data. - * It must be writeable and of size \p length Bytes. - * - * \return \c 0 on success. - */ -int mbedtls_aes_crypt_ofb( mbedtls_aes_context *ctx, - size_t length, - size_t *iv_off, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output ); - -#endif /* MBEDTLS_CIPHER_MODE_OFB */ - #if defined(MBEDTLS_CIPHER_MODE_CTR) /** * \brief This function performs an AES-CTR encryption or decryption @@ -532,68 +300,20 @@ int mbedtls_aes_crypt_ofb( mbedtls_aes_context *ctx, * must use the context initialized with mbedtls_aes_setkey_enc() * for both #MBEDTLS_AES_ENCRYPT and #MBEDTLS_AES_DECRYPT. * - * \warning You must never reuse a nonce value with the same key. Doing so - * would void the encryption for the two messages encrypted with - * the same nonce and key. - * - * There are two common strategies for managing nonces with CTR: - * - * 1. You can handle everything as a single message processed over - * successive calls to this function. In that case, you want to - * set \p nonce_counter and \p nc_off to 0 for the first call, and - * then preserve the values of \p nonce_counter, \p nc_off and \p - * stream_block across calls to this function as they will be - * updated by this function. - * - * With this strategy, you must not encrypt more than 2**128 - * blocks of data with the same key. - * - * 2. You can encrypt separate messages by dividing the \p - * nonce_counter buffer in two areas: the first one used for a - * per-message nonce, handled by yourself, and the second one - * updated by this function internally. - * - * For example, you might reserve the first 12 bytes for the - * per-message nonce, and the last 4 bytes for internal use. In that - * case, before calling this function on a new message you need to - * set the first 12 bytes of \p nonce_counter to your chosen nonce - * value, the last 4 to 0, and \p nc_off to 0 (which will cause \p - * stream_block to be ignored). That way, you can encrypt at most - * 2**96 messages of up to 2**32 blocks each with the same key. - * - * The per-message nonce (or information sufficient to reconstruct - * it) needs to be communicated with the ciphertext and must be unique. - * The recommended way to ensure uniqueness is to use a message - * counter. An alternative is to generate random nonces, but this - * limits the number of messages that can be securely encrypted: - * for example, with 96-bit random nonces, you should not encrypt - * more than 2**32 messages with the same key. - * - * Note that for both stategies, sizes are measured in blocks and - * that an AES block is 16 bytes. - * - * \warning Upon return, \p stream_block contains sensitive data. Its - * content must not be written to insecure storage and should be - * securely discarded as soon as it's no longer needed. + * \warning You must keep the maximum use of your counter in mind. * * \param ctx The AES context to use for encryption or decryption. - * It must be initialized and bound to a key. * \param length The length of the input data. * \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. - * It must point to a valid \c size_t. * \param nonce_counter The 128-bit nonce and counter. - * It must be a readable-writeable buffer of \c 16 Bytes. * \param stream_block The saved stream block for resuming. This is * overwritten by the function. - * It must be a readable-writeable buffer of \c 16 Bytes. * \param input The buffer holding the input data. - * It must be readable and of size \p length Bytes. * \param output The buffer holding the output data. - * It must be writeable and of size \p length Bytes. * - * \return \c 0 on success. + * \return \c 0 on success. */ int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx, size_t length, @@ -614,7 +334,6 @@ int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx, * \param output The output (ciphertext) block. * * \return \c 0 on success. - * \return #MBEDTLS_ERR_PLATFORM_FAULT_DETECTED in case of error. */ int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx, const unsigned char input[16], @@ -630,7 +349,6 @@ int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx, * \param output The output (plaintext) block. * * \return \c 0 on success. - * \return #MBEDTLS_ERR_PLATFORM_FAULT_DETECTED in case of error. */ int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx, const unsigned char input[16], @@ -646,7 +364,7 @@ int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx, * \brief Deprecated internal AES block encryption function * without return value. * - * \deprecated Superseded by mbedtls_internal_aes_encrypt() + * \deprecated Superseded by mbedtls_aes_encrypt_ext() in 2.5.0. * * \param ctx The AES context to use for encryption. * \param input Plaintext block. @@ -660,7 +378,7 @@ MBEDTLS_DEPRECATED void mbedtls_aes_encrypt( mbedtls_aes_context *ctx, * \brief Deprecated internal AES block decryption function * without return value. * - * \deprecated Superseded by mbedtls_internal_aes_decrypt() + * \deprecated Superseded by mbedtls_aes_decrypt_ext() in 2.5.0. * * \param ctx The AES context to use for decryption. * \param input Ciphertext block. @@ -673,18 +391,25 @@ MBEDTLS_DEPRECATED void mbedtls_aes_decrypt( mbedtls_aes_context *ctx, #undef MBEDTLS_DEPRECATED #endif /* !MBEDTLS_DEPRECATED_REMOVED */ +#ifdef __cplusplus +} +#endif + +#else /* MBEDTLS_AES_ALT */ +#include "aes_alt.h" +#endif /* MBEDTLS_AES_ALT */ + +#ifdef __cplusplus +extern "C" { +#endif -#if defined(MBEDTLS_SELF_TEST) /** * \brief Checkup routine. * - * \return \c 0 on success. - * \return \c 1 on failure. + * \return \c 0 on success, or \c 1 on failure. */ int mbedtls_aes_self_test( int verbose ); -#endif /* MBEDTLS_SELF_TEST */ - #ifdef __cplusplus } #endif diff --git a/APP_Framework/Framework/security/mbedtls/aesni.c b/APP_Framework/Framework/security/mbedtls/aesni.c new file mode 100644 index 000000000..879809c74 --- /dev/null +++ b/APP_Framework/Framework/security/mbedtls/aesni.c @@ -0,0 +1,464 @@ +/* + * AES-NI support functions + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +/* + * [AES-WP] http://software.intel.com/en-us/articles/intel-advanced-encryption-standard-aes-instructions-set + * [CLMUL-WP] http://software.intel.com/en-us/articles/intel-carry-less-multiplication-instruction-and-its-usage-for-computing-the-gcm-mode/ + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_AESNI_C) + +#include "aesni.h" + +#include + +#ifndef asm +#define asm __asm +#endif + +#if defined(MBEDTLS_HAVE_X86_64) + +/* + * AES-NI support detection routine + */ +int mbedtls_aesni_has_support( unsigned int what ) +{ + static int done = 0; + static unsigned int c = 0; + + if( ! done ) + { + asm( "movl $1, %%eax \n\t" + "cpuid \n\t" + : "=c" (c) + : + : "eax", "ebx", "edx" ); + done = 1; + } + + return( ( c & what ) != 0 ); +} + +/* + * Binutils needs to be at least 2.19 to support AES-NI instructions. + * Unfortunately, a lot of users have a lower version now (2014-04). + * Emit bytecode directly in order to support "old" version of gas. + * + * Opcodes from the Intel architecture reference manual, vol. 3. + * We always use registers, so we don't need prefixes for memory operands. + * Operand macros are in gas order (src, dst) as opposed to Intel order + * (dst, src) in order to blend better into the surrounding assembly code. + */ +#define AESDEC ".byte 0x66,0x0F,0x38,0xDE," +#define AESDECLAST ".byte 0x66,0x0F,0x38,0xDF," +#define AESENC ".byte 0x66,0x0F,0x38,0xDC," +#define AESENCLAST ".byte 0x66,0x0F,0x38,0xDD," +#define AESIMC ".byte 0x66,0x0F,0x38,0xDB," +#define AESKEYGENA ".byte 0x66,0x0F,0x3A,0xDF," +#define PCLMULQDQ ".byte 0x66,0x0F,0x3A,0x44," + +#define xmm0_xmm0 "0xC0" +#define xmm0_xmm1 "0xC8" +#define xmm0_xmm2 "0xD0" +#define xmm0_xmm3 "0xD8" +#define xmm0_xmm4 "0xE0" +#define xmm1_xmm0 "0xC1" +#define xmm1_xmm2 "0xD1" + +/* + * AES-NI AES-ECB block en(de)cryption + */ +int mbedtls_aesni_crypt_ecb( mbedtls_aes_context *ctx, + int mode, + const unsigned char input[16], + unsigned char output[16] ) +{ + asm( "movdqu (%3), %%xmm0 \n\t" // load input + "movdqu (%1), %%xmm1 \n\t" // load round key 0 + "pxor %%xmm1, %%xmm0 \n\t" // round 0 + "add $16, %1 \n\t" // point to next round key + "subl $1, %0 \n\t" // normal rounds = nr - 1 + "test %2, %2 \n\t" // mode? + "jz 2f \n\t" // 0 = decrypt + + "1: \n\t" // encryption loop + "movdqu (%1), %%xmm1 \n\t" // load round key + AESENC xmm1_xmm0 "\n\t" // do round + "add $16, %1 \n\t" // point to next round key + "subl $1, %0 \n\t" // loop + "jnz 1b \n\t" + "movdqu (%1), %%xmm1 \n\t" // load round key + AESENCLAST xmm1_xmm0 "\n\t" // last round + "jmp 3f \n\t" + + "2: \n\t" // decryption loop + "movdqu (%1), %%xmm1 \n\t" + AESDEC xmm1_xmm0 "\n\t" // do round + "add $16, %1 \n\t" + "subl $1, %0 \n\t" + "jnz 2b \n\t" + "movdqu (%1), %%xmm1 \n\t" // load round key + AESDECLAST xmm1_xmm0 "\n\t" // last round + + "3: \n\t" + "movdqu %%xmm0, (%4) \n\t" // export output + : + : "r" (ctx->nr), "r" (ctx->rk), "r" (mode), "r" (input), "r" (output) + : "memory", "cc", "xmm0", "xmm1" ); + + + return( 0 ); +} + +/* + * GCM multiplication: c = a times b in GF(2^128) + * Based on [CLMUL-WP] algorithms 1 (with equation 27) and 5. + */ +void mbedtls_aesni_gcm_mult( unsigned char c[16], + const unsigned char a[16], + const unsigned char b[16] ) +{ + unsigned char aa[16], bb[16], cc[16]; + size_t i; + + /* The inputs are in big-endian order, so byte-reverse them */ + for( i = 0; i < 16; i++ ) + { + aa[i] = a[15 - i]; + bb[i] = b[15 - i]; + } + + asm( "movdqu (%0), %%xmm0 \n\t" // a1:a0 + "movdqu (%1), %%xmm1 \n\t" // b1:b0 + + /* + * Caryless multiplication xmm2:xmm1 = xmm0 * xmm1 + * using [CLMUL-WP] algorithm 1 (p. 13). + */ + "movdqa %%xmm1, %%xmm2 \n\t" // copy of b1:b0 + "movdqa %%xmm1, %%xmm3 \n\t" // same + "movdqa %%xmm1, %%xmm4 \n\t" // same + PCLMULQDQ xmm0_xmm1 ",0x00 \n\t" // a0*b0 = c1:c0 + PCLMULQDQ xmm0_xmm2 ",0x11 \n\t" // a1*b1 = d1:d0 + PCLMULQDQ xmm0_xmm3 ",0x10 \n\t" // a0*b1 = e1:e0 + PCLMULQDQ xmm0_xmm4 ",0x01 \n\t" // a1*b0 = f1:f0 + "pxor %%xmm3, %%xmm4 \n\t" // e1+f1:e0+f0 + "movdqa %%xmm4, %%xmm3 \n\t" // same + "psrldq $8, %%xmm4 \n\t" // 0:e1+f1 + "pslldq $8, %%xmm3 \n\t" // e0+f0:0 + "pxor %%xmm4, %%xmm2 \n\t" // d1:d0+e1+f1 + "pxor %%xmm3, %%xmm1 \n\t" // c1+e0+f1:c0 + + /* + * Now shift the result one bit to the left, + * taking advantage of [CLMUL-WP] eq 27 (p. 20) + */ + "movdqa %%xmm1, %%xmm3 \n\t" // r1:r0 + "movdqa %%xmm2, %%xmm4 \n\t" // r3:r2 + "psllq $1, %%xmm1 \n\t" // r1<<1:r0<<1 + "psllq $1, %%xmm2 \n\t" // r3<<1:r2<<1 + "psrlq $63, %%xmm3 \n\t" // r1>>63:r0>>63 + "psrlq $63, %%xmm4 \n\t" // r3>>63:r2>>63 + "movdqa %%xmm3, %%xmm5 \n\t" // r1>>63:r0>>63 + "pslldq $8, %%xmm3 \n\t" // r0>>63:0 + "pslldq $8, %%xmm4 \n\t" // r2>>63:0 + "psrldq $8, %%xmm5 \n\t" // 0:r1>>63 + "por %%xmm3, %%xmm1 \n\t" // r1<<1|r0>>63:r0<<1 + "por %%xmm4, %%xmm2 \n\t" // r3<<1|r2>>62:r2<<1 + "por %%xmm5, %%xmm2 \n\t" // r3<<1|r2>>62:r2<<1|r1>>63 + + /* + * Now reduce modulo the GCM polynomial x^128 + x^7 + x^2 + x + 1 + * using [CLMUL-WP] algorithm 5 (p. 20). + * Currently xmm2:xmm1 holds x3:x2:x1:x0 (already shifted). + */ + /* Step 2 (1) */ + "movdqa %%xmm1, %%xmm3 \n\t" // x1:x0 + "movdqa %%xmm1, %%xmm4 \n\t" // same + "movdqa %%xmm1, %%xmm5 \n\t" // same + "psllq $63, %%xmm3 \n\t" // x1<<63:x0<<63 = stuff:a + "psllq $62, %%xmm4 \n\t" // x1<<62:x0<<62 = stuff:b + "psllq $57, %%xmm5 \n\t" // x1<<57:x0<<57 = stuff:c + + /* Step 2 (2) */ + "pxor %%xmm4, %%xmm3 \n\t" // stuff:a+b + "pxor %%xmm5, %%xmm3 \n\t" // stuff:a+b+c + "pslldq $8, %%xmm3 \n\t" // a+b+c:0 + "pxor %%xmm3, %%xmm1 \n\t" // x1+a+b+c:x0 = d:x0 + + /* Steps 3 and 4 */ + "movdqa %%xmm1,%%xmm0 \n\t" // d:x0 + "movdqa %%xmm1,%%xmm4 \n\t" // same + "movdqa %%xmm1,%%xmm5 \n\t" // same + "psrlq $1, %%xmm0 \n\t" // e1:x0>>1 = e1:e0' + "psrlq $2, %%xmm4 \n\t" // f1:x0>>2 = f1:f0' + "psrlq $7, %%xmm5 \n\t" // g1:x0>>7 = g1:g0' + "pxor %%xmm4, %%xmm0 \n\t" // e1+f1:e0'+f0' + "pxor %%xmm5, %%xmm0 \n\t" // e1+f1+g1:e0'+f0'+g0' + // e0'+f0'+g0' is almost e0+f0+g0, ex\tcept for some missing + // bits carried from d. Now get those\t bits back in. + "movdqa %%xmm1,%%xmm3 \n\t" // d:x0 + "movdqa %%xmm1,%%xmm4 \n\t" // same + "movdqa %%xmm1,%%xmm5 \n\t" // same + "psllq $63, %%xmm3 \n\t" // d<<63:stuff + "psllq $62, %%xmm4 \n\t" // d<<62:stuff + "psllq $57, %%xmm5 \n\t" // d<<57:stuff + "pxor %%xmm4, %%xmm3 \n\t" // d<<63+d<<62:stuff + "pxor %%xmm5, %%xmm3 \n\t" // missing bits of d:stuff + "psrldq $8, %%xmm3 \n\t" // 0:missing bits of d + "pxor %%xmm3, %%xmm0 \n\t" // e1+f1+g1:e0+f0+g0 + "pxor %%xmm1, %%xmm0 \n\t" // h1:h0 + "pxor %%xmm2, %%xmm0 \n\t" // x3+h1:x2+h0 + + "movdqu %%xmm0, (%2) \n\t" // done + : + : "r" (aa), "r" (bb), "r" (cc) + : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" ); + + /* Now byte-reverse the outputs */ + for( i = 0; i < 16; i++ ) + c[i] = cc[15 - i]; + + return; +} + +/* + * Compute decryption round keys from encryption round keys + */ +void mbedtls_aesni_inverse_key( unsigned char *invkey, + const unsigned char *fwdkey, int nr ) +{ + unsigned char *ik = invkey; + const unsigned char *fk = fwdkey + 16 * nr; + + memcpy( ik, fk, 16 ); + + for( fk -= 16, ik += 16; fk > fwdkey; fk -= 16, ik += 16 ) + asm( "movdqu (%0), %%xmm0 \n\t" + AESIMC xmm0_xmm0 "\n\t" + "movdqu %%xmm0, (%1) \n\t" + : + : "r" (fk), "r" (ik) + : "memory", "xmm0" ); + + memcpy( ik, fk, 16 ); +} + +/* + * Key expansion, 128-bit case + */ +static void aesni_setkey_enc_128( unsigned char *rk, + const unsigned char *key ) +{ + asm( "movdqu (%1), %%xmm0 \n\t" // copy the original key + "movdqu %%xmm0, (%0) \n\t" // as round key 0 + "jmp 2f \n\t" // skip auxiliary routine + + /* + * Finish generating the next round key. + * + * On entry xmm0 is r3:r2:r1:r0 and xmm1 is X:stuff:stuff:stuff + * with X = rot( sub( r3 ) ) ^ RCON. + * + * On exit, xmm0 is r7:r6:r5:r4 + * with r4 = X + r0, r5 = r4 + r1, r6 = r5 + r2, r7 = r6 + r3 + * and those are written to the round key buffer. + */ + "1: \n\t" + "pshufd $0xff, %%xmm1, %%xmm1 \n\t" // X:X:X:X + "pxor %%xmm0, %%xmm1 \n\t" // X+r3:X+r2:X+r1:r4 + "pslldq $4, %%xmm0 \n\t" // r2:r1:r0:0 + "pxor %%xmm0, %%xmm1 \n\t" // X+r3+r2:X+r2+r1:r5:r4 + "pslldq $4, %%xmm0 \n\t" // etc + "pxor %%xmm0, %%xmm1 \n\t" + "pslldq $4, %%xmm0 \n\t" + "pxor %%xmm1, %%xmm0 \n\t" // update xmm0 for next time! + "add $16, %0 \n\t" // point to next round key + "movdqu %%xmm0, (%0) \n\t" // write it + "ret \n\t" + + /* Main "loop" */ + "2: \n\t" + AESKEYGENA xmm0_xmm1 ",0x01 \n\tcall 1b \n\t" + AESKEYGENA xmm0_xmm1 ",0x02 \n\tcall 1b \n\t" + AESKEYGENA xmm0_xmm1 ",0x04 \n\tcall 1b \n\t" + AESKEYGENA xmm0_xmm1 ",0x08 \n\tcall 1b \n\t" + AESKEYGENA xmm0_xmm1 ",0x10 \n\tcall 1b \n\t" + AESKEYGENA xmm0_xmm1 ",0x20 \n\tcall 1b \n\t" + AESKEYGENA xmm0_xmm1 ",0x40 \n\tcall 1b \n\t" + AESKEYGENA xmm0_xmm1 ",0x80 \n\tcall 1b \n\t" + AESKEYGENA xmm0_xmm1 ",0x1B \n\tcall 1b \n\t" + AESKEYGENA xmm0_xmm1 ",0x36 \n\tcall 1b \n\t" + : + : "r" (rk), "r" (key) + : "memory", "cc", "0" ); +} + +/* + * Key expansion, 192-bit case + */ +static void aesni_setkey_enc_192( unsigned char *rk, + const unsigned char *key ) +{ + asm( "movdqu (%1), %%xmm0 \n\t" // copy original round key + "movdqu %%xmm0, (%0) \n\t" + "add $16, %0 \n\t" + "movq 16(%1), %%xmm1 \n\t" + "movq %%xmm1, (%0) \n\t" + "add $8, %0 \n\t" + "jmp 2f \n\t" // skip auxiliary routine + + /* + * Finish generating the next 6 quarter-keys. + * + * On entry xmm0 is r3:r2:r1:r0, xmm1 is stuff:stuff:r5:r4 + * and xmm2 is stuff:stuff:X:stuff with X = rot( sub( r3 ) ) ^ RCON. + * + * On exit, xmm0 is r9:r8:r7:r6 and xmm1 is stuff:stuff:r11:r10 + * and those are written to the round key buffer. + */ + "1: \n\t" + "pshufd $0x55, %%xmm2, %%xmm2 \n\t" // X:X:X:X + "pxor %%xmm0, %%xmm2 \n\t" // X+r3:X+r2:X+r1:r4 + "pslldq $4, %%xmm0 \n\t" // etc + "pxor %%xmm0, %%xmm2 \n\t" + "pslldq $4, %%xmm0 \n\t" + "pxor %%xmm0, %%xmm2 \n\t" + "pslldq $4, %%xmm0 \n\t" + "pxor %%xmm2, %%xmm0 \n\t" // update xmm0 = r9:r8:r7:r6 + "movdqu %%xmm0, (%0) \n\t" + "add $16, %0 \n\t" + "pshufd $0xff, %%xmm0, %%xmm2 \n\t" // r9:r9:r9:r9 + "pxor %%xmm1, %%xmm2 \n\t" // stuff:stuff:r9+r5:r10 + "pslldq $4, %%xmm1 \n\t" // r2:r1:r0:0 + "pxor %%xmm2, %%xmm1 \n\t" // xmm1 = stuff:stuff:r11:r10 + "movq %%xmm1, (%0) \n\t" + "add $8, %0 \n\t" + "ret \n\t" + + "2: \n\t" + AESKEYGENA xmm1_xmm2 ",0x01 \n\tcall 1b \n\t" + AESKEYGENA xmm1_xmm2 ",0x02 \n\tcall 1b \n\t" + AESKEYGENA xmm1_xmm2 ",0x04 \n\tcall 1b \n\t" + AESKEYGENA xmm1_xmm2 ",0x08 \n\tcall 1b \n\t" + AESKEYGENA xmm1_xmm2 ",0x10 \n\tcall 1b \n\t" + AESKEYGENA xmm1_xmm2 ",0x20 \n\tcall 1b \n\t" + AESKEYGENA xmm1_xmm2 ",0x40 \n\tcall 1b \n\t" + AESKEYGENA xmm1_xmm2 ",0x80 \n\tcall 1b \n\t" + + : + : "r" (rk), "r" (key) + : "memory", "cc", "0" ); +} + +/* + * Key expansion, 256-bit case + */ +static void aesni_setkey_enc_256( unsigned char *rk, + const unsigned char *key ) +{ + asm( "movdqu (%1), %%xmm0 \n\t" + "movdqu %%xmm0, (%0) \n\t" + "add $16, %0 \n\t" + "movdqu 16(%1), %%xmm1 \n\t" + "movdqu %%xmm1, (%0) \n\t" + "jmp 2f \n\t" // skip auxiliary routine + + /* + * Finish generating the next two round keys. + * + * On entry xmm0 is r3:r2:r1:r0, xmm1 is r7:r6:r5:r4 and + * xmm2 is X:stuff:stuff:stuff with X = rot( sub( r7 )) ^ RCON + * + * On exit, xmm0 is r11:r10:r9:r8 and xmm1 is r15:r14:r13:r12 + * and those have been written to the output buffer. + */ + "1: \n\t" + "pshufd $0xff, %%xmm2, %%xmm2 \n\t" + "pxor %%xmm0, %%xmm2 \n\t" + "pslldq $4, %%xmm0 \n\t" + "pxor %%xmm0, %%xmm2 \n\t" + "pslldq $4, %%xmm0 \n\t" + "pxor %%xmm0, %%xmm2 \n\t" + "pslldq $4, %%xmm0 \n\t" + "pxor %%xmm2, %%xmm0 \n\t" + "add $16, %0 \n\t" + "movdqu %%xmm0, (%0) \n\t" + + /* Set xmm2 to stuff:Y:stuff:stuff with Y = subword( r11 ) + * and proceed to generate next round key from there */ + AESKEYGENA xmm0_xmm2 ",0x00 \n\t" + "pshufd $0xaa, %%xmm2, %%xmm2 \n\t" + "pxor %%xmm1, %%xmm2 \n\t" + "pslldq $4, %%xmm1 \n\t" + "pxor %%xmm1, %%xmm2 \n\t" + "pslldq $4, %%xmm1 \n\t" + "pxor %%xmm1, %%xmm2 \n\t" + "pslldq $4, %%xmm1 \n\t" + "pxor %%xmm2, %%xmm1 \n\t" + "add $16, %0 \n\t" + "movdqu %%xmm1, (%0) \n\t" + "ret \n\t" + + /* + * Main "loop" - Generating one more key than necessary, + * see definition of mbedtls_aes_context.buf + */ + "2: \n\t" + AESKEYGENA xmm1_xmm2 ",0x01 \n\tcall 1b \n\t" + AESKEYGENA xmm1_xmm2 ",0x02 \n\tcall 1b \n\t" + AESKEYGENA xmm1_xmm2 ",0x04 \n\tcall 1b \n\t" + AESKEYGENA xmm1_xmm2 ",0x08 \n\tcall 1b \n\t" + AESKEYGENA xmm1_xmm2 ",0x10 \n\tcall 1b \n\t" + AESKEYGENA xmm1_xmm2 ",0x20 \n\tcall 1b \n\t" + AESKEYGENA xmm1_xmm2 ",0x40 \n\tcall 1b \n\t" + : + : "r" (rk), "r" (key) + : "memory", "cc", "0" ); +} + +/* + * Key expansion, wrapper + */ +int mbedtls_aesni_setkey_enc( unsigned char *rk, + const unsigned char *key, + size_t bits ) +{ + switch( bits ) + { + case 128: aesni_setkey_enc_128( rk, key ); break; + case 192: aesni_setkey_enc_192( rk, key ); break; + case 256: aesni_setkey_enc_256( rk, key ); break; + default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH ); + } + + return( 0 ); +} + +#endif /* MBEDTLS_HAVE_X86_64 */ + +#endif /* MBEDTLS_AESNI_C */ diff --git a/APP_Framework/Framework/security/mbedtls/aesni.h b/APP_Framework/Framework/security/mbedtls/aesni.h index a4ca012f8..7b16b4bad 100644 --- a/APP_Framework/Framework/security/mbedtls/aesni.h +++ b/APP_Framework/Framework/security/mbedtls/aesni.h @@ -2,9 +2,6 @@ * \file aesni.h * * \brief AES-NI for hardware AES acceleration on some Intel processors - * - * \warning These functions are only for internal use by other library - * functions; you must not call them directly. */ /* * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved @@ -51,10 +48,7 @@ extern "C" { #endif /** - * \brief Internal function to detect the AES-NI feature in CPUs. - * - * \note This function is only for internal use by other library - * functions; you must not call it directly. + * \brief AES-NI features detection routine * * \param what The feature to detect * (MBEDTLS_AESNI_AES or MBEDTLS_AESNI_CLMUL) @@ -64,10 +58,7 @@ extern "C" { int mbedtls_aesni_has_support( unsigned int what ); /** - * \brief Internal AES-NI AES-ECB block encryption and decryption - * - * \note This function is only for internal use by other library - * functions; you must not call it directly. + * \brief AES-NI AES-ECB block en(de)cryption * * \param ctx AES context * \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT @@ -77,15 +68,12 @@ int mbedtls_aesni_has_support( unsigned int what ); * \return 0 on success (cannot fail) */ int mbedtls_aesni_crypt_ecb( mbedtls_aes_context *ctx, - int mode, - const unsigned char input[16], - unsigned char output[16] ); + int mode, + const unsigned char input[16], + unsigned char output[16] ); /** - * \brief Internal GCM multiplication: c = a * b in GF(2^128) - * - * \note This function is only for internal use by other library - * functions; you must not call it directly. + * \brief GCM multiplication: c = a * b in GF(2^128) * * \param c Result * \param a First operand @@ -95,29 +83,21 @@ int mbedtls_aesni_crypt_ecb( mbedtls_aes_context *ctx, * elements of GF(2^128) as per the GCM spec. */ void mbedtls_aesni_gcm_mult( unsigned char c[16], - const unsigned char a[16], - const unsigned char b[16] ); + const unsigned char a[16], + const unsigned char b[16] ); /** - * \brief Internal round key inversion. This function computes - * decryption round keys from the encryption round keys. - * - * \note This function is only for internal use by other library - * functions; you must not call it directly. + * \brief Compute decryption round keys from encryption round keys * * \param invkey Round keys for the equivalent inverse cipher * \param fwdkey Original round keys (for encryption) * \param nr Number of rounds (that is, number of round keys minus one) */ void mbedtls_aesni_inverse_key( unsigned char *invkey, - const unsigned char *fwdkey, - int nr ); + const unsigned char *fwdkey, int nr ); /** - * \brief Internal key expansion for encryption - * - * \note This function is only for internal use by other library - * functions; you must not call it directly. + * \brief Perform key expansion (for encryption) * * \param rk Destination buffer where the round keys are written * \param key Encryption key @@ -126,8 +106,8 @@ void mbedtls_aesni_inverse_key( unsigned char *invkey, * \return 0 if successful, or MBEDTLS_ERR_AES_INVALID_KEY_LENGTH */ int mbedtls_aesni_setkey_enc( unsigned char *rk, - const unsigned char *key, - size_t bits ); + const unsigned char *key, + size_t bits ); #ifdef __cplusplus } diff --git a/APP_Framework/Framework/security/mbedtls/arc4.c b/APP_Framework/Framework/security/mbedtls/arc4.c new file mode 100644 index 000000000..b43b4fee2 --- /dev/null +++ b/APP_Framework/Framework/security/mbedtls/arc4.c @@ -0,0 +1,205 @@ +/* + * An implementation of the ARCFOUR algorithm + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +/* + * The ARCFOUR algorithm was publicly disclosed on 94/09. + * + * http://groups.google.com/group/sci.crypt/msg/10a300c9d21afca0 + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_ARC4_C) + +#include "arc4.h" + +#include + +#if defined(MBEDTLS_SELF_TEST) +#if defined(MBEDTLS_PLATFORM_C) +#include "platform.h" +#else +#include +#define mbedtls_printf printf +#endif /* MBEDTLS_PLATFORM_C */ +#endif /* MBEDTLS_SELF_TEST */ + +#if !defined(MBEDTLS_ARC4_ALT) + +/* 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; +} + +void mbedtls_arc4_init( mbedtls_arc4_context *ctx ) +{ + memset( ctx, 0, sizeof( mbedtls_arc4_context ) ); +} + +void mbedtls_arc4_free( mbedtls_arc4_context *ctx ) +{ + if( ctx == NULL ) + return; + + mbedtls_zeroize( ctx, sizeof( mbedtls_arc4_context ) ); +} + +/* + * ARC4 key schedule + */ +void mbedtls_arc4_setup( mbedtls_arc4_context *ctx, const unsigned char *key, + unsigned int keylen ) +{ + int i, j, a; + unsigned int k; + unsigned char *m; + + ctx->x = 0; + ctx->y = 0; + m = ctx->m; + + for( i = 0; i < 256; i++ ) + m[i] = (unsigned char) i; + + j = k = 0; + + for( i = 0; i < 256; i++, k++ ) + { + if( k >= keylen ) k = 0; + + a = m[i]; + j = ( j + a + key[k] ) & 0xFF; + m[i] = m[j]; + m[j] = (unsigned char) a; + } +} + +/* + * ARC4 cipher function + */ +int mbedtls_arc4_crypt( mbedtls_arc4_context *ctx, size_t length, const unsigned char *input, + unsigned char *output ) +{ + int x, y, a, b; + size_t i; + unsigned char *m; + + x = ctx->x; + y = ctx->y; + m = ctx->m; + + for( i = 0; i < length; i++ ) + { + x = ( x + 1 ) & 0xFF; a = m[x]; + y = ( y + a ) & 0xFF; b = m[y]; + + m[x] = (unsigned char) b; + m[y] = (unsigned char) a; + + output[i] = (unsigned char) + ( input[i] ^ m[(unsigned char)( a + b )] ); + } + + ctx->x = x; + ctx->y = y; + + return( 0 ); +} + +#endif /* !MBEDTLS_ARC4_ALT */ + +#if defined(MBEDTLS_SELF_TEST) +/* + * ARC4 tests vectors as posted by Eric Rescorla in sep. 1994: + * + * http://groups.google.com/group/comp.security.misc/msg/10a300c9d21afca0 + */ +static const unsigned char arc4_test_key[3][8] = +{ + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }, + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } +}; + +static const unsigned char arc4_test_pt[3][8] = +{ + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } +}; + +static const unsigned char arc4_test_ct[3][8] = +{ + { 0x75, 0xB7, 0x87, 0x80, 0x99, 0xE0, 0xC5, 0x96 }, + { 0x74, 0x94, 0xC2, 0xE7, 0x10, 0x4B, 0x08, 0x79 }, + { 0xDE, 0x18, 0x89, 0x41, 0xA3, 0x37, 0x5D, 0x3A } +}; + +/* + * Checkup routine + */ +int mbedtls_arc4_self_test( int verbose ) +{ + int i, ret = 0; + unsigned char ibuf[8]; + unsigned char obuf[8]; + mbedtls_arc4_context ctx; + + mbedtls_arc4_init( &ctx ); + + for( i = 0; i < 3; i++ ) + { + if( verbose != 0 ) + mbedtls_printf( " ARC4 test #%d: ", i + 1 ); + + memcpy( ibuf, arc4_test_pt[i], 8 ); + + mbedtls_arc4_setup( &ctx, arc4_test_key[i], 8 ); + mbedtls_arc4_crypt( &ctx, 8, ibuf, obuf ); + + if( memcmp( obuf, arc4_test_ct[i], 8 ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + ret = 1; + goto exit; + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + } + + if( verbose != 0 ) + mbedtls_printf( "\n" ); + +exit: + mbedtls_arc4_free( &ctx ); + + return( ret ); +} + +#endif /* MBEDTLS_SELF_TEST */ + +#endif /* MBEDTLS_ARC4_C */ diff --git a/APP_Framework/Framework/security/mbedtls/arc4.h b/APP_Framework/Framework/security/mbedtls/arc4.h index fb044d5b7..f9d93f822 100644 --- a/APP_Framework/Framework/security/mbedtls/arc4.h +++ b/APP_Framework/Framework/security/mbedtls/arc4.h @@ -36,17 +36,16 @@ #include -/* MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED is deprecated and should not be used. */ #define MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED -0x0019 /**< ARC4 hardware accelerator failed. */ -#ifdef __cplusplus -extern "C" { -#endif - #if !defined(MBEDTLS_ARC4_ALT) // Regular implementation // +#ifdef __cplusplus +extern "C" { +#endif + /** * \brief ARC4 context structure * @@ -54,7 +53,7 @@ extern "C" { * security risk. We recommend considering stronger ciphers instead. * */ -typedef struct mbedtls_arc4_context +typedef struct { int x; /*!< permutation index */ int y; /*!< permutation index */ @@ -62,10 +61,6 @@ typedef struct mbedtls_arc4_context } mbedtls_arc4_context; -#else /* MBEDTLS_ARC4_ALT */ -#include "arc4_alt.h" -#endif /* MBEDTLS_ARC4_ALT */ - /** * \brief Initialize ARC4 context * @@ -123,7 +118,17 @@ void mbedtls_arc4_setup( mbedtls_arc4_context *ctx, const unsigned char *key, int mbedtls_arc4_crypt( mbedtls_arc4_context *ctx, size_t length, const unsigned char *input, unsigned char *output ); -#if defined(MBEDTLS_SELF_TEST) +#ifdef __cplusplus +} +#endif + +#else /* MBEDTLS_ARC4_ALT */ +#include "arc4_alt.h" +#endif /* MBEDTLS_ARC4_ALT */ + +#ifdef __cplusplus +extern "C" { +#endif /** * \brief Checkup routine @@ -137,8 +142,6 @@ int mbedtls_arc4_crypt( mbedtls_arc4_context *ctx, size_t length, const unsigned */ int mbedtls_arc4_self_test( int verbose ); -#endif /* MBEDTLS_SELF_TEST */ - #ifdef __cplusplus } #endif diff --git a/APP_Framework/Framework/security/mbedtls/aria.c b/APP_Framework/Framework/security/mbedtls/aria.c deleted file mode 100644 index ced89f757..000000000 --- a/APP_Framework/Framework/security/mbedtls/aria.c +++ /dev/null @@ -1,1079 +0,0 @@ -/* - * ARIA implementation - * - * Copyright (C) 2006-2017, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -/* - * This implementation is based on the following standards: - * [1] http://210.104.33.10/ARIA/doc/ARIA-specification-e.pdf - * [2] https://tools.ietf.org/html/rfc5794 - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_ARIA_C) - -#include "aria.h" - -#include - -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) -#include "platform.h" -#else -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ - -#if !defined(MBEDTLS_ARIA_ALT) - -#include "platform_util.h" - -#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ - !defined(inline) && !defined(__cplusplus) -#define inline __inline -#endif - -/* Parameter validation macros */ -#define ARIA_VALIDATE_RET( cond ) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ARIA_BAD_INPUT_DATA ) -#define ARIA_VALIDATE( cond ) \ - MBEDTLS_INTERNAL_VALIDATE( cond ) - -/* - * 32-bit integer manipulation macros (little endian) - */ -#ifndef GET_UINT32_LE -#define GET_UINT32_LE( n, b, i ) \ -{ \ - (n) = ( (uint32_t) (b)[(i) ] ) \ - | ( (uint32_t) (b)[(i) + 1] << 8 ) \ - | ( (uint32_t) (b)[(i) + 2] << 16 ) \ - | ( (uint32_t) (b)[(i) + 3] << 24 ); \ -} -#endif - -#ifndef PUT_UINT32_LE -#define PUT_UINT32_LE( n, b, i ) \ -{ \ - (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \ - (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \ - (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \ - (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \ -} -#endif - -/* - * modify byte order: ( A B C D ) -> ( B A D C ), i.e. swap pairs of bytes - * - * This is submatrix P1 in [1] Appendix B.1 - * - * Common compilers fail to translate this to minimal number of instructions, - * so let's provide asm versions for common platforms with C fallback. - */ -#if defined(MBEDTLS_HAVE_ASM) -#if defined(__arm__) /* rev16 available from v6 up */ -/* armcc5 --gnu defines __GNUC__ but doesn't support GNU's extended asm */ -#if defined(__GNUC__) && \ - ( !defined(__ARMCC_VERSION) || __ARMCC_VERSION >= 6000000 ) && \ - __ARM_ARCH >= 6 -static inline uint32_t aria_p1( uint32_t x ) -{ - uint32_t r; - __asm( "rev16 %0, %1" : "=l" (r) : "l" (x) ); - return( r ); -} -#define ARIA_P1 aria_p1 -#elif defined(__ARMCC_VERSION) && __ARMCC_VERSION < 6000000 && \ - ( __TARGET_ARCH_ARM >= 6 || __TARGET_ARCH_THUMB >= 3 ) -static inline uint32_t aria_p1( uint32_t x ) -{ - uint32_t r; - __asm( "rev16 r, x" ); - return( r ); -} -#define ARIA_P1 aria_p1 -#endif -#endif /* arm */ -#if defined(__GNUC__) && \ - defined(__i386__) || defined(__amd64__) || defined( __x86_64__) -/* I couldn't find an Intel equivalent of rev16, so two instructions */ -#define ARIA_P1(x) ARIA_P2( ARIA_P3( x ) ) -#endif /* x86 gnuc */ -#endif /* MBEDTLS_HAVE_ASM && GNUC */ -#if !defined(ARIA_P1) -#define ARIA_P1(x) ((((x) >> 8) & 0x00FF00FF) ^ (((x) & 0x00FF00FF) << 8)) -#endif - -/* - * modify byte order: ( A B C D ) -> ( C D A B ), i.e. rotate by 16 bits - * - * This is submatrix P2 in [1] Appendix B.1 - * - * Common compilers will translate this to a single instruction. - */ -#define ARIA_P2(x) (((x) >> 16) ^ ((x) << 16)) - -/* - * modify byte order: ( A B C D ) -> ( D C B A ), i.e. change endianness - * - * This is submatrix P3 in [1] Appendix B.1 - * - * Some compilers fail to translate this to a single instruction, - * so let's provide asm versions for common platforms with C fallback. - */ -#if defined(MBEDTLS_HAVE_ASM) -#if defined(__arm__) /* rev available from v6 up */ -/* armcc5 --gnu defines __GNUC__ but doesn't support GNU's extended asm */ -#if defined(__GNUC__) && \ - ( !defined(__ARMCC_VERSION) || __ARMCC_VERSION >= 6000000 ) && \ - __ARM_ARCH >= 6 -static inline uint32_t aria_p3( uint32_t x ) -{ - uint32_t r; - __asm( "rev %0, %1" : "=l" (r) : "l" (x) ); - return( r ); -} -#define ARIA_P3 aria_p3 -#elif defined(__ARMCC_VERSION) && __ARMCC_VERSION < 6000000 && \ - ( __TARGET_ARCH_ARM >= 6 || __TARGET_ARCH_THUMB >= 3 ) -static inline uint32_t aria_p3( uint32_t x ) -{ - uint32_t r; - __asm( "rev r, x" ); - return( r ); -} -#define ARIA_P3 aria_p3 -#endif -#endif /* arm */ -#if defined(__GNUC__) && \ - defined(__i386__) || defined(__amd64__) || defined( __x86_64__) -static inline uint32_t aria_p3( uint32_t x ) -{ - __asm( "bswap %0" : "=r" (x) : "0" (x) ); - return( x ); -} -#define ARIA_P3 aria_p3 -#endif /* x86 gnuc */ -#endif /* MBEDTLS_HAVE_ASM && GNUC */ -#if !defined(ARIA_P3) -#define ARIA_P3(x) ARIA_P2( ARIA_P1 ( x ) ) -#endif - -/* - * ARIA Affine Transform - * (a, b, c, d) = state in/out - * - * If we denote the first byte of input by 0, ..., the last byte by f, - * then inputs are: a = 0123, b = 4567, c = 89ab, d = cdef. - * - * Reading [1] 2.4 or [2] 2.4.3 in columns and performing simple - * rearrangements on adjacent pairs, output is: - * - * a = 3210 + 4545 + 6767 + 88aa + 99bb + dccd + effe - * = 3210 + 4567 + 6745 + 89ab + 98ba + dcfe + efcd - * b = 0101 + 2323 + 5476 + 8998 + baab + eecc + ffdd - * = 0123 + 2301 + 5476 + 89ab + ba98 + efcd + fedc - * c = 0022 + 1133 + 4554 + 7667 + ab89 + dcdc + fefe - * = 0123 + 1032 + 4567 + 7654 + ab89 + dcfe + fedc - * d = 1001 + 2332 + 6644 + 7755 + 9898 + baba + cdef - * = 1032 + 2301 + 6745 + 7654 + 98ba + ba98 + cdef - * - * Note: another presentation of the A transform can be found as the first - * half of App. B.1 in [1] in terms of 4-byte operators P1, P2, P3 and P4. - * The implementation below uses only P1 and P2 as they are sufficient. - */ -static inline void aria_a( uint32_t *a, uint32_t *b, - uint32_t *c, uint32_t *d ) -{ - uint32_t ta, tb, tc; - ta = *b; // 4567 - *b = *a; // 0123 - *a = ARIA_P2( ta ); // 6745 - tb = ARIA_P2( *d ); // efcd - *d = ARIA_P1( *c ); // 98ba - *c = ARIA_P1( tb ); // fedc - ta ^= *d; // 4567+98ba - tc = ARIA_P2( *b ); // 2301 - ta = ARIA_P1( ta ) ^ tc ^ *c; // 2301+5476+89ab+fedc - tb ^= ARIA_P2( *d ); // ba98+efcd - tc ^= ARIA_P1( *a ); // 2301+7654 - *b ^= ta ^ tb; // 0123+2301+5476+89ab+ba98+efcd+fedc OUT - tb = ARIA_P2( tb ) ^ ta; // 2301+5476+89ab+98ba+cdef+fedc - *a ^= ARIA_P1( tb ); // 3210+4567+6745+89ab+98ba+dcfe+efcd OUT - ta = ARIA_P2( ta ); // 0123+7654+ab89+dcfe - *d ^= ARIA_P1( ta ) ^ tc; // 1032+2301+6745+7654+98ba+ba98+cdef OUT - tc = ARIA_P2( tc ); // 0123+5476 - *c ^= ARIA_P1( tc ) ^ ta; // 0123+1032+4567+7654+ab89+dcfe+fedc OUT -} - -/* - * ARIA Substitution Layer SL1 / SL2 - * (a, b, c, d) = state in/out - * (sa, sb, sc, sd) = 256 8-bit S-Boxes (see below) - * - * By passing sb1, sb2, is1, is2 as S-Boxes you get SL1 - * By passing is1, is2, sb1, sb2 as S-Boxes you get SL2 - */ -static inline void aria_sl( uint32_t *a, uint32_t *b, - uint32_t *c, uint32_t *d, - const uint8_t sa[256], const uint8_t sb[256], - const uint8_t sc[256], const uint8_t sd[256] ) -{ - *a = ( (uint32_t) sa[ *a & 0xFF] ) ^ - (((uint32_t) sb[(*a >> 8) & 0xFF]) << 8) ^ - (((uint32_t) sc[(*a >> 16) & 0xFF]) << 16) ^ - (((uint32_t) sd[ *a >> 24 ]) << 24); - *b = ( (uint32_t) sa[ *b & 0xFF] ) ^ - (((uint32_t) sb[(*b >> 8) & 0xFF]) << 8) ^ - (((uint32_t) sc[(*b >> 16) & 0xFF]) << 16) ^ - (((uint32_t) sd[ *b >> 24 ]) << 24); - *c = ( (uint32_t) sa[ *c & 0xFF] ) ^ - (((uint32_t) sb[(*c >> 8) & 0xFF]) << 8) ^ - (((uint32_t) sc[(*c >> 16) & 0xFF]) << 16) ^ - (((uint32_t) sd[ *c >> 24 ]) << 24); - *d = ( (uint32_t) sa[ *d & 0xFF] ) ^ - (((uint32_t) sb[(*d >> 8) & 0xFF]) << 8) ^ - (((uint32_t) sc[(*d >> 16) & 0xFF]) << 16) ^ - (((uint32_t) sd[ *d >> 24 ]) << 24); -} - -/* - * S-Boxes - */ -static const uint8_t aria_sb1[256] = -{ - 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, - 0xFE, 0xD7, 0xAB, 0x76, 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, - 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, 0xB7, 0xFD, 0x93, 0x26, - 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, - 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, - 0xEB, 0x27, 0xB2, 0x75, 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, - 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, 0x53, 0xD1, 0x00, 0xED, - 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, - 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, - 0x50, 0x3C, 0x9F, 0xA8, 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, - 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 0xCD, 0x0C, 0x13, 0xEC, - 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, - 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, - 0xDE, 0x5E, 0x0B, 0xDB, 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, - 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 0xE7, 0xC8, 0x37, 0x6D, - 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, - 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, - 0x4B, 0xBD, 0x8B, 0x8A, 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, - 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, 0xE1, 0xF8, 0x98, 0x11, - 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, - 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, - 0xB0, 0x54, 0xBB, 0x16 -}; - -static const uint8_t aria_sb2[256] = -{ - 0xE2, 0x4E, 0x54, 0xFC, 0x94, 0xC2, 0x4A, 0xCC, 0x62, 0x0D, 0x6A, 0x46, - 0x3C, 0x4D, 0x8B, 0xD1, 0x5E, 0xFA, 0x64, 0xCB, 0xB4, 0x97, 0xBE, 0x2B, - 0xBC, 0x77, 0x2E, 0x03, 0xD3, 0x19, 0x59, 0xC1, 0x1D, 0x06, 0x41, 0x6B, - 0x55, 0xF0, 0x99, 0x69, 0xEA, 0x9C, 0x18, 0xAE, 0x63, 0xDF, 0xE7, 0xBB, - 0x00, 0x73, 0x66, 0xFB, 0x96, 0x4C, 0x85, 0xE4, 0x3A, 0x09, 0x45, 0xAA, - 0x0F, 0xEE, 0x10, 0xEB, 0x2D, 0x7F, 0xF4, 0x29, 0xAC, 0xCF, 0xAD, 0x91, - 0x8D, 0x78, 0xC8, 0x95, 0xF9, 0x2F, 0xCE, 0xCD, 0x08, 0x7A, 0x88, 0x38, - 0x5C, 0x83, 0x2A, 0x28, 0x47, 0xDB, 0xB8, 0xC7, 0x93, 0xA4, 0x12, 0x53, - 0xFF, 0x87, 0x0E, 0x31, 0x36, 0x21, 0x58, 0x48, 0x01, 0x8E, 0x37, 0x74, - 0x32, 0xCA, 0xE9, 0xB1, 0xB7, 0xAB, 0x0C, 0xD7, 0xC4, 0x56, 0x42, 0x26, - 0x07, 0x98, 0x60, 0xD9, 0xB6, 0xB9, 0x11, 0x40, 0xEC, 0x20, 0x8C, 0xBD, - 0xA0, 0xC9, 0x84, 0x04, 0x49, 0x23, 0xF1, 0x4F, 0x50, 0x1F, 0x13, 0xDC, - 0xD8, 0xC0, 0x9E, 0x57, 0xE3, 0xC3, 0x7B, 0x65, 0x3B, 0x02, 0x8F, 0x3E, - 0xE8, 0x25, 0x92, 0xE5, 0x15, 0xDD, 0xFD, 0x17, 0xA9, 0xBF, 0xD4, 0x9A, - 0x7E, 0xC5, 0x39, 0x67, 0xFE, 0x76, 0x9D, 0x43, 0xA7, 0xE1, 0xD0, 0xF5, - 0x68, 0xF2, 0x1B, 0x34, 0x70, 0x05, 0xA3, 0x8A, 0xD5, 0x79, 0x86, 0xA8, - 0x30, 0xC6, 0x51, 0x4B, 0x1E, 0xA6, 0x27, 0xF6, 0x35, 0xD2, 0x6E, 0x24, - 0x16, 0x82, 0x5F, 0xDA, 0xE6, 0x75, 0xA2, 0xEF, 0x2C, 0xB2, 0x1C, 0x9F, - 0x5D, 0x6F, 0x80, 0x0A, 0x72, 0x44, 0x9B, 0x6C, 0x90, 0x0B, 0x5B, 0x33, - 0x7D, 0x5A, 0x52, 0xF3, 0x61, 0xA1, 0xF7, 0xB0, 0xD6, 0x3F, 0x7C, 0x6D, - 0xED, 0x14, 0xE0, 0xA5, 0x3D, 0x22, 0xB3, 0xF8, 0x89, 0xDE, 0x71, 0x1A, - 0xAF, 0xBA, 0xB5, 0x81 -}; - -static const uint8_t aria_is1[256] = -{ - 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, - 0x81, 0xF3, 0xD7, 0xFB, 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, - 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, 0x54, 0x7B, 0x94, 0x32, - 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, - 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, - 0x6D, 0x8B, 0xD1, 0x25, 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, - 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, 0x6C, 0x70, 0x48, 0x50, - 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, - 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, - 0xB8, 0xB3, 0x45, 0x06, 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, - 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, 0x3A, 0x91, 0x11, 0x41, - 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, - 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, - 0x1C, 0x75, 0xDF, 0x6E, 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, - 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, 0xFC, 0x56, 0x3E, 0x4B, - 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, - 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, - 0x27, 0x80, 0xEC, 0x5F, 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, - 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, 0xA0, 0xE0, 0x3B, 0x4D, - 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, - 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, - 0x55, 0x21, 0x0C, 0x7D -}; - -static const uint8_t aria_is2[256] = -{ - 0x30, 0x68, 0x99, 0x1B, 0x87, 0xB9, 0x21, 0x78, 0x50, 0x39, 0xDB, 0xE1, - 0x72, 0x09, 0x62, 0x3C, 0x3E, 0x7E, 0x5E, 0x8E, 0xF1, 0xA0, 0xCC, 0xA3, - 0x2A, 0x1D, 0xFB, 0xB6, 0xD6, 0x20, 0xC4, 0x8D, 0x81, 0x65, 0xF5, 0x89, - 0xCB, 0x9D, 0x77, 0xC6, 0x57, 0x43, 0x56, 0x17, 0xD4, 0x40, 0x1A, 0x4D, - 0xC0, 0x63, 0x6C, 0xE3, 0xB7, 0xC8, 0x64, 0x6A, 0x53, 0xAA, 0x38, 0x98, - 0x0C, 0xF4, 0x9B, 0xED, 0x7F, 0x22, 0x76, 0xAF, 0xDD, 0x3A, 0x0B, 0x58, - 0x67, 0x88, 0x06, 0xC3, 0x35, 0x0D, 0x01, 0x8B, 0x8C, 0xC2, 0xE6, 0x5F, - 0x02, 0x24, 0x75, 0x93, 0x66, 0x1E, 0xE5, 0xE2, 0x54, 0xD8, 0x10, 0xCE, - 0x7A, 0xE8, 0x08, 0x2C, 0x12, 0x97, 0x32, 0xAB, 0xB4, 0x27, 0x0A, 0x23, - 0xDF, 0xEF, 0xCA, 0xD9, 0xB8, 0xFA, 0xDC, 0x31, 0x6B, 0xD1, 0xAD, 0x19, - 0x49, 0xBD, 0x51, 0x96, 0xEE, 0xE4, 0xA8, 0x41, 0xDA, 0xFF, 0xCD, 0x55, - 0x86, 0x36, 0xBE, 0x61, 0x52, 0xF8, 0xBB, 0x0E, 0x82, 0x48, 0x69, 0x9A, - 0xE0, 0x47, 0x9E, 0x5C, 0x04, 0x4B, 0x34, 0x15, 0x79, 0x26, 0xA7, 0xDE, - 0x29, 0xAE, 0x92, 0xD7, 0x84, 0xE9, 0xD2, 0xBA, 0x5D, 0xF3, 0xC5, 0xB0, - 0xBF, 0xA4, 0x3B, 0x71, 0x44, 0x46, 0x2B, 0xFC, 0xEB, 0x6F, 0xD5, 0xF6, - 0x14, 0xFE, 0x7C, 0x70, 0x5A, 0x7D, 0xFD, 0x2F, 0x18, 0x83, 0x16, 0xA5, - 0x91, 0x1F, 0x05, 0x95, 0x74, 0xA9, 0xC1, 0x5B, 0x4A, 0x85, 0x6D, 0x13, - 0x07, 0x4F, 0x4E, 0x45, 0xB2, 0x0F, 0xC9, 0x1C, 0xA6, 0xBC, 0xEC, 0x73, - 0x90, 0x7B, 0xCF, 0x59, 0x8F, 0xA1, 0xF9, 0x2D, 0xF2, 0xB1, 0x00, 0x94, - 0x37, 0x9F, 0xD0, 0x2E, 0x9C, 0x6E, 0x28, 0x3F, 0x80, 0xF0, 0x3D, 0xD3, - 0x25, 0x8A, 0xB5, 0xE7, 0x42, 0xB3, 0xC7, 0xEA, 0xF7, 0x4C, 0x11, 0x33, - 0x03, 0xA2, 0xAC, 0x60 -}; - -/* - * Helper for key schedule: r = FO( p, k ) ^ x - */ -static void aria_fo_xor( uint32_t r[4], const uint32_t p[4], - const uint32_t k[4], const uint32_t x[4] ) -{ - uint32_t a, b, c, d; - - a = p[0] ^ k[0]; - b = p[1] ^ k[1]; - c = p[2] ^ k[2]; - d = p[3] ^ k[3]; - - aria_sl( &a, &b, &c, &d, aria_sb1, aria_sb2, aria_is1, aria_is2 ); - aria_a( &a, &b, &c, &d ); - - r[0] = a ^ x[0]; - r[1] = b ^ x[1]; - r[2] = c ^ x[2]; - r[3] = d ^ x[3]; -} - -/* - * Helper for key schedule: r = FE( p, k ) ^ x - */ -static void aria_fe_xor( uint32_t r[4], const uint32_t p[4], - const uint32_t k[4], const uint32_t x[4] ) -{ - uint32_t a, b, c, d; - - a = p[0] ^ k[0]; - b = p[1] ^ k[1]; - c = p[2] ^ k[2]; - d = p[3] ^ k[3]; - - aria_sl( &a, &b, &c, &d, aria_is1, aria_is2, aria_sb1, aria_sb2 ); - aria_a( &a, &b, &c, &d ); - - r[0] = a ^ x[0]; - r[1] = b ^ x[1]; - r[2] = c ^ x[2]; - r[3] = d ^ x[3]; -} - -/* - * Big endian 128-bit rotation: r = a ^ (b <<< n), used only in key setup. - * - * We chose to store bytes into 32-bit words in little-endian format (see - * GET/PUT_UINT32_LE) so we need to reverse bytes here. - */ -static void aria_rot128( uint32_t r[4], const uint32_t a[4], - const uint32_t b[4], uint8_t n ) -{ - uint8_t i, j; - uint32_t t, u; - - const uint8_t n1 = n % 32; // bit offset - const uint8_t n2 = n1 ? 32 - n1 : 0; // reverse bit offset - - j = ( n / 32 ) % 4; // initial word offset - t = ARIA_P3( b[j] ); // big endian - for( i = 0; i < 4; i++ ) - { - j = ( j + 1 ) % 4; // get next word, big endian - u = ARIA_P3( b[j] ); - t <<= n1; // rotate - t |= u >> n2; - t = ARIA_P3( t ); // back to little endian - r[i] = a[i] ^ t; // store - t = u; // move to next word - } -} - -/* - * Set encryption key - */ -int mbedtls_aria_setkey_enc( mbedtls_aria_context *ctx, - const unsigned char *key, unsigned int keybits ) -{ - /* round constant masks */ - const uint32_t rc[3][4] = - { - { 0xB7C17C51, 0x940A2227, 0xE8AB13FE, 0xE06E9AFA }, - { 0xCC4AB16D, 0x20C8219E, 0xD5B128FF, 0xB0E25DEF }, - { 0x1D3792DB, 0x70E92621, 0x75972403, 0x0EC9E804 } - }; - - int i; - uint32_t w[4][4], *w2; - ARIA_VALIDATE_RET( ctx != NULL ); - ARIA_VALIDATE_RET( key != NULL ); - - if( keybits != 128 && keybits != 192 && keybits != 256 ) - return( MBEDTLS_ERR_ARIA_BAD_INPUT_DATA ); - - /* Copy key to W0 (and potential remainder to W1) */ - GET_UINT32_LE( w[0][0], key, 0 ); - GET_UINT32_LE( w[0][1], key, 4 ); - GET_UINT32_LE( w[0][2], key, 8 ); - GET_UINT32_LE( w[0][3], key, 12 ); - - mbedtls_platform_memset( w[1], 0, 16 ); - if( keybits >= 192 ) - { - GET_UINT32_LE( w[1][0], key, 16 ); // 192 bit key - GET_UINT32_LE( w[1][1], key, 20 ); - } - if( keybits == 256 ) - { - GET_UINT32_LE( w[1][2], key, 24 ); // 256 bit key - GET_UINT32_LE( w[1][3], key, 28 ); - } - - i = ( keybits - 128 ) >> 6; // index: 0, 1, 2 - ctx->nr = 12 + 2 * i; // no. rounds: 12, 14, 16 - - aria_fo_xor( w[1], w[0], rc[i], w[1] ); // W1 = FO(W0, CK1) ^ KR - i = i < 2 ? i + 1 : 0; - aria_fe_xor( w[2], w[1], rc[i], w[0] ); // W2 = FE(W1, CK2) ^ W0 - i = i < 2 ? i + 1 : 0; - aria_fo_xor( w[3], w[2], rc[i], w[1] ); // W3 = FO(W2, CK3) ^ W1 - - for( i = 0; i < 4; i++ ) // create round keys - { - w2 = w[(i + 1) & 3]; - aria_rot128( ctx->rk[i ], w[i], w2, 128 - 19 ); - aria_rot128( ctx->rk[i + 4], w[i], w2, 128 - 31 ); - aria_rot128( ctx->rk[i + 8], w[i], w2, 61 ); - aria_rot128( ctx->rk[i + 12], w[i], w2, 31 ); - } - aria_rot128( ctx->rk[16], w[0], w[1], 19 ); - - /* w holds enough info to reconstruct the round keys */ - mbedtls_platform_zeroize( w, sizeof( w ) ); - - return( 0 ); -} - -/* - * Set decryption key - */ -int mbedtls_aria_setkey_dec( mbedtls_aria_context *ctx, - const unsigned char *key, unsigned int keybits ) -{ - int i, j, k, ret; - ARIA_VALIDATE_RET( ctx != NULL ); - ARIA_VALIDATE_RET( key != NULL ); - - ret = mbedtls_aria_setkey_enc( ctx, key, keybits ); - if( ret != 0 ) - return( ret ); - - /* flip the order of round keys */ - for( i = 0, j = ctx->nr; i < j; i++, j-- ) - { - for( k = 0; k < 4; k++ ) - { - uint32_t t = ctx->rk[i][k]; - ctx->rk[i][k] = ctx->rk[j][k]; - ctx->rk[j][k] = t; - } - } - - /* apply affine transform to middle keys */ - for( i = 1; i < ctx->nr; i++ ) - { - aria_a( &ctx->rk[i][0], &ctx->rk[i][1], - &ctx->rk[i][2], &ctx->rk[i][3] ); - } - - return( 0 ); -} - -/* - * Encrypt a block - */ -int mbedtls_aria_crypt_ecb( mbedtls_aria_context *ctx, - const unsigned char input[MBEDTLS_ARIA_BLOCKSIZE], - unsigned char output[MBEDTLS_ARIA_BLOCKSIZE] ) -{ - int i; - - uint32_t a, b, c, d; - ARIA_VALIDATE_RET( ctx != NULL ); - ARIA_VALIDATE_RET( input != NULL ); - ARIA_VALIDATE_RET( output != NULL ); - - GET_UINT32_LE( a, input, 0 ); - GET_UINT32_LE( b, input, 4 ); - GET_UINT32_LE( c, input, 8 ); - GET_UINT32_LE( d, input, 12 ); - - i = 0; - while( 1 ) - { - a ^= ctx->rk[i][0]; - b ^= ctx->rk[i][1]; - c ^= ctx->rk[i][2]; - d ^= ctx->rk[i][3]; - i++; - - aria_sl( &a, &b, &c, &d, aria_sb1, aria_sb2, aria_is1, aria_is2 ); - aria_a( &a, &b, &c, &d ); - - a ^= ctx->rk[i][0]; - b ^= ctx->rk[i][1]; - c ^= ctx->rk[i][2]; - d ^= ctx->rk[i][3]; - i++; - - aria_sl( &a, &b, &c, &d, aria_is1, aria_is2, aria_sb1, aria_sb2 ); - if( i >= ctx->nr ) - break; - aria_a( &a, &b, &c, &d ); - } - - /* final key mixing */ - a ^= ctx->rk[i][0]; - b ^= ctx->rk[i][1]; - c ^= ctx->rk[i][2]; - d ^= ctx->rk[i][3]; - - PUT_UINT32_LE( a, output, 0 ); - PUT_UINT32_LE( b, output, 4 ); - PUT_UINT32_LE( c, output, 8 ); - PUT_UINT32_LE( d, output, 12 ); - - return( 0 ); -} - -/* Initialize context */ -void mbedtls_aria_init( mbedtls_aria_context *ctx ) -{ - ARIA_VALIDATE( ctx != NULL ); - mbedtls_platform_memset( ctx, 0, sizeof( mbedtls_aria_context ) ); -} - -/* Clear context */ -void mbedtls_aria_free( mbedtls_aria_context *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_aria_context ) ); -} - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -/* - * ARIA-CBC buffer encryption/decryption - */ -int mbedtls_aria_crypt_cbc( mbedtls_aria_context *ctx, - int mode, - size_t length, - unsigned char iv[MBEDTLS_ARIA_BLOCKSIZE], - const unsigned char *input, - unsigned char *output ) -{ - int i; - unsigned char temp[MBEDTLS_ARIA_BLOCKSIZE]; - - ARIA_VALIDATE_RET( ctx != NULL ); - ARIA_VALIDATE_RET( mode == MBEDTLS_ARIA_ENCRYPT || - mode == MBEDTLS_ARIA_DECRYPT ); - ARIA_VALIDATE_RET( length == 0 || input != NULL ); - ARIA_VALIDATE_RET( length == 0 || output != NULL ); - ARIA_VALIDATE_RET( iv != NULL ); - - if( length % MBEDTLS_ARIA_BLOCKSIZE ) - return( MBEDTLS_ERR_ARIA_INVALID_INPUT_LENGTH ); - - if( mode == MBEDTLS_ARIA_DECRYPT ) - { - while( length > 0 ) - { - mbedtls_platform_memcpy( temp, input, MBEDTLS_ARIA_BLOCKSIZE ); - mbedtls_aria_crypt_ecb( ctx, input, output ); - - for( i = 0; i < MBEDTLS_ARIA_BLOCKSIZE; i++ ) - output[i] = (unsigned char)( output[i] ^ iv[i] ); - - mbedtls_platform_memcpy( iv, temp, MBEDTLS_ARIA_BLOCKSIZE ); - - input += MBEDTLS_ARIA_BLOCKSIZE; - output += MBEDTLS_ARIA_BLOCKSIZE; - length -= MBEDTLS_ARIA_BLOCKSIZE; - } - } - else - { - while( length > 0 ) - { - for( i = 0; i < MBEDTLS_ARIA_BLOCKSIZE; i++ ) - output[i] = (unsigned char)( input[i] ^ iv[i] ); - - mbedtls_aria_crypt_ecb( ctx, output, output ); - mbedtls_platform_memcpy( iv, output, MBEDTLS_ARIA_BLOCKSIZE ); - - input += MBEDTLS_ARIA_BLOCKSIZE; - output += MBEDTLS_ARIA_BLOCKSIZE; - length -= MBEDTLS_ARIA_BLOCKSIZE; - } - } - - return( 0 ); -} -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -/* - * ARIA-CFB128 buffer encryption/decryption - */ -int mbedtls_aria_crypt_cfb128( mbedtls_aria_context *ctx, - int mode, - size_t length, - size_t *iv_off, - unsigned char iv[MBEDTLS_ARIA_BLOCKSIZE], - const unsigned char *input, - unsigned char *output ) -{ - unsigned char c; - size_t n; - - ARIA_VALIDATE_RET( ctx != NULL ); - ARIA_VALIDATE_RET( mode == MBEDTLS_ARIA_ENCRYPT || - mode == MBEDTLS_ARIA_DECRYPT ); - ARIA_VALIDATE_RET( length == 0 || input != NULL ); - ARIA_VALIDATE_RET( length == 0 || output != NULL ); - ARIA_VALIDATE_RET( iv != NULL ); - ARIA_VALIDATE_RET( iv_off != NULL ); - - n = *iv_off; - - /* An overly large value of n can lead to an unlimited - * buffer overflow. Therefore, guard against this - * outside of parameter validation. */ - if( n >= MBEDTLS_ARIA_BLOCKSIZE ) - return( MBEDTLS_ERR_ARIA_BAD_INPUT_DATA ); - - if( mode == MBEDTLS_ARIA_DECRYPT ) - { - while( length-- ) - { - if( n == 0 ) - mbedtls_aria_crypt_ecb( ctx, iv, iv ); - - c = *input++; - *output++ = c ^ iv[n]; - iv[n] = c; - - n = ( n + 1 ) & 0x0F; - } - } - else - { - while( length-- ) - { - if( n == 0 ) - mbedtls_aria_crypt_ecb( ctx, iv, iv ); - - iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ ); - - n = ( n + 1 ) & 0x0F; - } - } - - *iv_off = n; - - return( 0 ); -} -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -/* - * ARIA-CTR buffer encryption/decryption - */ -int mbedtls_aria_crypt_ctr( mbedtls_aria_context *ctx, - size_t length, - size_t *nc_off, - unsigned char nonce_counter[MBEDTLS_ARIA_BLOCKSIZE], - unsigned char stream_block[MBEDTLS_ARIA_BLOCKSIZE], - const unsigned char *input, - unsigned char *output ) -{ - int c, i; - size_t n; - - ARIA_VALIDATE_RET( ctx != NULL ); - ARIA_VALIDATE_RET( length == 0 || input != NULL ); - ARIA_VALIDATE_RET( length == 0 || output != NULL ); - ARIA_VALIDATE_RET( nonce_counter != NULL ); - ARIA_VALIDATE_RET( stream_block != NULL ); - ARIA_VALIDATE_RET( nc_off != NULL ); - - n = *nc_off; - /* An overly large value of n can lead to an unlimited - * buffer overflow. Therefore, guard against this - * outside of parameter validation. */ - if( n >= MBEDTLS_ARIA_BLOCKSIZE ) - return( MBEDTLS_ERR_ARIA_BAD_INPUT_DATA ); - - while( length-- ) - { - if( n == 0 ) { - mbedtls_aria_crypt_ecb( ctx, nonce_counter, - stream_block ); - - for( i = MBEDTLS_ARIA_BLOCKSIZE; i > 0; i-- ) - if( ++nonce_counter[i - 1] != 0 ) - break; - } - c = *input++; - *output++ = (unsigned char)( c ^ stream_block[n] ); - - n = ( n + 1 ) & 0x0F; - } - - *nc_off = n; - - return( 0 ); -} -#endif /* MBEDTLS_CIPHER_MODE_CTR */ -#endif /* !MBEDTLS_ARIA_ALT */ - -#if defined(MBEDTLS_SELF_TEST) - -/* - * Basic ARIA ECB test vectors from RFC 5794 - */ -static const uint8_t aria_test1_ecb_key[32] = // test key -{ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // 128 bit - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, // 192 bit - 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F // 256 bit -}; - -static const uint8_t aria_test1_ecb_pt[MBEDTLS_ARIA_BLOCKSIZE] = // plaintext -{ - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, // same for all - 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF // key sizes -}; - -static const uint8_t aria_test1_ecb_ct[3][MBEDTLS_ARIA_BLOCKSIZE] = // ciphertext -{ - { 0xD7, 0x18, 0xFB, 0xD6, 0xAB, 0x64, 0x4C, 0x73, // 128 bit - 0x9D, 0xA9, 0x5F, 0x3B, 0xE6, 0x45, 0x17, 0x78 }, - { 0x26, 0x44, 0x9C, 0x18, 0x05, 0xDB, 0xE7, 0xAA, // 192 bit - 0x25, 0xA4, 0x68, 0xCE, 0x26, 0x3A, 0x9E, 0x79 }, - { 0xF9, 0x2B, 0xD7, 0xC7, 0x9F, 0xB7, 0x2E, 0x2F, // 256 bit - 0x2B, 0x8F, 0x80, 0xC1, 0x97, 0x2D, 0x24, 0xFC } -}; - -/* - * Mode tests from "Test Vectors for ARIA" Version 1.0 - * http://210.104.33.10/ARIA/doc/ARIA-testvector-e.pdf - */ -#if (defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \ - defined(MBEDTLS_CIPHER_MODE_CTR)) -static const uint8_t aria_test2_key[32] = -{ - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, // 128 bit - 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, // 192 bit - 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff // 256 bit -}; - -static const uint8_t aria_test2_pt[48] = -{ - 0x11, 0x11, 0x11, 0x11, 0xaa, 0xaa, 0xaa, 0xaa, // same for all - 0x11, 0x11, 0x11, 0x11, 0xbb, 0xbb, 0xbb, 0xbb, - 0x11, 0x11, 0x11, 0x11, 0xcc, 0xcc, 0xcc, 0xcc, - 0x11, 0x11, 0x11, 0x11, 0xdd, 0xdd, 0xdd, 0xdd, - 0x22, 0x22, 0x22, 0x22, 0xaa, 0xaa, 0xaa, 0xaa, - 0x22, 0x22, 0x22, 0x22, 0xbb, 0xbb, 0xbb, 0xbb, -}; -#endif - -#if (defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB)) -static const uint8_t aria_test2_iv[MBEDTLS_ARIA_BLOCKSIZE] = -{ - 0x0f, 0x1e, 0x2d, 0x3c, 0x4b, 0x5a, 0x69, 0x78, // same for CBC, CFB - 0x87, 0x96, 0xa5, 0xb4, 0xc3, 0xd2, 0xe1, 0xf0 // CTR has zero IV -}; -#endif - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static const uint8_t aria_test2_cbc_ct[3][48] = // CBC ciphertext -{ - { 0x49, 0xd6, 0x18, 0x60, 0xb1, 0x49, 0x09, 0x10, // 128-bit key - 0x9c, 0xef, 0x0d, 0x22, 0xa9, 0x26, 0x81, 0x34, - 0xfa, 0xdf, 0x9f, 0xb2, 0x31, 0x51, 0xe9, 0x64, - 0x5f, 0xba, 0x75, 0x01, 0x8b, 0xdb, 0x15, 0x38, - 0xb5, 0x33, 0x34, 0x63, 0x4b, 0xbf, 0x7d, 0x4c, - 0xd4, 0xb5, 0x37, 0x70, 0x33, 0x06, 0x0c, 0x15 }, - { 0xaf, 0xe6, 0xcf, 0x23, 0x97, 0x4b, 0x53, 0x3c, // 192-bit key - 0x67, 0x2a, 0x82, 0x62, 0x64, 0xea, 0x78, 0x5f, - 0x4e, 0x4f, 0x7f, 0x78, 0x0d, 0xc7, 0xf3, 0xf1, - 0xe0, 0x96, 0x2b, 0x80, 0x90, 0x23, 0x86, 0xd5, - 0x14, 0xe9, 0xc3, 0xe7, 0x72, 0x59, 0xde, 0x92, - 0xdd, 0x11, 0x02, 0xff, 0xab, 0x08, 0x6c, 0x1e }, - { 0x52, 0x3a, 0x8a, 0x80, 0x6a, 0xe6, 0x21, 0xf1, // 256-bit key - 0x55, 0xfd, 0xd2, 0x8d, 0xbc, 0x34, 0xe1, 0xab, - 0x7b, 0x9b, 0x42, 0x43, 0x2a, 0xd8, 0xb2, 0xef, - 0xb9, 0x6e, 0x23, 0xb1, 0x3f, 0x0a, 0x6e, 0x52, - 0xf3, 0x61, 0x85, 0xd5, 0x0a, 0xd0, 0x02, 0xc5, - 0xf6, 0x01, 0xbe, 0xe5, 0x49, 0x3f, 0x11, 0x8b } -}; -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -static const uint8_t aria_test2_cfb_ct[3][48] = // CFB ciphertext -{ - { 0x37, 0x20, 0xe5, 0x3b, 0xa7, 0xd6, 0x15, 0x38, // 128-bit key - 0x34, 0x06, 0xb0, 0x9f, 0x0a, 0x05, 0xa2, 0x00, - 0xc0, 0x7c, 0x21, 0xe6, 0x37, 0x0f, 0x41, 0x3a, - 0x5d, 0x13, 0x25, 0x00, 0xa6, 0x82, 0x85, 0x01, - 0x7c, 0x61, 0xb4, 0x34, 0xc7, 0xb7, 0xca, 0x96, - 0x85, 0xa5, 0x10, 0x71, 0x86, 0x1e, 0x4d, 0x4b }, - { 0x41, 0x71, 0xf7, 0x19, 0x2b, 0xf4, 0x49, 0x54, // 192-bit key - 0x94, 0xd2, 0x73, 0x61, 0x29, 0x64, 0x0f, 0x5c, - 0x4d, 0x87, 0xa9, 0xa2, 0x13, 0x66, 0x4c, 0x94, - 0x48, 0x47, 0x7c, 0x6e, 0xcc, 0x20, 0x13, 0x59, - 0x8d, 0x97, 0x66, 0x95, 0x2d, 0xd8, 0xc3, 0x86, - 0x8f, 0x17, 0xe3, 0x6e, 0xf6, 0x6f, 0xd8, 0x4b }, - { 0x26, 0x83, 0x47, 0x05, 0xb0, 0xf2, 0xc0, 0xe2, // 256-bit key - 0x58, 0x8d, 0x4a, 0x7f, 0x09, 0x00, 0x96, 0x35, - 0xf2, 0x8b, 0xb9, 0x3d, 0x8c, 0x31, 0xf8, 0x70, - 0xec, 0x1e, 0x0b, 0xdb, 0x08, 0x2b, 0x66, 0xfa, - 0x40, 0x2d, 0xd9, 0xc2, 0x02, 0xbe, 0x30, 0x0c, - 0x45, 0x17, 0xd1, 0x96, 0xb1, 0x4d, 0x4c, 0xe1 } -}; -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -static const uint8_t aria_test2_ctr_ct[3][48] = // CTR ciphertext -{ - { 0xac, 0x5d, 0x7d, 0xe8, 0x05, 0xa0, 0xbf, 0x1c, // 128-bit key - 0x57, 0xc8, 0x54, 0x50, 0x1a, 0xf6, 0x0f, 0xa1, - 0x14, 0x97, 0xe2, 0xa3, 0x45, 0x19, 0xde, 0xa1, - 0x56, 0x9e, 0x91, 0xe5, 0xb5, 0xcc, 0xae, 0x2f, - 0xf3, 0xbf, 0xa1, 0xbf, 0x97, 0x5f, 0x45, 0x71, - 0xf4, 0x8b, 0xe1, 0x91, 0x61, 0x35, 0x46, 0xc3 }, - { 0x08, 0x62, 0x5c, 0xa8, 0xfe, 0x56, 0x9c, 0x19, // 192-bit key - 0xba, 0x7a, 0xf3, 0x76, 0x0a, 0x6e, 0xd1, 0xce, - 0xf4, 0xd1, 0x99, 0x26, 0x3e, 0x99, 0x9d, 0xde, - 0x14, 0x08, 0x2d, 0xbb, 0xa7, 0x56, 0x0b, 0x79, - 0xa4, 0xc6, 0xb4, 0x56, 0xb8, 0x70, 0x7d, 0xce, - 0x75, 0x1f, 0x98, 0x54, 0xf1, 0x88, 0x93, 0xdf }, - { 0x30, 0x02, 0x6c, 0x32, 0x96, 0x66, 0x14, 0x17, // 256-bit key - 0x21, 0x17, 0x8b, 0x99, 0xc0, 0xa1, 0xf1, 0xb2, - 0xf0, 0x69, 0x40, 0x25, 0x3f, 0x7b, 0x30, 0x89, - 0xe2, 0xa3, 0x0e, 0xa8, 0x6a, 0xa3, 0xc8, 0x8f, - 0x59, 0x40, 0xf0, 0x5a, 0xd7, 0xee, 0x41, 0xd7, - 0x13, 0x47, 0xbb, 0x72, 0x61, 0xe3, 0x48, 0xf1 } -}; -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#define ARIA_SELF_TEST_IF_FAIL \ - { \ - if( verbose ) \ - mbedtls_printf( "failed\n" ); \ - return( 1 ); \ - } else { \ - if( verbose ) \ - mbedtls_printf( "passed\n" ); \ - } - -/* - * Checkup routine - */ -int mbedtls_aria_self_test( int verbose ) -{ - int i; - uint8_t blk[MBEDTLS_ARIA_BLOCKSIZE]; - mbedtls_aria_context ctx; - -#if (defined(MBEDTLS_CIPHER_MODE_CFB) || defined(MBEDTLS_CIPHER_MODE_CTR)) - size_t j; -#endif - -#if (defined(MBEDTLS_CIPHER_MODE_CBC) || \ - defined(MBEDTLS_CIPHER_MODE_CFB) || \ - defined(MBEDTLS_CIPHER_MODE_CTR)) - uint8_t buf[48], iv[MBEDTLS_ARIA_BLOCKSIZE]; -#endif - - /* - * Test set 1 - */ - for( i = 0; i < 3; i++ ) - { - /* test ECB encryption */ - if( verbose ) - mbedtls_printf( " ARIA-ECB-%d (enc): ", 128 + 64 * i ); - mbedtls_aria_setkey_enc( &ctx, aria_test1_ecb_key, 128 + 64 * i ); - mbedtls_aria_crypt_ecb( &ctx, aria_test1_ecb_pt, blk ); - if( memcmp( blk, aria_test1_ecb_ct[i], MBEDTLS_ARIA_BLOCKSIZE ) != 0 ) - ARIA_SELF_TEST_IF_FAIL; - - /* test ECB decryption */ - if( verbose ) - mbedtls_printf( " ARIA-ECB-%d (dec): ", 128 + 64 * i ); - mbedtls_aria_setkey_dec( &ctx, aria_test1_ecb_key, 128 + 64 * i ); - mbedtls_aria_crypt_ecb( &ctx, aria_test1_ecb_ct[i], blk ); - if( memcmp( blk, aria_test1_ecb_pt, MBEDTLS_ARIA_BLOCKSIZE ) != 0 ) - ARIA_SELF_TEST_IF_FAIL; - } - if( verbose ) - mbedtls_printf( "\n" ); - - /* - * Test set 2 - */ -#if defined(MBEDTLS_CIPHER_MODE_CBC) - for( i = 0; i < 3; i++ ) - { - /* Test CBC encryption */ - if( verbose ) - mbedtls_printf( " ARIA-CBC-%d (enc): ", 128 + 64 * i ); - mbedtls_aria_setkey_enc( &ctx, aria_test2_key, 128 + 64 * i ); - memcpy( iv, aria_test2_iv, MBEDTLS_ARIA_BLOCKSIZE ); - memset( buf, 0x55, sizeof( buf ) ); - mbedtls_aria_crypt_cbc( &ctx, MBEDTLS_ARIA_ENCRYPT, 48, iv, - aria_test2_pt, buf ); - if( memcmp( buf, aria_test2_cbc_ct[i], 48 ) != 0 ) - ARIA_SELF_TEST_IF_FAIL; - - /* Test CBC decryption */ - if( verbose ) - mbedtls_printf( " ARIA-CBC-%d (dec): ", 128 + 64 * i ); - mbedtls_aria_setkey_dec( &ctx, aria_test2_key, 128 + 64 * i ); - memcpy( iv, aria_test2_iv, MBEDTLS_ARIA_BLOCKSIZE ); - memset( buf, 0xAA, sizeof( buf ) ); - mbedtls_aria_crypt_cbc( &ctx, MBEDTLS_ARIA_DECRYPT, 48, iv, - aria_test2_cbc_ct[i], buf ); - if( memcmp( buf, aria_test2_pt, 48 ) != 0 ) - ARIA_SELF_TEST_IF_FAIL; - } - if( verbose ) - mbedtls_printf( "\n" ); - -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) - for( i = 0; i < 3; i++ ) - { - /* Test CFB encryption */ - if( verbose ) - mbedtls_printf( " ARIA-CFB-%d (enc): ", 128 + 64 * i ); - mbedtls_aria_setkey_enc( &ctx, aria_test2_key, 128 + 64 * i ); - memcpy( iv, aria_test2_iv, MBEDTLS_ARIA_BLOCKSIZE ); - memset( buf, 0x55, sizeof( buf ) ); - j = 0; - mbedtls_aria_crypt_cfb128( &ctx, MBEDTLS_ARIA_ENCRYPT, 48, &j, iv, - aria_test2_pt, buf ); - if( memcmp( buf, aria_test2_cfb_ct[i], 48 ) != 0 ) - ARIA_SELF_TEST_IF_FAIL; - - /* Test CFB decryption */ - if( verbose ) - mbedtls_printf( " ARIA-CFB-%d (dec): ", 128 + 64 * i ); - mbedtls_aria_setkey_enc( &ctx, aria_test2_key, 128 + 64 * i ); - memcpy( iv, aria_test2_iv, MBEDTLS_ARIA_BLOCKSIZE ); - memset( buf, 0xAA, sizeof( buf ) ); - j = 0; - mbedtls_aria_crypt_cfb128( &ctx, MBEDTLS_ARIA_DECRYPT, 48, &j, - iv, aria_test2_cfb_ct[i], buf ); - if( memcmp( buf, aria_test2_pt, 48 ) != 0 ) - ARIA_SELF_TEST_IF_FAIL; - } - if( verbose ) - mbedtls_printf( "\n" ); -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) - for( i = 0; i < 3; i++ ) - { - /* Test CTR encryption */ - if( verbose ) - mbedtls_printf( " ARIA-CTR-%d (enc): ", 128 + 64 * i ); - mbedtls_aria_setkey_enc( &ctx, aria_test2_key, 128 + 64 * i ); - memset( iv, 0, MBEDTLS_ARIA_BLOCKSIZE ); // IV = 0 - memset( buf, 0x55, sizeof( buf ) ); - j = 0; - mbedtls_aria_crypt_ctr( &ctx, 48, &j, iv, blk, - aria_test2_pt, buf ); - if( memcmp( buf, aria_test2_ctr_ct[i], 48 ) != 0 ) - ARIA_SELF_TEST_IF_FAIL; - - /* Test CTR decryption */ - if( verbose ) - mbedtls_printf( " ARIA-CTR-%d (dec): ", 128 + 64 * i ); - mbedtls_aria_setkey_enc( &ctx, aria_test2_key, 128 + 64 * i ); - memset( iv, 0, MBEDTLS_ARIA_BLOCKSIZE ); // IV = 0 - memset( buf, 0xAA, sizeof( buf ) ); - j = 0; - mbedtls_aria_crypt_ctr( &ctx, 48, &j, iv, blk, - aria_test2_ctr_ct[i], buf ); - if( memcmp( buf, aria_test2_pt, 48 ) != 0 ) - ARIA_SELF_TEST_IF_FAIL; - } - if( verbose ) - mbedtls_printf( "\n" ); -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - - return( 0 ); -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_ARIA_C */ diff --git a/APP_Framework/Framework/security/mbedtls/aria.h b/APP_Framework/Framework/security/mbedtls/aria.h deleted file mode 100644 index 1e8956ed1..000000000 --- a/APP_Framework/Framework/security/mbedtls/aria.h +++ /dev/null @@ -1,370 +0,0 @@ -/** - * \file aria.h - * - * \brief ARIA block cipher - * - * The ARIA algorithm is a symmetric block cipher that can encrypt and - * decrypt information. It is defined by the Korean Agency for - * Technology and Standards (KATS) in KS X 1213:2004 (in - * Korean, but see http://210.104.33.10/ARIA/index-e.html in English) - * and also described by the IETF in RFC 5794. - */ -/* Copyright (C) 2006-2018, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -#ifndef MBEDTLS_ARIA_H -#define MBEDTLS_ARIA_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include -#include - -#include "platform_util.h" - -#define MBEDTLS_ARIA_ENCRYPT 1 /**< ARIA encryption. */ -#define MBEDTLS_ARIA_DECRYPT 0 /**< ARIA decryption. */ - -#define MBEDTLS_ARIA_BLOCKSIZE 16 /**< ARIA block size in bytes. */ -#define MBEDTLS_ARIA_MAX_ROUNDS 16 /**< Maxiumum number of rounds in ARIA. */ -#define MBEDTLS_ARIA_MAX_KEYSIZE 32 /**< Maximum size of an ARIA key in bytes. */ - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -#define MBEDTLS_ERR_ARIA_INVALID_KEY_LENGTH MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( -0x005C ) -#endif /* !MBEDTLS_DEPRECATED_REMOVED */ -#define MBEDTLS_ERR_ARIA_BAD_INPUT_DATA -0x005C /**< Bad input data. */ - -#define MBEDTLS_ERR_ARIA_INVALID_INPUT_LENGTH -0x005E /**< Invalid data input length. */ - -/* MBEDTLS_ERR_ARIA_FEATURE_UNAVAILABLE is deprecated and should not be used. - */ -#define MBEDTLS_ERR_ARIA_FEATURE_UNAVAILABLE -0x005A /**< Feature not available. For example, an unsupported ARIA key size. */ - -/* MBEDTLS_ERR_ARIA_HW_ACCEL_FAILED is deprecated and should not be used. */ -#define MBEDTLS_ERR_ARIA_HW_ACCEL_FAILED -0x0058 /**< ARIA hardware accelerator failed. */ - -#if !defined(MBEDTLS_ARIA_ALT) -// Regular implementation -// - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief The ARIA context-type definition. - */ -typedef struct mbedtls_aria_context -{ - unsigned char nr; /*!< The number of rounds (12, 14 or 16) */ - /*! The ARIA round keys. */ - uint32_t rk[MBEDTLS_ARIA_MAX_ROUNDS + 1][MBEDTLS_ARIA_BLOCKSIZE / 4]; -} -mbedtls_aria_context; - -#else /* MBEDTLS_ARIA_ALT */ -#include "aria_alt.h" -#endif /* MBEDTLS_ARIA_ALT */ - -/** - * \brief This function initializes the specified ARIA context. - * - * It must be the first API called before using - * the context. - * - * \param ctx The ARIA context to initialize. This must not be \c NULL. - */ -void mbedtls_aria_init( mbedtls_aria_context *ctx ); - -/** - * \brief This function releases and clears the specified ARIA context. - * - * \param ctx The ARIA context to clear. This may be \c NULL, in which - * case this function returns immediately. If it is not \c NULL, - * it must point to an initialized ARIA context. - */ -void mbedtls_aria_free( mbedtls_aria_context *ctx ); - -/** - * \brief This function sets the encryption key. - * - * \param ctx The ARIA context to which the key should be bound. - * This must be initialized. - * \param key The encryption key. This must be a readable buffer - * of size \p keybits Bits. - * \param keybits The size of \p key in Bits. Valid options are: - *
    • 128 bits
    • - *
    • 192 bits
    • - *
    • 256 bits
    - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_aria_setkey_enc( mbedtls_aria_context *ctx, - const unsigned char *key, - unsigned int keybits ); - -/** - * \brief This function sets the decryption key. - * - * \param ctx The ARIA context to which the key should be bound. - * This must be initialized. - * \param key The decryption key. This must be a readable buffer - * of size \p keybits Bits. - * \param keybits The size of data passed. Valid options are: - *
    • 128 bits
    • - *
    • 192 bits
    • - *
    • 256 bits
    - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_aria_setkey_dec( mbedtls_aria_context *ctx, - const unsigned char *key, - unsigned int keybits ); - -/** - * \brief This function performs an ARIA single-block encryption or - * decryption operation. - * - * It performs encryption or decryption (depending on whether - * the key was set for encryption on decryption) on the input - * data buffer defined in the \p input parameter. - * - * mbedtls_aria_init(), and either mbedtls_aria_setkey_enc() or - * mbedtls_aria_setkey_dec() must be called before the first - * call to this API with the same context. - * - * \param ctx The ARIA context to use for encryption or decryption. - * This must be initialized and bound to a key. - * \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. - * \return A negative error code on failure. - */ -int mbedtls_aria_crypt_ecb( mbedtls_aria_context *ctx, - const unsigned char input[MBEDTLS_ARIA_BLOCKSIZE], - unsigned char output[MBEDTLS_ARIA_BLOCKSIZE] ); - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -/** - * \brief This function performs an ARIA-CBC encryption or decryption operation - * on full blocks. - * - * 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_aria_init(), and either - * mbedtls_aria_setkey_enc() or mbedtls_aria_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 ARIA block size of 16 Bytes. - * - * \note Upon exit, the content of the IV is updated so that you can - * call the same function again on the next - * block(s) of data and get the same result as if it was - * encrypted in one call. This allows a "streaming" usage. - * If you need to retain the contents of the IV, you should - * either save it manually or use the cipher module instead. - * - * - * \param ctx The ARIA context to use for encryption or decryption. - * This must be initialized and bound to a key. - * \param mode The mode of operation. This must be either - * #MBEDTLS_ARIA_ENCRYPT for encryption, or - * #MBEDTLS_ARIA_DECRYPT for decryption. - * \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). - * This must be a readable buffer of size 16 Bytes. - * \param input The buffer holding the input data. This must - * be a readable buffer of length \p length Bytes. - * \param output The buffer holding the output data. This must - * be a writable buffer of length \p length Bytes. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_aria_crypt_cbc( mbedtls_aria_context *ctx, - int mode, - size_t length, - unsigned char iv[MBEDTLS_ARIA_BLOCKSIZE], - const unsigned char *input, - unsigned char *output ); -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -/** - * \brief This function performs an ARIA-CFB128 encryption or decryption - * operation. - * - * It performs the operation defined in the \p mode - * parameter (encrypt or decrypt), on the input data buffer - * defined in the \p input parameter. - * - * For CFB, you must set up the context with mbedtls_aria_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 - * call the same function again on the next - * block(s) of data and get the same result as if it was - * encrypted in one call. This allows a "streaming" usage. - * If you need to retain the contents of the - * IV, you must either save it manually or use the cipher - * module instead. - * - * - * \param ctx The ARIA context to use for encryption or decryption. - * This must be initialized and bound to a key. - * \param mode The mode of operation. This must be either - * #MBEDTLS_ARIA_ENCRYPT for encryption, or - * #MBEDTLS_ARIA_DECRYPT for decryption. - * \param length The length of the input data \p input in Bytes. - * \param iv_off The offset in IV (updated after use). - * This must not be larger than 15. - * \param iv The initialization vector (updated after use). - * This must be a readable buffer of size 16 Bytes. - * \param input The buffer holding the input data. This must - * be a readable buffer of length \p length Bytes. - * \param output The buffer holding the output data. This must - * be a writable buffer of length \p length Bytes. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_aria_crypt_cfb128( mbedtls_aria_context *ctx, - int mode, - size_t length, - size_t *iv_off, - unsigned char iv[MBEDTLS_ARIA_BLOCKSIZE], - const unsigned char *input, - unsigned char *output ); -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -/** - * \brief This function performs an ARIA-CTR encryption or decryption - * operation. - * - * This function performs the operation defined in the \p mode - * parameter (encrypt/decrypt), on the input data buffer - * defined in the \p input parameter. - * - * Due to the nature of CTR, you must use the same key schedule - * for both encryption and decryption operations. Therefore, you - * must use the context initialized with mbedtls_aria_setkey_enc() - * for both #MBEDTLS_ARIA_ENCRYPT and #MBEDTLS_ARIA_DECRYPT. - * - * \warning You must never reuse a nonce value with the same key. Doing so - * would void the encryption for the two messages encrypted with - * the same nonce and key. - * - * There are two common strategies for managing nonces with CTR: - * - * 1. You can handle everything as a single message processed over - * successive calls to this function. In that case, you want to - * set \p nonce_counter and \p nc_off to 0 for the first call, and - * then preserve the values of \p nonce_counter, \p nc_off and \p - * stream_block across calls to this function as they will be - * updated by this function. - * - * With this strategy, you must not encrypt more than 2**128 - * blocks of data with the same key. - * - * 2. You can encrypt separate messages by dividing the \p - * nonce_counter buffer in two areas: the first one used for a - * per-message nonce, handled by yourself, and the second one - * updated by this function internally. - * - * For example, you might reserve the first 12 bytes for the - * per-message nonce, and the last 4 bytes for internal use. In that - * case, before calling this function on a new message you need to - * set the first 12 bytes of \p nonce_counter to your chosen nonce - * value, the last 4 to 0, and \p nc_off to 0 (which will cause \p - * stream_block to be ignored). That way, you can encrypt at most - * 2**96 messages of up to 2**32 blocks each with the same key. - * - * The per-message nonce (or information sufficient to reconstruct - * it) needs to be communicated with the ciphertext and must be unique. - * The recommended way to ensure uniqueness is to use a message - * counter. An alternative is to generate random nonces, but this - * limits the number of messages that can be securely encrypted: - * for example, with 96-bit random nonces, you should not encrypt - * more than 2**32 messages with the same key. - * - * Note that for both stategies, sizes are measured in blocks and - * that an ARIA block is 16 bytes. - * - * \warning Upon return, \p stream_block contains sensitive data. Its - * content must not be written to insecure storage and should be - * securely discarded as soon as it's no longer needed. - * - * \param ctx The ARIA context to use for encryption or decryption. - * This must be initialized and bound to a key. - * \param length The length of the input data \p input in Bytes. - * \param nc_off The offset in Bytes in the current \p stream_block, - * for resuming within the current cipher stream. The - * offset pointer should be \c 0 at the start of a - * stream. This must not be larger than \c 15 Bytes. - * \param nonce_counter The 128-bit nonce and counter. This must point to - * a read/write buffer of length \c 16 bytes. - * \param stream_block The saved stream block for resuming. This must - * point to a read/write buffer of length \c 16 bytes. - * This is overwritten by the function. - * \param input The buffer holding the input data. This must - * be a readable buffer of length \p length Bytes. - * \param output The buffer holding the output data. This must - * be a writable buffer of length \p length Bytes. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_aria_crypt_ctr( mbedtls_aria_context *ctx, - size_t length, - size_t *nc_off, - unsigned char nonce_counter[MBEDTLS_ARIA_BLOCKSIZE], - unsigned char stream_block[MBEDTLS_ARIA_BLOCKSIZE], - const unsigned char *input, - unsigned char *output ); -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -#if defined(MBEDTLS_SELF_TEST) -/** - * \brief Checkup routine. - * - * \return \c 0 on success, or \c 1 on failure. - */ -int mbedtls_aria_self_test( int verbose ); -#endif /* MBEDTLS_SELF_TEST */ - -#ifdef __cplusplus -} -#endif - -#endif /* aria.h */ diff --git a/APP_Framework/Framework/security/mbedtls/asn1.h b/APP_Framework/Framework/security/mbedtls/asn1.h index 44cf94aa1..96c1c9a8a 100644 --- a/APP_Framework/Framework/security/mbedtls/asn1.h +++ b/APP_Framework/Framework/security/mbedtls/asn1.h @@ -31,7 +31,6 @@ #endif #include -#include #if defined(MBEDTLS_BIGNUM_C) #include "bignum.h" @@ -90,18 +89,6 @@ #define MBEDTLS_ASN1_CONSTRUCTED 0x20 #define MBEDTLS_ASN1_CONTEXT_SPECIFIC 0x80 -/* Slightly smaller way to check if tag is a string tag - * compared to canonical implementation. */ -#define MBEDTLS_ASN1_IS_STRING_TAG( tag ) \ - ( ( tag ) < 32u && ( \ - ( ( 1u << ( tag ) ) & ( ( 1u << MBEDTLS_ASN1_BMP_STRING ) | \ - ( 1u << MBEDTLS_ASN1_UTF8_STRING ) | \ - ( 1u << MBEDTLS_ASN1_T61_STRING ) | \ - ( 1u << MBEDTLS_ASN1_IA5_STRING ) | \ - ( 1u << MBEDTLS_ASN1_UNIVERSAL_STRING ) | \ - ( 1u << MBEDTLS_ASN1_PRINTABLE_STRING ) | \ - ( 1u << MBEDTLS_ASN1_BIT_STRING ) ) ) != 0 ) ) - /* * 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", @@ -130,11 +117,7 @@ */ #define MBEDTLS_OID_CMP(oid_str, oid_buf) \ ( ( MBEDTLS_OID_SIZE(oid_str) != (oid_buf)->len ) || \ - mbedtls_platform_memequal( (oid_str), (oid_buf)->p, (oid_buf)->len) != 0 ) - -#define MBEDTLS_OID_CMP_RAW(oid_str, oid_buf, oid_buf_len) \ - ( ( MBEDTLS_OID_SIZE(oid_str) != (oid_buf_len) ) || \ - mbedtls_platform_memequal( (oid_str), (oid_buf), (oid_buf_len) ) != 0 ) + memcmp( (oid_str), (oid_buf)->p, (oid_buf)->len) != 0 ) #ifdef __cplusplus extern "C" { @@ -277,97 +260,20 @@ int mbedtls_asn1_get_bitstring_null( unsigned char **p, const unsigned char *end size_t *len ); /** - * \brief Free a heap-allocated linked list presentation of - * an ASN.1 sequence, including the first element. + * \brief Parses and splits an ASN.1 "SEQUENCE OF " + * Updated the pointer to immediately behind the full sequence tag. * - * \param seq The address of the first sequence component. This may - * be \c NULL, in which case this functions returns - * immediately. - */ -void mbedtls_asn1_sequence_free( mbedtls_asn1_sequence *seq ); - -/** - * \brief This function parses and splits an ASN.1 "SEQUENCE OF " - * and updates the source buffer pointer to immediately behind - * the full sequence. - * - * \param p The address of the pointer to the beginning of the - * ASN.1 SEQUENCE OF structure, including ASN.1 tag+length header. - * On success, `*p` is advanced to point to the first byte - * following the parsed ASN.1 sequence. - * \param end The end of the ASN.1 input buffer starting at \p p. This is - * used for bounds checking. - * \param cur The address at which to store the first entry in the parsed - * sequence. Further entries are heap-allocated and referenced - * from \p cur. - * \param tag The common tag of the entries in the ASN.1 sequence. - * - * \note Ownership for the heap-allocated elements \c cur->next, - * \c cur->next->next, ..., is passed to the caller. It - * is hence the caller's responsibility to free them when - * no longer needed, and mbedtls_asn1_sequence_free() can - * be used for that, passing \c cur->next as the \c seq - * argument (or \p cur if \p cur itself was heap-allocated - * by the caller). + * \param p The position in the ASN.1 data + * \param end End of data + * \param cur First variable in the chain to fill + * \param tag Type of sequence * * \return 0 if successful or a specific ASN.1 error code. */ int mbedtls_asn1_get_sequence_of( unsigned char **p, const unsigned char *end, mbedtls_asn1_sequence *cur, - int tag ); - -/** - * \brief Traverse an ASN.1 SEQUENCE container and - * call a callback for each entry. - * - * \warning This function is still experimental and may change - * at any time. - * - * \param p The address of the pointer to the beginning of - * the ASN.1 SEQUENCE header. This is updated to - * point to the end of the ASN.1 SEQUENCE container - * on a successful invocation. - * \param end The end of the ASN.1 SEQUENCE container. - * \param tag_must_mask A mask to be applied to the ASN.1 tags found within - * the SEQUENCE before comparing to \p tag_must_value. - * \param tag_must_val The required value of each ASN.1 tag found in the - * SEQUENCE, after masking with \p tag_must_mask. - * Mismatching tags lead to an error. - * For example, a value of \c 0 for both \p tag_must_mask - * and \p tag_must_val means that every tag is allowed, - * while a value of \c 0xFF for \p tag_must_mask means - * that \p tag_must_val is the only allowed tag. - * \param tag_may_mask A mask to be applied to the ASN.1 tags found within - * the SEQUENCE before comparing to \p tag_may_value. - * \param tag_may_val The desired value of each ASN.1 tag found in the - * SEQUENCE, after masking with \p tag_may_mask. - * Mismatching tags will be silently ignored. - * For example, a value of \c 0 for \p tag_may_mask and - * \p tag_may_val means that any tag will be considered, - * while a value of \c 0xFF for \p tag_may_mask means - * that all tags with value different from \p tag_may_val - * will be ignored. - * \param cb The callback to trigger for each component - * in the ASN.1 SEQUENCE. If the callback returns - * a non-zero value, the function stops immediately, - * forwarding the callback's return value. - * \param ctx The context to be passed to the callback \p cb. - * - * \return \c 0 if successful the entire ASN.1 SEQUENCE - * was traversed without parsing or callback errors. - * \return A negative ASN.1 error code on a parsing failure. - * \return A non-zero error code forwarded from the callback - * \p cb in case the latter returns a non-zero value. - */ -int mbedtls_asn1_traverse_sequence_of( - unsigned char **p, - const unsigned char *end, - uint8_t tag_must_mask, uint8_t tag_must_val, - uint8_t tag_may_mask, uint8_t tag_may_val, - int (*cb)( void *ctx, int tag, - unsigned char* start, size_t len ), - void *ctx ); + int tag); #if defined(MBEDTLS_BIGNUM_C) /** diff --git a/APP_Framework/Framework/security/mbedtls/asn1parse.c b/APP_Framework/Framework/security/mbedtls/asn1parse.c index 997e51816..24898c795 100644 --- a/APP_Framework/Framework/security/mbedtls/asn1parse.c +++ b/APP_Framework/Framework/security/mbedtls/asn1parse.c @@ -28,7 +28,6 @@ #if defined(MBEDTLS_ASN1_PARSE_C) #include "asn1.h" -#include "platform_util.h" #include @@ -44,6 +43,11 @@ #define mbedtls_free free #endif +/* 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; +} + /* * ASN.1 DER decoding routines */ @@ -229,103 +233,6 @@ int mbedtls_asn1_get_bitstring_null( unsigned char **p, const unsigned char *end return( 0 ); } -void mbedtls_asn1_sequence_free( mbedtls_asn1_sequence *seq ) -{ - while( seq != NULL ) - { - mbedtls_asn1_sequence *next = seq->next; - mbedtls_platform_zeroize( seq, sizeof( *seq ) ); - mbedtls_free( seq ); - seq = next; - } -} - -/* - * Traverse an ASN.1 "SEQUENCE OF " - * and call a callback for each entry found. - */ -int mbedtls_asn1_traverse_sequence_of( - unsigned char **p, - const unsigned char *end, - uint8_t tag_must_mask, uint8_t tag_must_val, - uint8_t tag_may_mask, uint8_t tag_may_val, - int (*cb)( void *ctx, int tag, - unsigned char *start, size_t len ), - void *ctx ) -{ - int ret; - size_t len; - - /* Get main sequence tag */ - if( ( ret = mbedtls_asn1_get_tag( p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - { - return( ret ); - } - - if( *p + len != end ) - return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - while( *p < end ) - { - unsigned char const tag = *(*p)++; - - if( ( tag & tag_must_mask ) != tag_must_val ) - return( MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); - - if( ( ret = mbedtls_asn1_get_len( p, end, &len ) ) != 0 ) - return( ret ); - - if( ( tag & tag_may_mask ) == tag_may_val ) - { - if( cb != NULL ) - { - ret = cb( ctx, tag, *p, len ); - if( ret != 0 ) - return( ret ); - } - } - - *p += len; - } - - return( 0 ); -} - -typedef struct -{ - int tag; - mbedtls_asn1_sequence *cur; -} asn1_get_sequence_of_cb_ctx_t; - -static int asn1_get_sequence_of_cb( void *ctx, - int tag, - unsigned char *start, - size_t len ) -{ - asn1_get_sequence_of_cb_ctx_t *cb_ctx = - (asn1_get_sequence_of_cb_ctx_t *) ctx; - mbedtls_asn1_sequence *cur = - cb_ctx->cur; - - if( cur->buf.p != NULL ) - { - cur->next = - mbedtls_calloc( 1, sizeof( mbedtls_asn1_sequence ) ); - - if( cur->next == NULL ) - return( MBEDTLS_ERR_ASN1_ALLOC_FAILED ); - - cur = cur->next; - } - - cur->buf.p = start; - cur->buf.len = len; - cur->buf.tag = tag; - - cb_ctx->cur = cur; - return( 0 ); -} /* @@ -336,11 +243,49 @@ int mbedtls_asn1_get_sequence_of( unsigned char **p, mbedtls_asn1_sequence *cur, int tag) { - asn1_get_sequence_of_cb_ctx_t cb_ctx = { tag, cur }; - mbedtls_platform_memset( cur, 0, sizeof( mbedtls_asn1_sequence ) ); - return( mbedtls_asn1_traverse_sequence_of( - p, end, 0xFF, tag, 0, 0, - asn1_get_sequence_of_cb, &cb_ctx ) ); + int ret; + size_t len; + mbedtls_asn1_buf *buf; + + /* Get main sequence tag */ + if( ( ret = mbedtls_asn1_get_tag( p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) + return( ret ); + + if( *p + len != end ) + return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + + while( *p < end ) + { + buf = &(cur->buf); + buf->tag = **p; + + if( ( ret = mbedtls_asn1_get_tag( p, end, &buf->len, tag ) ) != 0 ) + return( ret ); + + buf->p = *p; + *p += buf->len; + + /* Allocate and assign next pointer */ + if( *p < end ) + { + cur->next = (mbedtls_asn1_sequence*)mbedtls_calloc( 1, + sizeof( mbedtls_asn1_sequence ) ); + + if( cur->next == NULL ) + return( MBEDTLS_ERR_ASN1_ALLOC_FAILED ); + + cur = cur->next; + } + } + + /* Set final sequence entry's next pointer to NULL */ + cur->next = NULL; + + if( *p != end ) + return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + + return( 0 ); } int mbedtls_asn1_get_alg( unsigned char **p, @@ -354,18 +299,21 @@ int mbedtls_asn1_get_alg( unsigned char **p, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) return( ret ); + if( ( end - *p ) < 1 ) + return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); + + alg->tag = **p; end = *p + len; if( ( ret = mbedtls_asn1_get_tag( p, end, &alg->len, MBEDTLS_ASN1_OID ) ) != 0 ) return( ret ); - alg->tag = MBEDTLS_ASN1_OID; alg->p = *p; *p += alg->len; if( *p == end ) { - mbedtls_platform_zeroize( params, sizeof(mbedtls_asn1_buf) ); + mbedtls_zeroize( params, sizeof(mbedtls_asn1_buf) ); return( 0 ); } @@ -410,7 +358,7 @@ void mbedtls_asn1_free_named_data( mbedtls_asn1_named_data *cur ) mbedtls_free( cur->oid.p ); mbedtls_free( cur->val.p ); - mbedtls_platform_zeroize( cur, sizeof( mbedtls_asn1_named_data ) ); + mbedtls_zeroize( cur, sizeof( mbedtls_asn1_named_data ) ); } void mbedtls_asn1_free_named_data_list( mbedtls_asn1_named_data **head ) @@ -431,7 +379,7 @@ mbedtls_asn1_named_data *mbedtls_asn1_find_named_data( mbedtls_asn1_named_data * while( list != NULL ) { if( list->oid.len == len && - mbedtls_platform_memequal( list->oid.p, oid, len ) == 0 ) + memcmp( list->oid.p, oid, len ) == 0 ) { break; } diff --git a/APP_Framework/Framework/security/mbedtls/asn1write.c b/APP_Framework/Framework/security/mbedtls/asn1write.c index a95e2c298..fdfe556d9 100644 --- a/APP_Framework/Framework/security/mbedtls/asn1write.c +++ b/APP_Framework/Framework/security/mbedtls/asn1write.c @@ -28,7 +28,6 @@ #if defined(MBEDTLS_ASN1_WRITE_C) #include "asn1write.h" -#include "platform_util.h" #include @@ -124,7 +123,7 @@ int mbedtls_asn1_write_raw_buffer( unsigned char **p, unsigned char *start, len = size; (*p) -= len; - mbedtls_platform_memcpy( *p, buf, len ); + memcpy( *p, buf, len ); return( (int) len ); } @@ -237,6 +236,9 @@ int mbedtls_asn1_write_int( unsigned char **p, unsigned char *start, int val ) int ret; size_t len = 0; + // DER format assumes 2s complement for numbers, so the leftmost bit + // should be 0 for positive numbers and 1 for negative numbers. + // if( *p - start < 1 ) return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); @@ -258,37 +260,34 @@ int mbedtls_asn1_write_int( unsigned char **p, unsigned char *start, int val ) return( (int) len ); } -int mbedtls_asn1_write_tagged_string( unsigned char **p, unsigned char *start, int tag, - const char *text, size_t text_len ) +int mbedtls_asn1_write_printable_string( unsigned char **p, unsigned char *start, + const char *text, size_t text_len ) { int ret; size_t len = 0; MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, - (const unsigned char *) text, text_len ) ); + (const unsigned char *) text, text_len ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, tag ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_PRINTABLE_STRING ) ); return( (int) len ); } -int mbedtls_asn1_write_utf8_string( unsigned char **p, unsigned char *start, - const char *text, size_t text_len ) -{ - return( mbedtls_asn1_write_tagged_string(p, start, MBEDTLS_ASN1_UTF8_STRING, text, text_len) ); -} - -int mbedtls_asn1_write_printable_string( unsigned char **p, unsigned char *start, - const char *text, size_t text_len ) -{ - return( mbedtls_asn1_write_tagged_string(p, start, MBEDTLS_ASN1_PRINTABLE_STRING, text, text_len) ); -} - int mbedtls_asn1_write_ia5_string( unsigned char **p, unsigned char *start, const char *text, size_t text_len ) { - return( mbedtls_asn1_write_tagged_string(p, start, MBEDTLS_ASN1_IA5_STRING, text, text_len) ); + int ret; + size_t len = 0; + + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, + (const unsigned char *) text, text_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_IA5_STRING ) ); + + return( (int) len ); } int mbedtls_asn1_write_bitstring( unsigned char **p, unsigned char *start, @@ -312,7 +311,7 @@ int mbedtls_asn1_write_bitstring( unsigned char **p, unsigned char *start, byte_len--; *--( *p ) = buf[byte_len] & ~( ( 0x1 << unused_bits ) - 1 ); ( *p ) -= byte_len; - mbedtls_platform_memcpy( *p, buf, byte_len ); + memcpy( *p, buf, byte_len ); } /* Write unused bits */ @@ -348,7 +347,7 @@ static mbedtls_asn1_named_data *asn1_find_named_data( while( list != NULL ) { if( list->oid.len == len && - mbedtls_platform_memequal( list->oid.p, oid, len ) == 0 ) + memcmp( list->oid.p, oid, len ) == 0 ) { break; } @@ -384,7 +383,7 @@ mbedtls_asn1_named_data *mbedtls_asn1_store_named_data( return( NULL ); } - mbedtls_platform_memcpy( cur->oid.p, oid, oid_len ); + memcpy( cur->oid.p, oid, oid_len ); cur->val.len = val_len; cur->val.p = mbedtls_calloc( 1, val_len ); @@ -415,7 +414,7 @@ mbedtls_asn1_named_data *mbedtls_asn1_store_named_data( } if( val != NULL ) - mbedtls_platform_memcpy( cur->val.p, val, val_len ); + memcpy( cur->val.p, val, val_len ); return( cur ); } diff --git a/APP_Framework/Framework/security/mbedtls/asn1write.h b/APP_Framework/Framework/security/mbedtls/asn1write.h index a19424369..083601af3 100644 --- a/APP_Framework/Framework/security/mbedtls/asn1write.h +++ b/APP_Framework/Framework/security/mbedtls/asn1write.h @@ -32,239 +32,161 @@ #include "asn1.h" -#define MBEDTLS_ASN1_CHK_ADD(g, f) \ - do \ - { \ - if( ( ret = (f) ) < 0 ) \ - return( ret ); \ - else \ - (g) += ret; \ - } while( 0 ) +#define MBEDTLS_ASN1_CHK_ADD(g, f) do { if( ( ret = f ) < 0 ) return( ret ); else \ + g += ret; } while( 0 ) #ifdef __cplusplus extern "C" { #endif /** - * \brief Write a length field in ASN.1 format. + * \brief Write a length field in ASN.1 format + * Note: function works backwards in data buffer * - * \note This function works backwards in data buffer. + * \param p reference to current position pointer + * \param start start of the buffer (for bounds-checking) + * \param len the length to write * - * \param p The reference to the current position pointer. - * \param start The start of the buffer, for bounds-checking. - * \param len The length value to write. - * - * \return The number of bytes written to \p p on success. - * \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure. + * \return the length written or a negative error code */ -int mbedtls_asn1_write_len( unsigned char **p, unsigned char *start, - size_t len ); -/** - * \brief Write an ASN.1 tag in ASN.1 format. - * - * \note This function works backwards in data buffer. - * - * \param p The reference to the current position pointer. - * \param start The start of the buffer, for bounds-checking. - * \param tag The tag to write. - * - * \return The number of bytes written to \p p on success. - * \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure. - */ -int mbedtls_asn1_write_tag( unsigned char **p, unsigned char *start, - unsigned char tag ); +int mbedtls_asn1_write_len( unsigned char **p, unsigned char *start, size_t len ); /** - * \brief Write raw buffer data. + * \brief Write a ASN.1 tag in ASN.1 format + * Note: function works backwards in data buffer * - * \note This function works backwards in data buffer. + * \param p reference to current position pointer + * \param start start of the buffer (for bounds-checking) + * \param tag the tag to write * - * \param p The reference to the current position pointer. - * \param start The start of the buffer, for bounds-checking. - * \param buf The data buffer to write. - * \param size The length of the data buffer. + * \return the length written or a negative error code + */ +int mbedtls_asn1_write_tag( unsigned char **p, unsigned char *start, + unsigned char tag ); + +/** + * \brief Write raw buffer data + * Note: function works backwards in data buffer * - * \return The number of bytes written to \p p on success. - * \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure. + * \param p reference to current position pointer + * \param start start of the buffer (for bounds-checking) + * \param buf data buffer to write + * \param size length of the data buffer + * + * \return the length written or a negative error code */ int mbedtls_asn1_write_raw_buffer( unsigned char **p, unsigned char *start, - const unsigned char *buf, size_t size ); + const unsigned char *buf, size_t size ); #if defined(MBEDTLS_BIGNUM_C) /** - * \brief Write a arbitrary-precision number (#MBEDTLS_ASN1_INTEGER) - * in ASN.1 format. + * \brief Write a big number (MBEDTLS_ASN1_INTEGER) in ASN.1 format + * Note: function works backwards in data buffer * - * \note This function works backwards in data buffer. + * \param p reference to current position pointer + * \param start start of the buffer (for bounds-checking) + * \param X the MPI to write * - * \param p The reference to the current position pointer. - * \param start The start of the buffer, for bounds-checking. - * \param X The MPI to write. - * - * \return The number of bytes written to \p p on success. - * \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure. + * \return the length written or a negative error code */ -int mbedtls_asn1_write_mpi( unsigned char **p, unsigned char *start, - const mbedtls_mpi *X ); +int mbedtls_asn1_write_mpi( unsigned char **p, unsigned char *start, const mbedtls_mpi *X ); #endif /* MBEDTLS_BIGNUM_C */ /** - * \brief Write a NULL tag (#MBEDTLS_ASN1_NULL) with zero data - * in ASN.1 format. + * \brief Write a NULL tag (MBEDTLS_ASN1_NULL) with zero data in ASN.1 format + * Note: function works backwards in data buffer * - * \note This function works backwards in data buffer. + * \param p reference to current position pointer + * \param start start of the buffer (for bounds-checking) * - * \param p The reference to the current position pointer. - * \param start The start of the buffer, for bounds-checking. - * - * \return The number of bytes written to \p p on success. - * \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure. + * \return the length written or a negative error code */ int mbedtls_asn1_write_null( unsigned char **p, unsigned char *start ); /** - * \brief Write an OID tag (#MBEDTLS_ASN1_OID) and data - * in ASN.1 format. + * \brief Write an OID tag (MBEDTLS_ASN1_OID) and data in ASN.1 format + * Note: function works backwards in data buffer * - * \note This function works backwards in data buffer. + * \param p reference to current position pointer + * \param start start of the buffer (for bounds-checking) + * \param oid the OID to write + * \param oid_len length of the OID * - * \param p The reference to the current position pointer. - * \param start The start of the buffer, for bounds-checking. - * \param oid The OID to write. - * \param oid_len The length of the OID. - * - * \return The number of bytes written to \p p on success. - * \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure. + * \return the length written or a negative error code */ int mbedtls_asn1_write_oid( unsigned char **p, unsigned char *start, - const char *oid, size_t oid_len ); + const char *oid, size_t oid_len ); /** - * \brief Write an AlgorithmIdentifier sequence in ASN.1 format. + * \brief Write an AlgorithmIdentifier sequence in ASN.1 format + * Note: function works backwards in data buffer * - * \note This function works backwards in data buffer. - * - * \param p The reference to the current position pointer. - * \param start The start of the buffer, for bounds-checking. - * \param oid The OID of the algorithm to write. - * \param oid_len The length of the algorithm's OID. - * \param par_len The length of the parameters, which must be already written. + * \param p reference to current position pointer + * \param start start of the buffer (for bounds-checking) + * \param oid the OID of the algorithm + * \param oid_len length of the OID + * \param par_len length of parameters, which must be already written. * If 0, NULL parameters are added * - * \return The number of bytes written to \p p on success. - * \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure. + * \return the length written or a negative error code */ -int mbedtls_asn1_write_algorithm_identifier( unsigned char **p, - unsigned char *start, - const char *oid, size_t oid_len, - size_t par_len ); +int mbedtls_asn1_write_algorithm_identifier( unsigned char **p, unsigned char *start, + const char *oid, size_t oid_len, + size_t par_len ); /** - * \brief Write a boolean tag (#MBEDTLS_ASN1_BOOLEAN) and value - * in ASN.1 format. + * \brief Write a boolean tag (MBEDTLS_ASN1_BOOLEAN) and value in ASN.1 format + * Note: function works backwards in data buffer * - * \note This function works backwards in data buffer. + * \param p reference to current position pointer + * \param start start of the buffer (for bounds-checking) + * \param boolean 0 or 1 * - * \param p The reference to the current position pointer. - * \param start The start of the buffer, for bounds-checking. - * \param boolean The boolean value to write, either \c 0 or \c 1. - * - * \return The number of bytes written to \p p on success. - * \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure. + * \return the length written or a negative error code */ -int mbedtls_asn1_write_bool( unsigned char **p, unsigned char *start, - int boolean ); +int mbedtls_asn1_write_bool( unsigned char **p, unsigned char *start, int boolean ); /** - * \brief Write an int tag (#MBEDTLS_ASN1_INTEGER) and value - * in ASN.1 format. + * \brief Write an int tag (MBEDTLS_ASN1_INTEGER) and value in ASN.1 format + * Note: function works backwards in data buffer * - * \note This function works backwards in data buffer. + * \param p reference to current position pointer + * \param start start of the buffer (for bounds-checking) + * \param val the integer value * - * \param p The reference to the current position pointer. - * \param start The start of the buffer, for bounds-checking. - * \param val The integer value to write. - * - * \return The number of bytes written to \p p on success. - * \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure. + * \return the length written or a negative error code */ int mbedtls_asn1_write_int( unsigned char **p, unsigned char *start, int val ); /** - * \brief Write a string in ASN.1 format using a specific - * string encoding tag. - - * \note This function works backwards in data buffer. + * \brief Write a printable string tag (MBEDTLS_ASN1_PRINTABLE_STRING) and + * value in ASN.1 format + * Note: function works backwards in data buffer * - * \param p The reference to the current position pointer. - * \param start The start of the buffer, for bounds-checking. - * \param tag The string encoding tag to write, e.g. - * #MBEDTLS_ASN1_UTF8_STRING. - * \param text The string to write. - * \param text_len The length of \p text in bytes (which might - * be strictly larger than the number of characters). + * \param p reference to current position pointer + * \param start start of the buffer (for bounds-checking) + * \param text the text to write + * \param text_len length of the text * - * \return The number of bytes written to \p p on success. - * \return A negative error code on failure. + * \return the length written or a negative error code */ -int mbedtls_asn1_write_tagged_string( unsigned char **p, unsigned char *start, - int tag, const char *text, - size_t text_len ); +int mbedtls_asn1_write_printable_string( unsigned char **p, unsigned char *start, + const char *text, size_t text_len ); /** - * \brief Write a string in ASN.1 format using the PrintableString - * string encoding tag (#MBEDTLS_ASN1_PRINTABLE_STRING). + * \brief Write an IA5 string tag (MBEDTLS_ASN1_IA5_STRING) and + * value in ASN.1 format + * Note: function works backwards in data buffer * - * \note This function works backwards in data buffer. + * \param p reference to current position pointer + * \param start start of the buffer (for bounds-checking) + * \param text the text to write + * \param text_len length of the text * - * \param p The reference to the current position pointer. - * \param start The start of the buffer, for bounds-checking. - * \param text The string to write. - * \param text_len The length of \p text in bytes (which might - * be strictly larger than the number of characters). - * - * \return The number of bytes written to \p p on success. - * \return A negative error code on failure. - */ -int mbedtls_asn1_write_printable_string( unsigned char **p, - unsigned char *start, - const char *text, size_t text_len ); - -/** - * \brief Write a UTF8 string in ASN.1 format using the UTF8String - * string encoding tag (#MBEDTLS_ASN1_PRINTABLE_STRING). - * - * \note This function works backwards in data buffer. - * - * \param p The reference to the current position pointer. - * \param start The start of the buffer, for bounds-checking. - * \param text The string to write. - * \param text_len The length of \p text in bytes (which might - * be strictly larger than the number of characters). - * - * \return The number of bytes written to \p p on success. - * \return A negative error code on failure. - */ -int mbedtls_asn1_write_utf8_string( unsigned char **p, unsigned char *start, - const char *text, size_t text_len ); - -/** - * \brief Write a string in ASN.1 format using the IA5String - * string encoding tag (#MBEDTLS_ASN1_IA5_STRING). - * - * \note This function works backwards in data buffer. - * - * \param p The reference to the current position pointer. - * \param start The start of the buffer, for bounds-checking. - * \param text The string to write. - * \param text_len The length of \p text in bytes (which might - * be strictly larger than the number of characters). - * - * \return The number of bytes written to \p p on success. - * \return A negative error code on failure. + * \return the length written or a negative error code */ int mbedtls_asn1_write_ia5_string( unsigned char **p, unsigned char *start, - const char *text, size_t text_len ); + const char *text, size_t text_len ); /** * \brief Write a bitstring tag (#MBEDTLS_ASN1_BIT_STRING) and @@ -281,7 +203,7 @@ int mbedtls_asn1_write_ia5_string( unsigned char **p, unsigned char *start, * \return A negative error code on failure. */ int mbedtls_asn1_write_bitstring( unsigned char **p, unsigned char *start, - const unsigned char *buf, size_t bits ); + const unsigned char *buf, size_t bits ); /** * \brief Write an octet string tag (#MBEDTLS_ASN1_OCTET_STRING) @@ -289,16 +211,15 @@ int mbedtls_asn1_write_bitstring( unsigned char **p, unsigned char *start, * * \note This function works backwards in data buffer. * - * \param p The reference to the current position pointer. - * \param start The start of the buffer, for bounds-checking. - * \param buf The buffer holding the data to write. - * \param size The length of the data buffer \p buf. + * \param p reference to current position pointer + * \param start start of the buffer (for bounds-checking) + * \param buf data buffer to write + * \param size length of the data buffer * - * \return The number of bytes written to \p p on success. - * \return A negative error code on failure. + * \return the length written or a negative error code */ int mbedtls_asn1_write_octet_string( unsigned char **p, unsigned char *start, - const unsigned char *buf, size_t size ); + const unsigned char *buf, size_t size ); /** * \brief Create or find a specific named_data entry for writing in a @@ -306,16 +227,15 @@ int mbedtls_asn1_write_octet_string( unsigned char **p, unsigned char *start, * a new entry is added to the head of the list. * Warning: Destructive behaviour for the val data! * - * \param list The pointer to the location of the head of the list to seek - * through (will be updated in case of a new entry). - * \param oid The OID to look for. - * \param oid_len The size of the OID. - * \param val The data to store (can be \c NULL if you want to fill - * it by hand). - * \param val_len The minimum length of the data buffer needed. + * \param list Pointer to the location of the head of the list to seek + * through (will be updated in case of a new entry) + * \param oid The OID to look for + * \param oid_len Size of the OID + * \param val Data to store (can be NULL if you want to fill it by hand) + * \param val_len Minimum length of the data buffer needed * - * \return A pointer to the new / existing entry on success. - * \return \c NULL if if there was a memory allocation error. + * \return NULL if if there was a memory allocation error, or a pointer + * to the new / existing entry. */ mbedtls_asn1_named_data *mbedtls_asn1_store_named_data( mbedtls_asn1_named_data **list, const char *oid, size_t oid_len, diff --git a/APP_Framework/Framework/security/mbedtls/base64.c b/APP_Framework/Framework/security/mbedtls/base64.c index 1dfec14e9..caa363545 100644 --- a/APP_Framework/Framework/security/mbedtls/base64.c +++ b/APP_Framework/Framework/security/mbedtls/base64.c @@ -260,7 +260,7 @@ int mbedtls_base64_self_test( int verbose ) src = base64_test_dec; if( mbedtls_base64_encode( buffer, sizeof( buffer ), &len, src, 64 ) != 0 || - memcmp( base64_test_enc, buffer, 88 ) != 0 ) + memcmp( base64_test_enc, buffer, 88 ) != 0 ) { if( verbose != 0 ) mbedtls_printf( "failed\n" ); @@ -274,7 +274,7 @@ int mbedtls_base64_self_test( int verbose ) src = base64_test_enc; if( mbedtls_base64_decode( buffer, sizeof( buffer ), &len, src, 88 ) != 0 || - memcmp( base64_test_dec, buffer, 64 ) != 0 ) + memcmp( base64_test_dec, buffer, 64 ) != 0 ) { if( verbose != 0 ) mbedtls_printf( "failed\n" ); diff --git a/APP_Framework/Framework/security/mbedtls/base64.h b/APP_Framework/Framework/security/mbedtls/base64.h index 0d024164c..10e4145ee 100644 --- a/APP_Framework/Framework/security/mbedtls/base64.h +++ b/APP_Framework/Framework/security/mbedtls/base64.h @@ -81,7 +81,6 @@ int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen, int mbedtls_base64_decode( unsigned char *dst, size_t dlen, size_t *olen, const unsigned char *src, size_t slen ); -#if defined(MBEDTLS_SELF_TEST) /** * \brief Checkup routine * @@ -89,8 +88,6 @@ int mbedtls_base64_decode( unsigned char *dst, size_t dlen, size_t *olen, */ int mbedtls_base64_self_test( int verbose ); -#endif /* MBEDTLS_SELF_TEST */ - #ifdef __cplusplus } #endif diff --git a/APP_Framework/Framework/security/mbedtls/bignum.c b/APP_Framework/Framework/security/mbedtls/bignum.c index 495624442..ed6261b86 100644 --- a/APP_Framework/Framework/security/mbedtls/bignum.c +++ b/APP_Framework/Framework/security/mbedtls/bignum.c @@ -45,7 +45,6 @@ #include "bignum.h" #include "bn_mul.h" -#include "platform_util.h" #include @@ -59,10 +58,15 @@ #define mbedtls_free free #endif -#define MPI_VALIDATE_RET( cond ) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_MPI_BAD_INPUT_DATA ) -#define MPI_VALIDATE( cond ) \ - MBEDTLS_INTERNAL_VALIDATE( cond ) +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_mpi_zeroize( mbedtls_mpi_uint *v, size_t n ) { + 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 biL (ciL << 3) /* bits in limb */ @@ -77,18 +81,13 @@ #define BITS_TO_LIMBS(i) ( (i) / biL + ( (i) % biL != 0 ) ) #define CHARS_TO_LIMBS(i) ( (i) / ciL + ( (i) % ciL != 0 ) ) -/* Implementation that should never be optimized out by the compiler */ -static void mbedtls_mpi_zeroize( mbedtls_mpi_uint *v, size_t n ) -{ - mbedtls_platform_zeroize( v, ciL * n ); -} - /* * Initialize one MPI */ void mbedtls_mpi_init( mbedtls_mpi *X ) { - MPI_VALIDATE( X != NULL ); + if( X == NULL ) + return; X->s = 1; X->n = 0; @@ -120,19 +119,18 @@ void mbedtls_mpi_free( mbedtls_mpi *X ) int mbedtls_mpi_grow( mbedtls_mpi *X, size_t nblimbs ) { mbedtls_mpi_uint *p; - MPI_VALIDATE_RET( X != NULL ); if( nblimbs > MBEDTLS_MPI_MAX_LIMBS ) return( MBEDTLS_ERR_MPI_ALLOC_FAILED ); if( X->n < nblimbs ) { - if( ( p = (mbedtls_mpi_uint *)mbedtls_calloc( nblimbs, ciL ) ) == NULL ) + if( ( p = (mbedtls_mpi_uint*)mbedtls_calloc( nblimbs, ciL ) ) == NULL ) return( MBEDTLS_ERR_MPI_ALLOC_FAILED ); if( X->p != NULL ) { - mbedtls_platform_memcpy( p, X->p, X->n * ciL ); + memcpy( p, X->p, X->n * ciL ); mbedtls_mpi_zeroize( X->p, X->n ); mbedtls_free( X->p ); } @@ -152,15 +150,10 @@ int mbedtls_mpi_shrink( mbedtls_mpi *X, size_t nblimbs ) { mbedtls_mpi_uint *p; size_t i; - MPI_VALIDATE_RET( X != NULL ); - if( nblimbs > MBEDTLS_MPI_MAX_LIMBS ) - return( MBEDTLS_ERR_MPI_ALLOC_FAILED ); - - /* Actually resize up if there are currently fewer than nblimbs limbs. */ + /* Actually resize up in this case */ if( X->n <= nblimbs ) return( mbedtls_mpi_grow( X, nblimbs ) ); - /* After this point, then X->n > nblimbs and in particular X->n > 0. */ for( i = X->n - 1; i > 0; i-- ) if( X->p[i] != 0 ) @@ -170,12 +163,12 @@ int mbedtls_mpi_shrink( mbedtls_mpi *X, size_t nblimbs ) if( i < nblimbs ) i = nblimbs; - if( ( p = (mbedtls_mpi_uint *)mbedtls_calloc( i, ciL ) ) == NULL ) + if( ( p = (mbedtls_mpi_uint*)mbedtls_calloc( i, ciL ) ) == NULL ) return( MBEDTLS_ERR_MPI_ALLOC_FAILED ); if( X->p != NULL ) { - mbedtls_platform_memcpy( p, X->p, i * ciL ); + memcpy( p, X->p, i * ciL ); mbedtls_mpi_zeroize( X->p, X->n ); mbedtls_free( X->p ); } @@ -191,15 +184,13 @@ int mbedtls_mpi_shrink( mbedtls_mpi *X, size_t nblimbs ) */ int mbedtls_mpi_copy( mbedtls_mpi *X, const mbedtls_mpi *Y ) { - int ret = 0; + int ret; size_t i; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( Y != NULL ); if( X == Y ) return( 0 ); - if( Y->n == 0 ) + if( Y->p == NULL ) { mbedtls_mpi_free( X ); return( 0 ); @@ -212,16 +203,10 @@ int mbedtls_mpi_copy( mbedtls_mpi *X, const mbedtls_mpi *Y ) X->s = Y->s; - if( X->n < i ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, i ) ); - } - else - { - mbedtls_platform_memset( X->p + i, 0, ( X->n - i ) * ciL ); - } + MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, i ) ); - mbedtls_platform_memcpy( X->p, Y->p, i * ciL ); + memset( X->p, 0, X->n * ciL ); + memcpy( X->p, Y->p, i * ciL ); cleanup: @@ -234,12 +219,10 @@ cleanup: void mbedtls_mpi_swap( mbedtls_mpi *X, mbedtls_mpi *Y ) { mbedtls_mpi T; - MPI_VALIDATE( X != NULL ); - MPI_VALIDATE( Y != NULL ); - mbedtls_platform_memcpy( &T, X, sizeof( mbedtls_mpi ) ); - mbedtls_platform_memcpy( X, Y, sizeof( mbedtls_mpi ) ); - mbedtls_platform_memcpy( Y, &T, sizeof( mbedtls_mpi ) ); + memcpy( &T, X, sizeof( mbedtls_mpi ) ); + memcpy( X, Y, sizeof( mbedtls_mpi ) ); + memcpy( Y, &T, sizeof( mbedtls_mpi ) ); } /* @@ -251,8 +234,6 @@ int mbedtls_mpi_safe_cond_assign( mbedtls_mpi *X, const mbedtls_mpi *Y, unsigned { int ret = 0; size_t i; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( Y != NULL ); /* make sure assign is 0 or 1 in a time-constant manner */ assign = (assign | (unsigned char)-assign) >> 7; @@ -282,8 +263,6 @@ int mbedtls_mpi_safe_cond_swap( mbedtls_mpi *X, mbedtls_mpi *Y, unsigned char sw int ret, s; size_t i; mbedtls_mpi_uint tmp; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( Y != NULL ); if( X == Y ) return( 0 ); @@ -316,10 +295,9 @@ cleanup: int mbedtls_mpi_lset( mbedtls_mpi *X, mbedtls_mpi_sint z ) { int ret; - MPI_VALIDATE_RET( X != NULL ); MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, 1 ) ); - mbedtls_platform_memset( X->p, 0, X->n * ciL ); + memset( X->p, 0, X->n * ciL ); X->p[0] = ( z < 0 ) ? -z : z; X->s = ( z < 0 ) ? -1 : 1; @@ -334,8 +312,6 @@ cleanup: */ int mbedtls_mpi_get_bit( const mbedtls_mpi *X, size_t pos ) { - MPI_VALIDATE_RET( X != NULL ); - if( X->n * biL <= pos ) return( 0 ); @@ -354,7 +330,6 @@ int mbedtls_mpi_set_bit( mbedtls_mpi *X, size_t pos, unsigned char val ) int ret = 0; size_t off = pos / biL; size_t idx = pos % biL; - MPI_VALIDATE_RET( X != NULL ); if( val != 0 && val != 1 ) return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); @@ -381,7 +356,6 @@ cleanup: size_t mbedtls_mpi_lsb( const mbedtls_mpi *X ) { size_t i, j, count = 0; - MBEDTLS_INTERNAL_VALIDATE_RET( X != NULL, 0 ); for( i = 0; i < X->n; i++ ) for( j = 0; j < biL; j++, count++ ) @@ -462,8 +436,6 @@ int mbedtls_mpi_read_string( mbedtls_mpi *X, int radix, const char *s ) size_t i, j, slen, n; mbedtls_mpi_uint d; mbedtls_mpi T; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( s != NULL ); if( radix < 2 || radix > 16 ) return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); @@ -558,7 +530,7 @@ static int mpi_write_hlp( mbedtls_mpi *X, int radix, length++; } while( mbedtls_mpi_cmp_int( X, 0 ) != 0 ); - MBEDTLS_MPI_CHK( mbedtls_platform_memmove( *p, p_end, length ) ); + memmove( *p, p_end, length ); *p += length; cleanup: @@ -576,27 +548,19 @@ int mbedtls_mpi_write_string( const mbedtls_mpi *X, int radix, size_t n; char *p; mbedtls_mpi T; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( olen != NULL ); - MPI_VALIDATE_RET( buflen == 0 || buf != NULL ); if( radix < 2 || radix > 16 ) return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); - n = mbedtls_mpi_bitlen( X ); /* Number of bits necessary to present `n`. */ - if( radix >= 4 ) n >>= 1; /* Number of 4-adic digits necessary to present - * `n`. If radix > 4, this might be a strict - * overapproximation of the number of - * radix-adic digits needed to present `n`. */ - if( radix >= 16 ) n >>= 1; /* Number of hexadecimal digits necessary to - * present `n`. */ - - n += 1; /* Terminating null byte */ - n += 1; /* Compensate for the divisions above, which round down `n` - * in case it's not even. */ - n += 1; /* Potential '-'-sign. */ - n += ( n & 1 ); /* Make n even to have enough space for hexadecimal writing, - * which always uses an even number of hex-digits. */ + n = mbedtls_mpi_bitlen( X ); + if( radix >= 4 ) n >>= 1; + if( radix >= 16 ) n >>= 1; + /* + * Round up the buffer length to an even value to ensure that there is + * enough room for hexadecimal values that can be represented in an odd + * number of digits. + */ + n += 3 + ( ( n + 1 ) & 1 ); if( buflen < n ) { @@ -608,10 +572,7 @@ int mbedtls_mpi_write_string( const mbedtls_mpi *X, int radix, mbedtls_mpi_init( &T ); if( X->s == -1 ) - { *p++ = '-'; - buflen--; - } if( radix == 16 ) { @@ -668,13 +629,7 @@ int mbedtls_mpi_read_file( mbedtls_mpi *X, int radix, FILE *fin ) */ char s[ MBEDTLS_MPI_RW_BUFFER_SIZE ]; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( fin != NULL ); - - if( radix < 2 || radix > 16 ) - return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); - - mbedtls_platform_memset( s, 0, sizeof( s ) ); + memset( s, 0, sizeof( s ) ); if( fgets( s, sizeof( s ) - 1, fin ) == NULL ) return( MBEDTLS_ERR_MPI_FILE_IO_ERROR ); @@ -705,12 +660,8 @@ int mbedtls_mpi_write_file( const char *p, const mbedtls_mpi *X, int radix, FILE * newline characters and '\0' */ char s[ MBEDTLS_MPI_RW_BUFFER_SIZE ]; - MPI_VALIDATE_RET( X != NULL ); - if( radix < 2 || radix > 16 ) - return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); - - mbedtls_platform_memset( s, 0, sizeof( s ) ); + memset( s, 0, sizeof( s ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_write_string( X, radix, s, sizeof( s ) - 2, &n ) ); @@ -736,109 +687,14 @@ cleanup: } #endif /* MBEDTLS_FS_IO */ - -/* Convert a big-endian byte array aligned to the size of mbedtls_mpi_uint - * into the storage form used by mbedtls_mpi. */ - -static mbedtls_mpi_uint mpi_uint_bigendian_to_host_c( mbedtls_mpi_uint x ) -{ - uint8_t i; - unsigned char *x_ptr; - mbedtls_mpi_uint tmp = 0; - - for( i = 0, x_ptr = (unsigned char*) &x; i < ciL; i++, x_ptr++ ) - { - tmp <<= CHAR_BIT; - tmp |= (mbedtls_mpi_uint) *x_ptr; - } - - return( tmp ); -} - -static mbedtls_mpi_uint mpi_uint_bigendian_to_host( mbedtls_mpi_uint x ) -{ -#if defined(__BYTE_ORDER__) - -/* Nothing to do on bigendian systems. */ -#if ( __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ ) - return( x ); -#endif /* __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ */ - -#if ( __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ ) - -/* For GCC and Clang, have builtins for byte swapping. */ -#if defined(__GNUC__) && defined(__GNUC_PREREQ) -#if __GNUC_PREREQ(4,3) -#define have_bswap -#endif -#endif - -#if defined(__clang__) && defined(__has_builtin) -#if __has_builtin(__builtin_bswap32) && \ - __has_builtin(__builtin_bswap64) -#define have_bswap -#endif -#endif - -#if defined(have_bswap) - /* The compiler is hopefully able to statically evaluate this! */ - switch( sizeof(mbedtls_mpi_uint) ) - { - case 4: - return( __builtin_bswap32(x) ); - case 8: - return( __builtin_bswap64(x) ); - } -#endif -#endif /* __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ */ -#endif /* __BYTE_ORDER__ */ - - /* Fall back to C-based reordering if we don't know the byte order - * or we couldn't use a compiler-specific builtin. */ - return( mpi_uint_bigendian_to_host_c( x ) ); -} - -static void mpi_bigendian_to_host( mbedtls_mpi_uint * const p, size_t limbs ) -{ - mbedtls_mpi_uint *cur_limb_left; - mbedtls_mpi_uint *cur_limb_right; - if( limbs == 0 ) - return; - - /* - * Traverse limbs and - * - adapt byte-order in each limb - * - swap the limbs themselves. - * For that, simultaneously traverse the limbs from left to right - * and from right to left, as long as the left index is not bigger - * than the right index (it's not a problem if limbs is odd and the - * indices coincide in the last iteration). - */ - for( cur_limb_left = p, cur_limb_right = p + ( limbs - 1 ); - cur_limb_left <= cur_limb_right; - cur_limb_left++, cur_limb_right-- ) - { - mbedtls_mpi_uint tmp; - /* Note that if cur_limb_left == cur_limb_right, - * this code effectively swaps the bytes only once. */ - tmp = mpi_uint_bigendian_to_host( *cur_limb_left ); - *cur_limb_left = mpi_uint_bigendian_to_host( *cur_limb_right ); - *cur_limb_right = tmp; - } -} - /* * Import X from unsigned binary data, big endian */ int mbedtls_mpi_read_binary( mbedtls_mpi *X, const unsigned char *buf, size_t buflen ) { int ret; - size_t const limbs = CHARS_TO_LIMBS( buflen ); - size_t const overhead = ( limbs * ciL ) - buflen; - unsigned char *Xp; - - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( buflen == 0 || buf != NULL ); + size_t i, j; + size_t const limbs = CHARS_TO_LIMBS( buflen ); /* Ensure that target MPI has exactly the necessary number of limbs */ if( X->n != limbs ) @@ -847,17 +703,11 @@ int mbedtls_mpi_read_binary( mbedtls_mpi *X, const unsigned char *buf, size_t bu mbedtls_mpi_init( X ); MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, limbs ) ); } + MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) ); - /* Avoid calling `mbedtls_platform_memcpy` with NULL source argument, - * even if buflen is 0. */ - if( buf != NULL ) - { - Xp = (unsigned char*) X->p; - mbedtls_platform_memcpy( Xp + overhead, buf, buflen ); - - mpi_bigendian_to_host( X->p, limbs ); - } + for( i = buflen, j = 0; i > 0; i--, j++ ) + X->p[j / ciL] |= ((mbedtls_mpi_uint) buf[i - 1]) << ((j % ciL) << 3); cleanup: @@ -870,16 +720,11 @@ cleanup: int mbedtls_mpi_write_binary( const mbedtls_mpi *X, unsigned char *buf, size_t buflen ) { - size_t stored_bytes; + size_t stored_bytes = X->n * ciL; size_t bytes_to_copy; unsigned char *p; size_t i; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( buflen == 0 || buf != NULL ); - - stored_bytes = X->n * ciL; - if( stored_bytes < buflen ) { /* There is enough space in the output buffer. Write initial @@ -889,7 +734,7 @@ int mbedtls_mpi_write_binary( const mbedtls_mpi *X, * number. */ bytes_to_copy = stored_bytes; p = buf + buflen - stored_bytes; - mbedtls_platform_memset( buf, 0, buflen - stored_bytes ); + memset( buf, 0, buflen - stored_bytes ); } else { @@ -918,7 +763,6 @@ int mbedtls_mpi_shift_l( mbedtls_mpi *X, size_t count ) int ret; size_t i, v0, t1; mbedtls_mpi_uint r0 = 0, r1; - MPI_VALIDATE_RET( X != NULL ); v0 = count / (biL ); t1 = count & (biL - 1); @@ -968,7 +812,6 @@ int mbedtls_mpi_shift_r( mbedtls_mpi *X, size_t count ) { size_t i, v0, v1; mbedtls_mpi_uint r0 = 0, r1; - MPI_VALIDATE_RET( X != NULL ); v0 = count / biL; v1 = count & (biL - 1); @@ -1011,8 +854,6 @@ int mbedtls_mpi_shift_r( mbedtls_mpi *X, size_t count ) int mbedtls_mpi_cmp_abs( const mbedtls_mpi *X, const mbedtls_mpi *Y ) { size_t i, j; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( Y != NULL ); for( i = X->n; i > 0; i-- ) if( X->p[i - 1] != 0 ) @@ -1043,8 +884,6 @@ int mbedtls_mpi_cmp_abs( const mbedtls_mpi *X, const mbedtls_mpi *Y ) int mbedtls_mpi_cmp_mpi( const mbedtls_mpi *X, const mbedtls_mpi *Y ) { size_t i, j; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( Y != NULL ); for( i = X->n; i > 0; i-- ) if( X->p[i - 1] != 0 ) @@ -1072,107 +911,6 @@ int mbedtls_mpi_cmp_mpi( const mbedtls_mpi *X, const mbedtls_mpi *Y ) return( 0 ); } -/** Decide if an integer is less than the other, without branches. - * - * \param x First integer. - * \param y Second integer. - * - * \return 1 if \p x is less than \p y, 0 otherwise - */ -static unsigned ct_lt_mpi_uint( const mbedtls_mpi_uint x, - const mbedtls_mpi_uint y ) -{ - mbedtls_mpi_uint ret; - mbedtls_mpi_uint cond; - - /* - * Check if the most significant bits (MSB) of the operands are different. - */ - cond = ( x ^ y ); - /* - * If the MSB are the same then the difference x-y will be negative (and - * have its MSB set to 1 during conversion to unsigned) if and only if x> ( biL - 1 ); - - return (unsigned) ret; -} - -/* - * Compare signed values in constant time - */ -int mbedtls_mpi_lt_mpi_ct( const mbedtls_mpi *X, const mbedtls_mpi *Y, - unsigned *ret ) -{ - size_t i; - /* The value of any of these variables is either 0 or 1 at all times. */ - unsigned cond, done, X_is_negative, Y_is_negative; - - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( Y != NULL ); - MPI_VALIDATE_RET( ret != NULL ); - - if( X->n != Y->n ) - return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - - /* - * Set sign_N to 1 if N >= 0, 0 if N < 0. - * We know that N->s == 1 if N >= 0 and N->s == -1 if N < 0. - */ - X_is_negative = ( X->s & 2 ) >> 1; - Y_is_negative = ( Y->s & 2 ) >> 1; - - /* - * If the signs are different, then the positive operand is the bigger. - * That is if X is negative (X_is_negative == 1), then X < Y is true and it - * is false if X is positive (X_is_negative == 0). - */ - cond = ( X_is_negative ^ Y_is_negative ); - *ret = cond & X_is_negative; - - /* - * This is a constant-time function. We might have the result, but we still - * need to go through the loop. Record if we have the result already. - */ - done = cond; - - for( i = X->n; i > 0; i-- ) - { - /* - * If Y->p[i - 1] < X->p[i - 1] then X < Y is true if and only if both - * X and Y are negative. - * - * Again even if we can make a decision, we just mark the result and - * the fact that we are done and continue looping. - */ - cond = ct_lt_mpi_uint( Y->p[i - 1], X->p[i - 1] ); - *ret |= cond & ( 1 - done ) & X_is_negative; - done |= cond; - - /* - * If X->p[i - 1] < Y->p[i - 1] then X < Y is true if and only if both - * X and Y are positive. - * - * Again even if we can make a decision, we just mark the result and - * the fact that we are done and continue looping. - */ - cond = ct_lt_mpi_uint( X->p[i - 1], Y->p[i - 1] ); - *ret |= cond & ( 1 - done ) & ( 1 - X_is_negative ); - done |= cond; - } - - return( 0 ); -} - /* * Compare signed values */ @@ -1180,7 +918,6 @@ int mbedtls_mpi_cmp_int( const mbedtls_mpi *X, mbedtls_mpi_sint z ) { mbedtls_mpi Y; mbedtls_mpi_uint p[1]; - MPI_VALIDATE_RET( X != NULL ); *p = ( z < 0 ) ? -z : z; Y.s = ( z < 0 ) ? -1 : 1; @@ -1198,9 +935,6 @@ int mbedtls_mpi_add_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi int ret; size_t i, j; mbedtls_mpi_uint *o, *p, c, tmp; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( A != NULL ); - MPI_VALIDATE_RET( B != NULL ); if( X == B ) { @@ -1266,7 +1000,7 @@ static void mpi_sub_hlp( size_t n, mbedtls_mpi_uint *s, mbedtls_mpi_uint *d ) while( c != 0 ) { z = ( *d < c ); *d -= c; - c = z; d++; + c = z; i++; d++; } } @@ -1278,9 +1012,6 @@ int mbedtls_mpi_sub_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi mbedtls_mpi TB; int ret; size_t n; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( A != NULL ); - MPI_VALIDATE_RET( B != NULL ); if( mbedtls_mpi_cmp_abs( A, B ) < 0 ) return( MBEDTLS_ERR_MPI_NEGATIVE_VALUE ); @@ -1321,12 +1052,8 @@ cleanup: */ int mbedtls_mpi_add_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B ) { - int ret, s; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( A != NULL ); - MPI_VALIDATE_RET( B != NULL ); + int ret, s = A->s; - s = A->s; if( A->s * B->s < 0 ) { if( mbedtls_mpi_cmp_abs( A, B ) >= 0 ) @@ -1356,12 +1083,8 @@ cleanup: */ int mbedtls_mpi_sub_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B ) { - int ret, s; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( A != NULL ); - MPI_VALIDATE_RET( B != NULL ); + int ret, s = A->s; - s = A->s; if( A->s * B->s > 0 ) { if( mbedtls_mpi_cmp_abs( A, B ) >= 0 ) @@ -1393,8 +1116,6 @@ int mbedtls_mpi_add_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint { mbedtls_mpi _B; mbedtls_mpi_uint p[1]; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( A != NULL ); p[0] = ( b < 0 ) ? -b : b; _B.s = ( b < 0 ) ? -1 : 1; @@ -1411,8 +1132,6 @@ int mbedtls_mpi_sub_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint { mbedtls_mpi _B; mbedtls_mpi_uint p[1]; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( A != NULL ); p[0] = ( b < 0 ) ? -b : b; _B.s = ( b < 0 ) ? -1 : 1; @@ -1502,9 +1221,6 @@ int mbedtls_mpi_mul_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi int ret; size_t i, j; mbedtls_mpi TA, TB; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( A != NULL ); - MPI_VALIDATE_RET( B != NULL ); mbedtls_mpi_init( &TA ); mbedtls_mpi_init( &TB ); @@ -1522,8 +1238,8 @@ int mbedtls_mpi_mul_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, i + j ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) ); - for( ; j > 0; j-- ) - mpi_mul_hlp( i, A->p, X->p + j - 1, B->p[j - 1] ); + for( i++; j > 0; j-- ) + mpi_mul_hlp( i - 1, A->p, X->p + j - 1, B->p[j - 1] ); X->s = A->s * B->s; @@ -1541,8 +1257,6 @@ int mbedtls_mpi_mul_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_uint { mbedtls_mpi _B; mbedtls_mpi_uint p[1]; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( A != NULL ); _B.s = 1; _B.n = 1; @@ -1651,14 +1365,11 @@ static mbedtls_mpi_uint mbedtls_int_div_int( mbedtls_mpi_uint u1, /* * Division by mbedtls_mpi: A = Q * B + R (HAC 14.20) */ -int mbedtls_mpi_div_mpi( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A, - const mbedtls_mpi *B ) +int mbedtls_mpi_div_mpi( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B ) { int ret; size_t i, n, t, k; mbedtls_mpi X, Y, Z, T1, T2; - MPI_VALIDATE_RET( A != NULL ); - MPI_VALIDATE_RET( B != NULL ); if( mbedtls_mpi_cmp_int( B, 0 ) == 0 ) return( MBEDTLS_ERR_MPI_DIVISION_BY_ZERO ); @@ -1769,13 +1480,10 @@ cleanup: /* * Division by int: A = Q * b + R */ -int mbedtls_mpi_div_int( mbedtls_mpi *Q, mbedtls_mpi *R, - const mbedtls_mpi *A, - mbedtls_mpi_sint b ) +int mbedtls_mpi_div_int( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A, mbedtls_mpi_sint b ) { mbedtls_mpi _B; mbedtls_mpi_uint p[1]; - MPI_VALIDATE_RET( A != NULL ); p[0] = ( b < 0 ) ? -b : b; _B.s = ( b < 0 ) ? -1 : 1; @@ -1791,9 +1499,6 @@ int mbedtls_mpi_div_int( mbedtls_mpi *Q, mbedtls_mpi *R, int mbedtls_mpi_mod_mpi( mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B ) { int ret; - MPI_VALIDATE_RET( R != NULL ); - MPI_VALIDATE_RET( A != NULL ); - MPI_VALIDATE_RET( B != NULL ); if( mbedtls_mpi_cmp_int( B, 0 ) < 0 ) return( MBEDTLS_ERR_MPI_NEGATIVE_VALUE ); @@ -1818,8 +1523,6 @@ int mbedtls_mpi_mod_int( mbedtls_mpi_uint *r, const mbedtls_mpi *A, mbedtls_mpi_ { size_t i; mbedtls_mpi_uint x, y, z; - MPI_VALIDATE_RET( r != NULL ); - MPI_VALIDATE_RET( A != NULL ); if( b == 0 ) return( MBEDTLS_ERR_MPI_DIVISION_BY_ZERO ); @@ -1899,7 +1602,7 @@ static int mpi_montmul( mbedtls_mpi *A, const mbedtls_mpi *B, const mbedtls_mpi if( T->n < N->n + 1 || T->p == NULL ) return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); - mbedtls_platform_memset( T->p, 0, T->n * ciL ); + memset( T->p, 0, T->n * ciL ); d = T->p; n = N->n; @@ -1919,7 +1622,7 @@ static int mpi_montmul( mbedtls_mpi *A, const mbedtls_mpi *B, const mbedtls_mpi *d++ = u0; d[n + 1] = 0; } - mbedtls_platform_memcpy( A->p, d, ( n + 1 ) * ciL ); + memcpy( A->p, d, ( n + 1 ) * ciL ); if( mbedtls_mpi_cmp_abs( A, N ) >= 0 ) mpi_sub_hlp( n, N->p, A->p ); @@ -1933,8 +1636,7 @@ static int mpi_montmul( mbedtls_mpi *A, const mbedtls_mpi *B, const mbedtls_mpi /* * Montgomery reduction: A = A * R^-1 mod N */ -static int mpi_montred( mbedtls_mpi *A, const mbedtls_mpi *N, - mbedtls_mpi_uint mm, const mbedtls_mpi *T ) +static int mpi_montred( mbedtls_mpi *A, const mbedtls_mpi *N, mbedtls_mpi_uint mm, const mbedtls_mpi *T ) { mbedtls_mpi_uint z = 1; mbedtls_mpi U; @@ -1948,9 +1650,7 @@ static int mpi_montred( mbedtls_mpi *A, const mbedtls_mpi *N, /* * Sliding-window exponentiation: X = A^E mod N (HAC 14.85) */ -int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, - const mbedtls_mpi *E, const mbedtls_mpi *N, - mbedtls_mpi *_RR ) +int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *E, const mbedtls_mpi *N, mbedtls_mpi *_RR ) { int ret; size_t wbits, wsize, one = 1; @@ -1960,11 +1660,6 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi RR, T, W[ 2 << MBEDTLS_MPI_WINDOW_SIZE ], Apos; int neg; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( A != NULL ); - MPI_VALIDATE_RET( E != NULL ); - MPI_VALIDATE_RET( N != NULL ); - if( mbedtls_mpi_cmp_int( N, 0 ) <= 0 || ( N->p[0] & 1 ) == 0 ) return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); @@ -1977,17 +1672,15 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, mpi_montg_init( &mm, N ); mbedtls_mpi_init( &RR ); mbedtls_mpi_init( &T ); mbedtls_mpi_init( &Apos ); - mbedtls_platform_memset( W, 0, sizeof( W ) ); + memset( W, 0, sizeof( W ) ); i = mbedtls_mpi_bitlen( E ); wsize = ( i > 671 ) ? 6 : ( i > 239 ) ? 5 : ( i > 79 ) ? 4 : ( i > 23 ) ? 3 : 1; -#if( MBEDTLS_MPI_WINDOW_SIZE < 6 ) if( wsize > MBEDTLS_MPI_WINDOW_SIZE ) wsize = MBEDTLS_MPI_WINDOW_SIZE; -#endif j = N->n + 1; MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, j ) ); @@ -2015,10 +1708,10 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &RR, &RR, N ) ); if( _RR != NULL ) - mbedtls_platform_memcpy( _RR, &RR, sizeof( mbedtls_mpi ) ); + memcpy( _RR, &RR, sizeof( mbedtls_mpi ) ); } else - mbedtls_platform_memcpy( &RR, _RR, sizeof( mbedtls_mpi ) ); + memcpy( &RR, _RR, sizeof( mbedtls_mpi ) ); /* * W[1] = A * R^2 * R^-1 mod N = A * R mod N @@ -2171,10 +1864,6 @@ int mbedtls_mpi_gcd( mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B size_t lz, lzt; mbedtls_mpi TG, TA, TB; - MPI_VALIDATE_RET( G != NULL ); - MPI_VALIDATE_RET( A != NULL ); - MPI_VALIDATE_RET( B != NULL ); - mbedtls_mpi_init( &TG ); mbedtls_mpi_init( &TA ); mbedtls_mpi_init( &TB ); MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TA, A ) ); @@ -2230,28 +1919,16 @@ int mbedtls_mpi_fill_random( mbedtls_mpi *X, size_t size, void *p_rng ) { int ret; - size_t const limbs = CHARS_TO_LIMBS( size ); - size_t const overhead = ( limbs * ciL ) - size; - unsigned char *Xp; + unsigned char buf[MBEDTLS_MPI_MAX_SIZE]; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( f_rng != NULL ); + if( size > MBEDTLS_MPI_MAX_SIZE ) + return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); - /* Ensure that target MPI has exactly the necessary number of limbs */ - if( X->n != limbs ) - { - mbedtls_mpi_free( X ); - mbedtls_mpi_init( X ); - MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, limbs ) ); - } - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) ); - - Xp = (unsigned char*) X->p; - f_rng( p_rng, Xp + overhead, size ); - - mpi_bigendian_to_host( X->p, limbs ); + MBEDTLS_MPI_CHK( f_rng( p_rng, buf, size ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( X, buf, size ) ); cleanup: + mbedtls_zeroize( buf, sizeof( buf ) ); return( ret ); } @@ -2262,9 +1939,6 @@ int mbedtls_mpi_inv_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi { int ret; mbedtls_mpi G, TA, TU, U1, U2, TB, TV, V1, V2; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( A != NULL ); - MPI_VALIDATE_RET( N != NULL ); if( mbedtls_mpi_cmp_int( N, 1 ) <= 0 ) return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); @@ -2424,11 +2098,7 @@ static int mpi_miller_rabin( const mbedtls_mpi *X, size_t rounds, size_t i, j, k, s; mbedtls_mpi W, R, T, A, RR; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( f_rng != NULL ); - - mbedtls_mpi_init( &W ); mbedtls_mpi_init( &R ); - mbedtls_mpi_init( &T ); mbedtls_mpi_init( &A ); + mbedtls_mpi_init( &W ); mbedtls_mpi_init( &R ); mbedtls_mpi_init( &T ); mbedtls_mpi_init( &A ); mbedtls_mpi_init( &RR ); /* @@ -2440,6 +2110,8 @@ static int mpi_miller_rabin( const mbedtls_mpi *X, size_t rounds, MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R, &W ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &R, s ) ); + i = mbedtls_mpi_bitlen( X ); + for( i = 0; i < rounds; i++ ) { /* @@ -2456,8 +2128,7 @@ static int mpi_miller_rabin( const mbedtls_mpi *X, size_t rounds, } if (count++ > 30) { - ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE; - goto cleanup; + return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE; } } while ( mbedtls_mpi_cmp_mpi( &A, &W ) >= 0 || @@ -2499,8 +2170,7 @@ static int mpi_miller_rabin( const mbedtls_mpi *X, size_t rounds, } cleanup: - mbedtls_mpi_free( &W ); mbedtls_mpi_free( &R ); - mbedtls_mpi_free( &T ); mbedtls_mpi_free( &A ); + mbedtls_mpi_free( &W ); mbedtls_mpi_free( &R ); mbedtls_mpi_free( &T ); mbedtls_mpi_free( &A ); mbedtls_mpi_free( &RR ); return( ret ); @@ -2509,14 +2179,12 @@ cleanup: /* * Pseudo-primality test: small factors, then Miller-Rabin */ -int mbedtls_mpi_is_prime_ext( const mbedtls_mpi *X, int rounds, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) +static int mpi_is_prime_internal( const mbedtls_mpi *X, int rounds, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) { int ret; mbedtls_mpi XX; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( f_rng != NULL ); XX.s = 1; XX.n = X->n; @@ -2540,7 +2208,6 @@ int mbedtls_mpi_is_prime_ext( const mbedtls_mpi *X, int rounds, return( mpi_miller_rabin( &XX, rounds, f_rng, p_rng ) ); } -#if !defined(MBEDTLS_DEPRECATED_REMOVED) /* * Pseudo-primality test, error probability 2^-80 */ @@ -2548,45 +2215,22 @@ int mbedtls_mpi_is_prime( const mbedtls_mpi *X, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) { - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( f_rng != NULL ); - - /* - * In the past our key generation aimed for an error rate of at most - * 2^-80. Since this function is deprecated, aim for the same certainty - * here as well. - */ - return( mbedtls_mpi_is_prime_ext( X, 40, f_rng, p_rng ) ); + return mpi_is_prime_internal( X, 40, f_rng, p_rng ); } -#endif /* * Prime number generation - * - * To generate an RSA key in a way recommended by FIPS 186-4, both primes must - * be either 1024 bits or 1536 bits long, and flags must contain - * MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR. */ -int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int flags, +int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int dh_flag, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) { -#ifdef MBEDTLS_HAVE_INT64 -// ceil(2^63.5) -#define CEIL_MAXUINT_DIV_SQRT2 0xb504f333f9de6485ULL -#else -// ceil(2^31.5) -#define CEIL_MAXUINT_DIV_SQRT2 0xb504f334U -#endif - int ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE; + int ret; size_t k, n; int rounds; mbedtls_mpi_uint r; mbedtls_mpi Y; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( f_rng != NULL ); - if( nbits < 3 || nbits > MBEDTLS_MPI_MAX_BITS ) return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); @@ -2594,89 +2238,78 @@ int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int flags, n = BITS_TO_LIMBS( nbits ); - if( ( flags & MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR ) == 0 ) + /* + * 2^-80 error probability, number of rounds chosen per HAC, table 4.4 + */ + rounds = ( ( nbits >= 1300 ) ? 2 : ( nbits >= 850 ) ? 3 : + ( nbits >= 650 ) ? 4 : ( nbits >= 350 ) ? 8 : + ( nbits >= 250 ) ? 12 : ( nbits >= 150 ) ? 18 : 27 ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( X, n * ciL, f_rng, p_rng ) ); + + k = mbedtls_mpi_bitlen( X ); + if( k > nbits ) MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( X, k - nbits + 1 ) ); + + mbedtls_mpi_set_bit( X, nbits-1, 1 ); + + X->p[0] |= 1; + + if( dh_flag == 0 ) { - /* - * 2^-80 error probability, number of rounds chosen per HAC, table 4.4 - */ - rounds = ( ( nbits >= 1300 ) ? 2 : ( nbits >= 850 ) ? 3 : - ( nbits >= 650 ) ? 4 : ( nbits >= 350 ) ? 8 : - ( nbits >= 250 ) ? 12 : ( nbits >= 150 ) ? 18 : 27 ); + while( ( ret = mpi_is_prime_internal( X, rounds, f_rng, p_rng ) ) != 0 ) + { + if( ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE ) + goto cleanup; + + MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 2 ) ); + } } else { /* - * 2^-100 error probability, number of rounds computed based on HAC, - * fact 4.48 + * An necessary condition for Y and X = 2Y + 1 to be prime + * is X = 2 mod 3 (which is equivalent to Y = 2 mod 3). + * Make sure it is satisfied, while keeping X = 3 mod 4 */ - rounds = ( ( nbits >= 1450 ) ? 4 : ( nbits >= 1150 ) ? 5 : - ( nbits >= 1000 ) ? 6 : ( nbits >= 850 ) ? 7 : - ( nbits >= 750 ) ? 8 : ( nbits >= 500 ) ? 13 : - ( nbits >= 250 ) ? 28 : ( nbits >= 150 ) ? 40 : 51 ); - } - while( 1 ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( X, n * ciL, f_rng, p_rng ) ); - /* make sure generated number is at least (nbits-1)+0.5 bits (FIPS 186-4 §B.3.3 steps 4.4, 5.5) */ - if( X->p[n-1] < CEIL_MAXUINT_DIV_SQRT2 ) continue; + X->p[0] |= 2; - k = n * biL; - if( k > nbits ) MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( X, k - nbits ) ); - X->p[0] |= 1; + MBEDTLS_MPI_CHK( mbedtls_mpi_mod_int( &r, X, 3 ) ); + if( r == 0 ) + MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 8 ) ); + else if( r == 1 ) + MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 4 ) ); - if( ( flags & MBEDTLS_MPI_GEN_PRIME_FLAG_DH ) == 0 ) + /* Set Y = (X-1) / 2, which is X / 2 because X is odd */ + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &Y, X ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &Y, 1 ) ); + + while( 1 ) { - ret = mbedtls_mpi_is_prime_ext( X, rounds, f_rng, p_rng ); + /* + * First, check small factors for X and Y + * before doing Miller-Rabin on any of them + */ + if( ( ret = mpi_check_small_factors( X ) ) == 0 && + ( ret = mpi_check_small_factors( &Y ) ) == 0 && + ( ret = mpi_miller_rabin( X, rounds, f_rng, p_rng ) ) + == 0 && + ( ret = mpi_miller_rabin( &Y, rounds, f_rng, p_rng ) ) + == 0 ) + { + break; + } if( ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE ) goto cleanup; - } - else - { + /* - * An necessary condition for Y and X = 2Y + 1 to be prime - * is X = 2 mod 3 (which is equivalent to Y = 2 mod 3). - * Make sure it is satisfied, while keeping X = 3 mod 4 + * Next candidates. We want to preserve Y = (X-1) / 2 and + * Y = 1 mod 2 and Y = 2 mod 3 (eq X = 3 mod 4 and X = 2 mod 3) + * so up Y by 6 and X by 12. */ - - X->p[0] |= 2; - - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_int( &r, X, 3 ) ); - if( r == 0 ) - MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 8 ) ); - else if( r == 1 ) - MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 4 ) ); - - /* Set Y = (X-1) / 2, which is X / 2 because X is odd */ - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &Y, X ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &Y, 1 ) ); - - while( 1 ) - { - /* - * First, check small factors for X and Y - * before doing Miller-Rabin on any of them - */ - if( ( ret = mpi_check_small_factors( X ) ) == 0 && - ( ret = mpi_check_small_factors( &Y ) ) == 0 && - ( ret = mpi_miller_rabin( X, rounds, f_rng, p_rng ) ) - == 0 && - ( ret = mpi_miller_rabin( &Y, rounds, f_rng, p_rng ) ) - == 0 ) - goto cleanup; - - if( ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE ) - goto cleanup; - - /* - * Next candidates. We want to preserve Y = (X-1) / 2 and - * Y = 1 mod 2 and Y = 2 mod 3 (eq X = 3 mod 4 and X = 2 mod 3) - * so up Y by 6 and X by 12. - */ - MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 12 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &Y, &Y, 6 ) ); - } + MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 12 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &Y, &Y, 6 ) ); } } diff --git a/APP_Framework/Framework/security/mbedtls/bignum.h b/APP_Framework/Framework/security/mbedtls/bignum.h index 22b373113..3bf02a7ee 100644 --- a/APP_Framework/Framework/security/mbedtls/bignum.h +++ b/APP_Framework/Framework/security/mbedtls/bignum.h @@ -46,12 +46,7 @@ #define MBEDTLS_ERR_MPI_NOT_ACCEPTABLE -0x000E /**< The input arguments are not acceptable. */ #define MBEDTLS_ERR_MPI_ALLOC_FAILED -0x0010 /**< Memory allocation failed. */ -#define MBEDTLS_MPI_CHK(f) \ - do \ - { \ - if( ( ret = (f) ) != 0 ) \ - goto cleanup; \ - } while( 0 ) +#define MBEDTLS_MPI_CHK(f) do { if( ( ret = f ) != 0 ) goto cleanup; } while( 0 ) /* * Maximum size MPIs are allowed to grow to in number of limbs. @@ -182,124 +177,99 @@ extern "C" { /** * \brief MPI structure */ -typedef struct mbedtls_mpi +typedef struct { - int s; /*!< Sign: -1 if the mpi is negative, 1 otherwise */ + int s; /*!< integer sign */ size_t n; /*!< total # of limbs */ mbedtls_mpi_uint *p; /*!< pointer to limbs */ } mbedtls_mpi; /** - * \brief Initialize an MPI context. - * - * This makes the MPI ready to be set or freed, + * \brief Initialize one MPI (make internal references valid) + * This just makes it ready to be set or freed, * but does not define a value for the MPI. * - * \param X The MPI context to initialize. This must not be \c NULL. + * \param X One MPI to initialize. */ void mbedtls_mpi_init( mbedtls_mpi *X ); /** - * \brief This function frees the components of an MPI context. + * \brief Unallocate one MPI * - * \param X The MPI context to be cleared. This may be \c NULL, - * in which case this function is a no-op. If it is - * not \c NULL, it must point to an initialized MPI. + * \param X One MPI to unallocate. */ void mbedtls_mpi_free( mbedtls_mpi *X ); /** - * \brief Enlarge an MPI to the specified number of limbs. + * \brief Enlarge to the specified number of limbs * - * \note This function does nothing if the MPI is - * already large enough. + * \param X MPI to grow + * \param nblimbs The target number of limbs * - * \param X The MPI to grow. It must be initialized. - * \param nblimbs The target number of limbs. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. - * \return Another negative error code on other kinds of failure. + * \return 0 if successful, + * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed */ int mbedtls_mpi_grow( mbedtls_mpi *X, size_t nblimbs ); /** - * \brief This function resizes an MPI downwards, keeping at least the - * specified number of limbs. + * \brief Resize down, keeping at least the specified number of limbs * - * If \c X is smaller than \c nblimbs, it is resized up - * instead. + * \param X MPI to shrink + * \param nblimbs The minimum number of limbs to keep * - * \param X The MPI to shrink. This must point to an initialized MPI. - * \param nblimbs The minimum number of limbs to keep. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed - * (this can only happen when resizing up). - * \return Another negative error code on other kinds of failure. + * \return 0 if successful, + * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed */ int mbedtls_mpi_shrink( mbedtls_mpi *X, size_t nblimbs ); /** - * \brief Make a copy of an MPI. + * \brief Copy the contents of Y into X * - * \param X The destination MPI. This must point to an initialized MPI. - * \param Y The source MPI. This must point to an initialized MPI. + * \param X Destination MPI + * \param Y Source MPI * - * \note The limb-buffer in the destination MPI is enlarged - * if necessary to hold the value in the source MPI. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. - * \return Another negative error code on other kinds of failure. + * \return 0 if successful, + * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed */ int mbedtls_mpi_copy( mbedtls_mpi *X, const mbedtls_mpi *Y ); /** - * \brief Swap the contents of two MPIs. + * \brief Swap the contents of X and Y * - * \param X The first MPI. It must be initialized. - * \param Y The second MPI. It must be initialized. + * \param X First MPI value + * \param Y Second MPI value */ void mbedtls_mpi_swap( mbedtls_mpi *X, mbedtls_mpi *Y ); /** - * \brief Perform a safe conditional copy of MPI which doesn't - * reveal whether the condition was true or not. + * \brief Safe conditional assignement X = Y if assign is 1 * - * \param X The MPI to conditionally assign to. This must point - * to an initialized MPI. - * \param Y The MPI to be assigned from. This must point to an - * initialized MPI. - * \param assign The condition deciding whether to perform the - * assignment or not. Possible values: - * * \c 1: Perform the assignment `X = Y`. - * * \c 0: Keep the original value of \p X. + * \param X MPI to conditionally assign to + * \param Y Value to be assigned + * \param assign 1: perform the assignment, 0: keep X's original value + * + * \return 0 if successful, + * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed, * * \note This function is equivalent to - * `if( assign ) mbedtls_mpi_copy( X, Y );` + * if( assign ) mbedtls_mpi_copy( X, Y ); * except that it avoids leaking any information about whether * the assignment was done or not (the above code may leak * information through branch prediction and/or memory access * patterns analysis). - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. - * \return Another negative error code on other kinds of failure. */ int mbedtls_mpi_safe_cond_assign( mbedtls_mpi *X, const mbedtls_mpi *Y, unsigned char assign ); /** - * \brief Perform a safe conditional swap which doesn't - * reveal whether the condition was true or not. + * \brief Safe conditional swap X <-> Y if swap is 1 * - * \param X The first MPI. This must be initialized. - * \param Y The second MPI. This must be initialized. - * \param assign The condition deciding whether to perform - * the swap or not. Possible values: - * * \c 1: Swap the values of \p X and \p Y. - * * \c 0: Keep the original values of \p X and \p Y. + * \param X First mbedtls_mpi value + * \param Y Second mbedtls_mpi value + * \param assign 1: perform the swap, 0: keep X and Y's original values + * + * \return 0 if successful, + * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed, * * \note This function is equivalent to * if( assign ) mbedtls_mpi_swap( X, Y ); @@ -307,530 +277,415 @@ int mbedtls_mpi_safe_cond_assign( mbedtls_mpi *X, const mbedtls_mpi *Y, unsigned * the assignment was done or not (the above code may leak * information through branch prediction and/or memory access * patterns analysis). - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. - * \return Another negative error code on other kinds of failure. - * */ int mbedtls_mpi_safe_cond_swap( mbedtls_mpi *X, mbedtls_mpi *Y, unsigned char assign ); /** - * \brief Store integer value in MPI. + * \brief Set value from integer * - * \param X The MPI to set. This must be initialized. - * \param z The value to use. + * \param X MPI to set + * \param z Value to use * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. - * \return Another negative error code on other kinds of failure. + * \return 0 if successful, + * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed */ int mbedtls_mpi_lset( mbedtls_mpi *X, mbedtls_mpi_sint z ); /** - * \brief Get a specific bit from an MPI. + * \brief Get a specific bit from X * - * \param X The MPI to query. This must be initialized. - * \param pos Zero-based index of the bit to query. + * \param X MPI to use + * \param pos Zero-based index of the bit in X * - * \return \c 0 or \c 1 on success, depending on whether bit \c pos - * of \c X is unset or set. - * \return A negative error code on failure. + * \return Either a 0 or a 1 */ int mbedtls_mpi_get_bit( const mbedtls_mpi *X, size_t pos ); /** - * \brief Modify a specific bit in an MPI. + * \brief Set a bit of X to a specific value of 0 or 1 * - * \note This function will grow the target MPI if necessary to set a - * bit to \c 1 in a not yet existing limb. It will not grow if - * the bit should be set to \c 0. + * \note Will grow X if necessary to set a bit to 1 in a not yet + * existing limb. Will not grow if bit should be set to 0 * - * \param X The MPI to modify. This must be initialized. - * \param pos Zero-based index of the bit to modify. - * \param val The desired value of bit \c pos: \c 0 or \c 1. + * \param X MPI to use + * \param pos Zero-based index of the bit in X + * \param val The value to set the bit to (0 or 1) * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. - * \return Another negative error code on other kinds of failure. + * \return 0 if successful, + * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed, + * MBEDTLS_ERR_MPI_BAD_INPUT_DATA if val is not 0 or 1 */ int mbedtls_mpi_set_bit( mbedtls_mpi *X, size_t pos, unsigned char val ); /** - * \brief Return the number of bits of value \c 0 before the - * least significant bit of value \c 1. + * \brief Return the number of zero-bits before the least significant + * '1' bit * - * \note This is the same as the zero-based index of - * the least significant bit of value \c 1. + * Note: Thus also the zero-based index of the least significant '1' bit * - * \param X The MPI to query. - * - * \return The number of bits of value \c 0 before the least significant - * bit of value \c 1 in \p X. + * \param X MPI to use */ size_t mbedtls_mpi_lsb( const mbedtls_mpi *X ); /** * \brief Return the number of bits up to and including the most - * significant bit of value \c 1. + * significant '1' bit' * - * * \note This is same as the one-based index of the most - * significant bit of value \c 1. + * Note: Thus also the one-based index of the most significant '1' bit * - * \param X The MPI to query. This must point to an initialized MPI. - * - * \return The number of bits up to and including the most - * significant bit of value \c 1. + * \param X MPI to use */ size_t mbedtls_mpi_bitlen( const mbedtls_mpi *X ); /** - * \brief Return the total size of an MPI value in bytes. + * \brief Return the total size in bytes * - * \param X The MPI to use. This must point to an initialized MPI. - * - * \note The value returned by this function may be less than - * the number of bytes used to store \p X internally. - * This happens if and only if there are trailing bytes - * of value zero. - * - * \return The least number of bytes capable of storing - * the absolute value of \p X. + * \param X MPI to use */ size_t mbedtls_mpi_size( const mbedtls_mpi *X ); /** - * \brief Import an MPI from an ASCII string. + * \brief Import from an ASCII string * - * \param X The destination MPI. This must point to an initialized MPI. - * \param radix The numeric base of the input string. - * \param s Null-terminated string buffer. + * \param X Destination MPI + * \param radix Input numeric base + * \param s Null-terminated string buffer * - * \return \c 0 if successful. - * \return A negative error code on failure. + * \return 0 if successful, or a MBEDTLS_ERR_MPI_XXX error code */ int mbedtls_mpi_read_string( mbedtls_mpi *X, int radix, const char *s ); /** - * \brief Export an MPI to an ASCII string. + * \brief Export into an ASCII string * - * \param X The source MPI. This must point to an initialized MPI. - * \param radix The numeric base of the output string. - * \param buf The buffer to write the string to. This must be writable - * buffer of length \p buflen Bytes. - * \param buflen The available size in Bytes of \p buf. - * \param olen The address at which to store the length of the string - * written, including the final \c NULL byte. This must - * not be \c NULL. + * \param X Source MPI + * \param radix Output numeric base + * \param buf Buffer to write the string to + * \param buflen Length of buf + * \param olen Length of the string written, including final NUL byte * - * \note You can call this function with `buflen == 0` to obtain the - * minimum required buffer size in `*olen`. + * \return 0 if successful, or a MBEDTLS_ERR_MPI_XXX error code. + * *olen is always updated to reflect the amount + * of data that has (or would have) been written. * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if the target buffer \p buf - * is too small to hold the value of \p X in the desired base. - * In this case, `*olen` is nonetheless updated to contain the - * size of \p buf required for a successful call. - * \return Another negative error code on different kinds of failure. + * \note Call this function with buflen = 0 to obtain the + * minimum required buffer size in *olen. */ int mbedtls_mpi_write_string( const mbedtls_mpi *X, int radix, char *buf, size_t buflen, size_t *olen ); #if defined(MBEDTLS_FS_IO) /** - * \brief Read an MPI from a line in an opened file. + * \brief Read MPI from a line in an opened file * - * \param X The destination MPI. This must point to an initialized MPI. - * \param radix The numeric base of the string representation used - * in the source line. - * \param fin The input file handle to use. This must not be \c NULL. + * \param X Destination MPI + * \param radix Input numeric base + * \param fin Input file handle + * + * \return 0 if successful, MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if + * the file read buffer is too small or a + * MBEDTLS_ERR_MPI_XXX error code * * \note On success, this function advances the file stream * to the end of the current line or to EOF. * - * The function returns \c 0 on an empty line. + * The function returns 0 on an empty line. * * Leading whitespaces are ignored, as is a - * '0x' prefix for radix \c 16. + * '0x' prefix for radix 16. * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if the file read buffer - * is too small. - * \return Another negative error code on failure. */ int mbedtls_mpi_read_file( mbedtls_mpi *X, int radix, FILE *fin ); /** - * \brief Export an MPI into an opened file. + * \brief Write X into an opened file, or stdout if fout is NULL * - * \param p A string prefix to emit prior to the MPI data. - * For example, this might be a label, or "0x" when - * printing in base \c 16. This may be \c NULL if no prefix - * is needed. - * \param X The source MPI. This must point to an initialized MPI. - * \param radix The numeric base to be used in the emitted string. - * \param fout The output file handle. This may be \c NULL, in which case - * the output is written to \c stdout. + * \param p Prefix, can be NULL + * \param X Source MPI + * \param radix Output numeric base + * \param fout Output file handle (can be NULL) * - * \return \c 0 if successful. - * \return A negative error code on failure. + * \return 0 if successful, or a MBEDTLS_ERR_MPI_XXX error code + * + * \note Set fout == NULL to print X on the console. */ -int mbedtls_mpi_write_file( const char *p, const mbedtls_mpi *X, - int radix, FILE *fout ); +int mbedtls_mpi_write_file( const char *p, const mbedtls_mpi *X, int radix, FILE *fout ); #endif /* MBEDTLS_FS_IO */ /** - * \brief Import an MPI from unsigned big endian binary data. + * \brief Import X from unsigned binary data, big endian * - * \param X The destination MPI. This must point to an initialized MPI. - * \param buf The input buffer. This must be a readable buffer of length - * \p buflen Bytes. - * \param buflen The length of the input buffer \p p in Bytes. + * \param X Destination MPI + * \param buf Input buffer + * \param buflen Input buffer size * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. - * \return Another negative error code on different kinds of failure. + * \return 0 if successful, + * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed */ -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 ); /** - * \brief Export an MPI into unsigned big endian binary data - * of fixed size. + * \brief Export X into unsigned binary data, big endian. + * Always fills the whole buffer, which will start with zeros + * if the number is smaller. * - * \param X The source MPI. This must point to an initialized MPI. - * \param buf The output buffer. This must be a writable buffer of length - * \p buflen Bytes. - * \param buflen The size of the output buffer \p buf in Bytes. + * \param X Source MPI + * \param buf Output buffer + * \param buflen Output buffer size * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p buf isn't - * large enough to hold the value of \p X. - * \return Another negative error code on different kinds of failure. + * \return 0 if successful, + * MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if buf isn't large enough */ -int mbedtls_mpi_write_binary( const mbedtls_mpi *X, unsigned char *buf, - size_t buflen ); +int mbedtls_mpi_write_binary( const mbedtls_mpi *X, unsigned char *buf, size_t buflen ); /** - * \brief Perform a left-shift on an MPI: X <<= count + * \brief Left-shift: X <<= count * - * \param X The MPI to shift. This must point to an initialized MPI. - * \param count The number of bits to shift by. + * \param X MPI to shift + * \param count Amount to shift * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return Another negative error code on different kinds of failure. + * \return 0 if successful, + * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed */ int mbedtls_mpi_shift_l( mbedtls_mpi *X, size_t count ); /** - * \brief Perform a right-shift on an MPI: X >>= count + * \brief Right-shift: X >>= count * - * \param X The MPI to shift. This must point to an initialized MPI. - * \param count The number of bits to shift by. + * \param X MPI to shift + * \param count Amount to shift * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return Another negative error code on different kinds of failure. + * \return 0 if successful, + * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed */ int mbedtls_mpi_shift_r( mbedtls_mpi *X, size_t count ); /** - * \brief Compare the absolute values of two MPIs. + * \brief Compare unsigned values * - * \param X The left-hand MPI. This must point to an initialized MPI. - * \param Y The right-hand MPI. This must point to an initialized MPI. + * \param X Left-hand MPI + * \param Y Right-hand MPI * - * \return \c 1 if `|X|` is greater than `|Y|`. - * \return \c -1 if `|X|` is lesser than `|Y|`. - * \return \c 0 if `|X|` is equal to `|Y|`. + * \return 1 if |X| is greater than |Y|, + * -1 if |X| is lesser than |Y| or + * 0 if |X| is equal to |Y| */ int mbedtls_mpi_cmp_abs( const mbedtls_mpi *X, const mbedtls_mpi *Y ); /** - * \brief Compare two MPIs. + * \brief Compare signed values * - * \param X The left-hand MPI. This must point to an initialized MPI. - * \param Y The right-hand MPI. This must point to an initialized MPI. + * \param X Left-hand MPI + * \param Y Right-hand MPI * - * \return \c 1 if \p X is greater than \p Y. - * \return \c -1 if \p X is lesser than \p Y. - * \return \c 0 if \p X is equal to \p Y. + * \return 1 if X is greater than Y, + * -1 if X is lesser than Y or + * 0 if X is equal to Y */ int mbedtls_mpi_cmp_mpi( const mbedtls_mpi *X, const mbedtls_mpi *Y ); /** - * \brief Check if an MPI is less than the other in constant time. + * \brief Compare signed values * - * \param X The left-hand MPI. This must point to an initialized MPI - * with the same allocated length as Y. - * \param Y The right-hand MPI. This must point to an initialized MPI - * with the same allocated length as X. - * \param ret The result of the comparison: - * \c 1 if \p X is less than \p Y. - * \c 0 if \p X is greater than or equal to \p Y. + * \param X Left-hand MPI + * \param z The integer value to compare to * - * \return 0 on success. - * \return MBEDTLS_ERR_MPI_BAD_INPUT_DATA if the allocated length of - * the two input MPIs is not the same. - */ -int mbedtls_mpi_lt_mpi_ct( const mbedtls_mpi *X, const mbedtls_mpi *Y, - unsigned *ret ); - -/** - * \brief Compare an MPI with an integer. - * - * \param X The left-hand MPI. This must point to an initialized MPI. - * \param z The integer value to compare \p X to. - * - * \return \c 1 if \p X is greater than \p z. - * \return \c -1 if \p X is lesser than \p z. - * \return \c 0 if \p X is equal to \p z. + * \return 1 if X is greater than z, + * -1 if X is lesser than z or + * 0 if X is equal to z */ int mbedtls_mpi_cmp_int( const mbedtls_mpi *X, mbedtls_mpi_sint z ); /** - * \brief Perform an unsigned addition of MPIs: X = |A| + |B| + * \brief Unsigned addition: X = |A| + |B| * - * \param X The destination MPI. This must point to an initialized MPI. - * \param A The first summand. This must point to an initialized MPI. - * \param B The second summand. This must point to an initialized MPI. + * \param X Destination MPI + * \param A Left-hand MPI + * \param B Right-hand MPI * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return Another negative error code on different kinds of failure. + * \return 0 if successful, + * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed */ -int mbedtls_mpi_add_abs( mbedtls_mpi *X, const mbedtls_mpi *A, - const mbedtls_mpi *B ); +int mbedtls_mpi_add_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B ); /** - * \brief Perform an unsigned subtraction of MPIs: X = |A| - |B| + * \brief Unsigned subtraction: X = |A| - |B| * - * \param X The destination MPI. This must point to an initialized MPI. - * \param A The minuend. This must point to an initialized MPI. - * \param B The subtrahend. This must point to an initialized MPI. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_NEGATIVE_VALUE if \p B is greater than \p A. - * \return Another negative error code on different kinds of failure. + * \param X Destination MPI + * \param A Left-hand MPI + * \param B Right-hand MPI * + * \return 0 if successful, + * MBEDTLS_ERR_MPI_NEGATIVE_VALUE if B is greater than A */ -int mbedtls_mpi_sub_abs( mbedtls_mpi *X, const mbedtls_mpi *A, - const mbedtls_mpi *B ); +int mbedtls_mpi_sub_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B ); /** - * \brief Perform a signed addition of MPIs: X = A + B + * \brief Signed addition: X = A + B * - * \param X The destination MPI. This must point to an initialized MPI. - * \param A The first summand. This must point to an initialized MPI. - * \param B The second summand. This must point to an initialized MPI. + * \param X Destination MPI + * \param A Left-hand MPI + * \param B Right-hand MPI * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return Another negative error code on different kinds of failure. + * \return 0 if successful, + * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed */ -int mbedtls_mpi_add_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, - const mbedtls_mpi *B ); +int mbedtls_mpi_add_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B ); /** - * \brief Perform a signed subtraction of MPIs: X = A - B + * \brief Signed subtraction: X = A - B * - * \param X The destination MPI. This must point to an initialized MPI. - * \param A The minuend. This must point to an initialized MPI. - * \param B The subtrahend. This must point to an initialized MPI. + * \param X Destination MPI + * \param A Left-hand MPI + * \param B Right-hand MPI * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return Another negative error code on different kinds of failure. + * \return 0 if successful, + * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed */ -int mbedtls_mpi_sub_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, - const mbedtls_mpi *B ); +int mbedtls_mpi_sub_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B ); /** - * \brief Perform a signed addition of an MPI and an integer: X = A + b + * \brief Signed addition: X = A + b * - * \param X The destination MPI. This must point to an initialized MPI. - * \param A The first summand. This must point to an initialized MPI. - * \param b The second summand. + * \param X Destination MPI + * \param A Left-hand MPI + * \param b The integer value to add * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return Another negative error code on different kinds of failure. + * \return 0 if successful, + * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed */ -int mbedtls_mpi_add_int( mbedtls_mpi *X, const mbedtls_mpi *A, - mbedtls_mpi_sint b ); +int mbedtls_mpi_add_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b ); /** - * \brief Perform a signed subtraction of an MPI and an integer: - * X = A - b + * \brief Signed subtraction: X = A - b * - * \param X The destination MPI. This must point to an initialized MPI. - * \param A The minuend. This must point to an initialized MPI. - * \param b The subtrahend. + * \param X Destination MPI + * \param A Left-hand MPI + * \param b The integer value to subtract * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return Another negative error code on different kinds of failure. + * \return 0 if successful, + * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed */ -int mbedtls_mpi_sub_int( mbedtls_mpi *X, const mbedtls_mpi *A, - mbedtls_mpi_sint b ); +int mbedtls_mpi_sub_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b ); /** - * \brief Perform a multiplication of two MPIs: X = A * B + * \brief Baseline multiplication: X = A * B * - * \param X The destination MPI. This must point to an initialized MPI. - * \param A The first factor. This must point to an initialized MPI. - * \param B The second factor. This must point to an initialized MPI. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return Another negative error code on different kinds of failure. + * \param X Destination MPI + * \param A Left-hand MPI + * \param B Right-hand MPI * + * \return 0 if successful, + * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed */ -int mbedtls_mpi_mul_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, - const mbedtls_mpi *B ); +int mbedtls_mpi_mul_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B ); /** - * \brief Perform a multiplication of an MPI with an unsigned integer: - * X = A * b + * \brief Baseline multiplication: X = A * b * - * \param X The destination MPI. This must point to an initialized MPI. - * \param A The first factor. This must point to an initialized MPI. - * \param b The second factor. + * \param X Destination MPI + * \param A Left-hand MPI + * \param b The unsigned integer value to multiply with * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return Another negative error code on different kinds of failure. + * \note b is unsigned * + * \return 0 if successful, + * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed */ -int mbedtls_mpi_mul_int( mbedtls_mpi *X, const mbedtls_mpi *A, - mbedtls_mpi_uint b ); +int mbedtls_mpi_mul_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_uint b ); /** - * \brief Perform a division with remainder of two MPIs: - * A = Q * B + R + * \brief Division by mbedtls_mpi: A = Q * B + R * - * \param Q The destination MPI for the quotient. - * This may be \c NULL if the value of the - * quotient is not needed. - * \param R The destination MPI for the remainder value. - * This may be \c NULL if the value of the - * remainder is not needed. - * \param A The dividend. This must point to an initialized MPi. - * \param B The divisor. This must point to an initialized MPI. + * \param Q Destination MPI for the quotient + * \param R Destination MPI for the rest value + * \param A Left-hand MPI + * \param B Right-hand MPI * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. - * \return #MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if \p B equals zero. - * \return Another negative error code on different kinds of failure. + * \return 0 if successful, + * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed, + * MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if B == 0 + * + * \note Either Q or R can be NULL. */ -int mbedtls_mpi_div_mpi( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A, - const mbedtls_mpi *B ); +int mbedtls_mpi_div_mpi( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B ); /** - * \brief Perform a division with remainder of an MPI by an integer: - * A = Q * b + R + * \brief Division by int: A = Q * b + R * - * \param Q The destination MPI for the quotient. - * This may be \c NULL if the value of the - * quotient is not needed. - * \param R The destination MPI for the remainder value. - * This may be \c NULL if the value of the - * remainder is not needed. - * \param A The dividend. This must point to an initialized MPi. - * \param b The divisor. + * \param Q Destination MPI for the quotient + * \param R Destination MPI for the rest value + * \param A Left-hand MPI + * \param b Integer to divide by * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. - * \return #MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if \p b equals zero. - * \return Another negative error code on different kinds of failure. + * \return 0 if successful, + * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed, + * MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if b == 0 + * + * \note Either Q or R can be NULL. */ -int mbedtls_mpi_div_int( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A, - mbedtls_mpi_sint b ); +int mbedtls_mpi_div_int( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A, mbedtls_mpi_sint b ); /** - * \brief Perform a modular reduction. R = A mod B + * \brief Modulo: R = A mod B * - * \param R The destination MPI for the residue value. - * This must point to an initialized MPI. - * \param A The MPI to compute the residue of. - * This must point to an initialized MPI. - * \param B The base of the modular reduction. - * This must point to an initialized MPI. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return #MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if \p B equals zero. - * \return #MBEDTLS_ERR_MPI_NEGATIVE_VALUE if \p B is negative. - * \return Another negative error code on different kinds of failure. + * \param R Destination MPI for the rest value + * \param A Left-hand MPI + * \param B Right-hand MPI * + * \return 0 if successful, + * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed, + * MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if B == 0, + * MBEDTLS_ERR_MPI_NEGATIVE_VALUE if B < 0 */ -int mbedtls_mpi_mod_mpi( mbedtls_mpi *R, const mbedtls_mpi *A, - const mbedtls_mpi *B ); +int mbedtls_mpi_mod_mpi( mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B ); /** - * \brief Perform a modular reduction with respect to an integer. - * r = A mod b + * \brief Modulo: r = A mod b * - * \param r The address at which to store the residue. - * This must not be \c NULL. - * \param A The MPI to compute the residue of. - * This must point to an initialized MPi. - * \param b The integer base of the modular reduction. + * \param r Destination mbedtls_mpi_uint + * \param A Left-hand MPI + * \param b Integer to divide by * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return #MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if \p b equals zero. - * \return #MBEDTLS_ERR_MPI_NEGATIVE_VALUE if \p b is negative. - * \return Another negative error code on different kinds of failure. + * \return 0 if successful, + * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed, + * MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if b == 0, + * MBEDTLS_ERR_MPI_NEGATIVE_VALUE if b < 0 */ -int mbedtls_mpi_mod_int( mbedtls_mpi_uint *r, const mbedtls_mpi *A, - mbedtls_mpi_sint b ); +int mbedtls_mpi_mod_int( mbedtls_mpi_uint *r, const mbedtls_mpi *A, mbedtls_mpi_sint b ); /** - * \brief Perform a sliding-window exponentiation: X = A^E mod N + * \brief Sliding-window exponentiation: X = A^E mod N * - * \param X The destination MPI. This must point to an initialized MPI. - * \param A The base of the exponentiation. - * This must point to an initialized MPI. - * \param E The exponent MPI. This must point to an initialized MPI. - * \param N The base for the modular reduction. This must point to an - * initialized MPI. - * \param _RR A helper MPI depending solely on \p N which can be used to - * speed-up multiple modular exponentiations for the same value - * of \p N. This may be \c NULL. If it is not \c NULL, it must - * point to an initialized MPI. If it hasn't been used after - * the call to mbedtls_mpi_init(), this function will compute - * the helper value and store it in \p _RR for reuse on - * subsequent calls to this function. Otherwise, the function - * will assume that \p _RR holds the helper value set by a - * previous call to mbedtls_mpi_exp_mod(), and reuse it. + * \param X Destination MPI + * \param A Left-hand MPI + * \param E Exponent MPI + * \param N Modular MPI + * \param _RR Speed-up MPI used for recalculations * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \c N is negative or - * even, or if \c E is negative. - * \return Another negative error code on different kinds of failures. + * \return 0 if successful, + * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed, + * MBEDTLS_ERR_MPI_BAD_INPUT_DATA if N is negative or even or + * if E is negative * + * \note _RR is used to avoid re-computing R*R mod N across + * multiple calls, which speeds up things a bit. It can + * be set to NULL if the extra performance is unneeded. */ -int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, - const mbedtls_mpi *E, const mbedtls_mpi *N, - mbedtls_mpi *_RR ); +int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *E, const mbedtls_mpi *N, mbedtls_mpi *_RR ); /** - * \brief Fill an MPI with a number of random bytes. + * \brief Fill an MPI X with size bytes of random * - * \param X The destination MPI. This must point to an initialized MPI. - * \param size The number of random bytes to generate. - * \param f_rng The RNG function to use. This must not be \c NULL. - * \param p_rng The RNG parameter to be passed to \p f_rng. This may be - * \c NULL if \p f_rng doesn't need a context argument. + * \param X Destination MPI + * \param size Size in bytes + * \param f_rng RNG function + * \param p_rng RNG parameter * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return Another negative error code on failure. + * \return 0 if successful, + * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed * - * \note The bytes obtained from the RNG are interpreted + * \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. */ @@ -839,135 +694,64 @@ int mbedtls_mpi_fill_random( mbedtls_mpi *X, size_t size, void *p_rng ); /** - * \brief Compute the greatest common divisor: G = gcd(A, B) + * \brief Greatest common divisor: G = gcd(A, B) * - * \param G The destination MPI. This must point to an initialized MPI. - * \param A The first operand. This must point to an initialized MPI. - * \param B The second operand. This must point to an initialized MPI. + * \param G Destination MPI + * \param A Left-hand MPI + * \param B Right-hand MPI * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return Another negative error code on different kinds of failure. + * \return 0 if successful, + * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed */ -int mbedtls_mpi_gcd( mbedtls_mpi *G, const mbedtls_mpi *A, - const mbedtls_mpi *B ); +int mbedtls_mpi_gcd( mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B ); /** - * \brief Compute the modular inverse: X = A^-1 mod N + * \brief Modular inverse: X = A^-1 mod N * - * \param X The destination MPI. This must point to an initialized MPI. - * \param A The MPI to calculate the modular inverse of. This must point - * to an initialized MPI. - * \param N The base of the modular inversion. This must point to an - * initialized MPI. + * \param X Destination MPI + * \param A Left-hand MPI + * \param N Right-hand MPI * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \p N is less than - * or equal to one. - * \return #MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if \p has no modular inverse - * with respect to \p N. + * \return 0 if successful, + * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed, + * MBEDTLS_ERR_MPI_BAD_INPUT_DATA if N is <= 1, + MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if A has no inverse mod N. */ -int mbedtls_mpi_inv_mod( mbedtls_mpi *X, const mbedtls_mpi *A, - const mbedtls_mpi *N ); - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -#if defined(MBEDTLS_DEPRECATED_WARNING) -#define MBEDTLS_DEPRECATED __attribute__((deprecated)) -#else -#define MBEDTLS_DEPRECATED -#endif -/** - * \brief Perform a Miller-Rabin primality test with error - * probability of 2-80. - * - * \deprecated Superseded by mbedtls_mpi_is_prime_ext() which allows - * specifying the number of Miller-Rabin rounds. - * - * \param X The MPI to check for primality. - * This must point to an initialized MPI. - * \param f_rng The RNG function to use. This must not be \c NULL. - * \param p_rng The RNG parameter to be passed to \p f_rng. - * This may be \c NULL if \p f_rng doesn't use a - * context parameter. - * - * \return \c 0 if successful, i.e. \p X is probably prime. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return #MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if \p X is not prime. - * \return Another negative error code on other kinds of failure. - */ -MBEDTLS_DEPRECATED int mbedtls_mpi_is_prime( const mbedtls_mpi *X, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ); -#undef MBEDTLS_DEPRECATED -#endif /* !MBEDTLS_DEPRECATED_REMOVED */ +int mbedtls_mpi_inv_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *N ); /** - * \brief Miller-Rabin primality test. + * \brief Miller-Rabin primality test * - * \warning If \p X is potentially generated by an adversary, for example - * when validating cryptographic parameters that you didn't - * generate yourself and that are supposed to be prime, then - * \p rounds should be at least the half of the security - * strength of the cryptographic algorithm. On the other hand, - * if \p X is chosen uniformly or non-adversially (as is the - * case when mbedtls_mpi_gen_prime calls this function), then - * \p rounds can be much lower. + * \param X MPI to check + * \param f_rng RNG function + * \param p_rng RNG parameter * - * \param X The MPI to check for primality. - * This must point to an initialized MPI. - * \param rounds The number of bases to perform the Miller-Rabin primality - * test for. The probability of returning 0 on a composite is - * at most 2-2*\p rounds. - * \param f_rng The RNG function to use. This must not be \c NULL. - * \param p_rng The RNG parameter to be passed to \p f_rng. - * This may be \c NULL if \p f_rng doesn't use - * a context parameter. - * - * \return \c 0 if successful, i.e. \p X is probably prime. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return #MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if \p X is not prime. - * \return Another negative error code on other kinds of failure. + * \return 0 if successful (probably prime), + * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed, + * MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if X is not prime */ -int mbedtls_mpi_is_prime_ext( const mbedtls_mpi *X, int rounds, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ); -/** - * \brief Flags for mbedtls_mpi_gen_prime() - * - * Each of these flags is a constraint on the result X returned by - * mbedtls_mpi_gen_prime(). - */ -typedef enum { - MBEDTLS_MPI_GEN_PRIME_FLAG_DH = 0x0001, /**< (X-1)/2 is prime too */ - MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR = 0x0002, /**< lower error rate from 2-80 to 2-128 */ -} mbedtls_mpi_gen_prime_flag_t; +int mbedtls_mpi_is_prime( const mbedtls_mpi *X, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ); /** - * \brief Generate a prime number. + * \brief Prime number generation * - * \param X The destination MPI to store the generated prime in. - * This must point to an initialized MPi. - * \param nbits The required size of the destination MPI in bits. - * This must be between \c 3 and #MBEDTLS_MPI_MAX_BITS. - * \param flags A mask of flags of type #mbedtls_mpi_gen_prime_flag_t. - * \param f_rng The RNG function to use. This must not be \c NULL. - * \param p_rng The RNG parameter to be passed to \p f_rng. - * This may be \c NULL if \p f_rng doesn't use - * a context parameter. + * \param X Destination MPI + * \param nbits Required size of X in bits + * ( 3 <= nbits <= MBEDTLS_MPI_MAX_BITS ) + * \param dh_flag If 1, then (X-1)/2 will be prime too + * \param f_rng RNG function + * \param p_rng RNG parameter * - * \return \c 0 if successful, in which case \p X holds a - * probably prime number. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if `nbits` is not between - * \c 3 and #MBEDTLS_MPI_MAX_BITS. + * \return 0 if successful (probably prime), + * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed, + * MBEDTLS_ERR_MPI_BAD_INPUT_DATA if nbits is < 3 */ -int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int flags, +int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int dh_flag, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); -#if defined(MBEDTLS_SELF_TEST) - /** * \brief Checkup routine * @@ -975,8 +759,6 @@ int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int flags, */ int mbedtls_mpi_self_test( int verbose ); -#endif /* MBEDTLS_SELF_TEST */ - #ifdef __cplusplus } #endif diff --git a/APP_Framework/Framework/security/mbedtls/blowfish.c b/APP_Framework/Framework/security/mbedtls/blowfish.c new file mode 100644 index 000000000..e9d8bba22 --- /dev/null +++ b/APP_Framework/Framework/security/mbedtls/blowfish.c @@ -0,0 +1,656 @@ +/* + * Blowfish implementation + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +/* + * The Blowfish block cipher was designed by Bruce Schneier in 1993. + * http://www.schneier.com/blowfish.html + * http://en.wikipedia.org/wiki/Blowfish_%28cipher%29 + * + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_BLOWFISH_C) + +#include "blowfish.h" + +#include + +#if !defined(MBEDTLS_BLOWFISH_ALT) + +/* 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; +} + +/* + * 32-bit integer manipulation macros (big endian) + */ +#ifndef GET_UINT32_BE +#define GET_UINT32_BE(n,b,i) \ +{ \ + (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ + | ( (uint32_t) (b)[(i) + 1] << 16 ) \ + | ( (uint32_t) (b)[(i) + 2] << 8 ) \ + | ( (uint32_t) (b)[(i) + 3] ); \ +} +#endif + +#ifndef PUT_UINT32_BE +#define PUT_UINT32_BE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) ); \ +} +#endif + +static const uint32_t P[MBEDTLS_BLOWFISH_ROUNDS + 2] = { + 0x243F6A88L, 0x85A308D3L, 0x13198A2EL, 0x03707344L, + 0xA4093822L, 0x299F31D0L, 0x082EFA98L, 0xEC4E6C89L, + 0x452821E6L, 0x38D01377L, 0xBE5466CFL, 0x34E90C6CL, + 0xC0AC29B7L, 0xC97C50DDL, 0x3F84D5B5L, 0xB5470917L, + 0x9216D5D9L, 0x8979FB1BL +}; + +/* declarations of data at the end of this file */ +static const uint32_t S[4][256]; + +static uint32_t F( mbedtls_blowfish_context *ctx, uint32_t x ) +{ + unsigned short a, b, c, d; + uint32_t y; + + d = (unsigned short)(x & 0xFF); + x >>= 8; + c = (unsigned short)(x & 0xFF); + x >>= 8; + b = (unsigned short)(x & 0xFF); + x >>= 8; + a = (unsigned short)(x & 0xFF); + y = ctx->S[0][a] + ctx->S[1][b]; + y = y ^ ctx->S[2][c]; + y = y + ctx->S[3][d]; + + return( y ); +} + +static void blowfish_enc( mbedtls_blowfish_context *ctx, uint32_t *xl, uint32_t *xr ) +{ + uint32_t Xl, Xr, temp; + short i; + + Xl = *xl; + Xr = *xr; + + for( i = 0; i < MBEDTLS_BLOWFISH_ROUNDS; ++i ) + { + Xl = Xl ^ ctx->P[i]; + Xr = F( ctx, Xl ) ^ Xr; + + temp = Xl; + Xl = Xr; + Xr = temp; + } + + temp = Xl; + Xl = Xr; + Xr = temp; + + Xr = Xr ^ ctx->P[MBEDTLS_BLOWFISH_ROUNDS]; + Xl = Xl ^ ctx->P[MBEDTLS_BLOWFISH_ROUNDS + 1]; + + *xl = Xl; + *xr = Xr; +} + +static void blowfish_dec( mbedtls_blowfish_context *ctx, uint32_t *xl, uint32_t *xr ) +{ + uint32_t Xl, Xr, temp; + short i; + + Xl = *xl; + Xr = *xr; + + for( i = MBEDTLS_BLOWFISH_ROUNDS + 1; i > 1; --i ) + { + Xl = Xl ^ ctx->P[i]; + Xr = F( ctx, Xl ) ^ Xr; + + temp = Xl; + Xl = Xr; + Xr = temp; + } + + temp = Xl; + Xl = Xr; + Xr = temp; + + Xr = Xr ^ ctx->P[1]; + Xl = Xl ^ ctx->P[0]; + + *xl = Xl; + *xr = Xr; +} + +void mbedtls_blowfish_init( mbedtls_blowfish_context *ctx ) +{ + memset( ctx, 0, sizeof( mbedtls_blowfish_context ) ); +} + +void mbedtls_blowfish_free( mbedtls_blowfish_context *ctx ) +{ + if( ctx == NULL ) + return; + + mbedtls_zeroize( ctx, sizeof( mbedtls_blowfish_context ) ); +} + +/* + * Blowfish key schedule + */ +int mbedtls_blowfish_setkey( mbedtls_blowfish_context *ctx, const unsigned char *key, + unsigned int keybits ) +{ + unsigned int i, j, k; + uint32_t data, datal, datar; + + if( keybits < MBEDTLS_BLOWFISH_MIN_KEY_BITS || keybits > MBEDTLS_BLOWFISH_MAX_KEY_BITS || + ( keybits % 8 ) ) + { + return( MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH ); + } + + keybits >>= 3; + + for( i = 0; i < 4; i++ ) + { + for( j = 0; j < 256; j++ ) + ctx->S[i][j] = S[i][j]; + } + + j = 0; + for( i = 0; i < MBEDTLS_BLOWFISH_ROUNDS + 2; ++i ) + { + data = 0x00000000; + for( k = 0; k < 4; ++k ) + { + data = ( data << 8 ) | key[j++]; + if( j >= keybits ) + j = 0; + } + ctx->P[i] = P[i] ^ data; + } + + datal = 0x00000000; + datar = 0x00000000; + + for( i = 0; i < MBEDTLS_BLOWFISH_ROUNDS + 2; i += 2 ) + { + blowfish_enc( ctx, &datal, &datar ); + ctx->P[i] = datal; + ctx->P[i + 1] = datar; + } + + for( i = 0; i < 4; i++ ) + { + for( j = 0; j < 256; j += 2 ) + { + blowfish_enc( ctx, &datal, &datar ); + ctx->S[i][j] = datal; + ctx->S[i][j + 1] = datar; + } + } + return( 0 ); +} + +/* + * Blowfish-ECB block encryption/decryption + */ +int mbedtls_blowfish_crypt_ecb( mbedtls_blowfish_context *ctx, + int mode, + const unsigned char input[MBEDTLS_BLOWFISH_BLOCKSIZE], + unsigned char output[MBEDTLS_BLOWFISH_BLOCKSIZE] ) +{ + uint32_t X0, X1; + + GET_UINT32_BE( X0, input, 0 ); + GET_UINT32_BE( X1, input, 4 ); + + if( mode == MBEDTLS_BLOWFISH_DECRYPT ) + { + blowfish_dec( ctx, &X0, &X1 ); + } + else /* MBEDTLS_BLOWFISH_ENCRYPT */ + { + blowfish_enc( ctx, &X0, &X1 ); + } + + PUT_UINT32_BE( X0, output, 0 ); + PUT_UINT32_BE( X1, output, 4 ); + + return( 0 ); +} + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +/* + * Blowfish-CBC buffer encryption/decryption + */ +int mbedtls_blowfish_crypt_cbc( mbedtls_blowfish_context *ctx, + int mode, + size_t length, + unsigned char iv[MBEDTLS_BLOWFISH_BLOCKSIZE], + const unsigned char *input, + unsigned char *output ) +{ + int i; + unsigned char temp[MBEDTLS_BLOWFISH_BLOCKSIZE]; + + if( length % MBEDTLS_BLOWFISH_BLOCKSIZE ) + return( MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH ); + + if( mode == MBEDTLS_BLOWFISH_DECRYPT ) + { + while( length > 0 ) + { + memcpy( temp, input, MBEDTLS_BLOWFISH_BLOCKSIZE ); + mbedtls_blowfish_crypt_ecb( ctx, mode, input, output ); + + for( i = 0; i < MBEDTLS_BLOWFISH_BLOCKSIZE;i++ ) + output[i] = (unsigned char)( output[i] ^ iv[i] ); + + memcpy( iv, temp, MBEDTLS_BLOWFISH_BLOCKSIZE ); + + input += MBEDTLS_BLOWFISH_BLOCKSIZE; + output += MBEDTLS_BLOWFISH_BLOCKSIZE; + length -= MBEDTLS_BLOWFISH_BLOCKSIZE; + } + } + else + { + while( length > 0 ) + { + for( i = 0; i < MBEDTLS_BLOWFISH_BLOCKSIZE; i++ ) + output[i] = (unsigned char)( input[i] ^ iv[i] ); + + mbedtls_blowfish_crypt_ecb( ctx, mode, output, output ); + memcpy( iv, output, MBEDTLS_BLOWFISH_BLOCKSIZE ); + + input += MBEDTLS_BLOWFISH_BLOCKSIZE; + output += MBEDTLS_BLOWFISH_BLOCKSIZE; + length -= MBEDTLS_BLOWFISH_BLOCKSIZE; + } + } + + return( 0 ); +} +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +/* + * Blowfish CFB buffer encryption/decryption + */ +int mbedtls_blowfish_crypt_cfb64( mbedtls_blowfish_context *ctx, + int mode, + size_t length, + size_t *iv_off, + unsigned char iv[MBEDTLS_BLOWFISH_BLOCKSIZE], + const unsigned char *input, + unsigned char *output ) +{ + int c; + size_t n = *iv_off; + + if( mode == MBEDTLS_BLOWFISH_DECRYPT ) + { + while( length-- ) + { + if( n == 0 ) + mbedtls_blowfish_crypt_ecb( ctx, MBEDTLS_BLOWFISH_ENCRYPT, iv, iv ); + + c = *input++; + *output++ = (unsigned char)( c ^ iv[n] ); + iv[n] = (unsigned char) c; + + n = ( n + 1 ) % MBEDTLS_BLOWFISH_BLOCKSIZE; + } + } + else + { + while( length-- ) + { + if( n == 0 ) + mbedtls_blowfish_crypt_ecb( ctx, MBEDTLS_BLOWFISH_ENCRYPT, iv, iv ); + + iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ ); + + n = ( n + 1 ) % MBEDTLS_BLOWFISH_BLOCKSIZE; + } + } + + *iv_off = n; + + return( 0 ); +} +#endif /*MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +/* + * Blowfish CTR buffer encryption/decryption + */ +int mbedtls_blowfish_crypt_ctr( mbedtls_blowfish_context *ctx, + size_t length, + size_t *nc_off, + unsigned char nonce_counter[MBEDTLS_BLOWFISH_BLOCKSIZE], + unsigned char stream_block[MBEDTLS_BLOWFISH_BLOCKSIZE], + const unsigned char *input, + unsigned char *output ) +{ + int c, i; + size_t n = *nc_off; + + while( length-- ) + { + if( n == 0 ) { + mbedtls_blowfish_crypt_ecb( ctx, MBEDTLS_BLOWFISH_ENCRYPT, nonce_counter, + stream_block ); + + for( i = MBEDTLS_BLOWFISH_BLOCKSIZE; i > 0; i-- ) + if( ++nonce_counter[i - 1] != 0 ) + break; + } + c = *input++; + *output++ = (unsigned char)( c ^ stream_block[n] ); + + n = ( n + 1 ) % MBEDTLS_BLOWFISH_BLOCKSIZE; + } + + *nc_off = n; + + return( 0 ); +} +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +static const uint32_t S[4][256] = { + { 0xD1310BA6L, 0x98DFB5ACL, 0x2FFD72DBL, 0xD01ADFB7L, + 0xB8E1AFEDL, 0x6A267E96L, 0xBA7C9045L, 0xF12C7F99L, + 0x24A19947L, 0xB3916CF7L, 0x0801F2E2L, 0x858EFC16L, + 0x636920D8L, 0x71574E69L, 0xA458FEA3L, 0xF4933D7EL, + 0x0D95748FL, 0x728EB658L, 0x718BCD58L, 0x82154AEEL, + 0x7B54A41DL, 0xC25A59B5L, 0x9C30D539L, 0x2AF26013L, + 0xC5D1B023L, 0x286085F0L, 0xCA417918L, 0xB8DB38EFL, + 0x8E79DCB0L, 0x603A180EL, 0x6C9E0E8BL, 0xB01E8A3EL, + 0xD71577C1L, 0xBD314B27L, 0x78AF2FDAL, 0x55605C60L, + 0xE65525F3L, 0xAA55AB94L, 0x57489862L, 0x63E81440L, + 0x55CA396AL, 0x2AAB10B6L, 0xB4CC5C34L, 0x1141E8CEL, + 0xA15486AFL, 0x7C72E993L, 0xB3EE1411L, 0x636FBC2AL, + 0x2BA9C55DL, 0x741831F6L, 0xCE5C3E16L, 0x9B87931EL, + 0xAFD6BA33L, 0x6C24CF5CL, 0x7A325381L, 0x28958677L, + 0x3B8F4898L, 0x6B4BB9AFL, 0xC4BFE81BL, 0x66282193L, + 0x61D809CCL, 0xFB21A991L, 0x487CAC60L, 0x5DEC8032L, + 0xEF845D5DL, 0xE98575B1L, 0xDC262302L, 0xEB651B88L, + 0x23893E81L, 0xD396ACC5L, 0x0F6D6FF3L, 0x83F44239L, + 0x2E0B4482L, 0xA4842004L, 0x69C8F04AL, 0x9E1F9B5EL, + 0x21C66842L, 0xF6E96C9AL, 0x670C9C61L, 0xABD388F0L, + 0x6A51A0D2L, 0xD8542F68L, 0x960FA728L, 0xAB5133A3L, + 0x6EEF0B6CL, 0x137A3BE4L, 0xBA3BF050L, 0x7EFB2A98L, + 0xA1F1651DL, 0x39AF0176L, 0x66CA593EL, 0x82430E88L, + 0x8CEE8619L, 0x456F9FB4L, 0x7D84A5C3L, 0x3B8B5EBEL, + 0xE06F75D8L, 0x85C12073L, 0x401A449FL, 0x56C16AA6L, + 0x4ED3AA62L, 0x363F7706L, 0x1BFEDF72L, 0x429B023DL, + 0x37D0D724L, 0xD00A1248L, 0xDB0FEAD3L, 0x49F1C09BL, + 0x075372C9L, 0x80991B7BL, 0x25D479D8L, 0xF6E8DEF7L, + 0xE3FE501AL, 0xB6794C3BL, 0x976CE0BDL, 0x04C006BAL, + 0xC1A94FB6L, 0x409F60C4L, 0x5E5C9EC2L, 0x196A2463L, + 0x68FB6FAFL, 0x3E6C53B5L, 0x1339B2EBL, 0x3B52EC6FL, + 0x6DFC511FL, 0x9B30952CL, 0xCC814544L, 0xAF5EBD09L, + 0xBEE3D004L, 0xDE334AFDL, 0x660F2807L, 0x192E4BB3L, + 0xC0CBA857L, 0x45C8740FL, 0xD20B5F39L, 0xB9D3FBDBL, + 0x5579C0BDL, 0x1A60320AL, 0xD6A100C6L, 0x402C7279L, + 0x679F25FEL, 0xFB1FA3CCL, 0x8EA5E9F8L, 0xDB3222F8L, + 0x3C7516DFL, 0xFD616B15L, 0x2F501EC8L, 0xAD0552ABL, + 0x323DB5FAL, 0xFD238760L, 0x53317B48L, 0x3E00DF82L, + 0x9E5C57BBL, 0xCA6F8CA0L, 0x1A87562EL, 0xDF1769DBL, + 0xD542A8F6L, 0x287EFFC3L, 0xAC6732C6L, 0x8C4F5573L, + 0x695B27B0L, 0xBBCA58C8L, 0xE1FFA35DL, 0xB8F011A0L, + 0x10FA3D98L, 0xFD2183B8L, 0x4AFCB56CL, 0x2DD1D35BL, + 0x9A53E479L, 0xB6F84565L, 0xD28E49BCL, 0x4BFB9790L, + 0xE1DDF2DAL, 0xA4CB7E33L, 0x62FB1341L, 0xCEE4C6E8L, + 0xEF20CADAL, 0x36774C01L, 0xD07E9EFEL, 0x2BF11FB4L, + 0x95DBDA4DL, 0xAE909198L, 0xEAAD8E71L, 0x6B93D5A0L, + 0xD08ED1D0L, 0xAFC725E0L, 0x8E3C5B2FL, 0x8E7594B7L, + 0x8FF6E2FBL, 0xF2122B64L, 0x8888B812L, 0x900DF01CL, + 0x4FAD5EA0L, 0x688FC31CL, 0xD1CFF191L, 0xB3A8C1ADL, + 0x2F2F2218L, 0xBE0E1777L, 0xEA752DFEL, 0x8B021FA1L, + 0xE5A0CC0FL, 0xB56F74E8L, 0x18ACF3D6L, 0xCE89E299L, + 0xB4A84FE0L, 0xFD13E0B7L, 0x7CC43B81L, 0xD2ADA8D9L, + 0x165FA266L, 0x80957705L, 0x93CC7314L, 0x211A1477L, + 0xE6AD2065L, 0x77B5FA86L, 0xC75442F5L, 0xFB9D35CFL, + 0xEBCDAF0CL, 0x7B3E89A0L, 0xD6411BD3L, 0xAE1E7E49L, + 0x00250E2DL, 0x2071B35EL, 0x226800BBL, 0x57B8E0AFL, + 0x2464369BL, 0xF009B91EL, 0x5563911DL, 0x59DFA6AAL, + 0x78C14389L, 0xD95A537FL, 0x207D5BA2L, 0x02E5B9C5L, + 0x83260376L, 0x6295CFA9L, 0x11C81968L, 0x4E734A41L, + 0xB3472DCAL, 0x7B14A94AL, 0x1B510052L, 0x9A532915L, + 0xD60F573FL, 0xBC9BC6E4L, 0x2B60A476L, 0x81E67400L, + 0x08BA6FB5L, 0x571BE91FL, 0xF296EC6BL, 0x2A0DD915L, + 0xB6636521L, 0xE7B9F9B6L, 0xFF34052EL, 0xC5855664L, + 0x53B02D5DL, 0xA99F8FA1L, 0x08BA4799L, 0x6E85076AL }, + { 0x4B7A70E9L, 0xB5B32944L, 0xDB75092EL, 0xC4192623L, + 0xAD6EA6B0L, 0x49A7DF7DL, 0x9CEE60B8L, 0x8FEDB266L, + 0xECAA8C71L, 0x699A17FFL, 0x5664526CL, 0xC2B19EE1L, + 0x193602A5L, 0x75094C29L, 0xA0591340L, 0xE4183A3EL, + 0x3F54989AL, 0x5B429D65L, 0x6B8FE4D6L, 0x99F73FD6L, + 0xA1D29C07L, 0xEFE830F5L, 0x4D2D38E6L, 0xF0255DC1L, + 0x4CDD2086L, 0x8470EB26L, 0x6382E9C6L, 0x021ECC5EL, + 0x09686B3FL, 0x3EBAEFC9L, 0x3C971814L, 0x6B6A70A1L, + 0x687F3584L, 0x52A0E286L, 0xB79C5305L, 0xAA500737L, + 0x3E07841CL, 0x7FDEAE5CL, 0x8E7D44ECL, 0x5716F2B8L, + 0xB03ADA37L, 0xF0500C0DL, 0xF01C1F04L, 0x0200B3FFL, + 0xAE0CF51AL, 0x3CB574B2L, 0x25837A58L, 0xDC0921BDL, + 0xD19113F9L, 0x7CA92FF6L, 0x94324773L, 0x22F54701L, + 0x3AE5E581L, 0x37C2DADCL, 0xC8B57634L, 0x9AF3DDA7L, + 0xA9446146L, 0x0FD0030EL, 0xECC8C73EL, 0xA4751E41L, + 0xE238CD99L, 0x3BEA0E2FL, 0x3280BBA1L, 0x183EB331L, + 0x4E548B38L, 0x4F6DB908L, 0x6F420D03L, 0xF60A04BFL, + 0x2CB81290L, 0x24977C79L, 0x5679B072L, 0xBCAF89AFL, + 0xDE9A771FL, 0xD9930810L, 0xB38BAE12L, 0xDCCF3F2EL, + 0x5512721FL, 0x2E6B7124L, 0x501ADDE6L, 0x9F84CD87L, + 0x7A584718L, 0x7408DA17L, 0xBC9F9ABCL, 0xE94B7D8CL, + 0xEC7AEC3AL, 0xDB851DFAL, 0x63094366L, 0xC464C3D2L, + 0xEF1C1847L, 0x3215D908L, 0xDD433B37L, 0x24C2BA16L, + 0x12A14D43L, 0x2A65C451L, 0x50940002L, 0x133AE4DDL, + 0x71DFF89EL, 0x10314E55L, 0x81AC77D6L, 0x5F11199BL, + 0x043556F1L, 0xD7A3C76BL, 0x3C11183BL, 0x5924A509L, + 0xF28FE6EDL, 0x97F1FBFAL, 0x9EBABF2CL, 0x1E153C6EL, + 0x86E34570L, 0xEAE96FB1L, 0x860E5E0AL, 0x5A3E2AB3L, + 0x771FE71CL, 0x4E3D06FAL, 0x2965DCB9L, 0x99E71D0FL, + 0x803E89D6L, 0x5266C825L, 0x2E4CC978L, 0x9C10B36AL, + 0xC6150EBAL, 0x94E2EA78L, 0xA5FC3C53L, 0x1E0A2DF4L, + 0xF2F74EA7L, 0x361D2B3DL, 0x1939260FL, 0x19C27960L, + 0x5223A708L, 0xF71312B6L, 0xEBADFE6EL, 0xEAC31F66L, + 0xE3BC4595L, 0xA67BC883L, 0xB17F37D1L, 0x018CFF28L, + 0xC332DDEFL, 0xBE6C5AA5L, 0x65582185L, 0x68AB9802L, + 0xEECEA50FL, 0xDB2F953BL, 0x2AEF7DADL, 0x5B6E2F84L, + 0x1521B628L, 0x29076170L, 0xECDD4775L, 0x619F1510L, + 0x13CCA830L, 0xEB61BD96L, 0x0334FE1EL, 0xAA0363CFL, + 0xB5735C90L, 0x4C70A239L, 0xD59E9E0BL, 0xCBAADE14L, + 0xEECC86BCL, 0x60622CA7L, 0x9CAB5CABL, 0xB2F3846EL, + 0x648B1EAFL, 0x19BDF0CAL, 0xA02369B9L, 0x655ABB50L, + 0x40685A32L, 0x3C2AB4B3L, 0x319EE9D5L, 0xC021B8F7L, + 0x9B540B19L, 0x875FA099L, 0x95F7997EL, 0x623D7DA8L, + 0xF837889AL, 0x97E32D77L, 0x11ED935FL, 0x16681281L, + 0x0E358829L, 0xC7E61FD6L, 0x96DEDFA1L, 0x7858BA99L, + 0x57F584A5L, 0x1B227263L, 0x9B83C3FFL, 0x1AC24696L, + 0xCDB30AEBL, 0x532E3054L, 0x8FD948E4L, 0x6DBC3128L, + 0x58EBF2EFL, 0x34C6FFEAL, 0xFE28ED61L, 0xEE7C3C73L, + 0x5D4A14D9L, 0xE864B7E3L, 0x42105D14L, 0x203E13E0L, + 0x45EEE2B6L, 0xA3AAABEAL, 0xDB6C4F15L, 0xFACB4FD0L, + 0xC742F442L, 0xEF6ABBB5L, 0x654F3B1DL, 0x41CD2105L, + 0xD81E799EL, 0x86854DC7L, 0xE44B476AL, 0x3D816250L, + 0xCF62A1F2L, 0x5B8D2646L, 0xFC8883A0L, 0xC1C7B6A3L, + 0x7F1524C3L, 0x69CB7492L, 0x47848A0BL, 0x5692B285L, + 0x095BBF00L, 0xAD19489DL, 0x1462B174L, 0x23820E00L, + 0x58428D2AL, 0x0C55F5EAL, 0x1DADF43EL, 0x233F7061L, + 0x3372F092L, 0x8D937E41L, 0xD65FECF1L, 0x6C223BDBL, + 0x7CDE3759L, 0xCBEE7460L, 0x4085F2A7L, 0xCE77326EL, + 0xA6078084L, 0x19F8509EL, 0xE8EFD855L, 0x61D99735L, + 0xA969A7AAL, 0xC50C06C2L, 0x5A04ABFCL, 0x800BCADCL, + 0x9E447A2EL, 0xC3453484L, 0xFDD56705L, 0x0E1E9EC9L, + 0xDB73DBD3L, 0x105588CDL, 0x675FDA79L, 0xE3674340L, + 0xC5C43465L, 0x713E38D8L, 0x3D28F89EL, 0xF16DFF20L, + 0x153E21E7L, 0x8FB03D4AL, 0xE6E39F2BL, 0xDB83ADF7L }, + { 0xE93D5A68L, 0x948140F7L, 0xF64C261CL, 0x94692934L, + 0x411520F7L, 0x7602D4F7L, 0xBCF46B2EL, 0xD4A20068L, + 0xD4082471L, 0x3320F46AL, 0x43B7D4B7L, 0x500061AFL, + 0x1E39F62EL, 0x97244546L, 0x14214F74L, 0xBF8B8840L, + 0x4D95FC1DL, 0x96B591AFL, 0x70F4DDD3L, 0x66A02F45L, + 0xBFBC09ECL, 0x03BD9785L, 0x7FAC6DD0L, 0x31CB8504L, + 0x96EB27B3L, 0x55FD3941L, 0xDA2547E6L, 0xABCA0A9AL, + 0x28507825L, 0x530429F4L, 0x0A2C86DAL, 0xE9B66DFBL, + 0x68DC1462L, 0xD7486900L, 0x680EC0A4L, 0x27A18DEEL, + 0x4F3FFEA2L, 0xE887AD8CL, 0xB58CE006L, 0x7AF4D6B6L, + 0xAACE1E7CL, 0xD3375FECL, 0xCE78A399L, 0x406B2A42L, + 0x20FE9E35L, 0xD9F385B9L, 0xEE39D7ABL, 0x3B124E8BL, + 0x1DC9FAF7L, 0x4B6D1856L, 0x26A36631L, 0xEAE397B2L, + 0x3A6EFA74L, 0xDD5B4332L, 0x6841E7F7L, 0xCA7820FBL, + 0xFB0AF54EL, 0xD8FEB397L, 0x454056ACL, 0xBA489527L, + 0x55533A3AL, 0x20838D87L, 0xFE6BA9B7L, 0xD096954BL, + 0x55A867BCL, 0xA1159A58L, 0xCCA92963L, 0x99E1DB33L, + 0xA62A4A56L, 0x3F3125F9L, 0x5EF47E1CL, 0x9029317CL, + 0xFDF8E802L, 0x04272F70L, 0x80BB155CL, 0x05282CE3L, + 0x95C11548L, 0xE4C66D22L, 0x48C1133FL, 0xC70F86DCL, + 0x07F9C9EEL, 0x41041F0FL, 0x404779A4L, 0x5D886E17L, + 0x325F51EBL, 0xD59BC0D1L, 0xF2BCC18FL, 0x41113564L, + 0x257B7834L, 0x602A9C60L, 0xDFF8E8A3L, 0x1F636C1BL, + 0x0E12B4C2L, 0x02E1329EL, 0xAF664FD1L, 0xCAD18115L, + 0x6B2395E0L, 0x333E92E1L, 0x3B240B62L, 0xEEBEB922L, + 0x85B2A20EL, 0xE6BA0D99L, 0xDE720C8CL, 0x2DA2F728L, + 0xD0127845L, 0x95B794FDL, 0x647D0862L, 0xE7CCF5F0L, + 0x5449A36FL, 0x877D48FAL, 0xC39DFD27L, 0xF33E8D1EL, + 0x0A476341L, 0x992EFF74L, 0x3A6F6EABL, 0xF4F8FD37L, + 0xA812DC60L, 0xA1EBDDF8L, 0x991BE14CL, 0xDB6E6B0DL, + 0xC67B5510L, 0x6D672C37L, 0x2765D43BL, 0xDCD0E804L, + 0xF1290DC7L, 0xCC00FFA3L, 0xB5390F92L, 0x690FED0BL, + 0x667B9FFBL, 0xCEDB7D9CL, 0xA091CF0BL, 0xD9155EA3L, + 0xBB132F88L, 0x515BAD24L, 0x7B9479BFL, 0x763BD6EBL, + 0x37392EB3L, 0xCC115979L, 0x8026E297L, 0xF42E312DL, + 0x6842ADA7L, 0xC66A2B3BL, 0x12754CCCL, 0x782EF11CL, + 0x6A124237L, 0xB79251E7L, 0x06A1BBE6L, 0x4BFB6350L, + 0x1A6B1018L, 0x11CAEDFAL, 0x3D25BDD8L, 0xE2E1C3C9L, + 0x44421659L, 0x0A121386L, 0xD90CEC6EL, 0xD5ABEA2AL, + 0x64AF674EL, 0xDA86A85FL, 0xBEBFE988L, 0x64E4C3FEL, + 0x9DBC8057L, 0xF0F7C086L, 0x60787BF8L, 0x6003604DL, + 0xD1FD8346L, 0xF6381FB0L, 0x7745AE04L, 0xD736FCCCL, + 0x83426B33L, 0xF01EAB71L, 0xB0804187L, 0x3C005E5FL, + 0x77A057BEL, 0xBDE8AE24L, 0x55464299L, 0xBF582E61L, + 0x4E58F48FL, 0xF2DDFDA2L, 0xF474EF38L, 0x8789BDC2L, + 0x5366F9C3L, 0xC8B38E74L, 0xB475F255L, 0x46FCD9B9L, + 0x7AEB2661L, 0x8B1DDF84L, 0x846A0E79L, 0x915F95E2L, + 0x466E598EL, 0x20B45770L, 0x8CD55591L, 0xC902DE4CL, + 0xB90BACE1L, 0xBB8205D0L, 0x11A86248L, 0x7574A99EL, + 0xB77F19B6L, 0xE0A9DC09L, 0x662D09A1L, 0xC4324633L, + 0xE85A1F02L, 0x09F0BE8CL, 0x4A99A025L, 0x1D6EFE10L, + 0x1AB93D1DL, 0x0BA5A4DFL, 0xA186F20FL, 0x2868F169L, + 0xDCB7DA83L, 0x573906FEL, 0xA1E2CE9BL, 0x4FCD7F52L, + 0x50115E01L, 0xA70683FAL, 0xA002B5C4L, 0x0DE6D027L, + 0x9AF88C27L, 0x773F8641L, 0xC3604C06L, 0x61A806B5L, + 0xF0177A28L, 0xC0F586E0L, 0x006058AAL, 0x30DC7D62L, + 0x11E69ED7L, 0x2338EA63L, 0x53C2DD94L, 0xC2C21634L, + 0xBBCBEE56L, 0x90BCB6DEL, 0xEBFC7DA1L, 0xCE591D76L, + 0x6F05E409L, 0x4B7C0188L, 0x39720A3DL, 0x7C927C24L, + 0x86E3725FL, 0x724D9DB9L, 0x1AC15BB4L, 0xD39EB8FCL, + 0xED545578L, 0x08FCA5B5L, 0xD83D7CD3L, 0x4DAD0FC4L, + 0x1E50EF5EL, 0xB161E6F8L, 0xA28514D9L, 0x6C51133CL, + 0x6FD5C7E7L, 0x56E14EC4L, 0x362ABFCEL, 0xDDC6C837L, + 0xD79A3234L, 0x92638212L, 0x670EFA8EL, 0x406000E0L }, + { 0x3A39CE37L, 0xD3FAF5CFL, 0xABC27737L, 0x5AC52D1BL, + 0x5CB0679EL, 0x4FA33742L, 0xD3822740L, 0x99BC9BBEL, + 0xD5118E9DL, 0xBF0F7315L, 0xD62D1C7EL, 0xC700C47BL, + 0xB78C1B6BL, 0x21A19045L, 0xB26EB1BEL, 0x6A366EB4L, + 0x5748AB2FL, 0xBC946E79L, 0xC6A376D2L, 0x6549C2C8L, + 0x530FF8EEL, 0x468DDE7DL, 0xD5730A1DL, 0x4CD04DC6L, + 0x2939BBDBL, 0xA9BA4650L, 0xAC9526E8L, 0xBE5EE304L, + 0xA1FAD5F0L, 0x6A2D519AL, 0x63EF8CE2L, 0x9A86EE22L, + 0xC089C2B8L, 0x43242EF6L, 0xA51E03AAL, 0x9CF2D0A4L, + 0x83C061BAL, 0x9BE96A4DL, 0x8FE51550L, 0xBA645BD6L, + 0x2826A2F9L, 0xA73A3AE1L, 0x4BA99586L, 0xEF5562E9L, + 0xC72FEFD3L, 0xF752F7DAL, 0x3F046F69L, 0x77FA0A59L, + 0x80E4A915L, 0x87B08601L, 0x9B09E6ADL, 0x3B3EE593L, + 0xE990FD5AL, 0x9E34D797L, 0x2CF0B7D9L, 0x022B8B51L, + 0x96D5AC3AL, 0x017DA67DL, 0xD1CF3ED6L, 0x7C7D2D28L, + 0x1F9F25CFL, 0xADF2B89BL, 0x5AD6B472L, 0x5A88F54CL, + 0xE029AC71L, 0xE019A5E6L, 0x47B0ACFDL, 0xED93FA9BL, + 0xE8D3C48DL, 0x283B57CCL, 0xF8D56629L, 0x79132E28L, + 0x785F0191L, 0xED756055L, 0xF7960E44L, 0xE3D35E8CL, + 0x15056DD4L, 0x88F46DBAL, 0x03A16125L, 0x0564F0BDL, + 0xC3EB9E15L, 0x3C9057A2L, 0x97271AECL, 0xA93A072AL, + 0x1B3F6D9BL, 0x1E6321F5L, 0xF59C66FBL, 0x26DCF319L, + 0x7533D928L, 0xB155FDF5L, 0x03563482L, 0x8ABA3CBBL, + 0x28517711L, 0xC20AD9F8L, 0xABCC5167L, 0xCCAD925FL, + 0x4DE81751L, 0x3830DC8EL, 0x379D5862L, 0x9320F991L, + 0xEA7A90C2L, 0xFB3E7BCEL, 0x5121CE64L, 0x774FBE32L, + 0xA8B6E37EL, 0xC3293D46L, 0x48DE5369L, 0x6413E680L, + 0xA2AE0810L, 0xDD6DB224L, 0x69852DFDL, 0x09072166L, + 0xB39A460AL, 0x6445C0DDL, 0x586CDECFL, 0x1C20C8AEL, + 0x5BBEF7DDL, 0x1B588D40L, 0xCCD2017FL, 0x6BB4E3BBL, + 0xDDA26A7EL, 0x3A59FF45L, 0x3E350A44L, 0xBCB4CDD5L, + 0x72EACEA8L, 0xFA6484BBL, 0x8D6612AEL, 0xBF3C6F47L, + 0xD29BE463L, 0x542F5D9EL, 0xAEC2771BL, 0xF64E6370L, + 0x740E0D8DL, 0xE75B1357L, 0xF8721671L, 0xAF537D5DL, + 0x4040CB08L, 0x4EB4E2CCL, 0x34D2466AL, 0x0115AF84L, + 0xE1B00428L, 0x95983A1DL, 0x06B89FB4L, 0xCE6EA048L, + 0x6F3F3B82L, 0x3520AB82L, 0x011A1D4BL, 0x277227F8L, + 0x611560B1L, 0xE7933FDCL, 0xBB3A792BL, 0x344525BDL, + 0xA08839E1L, 0x51CE794BL, 0x2F32C9B7L, 0xA01FBAC9L, + 0xE01CC87EL, 0xBCC7D1F6L, 0xCF0111C3L, 0xA1E8AAC7L, + 0x1A908749L, 0xD44FBD9AL, 0xD0DADECBL, 0xD50ADA38L, + 0x0339C32AL, 0xC6913667L, 0x8DF9317CL, 0xE0B12B4FL, + 0xF79E59B7L, 0x43F5BB3AL, 0xF2D519FFL, 0x27D9459CL, + 0xBF97222CL, 0x15E6FC2AL, 0x0F91FC71L, 0x9B941525L, + 0xFAE59361L, 0xCEB69CEBL, 0xC2A86459L, 0x12BAA8D1L, + 0xB6C1075EL, 0xE3056A0CL, 0x10D25065L, 0xCB03A442L, + 0xE0EC6E0EL, 0x1698DB3BL, 0x4C98A0BEL, 0x3278E964L, + 0x9F1F9532L, 0xE0D392DFL, 0xD3A0342BL, 0x8971F21EL, + 0x1B0A7441L, 0x4BA3348CL, 0xC5BE7120L, 0xC37632D8L, + 0xDF359F8DL, 0x9B992F2EL, 0xE60B6F47L, 0x0FE3F11DL, + 0xE54CDA54L, 0x1EDAD891L, 0xCE6279CFL, 0xCD3E7E6FL, + 0x1618B166L, 0xFD2C1D05L, 0x848FD2C5L, 0xF6FB2299L, + 0xF523F357L, 0xA6327623L, 0x93A83531L, 0x56CCCD02L, + 0xACF08162L, 0x5A75EBB5L, 0x6E163697L, 0x88D273CCL, + 0xDE966292L, 0x81B949D0L, 0x4C50901BL, 0x71C65614L, + 0xE6C6C7BDL, 0x327A140AL, 0x45E1D006L, 0xC3F27B9AL, + 0xC9AA53FDL, 0x62A80F00L, 0xBB25BFE2L, 0x35BDD2F6L, + 0x71126905L, 0xB2040222L, 0xB6CBCF7CL, 0xCD769C2BL, + 0x53113EC0L, 0x1640E3D3L, 0x38ABBD60L, 0x2547ADF0L, + 0xBA38209CL, 0xF746CE76L, 0x77AFA1C5L, 0x20756060L, + 0x85CBFE4EL, 0x8AE88DD8L, 0x7AAAF9B0L, 0x4CF9AA7EL, + 0x1948C25CL, 0x02FB8A8CL, 0x01C36AE4L, 0xD6EBE1F9L, + 0x90D4F869L, 0xA65CDEA0L, 0x3F09252DL, 0xC208E69FL, + 0xB74E6132L, 0xCE77E25BL, 0x578FDFE3L, 0x3AC372E6L } +}; + +#endif /* !MBEDTLS_BLOWFISH_ALT */ +#endif /* MBEDTLS_BLOWFISH_C */ diff --git a/APP_Framework/Framework/security/mbedtls/blowfish.h b/APP_Framework/Framework/security/mbedtls/blowfish.h index f01573dca..c0ef5a04c 100644 --- a/APP_Framework/Framework/security/mbedtls/blowfish.h +++ b/APP_Framework/Framework/security/mbedtls/blowfish.h @@ -33,8 +33,6 @@ #include #include -#include "platform_util.h" - #define MBEDTLS_BLOWFISH_ENCRYPT 1 #define MBEDTLS_BLOWFISH_DECRYPT 0 #define MBEDTLS_BLOWFISH_MAX_KEY_BITS 448 @@ -42,87 +40,63 @@ #define MBEDTLS_BLOWFISH_ROUNDS 16 /**< Rounds to use. When increasing this value, make sure to extend the initialisation vectors */ #define MBEDTLS_BLOWFISH_BLOCKSIZE 8 /* Blowfish uses 64 bit blocks */ -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -#define MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( -0x0016 ) -#endif /* !MBEDTLS_DEPRECATED_REMOVED */ -#define MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA -0x0016 /**< Bad input data. */ - -#define MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH -0x0018 /**< Invalid data input length. */ - -/* MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED is deprecated and should not be used. - */ +#define MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH -0x0016 /**< Invalid key length. */ #define MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED -0x0017 /**< Blowfish hardware accelerator failed. */ - -#ifdef __cplusplus -extern "C" { -#endif +#define MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH -0x0018 /**< Invalid data input length. */ #if !defined(MBEDTLS_BLOWFISH_ALT) // Regular implementation // +#ifdef __cplusplus +extern "C" { +#endif + /** * \brief Blowfish context structure */ -typedef struct mbedtls_blowfish_context +typedef struct { uint32_t P[MBEDTLS_BLOWFISH_ROUNDS + 2]; /*!< Blowfish round keys */ uint32_t S[4][256]; /*!< key dependent S-boxes */ } mbedtls_blowfish_context; -#else /* MBEDTLS_BLOWFISH_ALT */ -#include "blowfish_alt.h" -#endif /* MBEDTLS_BLOWFISH_ALT */ - /** - * \brief Initialize a Blowfish context. + * \brief Initialize Blowfish context * - * \param ctx The Blowfish context to be initialized. - * This must not be \c NULL. + * \param ctx Blowfish context to be initialized */ void mbedtls_blowfish_init( mbedtls_blowfish_context *ctx ); /** - * \brief Clear a Blowfish context. + * \brief Clear Blowfish context * - * \param ctx The Blowfish context to be cleared. - * This may be \c NULL, in which case this function - * returns immediately. If it is not \c NULL, it must - * point to an initialized Blowfish context. + * \param ctx Blowfish context to be cleared */ void mbedtls_blowfish_free( mbedtls_blowfish_context *ctx ); /** - * \brief Perform a Blowfish key schedule operation. + * \brief Blowfish key schedule * - * \param ctx The Blowfish context to perform the key schedule on. - * \param key The encryption key. This must be a readable buffer of - * length \p keybits Bits. - * \param keybits The length of \p key in Bits. This must be between - * \c 32 and \c 448 and a multiple of \c 8. + * \param ctx Blowfish context to be initialized + * \param key encryption key + * \param keybits must be between 32 and 448 bits * - * \return \c 0 if successful. - * \return A negative error code on failure. + * \return 0 if successful, or MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH */ int mbedtls_blowfish_setkey( mbedtls_blowfish_context *ctx, const unsigned char *key, unsigned int keybits ); /** - * \brief Perform a Blowfish-ECB block encryption/decryption operation. + * \brief Blowfish-ECB block encryption/decryption * - * \param ctx The Blowfish context to use. This must be initialized - * and bound to a key. - * \param mode The mode of operation. Possible values are - * #MBEDTLS_BLOWFISH_ENCRYPT for encryption, or - * #MBEDTLS_BLOWFISH_DECRYPT for decryption. - * \param input The input block. This must be a readable buffer - * of size \c 8 Bytes. - * \param output The output block. This must be a writable buffer - * of size \c 8 Bytes. + * \param ctx Blowfish context + * \param mode MBEDTLS_BLOWFISH_ENCRYPT or MBEDTLS_BLOWFISH_DECRYPT + * \param input 8-byte input block + * \param output 8-byte output block * - * \return \c 0 if successful. - * \return A negative error code on failure. + * \return 0 if successful */ int mbedtls_blowfish_crypt_ecb( mbedtls_blowfish_context *ctx, int mode, @@ -131,7 +105,9 @@ int mbedtls_blowfish_crypt_ecb( mbedtls_blowfish_context *ctx, #if defined(MBEDTLS_CIPHER_MODE_CBC) /** - * \brief Perform a Blowfish-CBC buffer encryption/decryption operation. + * \brief Blowfish-CBC buffer encryption/decryption + * Length should be a multiple of the block + * size (8 bytes) * * \note Upon exit, the content of the IV is updated so that you can * call the function same function again on the following @@ -141,22 +117,15 @@ int mbedtls_blowfish_crypt_ecb( mbedtls_blowfish_context *ctx, * IV, you should either save it manually or use the cipher * module instead. * - * \param ctx The Blowfish context to use. This must be initialized - * and bound to a key. - * \param mode The mode of operation. Possible values are - * #MBEDTLS_BLOWFISH_ENCRYPT for encryption, or - * #MBEDTLS_BLOWFISH_DECRYPT for decryption. - * \param length The length of the input data in Bytes. This must be - * multiple of \c 8. - * \param iv The initialization vector. This must be a read/write buffer - * of length \c 8 Bytes. It is updated by this function. - * \param input The input data. This must be a readable buffer of length - * \p length Bytes. - * \param output The output data. This must be a writable buffer of length - * \p length Bytes. + * \param ctx Blowfish context + * \param mode MBEDTLS_BLOWFISH_ENCRYPT or MBEDTLS_BLOWFISH_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 \c 0 if successful. - * \return A negative error code on failure. + * \return 0 if successful, or + * MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH */ int mbedtls_blowfish_crypt_cbc( mbedtls_blowfish_context *ctx, int mode, @@ -168,7 +137,7 @@ int mbedtls_blowfish_crypt_cbc( mbedtls_blowfish_context *ctx, #if defined(MBEDTLS_CIPHER_MODE_CFB) /** - * \brief Perform a Blowfish CFB buffer encryption/decryption operation. + * \brief Blowfish CFB buffer encryption/decryption. * * \note Upon exit, the content of the IV is updated so that you can * call the function same function again on the following @@ -178,25 +147,15 @@ int mbedtls_blowfish_crypt_cbc( mbedtls_blowfish_context *ctx, * IV, you should either save it manually or use the cipher * module instead. * - * \param ctx The Blowfish context to use. This must be initialized - * and bound to a key. - * \param mode The mode of operation. Possible values are - * #MBEDTLS_BLOWFISH_ENCRYPT for encryption, or - * #MBEDTLS_BLOWFISH_DECRYPT for decryption. - * \param length The length of the input data in Bytes. - * \param iv_off The offset in the initialiation vector. - * The value pointed to must be smaller than \c 8 Bytes. - * It is updated by this function to support the aforementioned - * streaming usage. - * \param iv The initialization vector. This must be a read/write buffer - * of size \c 8 Bytes. It is updated after use. - * \param input The input data. This must be a readable buffer of length - * \p length Bytes. - * \param output The output data. This must be a writable buffer of length - * \p length Bytes. + * \param ctx Blowfish context + * \param mode MBEDTLS_BLOWFISH_ENCRYPT or MBEDTLS_BLOWFISH_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 \c 0 if successful. - * \return A negative error code on failure. + * \return 0 if successful */ int mbedtls_blowfish_crypt_cfb64( mbedtls_blowfish_context *ctx, int mode, @@ -209,67 +168,22 @@ int mbedtls_blowfish_crypt_cfb64( mbedtls_blowfish_context *ctx, #if defined(MBEDTLS_CIPHER_MODE_CTR) /** - * \brief Perform a Blowfish-CTR buffer encryption/decryption operation. + * \brief Blowfish-CTR buffer encryption/decryption * - * \warning You must never reuse a nonce value with the same key. Doing so - * would void the encryption for the two messages encrypted with - * the same nonce and key. + * Warning: You have to keep the maximum use of your counter in mind! * - * There are two common strategies for managing nonces with CTR: - * - * 1. You can handle everything as a single message processed over - * successive calls to this function. In that case, you want to - * set \p nonce_counter and \p nc_off to 0 for the first call, and - * then preserve the values of \p nonce_counter, \p nc_off and \p - * stream_block across calls to this function as they will be - * updated by this function. - * - * With this strategy, you must not encrypt more than 2**64 - * blocks of data with the same key. - * - * 2. You can encrypt separate messages by dividing the \p - * nonce_counter buffer in two areas: the first one used for a - * per-message nonce, handled by yourself, and the second one - * updated by this function internally. - * - * For example, you might reserve the first 4 bytes for the - * per-message nonce, and the last 4 bytes for internal use. In that - * case, before calling this function on a new message you need to - * set the first 4 bytes of \p nonce_counter to your chosen nonce - * value, the last 4 to 0, and \p nc_off to 0 (which will cause \p - * stream_block to be ignored). That way, you can encrypt at most - * 2**32 messages of up to 2**32 blocks each with the same key. - * - * The per-message nonce (or information sufficient to reconstruct - * it) needs to be communicated with the ciphertext and must be unique. - * The recommended way to ensure uniqueness is to use a message - * counter. - * - * Note that for both stategies, sizes are measured in blocks and - * that a Blowfish block is 8 bytes. - * - * \warning Upon return, \p stream_block contains sensitive data. Its - * content must not be written to insecure storage and should be - * securely discarded as soon as it's no longer needed. - * - * \param ctx The Blowfish context to use. This must be initialized - * and bound to a key. - * \param length The length of the input data in Bytes. + * \param ctx Blowfish context + * \param length The length of the data * \param nc_off The offset in the current stream_block (for resuming - * within current cipher stream). The offset pointer - * should be \c 0 at the start of a stream and must be - * smaller than \c 8. It is updated by this function. - * \param nonce_counter The 64-bit nonce and counter. This must point to a - * read/write buffer of length \c 8 Bytes. - * \param stream_block The saved stream-block for resuming. This must point to - * a read/write buffer of length \c 8 Bytes. - * \param input The input data. This must be a readable buffer of - * length \p length Bytes. - * \param output The output data. This must be a writable buffer of - * length \p length Bytes. + * within current cipher stream). The offset pointer to + * should be 0 at the start of a stream. + * \param nonce_counter The 64-bit nonce and counter. + * \param stream_block The saved stream-block for resuming. Is overwritten + * by the function. + * \param input The input data stream + * \param output The output data stream * - * \return \c 0 if successful. - * \return A negative error code on failure. + * \return 0 if successful */ int mbedtls_blowfish_crypt_ctr( mbedtls_blowfish_context *ctx, size_t length, @@ -284,4 +198,8 @@ int mbedtls_blowfish_crypt_ctr( mbedtls_blowfish_context *ctx, } #endif +#else /* MBEDTLS_BLOWFISH_ALT */ +#include "blowfish_alt.h" +#endif /* MBEDTLS_BLOWFISH_ALT */ + #endif /* blowfish.h */ diff --git a/APP_Framework/Framework/security/mbedtls/bn_mul.h b/APP_Framework/Framework/security/mbedtls/bn_mul.h index 748975ea5..3a254aae9 100644 --- a/APP_Framework/Framework/security/mbedtls/bn_mul.h +++ b/APP_Framework/Framework/security/mbedtls/bn_mul.h @@ -571,8 +571,9 @@ #endif /* TriCore */ /* - * Note, gcc -O0 by default uses r7 for the frame pointer, so it complains about - * our use of r7 below, unless -fomit-frame-pointer is passed. + * gcc -O0 by default uses r7 for the frame pointer, so it complains about our + * use of r7 below, unless -fomit-frame-pointer is passed. Unfortunately, + * passing that option is not easy when building with yotta. * * On the other hand, -fomit-frame-pointer is implied by any -Ox options with * x !=0, which we can detect using __OPTIMIZE__ (which is also defined by @@ -642,24 +643,6 @@ "r6", "r7", "r8", "r9", "cc" \ ); -#elif (__ARM_ARCH >= 6) && \ - defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1) - -#define MULADDC_INIT \ - asm( - -#define MULADDC_CORE \ - "ldr r0, [%0], #4 \n\t" \ - "ldr r1, [%1] \n\t" \ - "umaal r1, %2, %3, r0 \n\t" \ - "str r1, [%1], #4 \n\t" - -#define MULADDC_STOP \ - : "=r" (s), "=r" (d), "=r" (c) \ - : "r" (b), "0" (s), "1" (d), "2" (c) \ - : "r0", "r1", "memory" \ - ); - #else #define MULADDC_INIT \ diff --git a/APP_Framework/Framework/security/mbedtls/camellia.c b/APP_Framework/Framework/security/mbedtls/camellia.c new file mode 100644 index 000000000..c69630732 --- /dev/null +++ b/APP_Framework/Framework/security/mbedtls/camellia.c @@ -0,0 +1,1072 @@ +/* + * Camellia implementation + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +/* + * The Camellia block cipher was designed by NTT and Mitsubishi Electric + * Corporation. + * + * http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/01espec.pdf + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_CAMELLIA_C) + +#include "camellia.h" + +#include + +#if defined(MBEDTLS_SELF_TEST) +#if defined(MBEDTLS_PLATFORM_C) +#include "platform.h" +#else +#include +#define mbedtls_printf printf +#endif /* MBEDTLS_PLATFORM_C */ +#endif /* MBEDTLS_SELF_TEST */ + +#if !defined(MBEDTLS_CAMELLIA_ALT) + +/* 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; +} + +/* + * 32-bit integer manipulation macros (big endian) + */ +#ifndef GET_UINT32_BE +#define GET_UINT32_BE(n,b,i) \ +{ \ + (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ + | ( (uint32_t) (b)[(i) + 1] << 16 ) \ + | ( (uint32_t) (b)[(i) + 2] << 8 ) \ + | ( (uint32_t) (b)[(i) + 3] ); \ +} +#endif + +#ifndef PUT_UINT32_BE +#define PUT_UINT32_BE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) ); \ +} +#endif + +static const unsigned char SIGMA_CHARS[6][8] = +{ + { 0xa0, 0x9e, 0x66, 0x7f, 0x3b, 0xcc, 0x90, 0x8b }, + { 0xb6, 0x7a, 0xe8, 0x58, 0x4c, 0xaa, 0x73, 0xb2 }, + { 0xc6, 0xef, 0x37, 0x2f, 0xe9, 0x4f, 0x82, 0xbe }, + { 0x54, 0xff, 0x53, 0xa5, 0xf1, 0xd3, 0x6f, 0x1c }, + { 0x10, 0xe5, 0x27, 0xfa, 0xde, 0x68, 0x2d, 0x1d }, + { 0xb0, 0x56, 0x88, 0xc2, 0xb3, 0xe6, 0xc1, 0xfd } +}; + +#if defined(MBEDTLS_CAMELLIA_SMALL_MEMORY) + +static const unsigned char FSb[256] = +{ + 112,130, 44,236,179, 39,192,229,228,133, 87, 53,234, 12,174, 65, + 35,239,107,147, 69, 25,165, 33,237, 14, 79, 78, 29,101,146,189, + 134,184,175,143,124,235, 31,206, 62, 48,220, 95, 94,197, 11, 26, + 166,225, 57,202,213, 71, 93, 61,217, 1, 90,214, 81, 86,108, 77, + 139, 13,154,102,251,204,176, 45,116, 18, 43, 32,240,177,132,153, + 223, 76,203,194, 52,126,118, 5,109,183,169, 49,209, 23, 4,215, + 20, 88, 58, 97,222, 27, 17, 28, 50, 15,156, 22, 83, 24,242, 34, + 254, 68,207,178,195,181,122,145, 36, 8,232,168, 96,252,105, 80, + 170,208,160,125,161,137, 98,151, 84, 91, 30,149,224,255,100,210, + 16,196, 0, 72,163,247,117,219,138, 3,230,218, 9, 63,221,148, + 135, 92,131, 2,205, 74,144, 51,115,103,246,243,157,127,191,226, + 82,155,216, 38,200, 55,198, 59,129,150,111, 75, 19,190, 99, 46, + 233,121,167,140,159,110,188,142, 41,245,249,182, 47,253,180, 89, + 120,152, 6,106,231, 70,113,186,212, 37,171, 66,136,162,141,250, + 114, 7,185, 85,248,238,172, 10, 54, 73, 42,104, 60, 56,241,164, + 64, 40,211,123,187,201, 67,193, 21,227,173,244,119,199,128,158 +}; + +#define SBOX1(n) FSb[(n)] +#define SBOX2(n) (unsigned char)((FSb[(n)] >> 7 ^ FSb[(n)] << 1) & 0xff) +#define SBOX3(n) (unsigned char)((FSb[(n)] >> 1 ^ FSb[(n)] << 7) & 0xff) +#define SBOX4(n) FSb[((n) << 1 ^ (n) >> 7) &0xff] + +#else /* MBEDTLS_CAMELLIA_SMALL_MEMORY */ + +static const unsigned char FSb[256] = +{ + 112, 130, 44, 236, 179, 39, 192, 229, 228, 133, 87, 53, 234, 12, 174, 65, + 35, 239, 107, 147, 69, 25, 165, 33, 237, 14, 79, 78, 29, 101, 146, 189, + 134, 184, 175, 143, 124, 235, 31, 206, 62, 48, 220, 95, 94, 197, 11, 26, + 166, 225, 57, 202, 213, 71, 93, 61, 217, 1, 90, 214, 81, 86, 108, 77, + 139, 13, 154, 102, 251, 204, 176, 45, 116, 18, 43, 32, 240, 177, 132, 153, + 223, 76, 203, 194, 52, 126, 118, 5, 109, 183, 169, 49, 209, 23, 4, 215, + 20, 88, 58, 97, 222, 27, 17, 28, 50, 15, 156, 22, 83, 24, 242, 34, + 254, 68, 207, 178, 195, 181, 122, 145, 36, 8, 232, 168, 96, 252, 105, 80, + 170, 208, 160, 125, 161, 137, 98, 151, 84, 91, 30, 149, 224, 255, 100, 210, + 16, 196, 0, 72, 163, 247, 117, 219, 138, 3, 230, 218, 9, 63, 221, 148, + 135, 92, 131, 2, 205, 74, 144, 51, 115, 103, 246, 243, 157, 127, 191, 226, + 82, 155, 216, 38, 200, 55, 198, 59, 129, 150, 111, 75, 19, 190, 99, 46, + 233, 121, 167, 140, 159, 110, 188, 142, 41, 245, 249, 182, 47, 253, 180, 89, + 120, 152, 6, 106, 231, 70, 113, 186, 212, 37, 171, 66, 136, 162, 141, 250, + 114, 7, 185, 85, 248, 238, 172, 10, 54, 73, 42, 104, 60, 56, 241, 164, + 64, 40, 211, 123, 187, 201, 67, 193, 21, 227, 173, 244, 119, 199, 128, 158 +}; + +static const unsigned char FSb2[256] = +{ + 224, 5, 88, 217, 103, 78, 129, 203, 201, 11, 174, 106, 213, 24, 93, 130, + 70, 223, 214, 39, 138, 50, 75, 66, 219, 28, 158, 156, 58, 202, 37, 123, + 13, 113, 95, 31, 248, 215, 62, 157, 124, 96, 185, 190, 188, 139, 22, 52, + 77, 195, 114, 149, 171, 142, 186, 122, 179, 2, 180, 173, 162, 172, 216, 154, + 23, 26, 53, 204, 247, 153, 97, 90, 232, 36, 86, 64, 225, 99, 9, 51, + 191, 152, 151, 133, 104, 252, 236, 10, 218, 111, 83, 98, 163, 46, 8, 175, + 40, 176, 116, 194, 189, 54, 34, 56, 100, 30, 57, 44, 166, 48, 229, 68, + 253, 136, 159, 101, 135, 107, 244, 35, 72, 16, 209, 81, 192, 249, 210, 160, + 85, 161, 65, 250, 67, 19, 196, 47, 168, 182, 60, 43, 193, 255, 200, 165, + 32, 137, 0, 144, 71, 239, 234, 183, 21, 6, 205, 181, 18, 126, 187, 41, + 15, 184, 7, 4, 155, 148, 33, 102, 230, 206, 237, 231, 59, 254, 127, 197, + 164, 55, 177, 76, 145, 110, 141, 118, 3, 45, 222, 150, 38, 125, 198, 92, + 211, 242, 79, 25, 63, 220, 121, 29, 82, 235, 243, 109, 94, 251, 105, 178, + 240, 49, 12, 212, 207, 140, 226, 117, 169, 74, 87, 132, 17, 69, 27, 245, + 228, 14, 115, 170, 241, 221, 89, 20, 108, 146, 84, 208, 120, 112, 227, 73, + 128, 80, 167, 246, 119, 147, 134, 131, 42, 199, 91, 233, 238, 143, 1, 61 +}; + +static const unsigned char FSb3[256] = +{ + 56, 65, 22, 118, 217, 147, 96, 242, 114, 194, 171, 154, 117, 6, 87, 160, + 145, 247, 181, 201, 162, 140, 210, 144, 246, 7, 167, 39, 142, 178, 73, 222, + 67, 92, 215, 199, 62, 245, 143, 103, 31, 24, 110, 175, 47, 226, 133, 13, + 83, 240, 156, 101, 234, 163, 174, 158, 236, 128, 45, 107, 168, 43, 54, 166, + 197, 134, 77, 51, 253, 102, 88, 150, 58, 9, 149, 16, 120, 216, 66, 204, + 239, 38, 229, 97, 26, 63, 59, 130, 182, 219, 212, 152, 232, 139, 2, 235, + 10, 44, 29, 176, 111, 141, 136, 14, 25, 135, 78, 11, 169, 12, 121, 17, + 127, 34, 231, 89, 225, 218, 61, 200, 18, 4, 116, 84, 48, 126, 180, 40, + 85, 104, 80, 190, 208, 196, 49, 203, 42, 173, 15, 202, 112, 255, 50, 105, + 8, 98, 0, 36, 209, 251, 186, 237, 69, 129, 115, 109, 132, 159, 238, 74, + 195, 46, 193, 1, 230, 37, 72, 153, 185, 179, 123, 249, 206, 191, 223, 113, + 41, 205, 108, 19, 100, 155, 99, 157, 192, 75, 183, 165, 137, 95, 177, 23, + 244, 188, 211, 70, 207, 55, 94, 71, 148, 250, 252, 91, 151, 254, 90, 172, + 60, 76, 3, 53, 243, 35, 184, 93, 106, 146, 213, 33, 68, 81, 198, 125, + 57, 131, 220, 170, 124, 119, 86, 5, 27, 164, 21, 52, 30, 28, 248, 82, + 32, 20, 233, 189, 221, 228, 161, 224, 138, 241, 214, 122, 187, 227, 64, 79 +}; + +static const unsigned char FSb4[256] = +{ + 112, 44, 179, 192, 228, 87, 234, 174, 35, 107, 69, 165, 237, 79, 29, 146, + 134, 175, 124, 31, 62, 220, 94, 11, 166, 57, 213, 93, 217, 90, 81, 108, + 139, 154, 251, 176, 116, 43, 240, 132, 223, 203, 52, 118, 109, 169, 209, 4, + 20, 58, 222, 17, 50, 156, 83, 242, 254, 207, 195, 122, 36, 232, 96, 105, + 170, 160, 161, 98, 84, 30, 224, 100, 16, 0, 163, 117, 138, 230, 9, 221, + 135, 131, 205, 144, 115, 246, 157, 191, 82, 216, 200, 198, 129, 111, 19, 99, + 233, 167, 159, 188, 41, 249, 47, 180, 120, 6, 231, 113, 212, 171, 136, 141, + 114, 185, 248, 172, 54, 42, 60, 241, 64, 211, 187, 67, 21, 173, 119, 128, + 130, 236, 39, 229, 133, 53, 12, 65, 239, 147, 25, 33, 14, 78, 101, 189, + 184, 143, 235, 206, 48, 95, 197, 26, 225, 202, 71, 61, 1, 214, 86, 77, + 13, 102, 204, 45, 18, 32, 177, 153, 76, 194, 126, 5, 183, 49, 23, 215, + 88, 97, 27, 28, 15, 22, 24, 34, 68, 178, 181, 145, 8, 168, 252, 80, + 208, 125, 137, 151, 91, 149, 255, 210, 196, 72, 247, 219, 3, 218, 63, 148, + 92, 2, 74, 51, 103, 243, 127, 226, 155, 38, 55, 59, 150, 75, 190, 46, + 121, 140, 110, 142, 245, 182, 253, 89, 152, 106, 70, 186, 37, 66, 162, 250, + 7, 85, 238, 10, 73, 104, 56, 164, 40, 123, 201, 193, 227, 244, 199, 158 +}; + +#define SBOX1(n) FSb[(n)] +#define SBOX2(n) FSb2[(n)] +#define SBOX3(n) FSb3[(n)] +#define SBOX4(n) FSb4[(n)] + +#endif /* MBEDTLS_CAMELLIA_SMALL_MEMORY */ + +static const unsigned char shifts[2][4][4] = +{ + { + { 1, 1, 1, 1 }, /* KL */ + { 0, 0, 0, 0 }, /* KR */ + { 1, 1, 1, 1 }, /* KA */ + { 0, 0, 0, 0 } /* KB */ + }, + { + { 1, 0, 1, 1 }, /* KL */ + { 1, 1, 0, 1 }, /* KR */ + { 1, 1, 1, 0 }, /* KA */ + { 1, 1, 0, 1 } /* KB */ + } +}; + +static const signed char indexes[2][4][20] = +{ + { + { 0, 1, 2, 3, 8, 9, 10, 11, 38, 39, + 36, 37, 23, 20, 21, 22, 27, -1, -1, 26 }, /* KL -> RK */ + { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /* KR -> RK */ + { 4, 5, 6, 7, 12, 13, 14, 15, 16, 17, + 18, 19, -1, 24, 25, -1, 31, 28, 29, 30 }, /* KA -> RK */ + { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } /* KB -> RK */ + }, + { + { 0, 1, 2, 3, 61, 62, 63, 60, -1, -1, + -1, -1, 27, 24, 25, 26, 35, 32, 33, 34 }, /* KL -> RK */ + { -1, -1, -1, -1, 8, 9, 10, 11, 16, 17, + 18, 19, -1, -1, -1, -1, 39, 36, 37, 38 }, /* KR -> RK */ + { -1, -1, -1, -1, 12, 13, 14, 15, 58, 59, + 56, 57, 31, 28, 29, 30, -1, -1, -1, -1 }, /* KA -> RK */ + { 4, 5, 6, 7, 65, 66, 67, 64, 20, 21, + 22, 23, -1, -1, -1, -1, 43, 40, 41, 42 } /* KB -> RK */ + } +}; + +static const signed char transposes[2][20] = +{ + { + 21, 22, 23, 20, + -1, -1, -1, -1, + 18, 19, 16, 17, + 11, 8, 9, 10, + 15, 12, 13, 14 + }, + { + 25, 26, 27, 24, + 29, 30, 31, 28, + 18, 19, 16, 17, + -1, -1, -1, -1, + -1, -1, -1, -1 + } +}; + +/* Shift macro for 128 bit strings with rotation smaller than 32 bits (!) */ +#define ROTL(DEST, SRC, SHIFT) \ +{ \ + (DEST)[0] = (SRC)[0] << (SHIFT) ^ (SRC)[1] >> (32 - (SHIFT)); \ + (DEST)[1] = (SRC)[1] << (SHIFT) ^ (SRC)[2] >> (32 - (SHIFT)); \ + (DEST)[2] = (SRC)[2] << (SHIFT) ^ (SRC)[3] >> (32 - (SHIFT)); \ + (DEST)[3] = (SRC)[3] << (SHIFT) ^ (SRC)[0] >> (32 - (SHIFT)); \ +} + +#define FL(XL, XR, KL, KR) \ +{ \ + (XR) = ((((XL) & (KL)) << 1) | (((XL) & (KL)) >> 31)) ^ (XR); \ + (XL) = ((XR) | (KR)) ^ (XL); \ +} + +#define FLInv(YL, YR, KL, KR) \ +{ \ + (YL) = ((YR) | (KR)) ^ (YL); \ + (YR) = ((((YL) & (KL)) << 1) | (((YL) & (KL)) >> 31)) ^ (YR); \ +} + +#define SHIFT_AND_PLACE(INDEX, OFFSET) \ +{ \ + TK[0] = KC[(OFFSET) * 4 + 0]; \ + TK[1] = KC[(OFFSET) * 4 + 1]; \ + TK[2] = KC[(OFFSET) * 4 + 2]; \ + TK[3] = KC[(OFFSET) * 4 + 3]; \ + \ + for( i = 1; i <= 4; i++ ) \ + if( shifts[(INDEX)][(OFFSET)][i -1] ) \ + ROTL(TK + i * 4, TK, ( 15 * i ) % 32); \ + \ + for( i = 0; i < 20; i++ ) \ + if( indexes[(INDEX)][(OFFSET)][i] != -1 ) { \ + RK[indexes[(INDEX)][(OFFSET)][i]] = TK[ i ]; \ + } \ +} + +static void camellia_feistel( const uint32_t x[2], const uint32_t k[2], + uint32_t z[2]) +{ + uint32_t I0, I1; + I0 = x[0] ^ k[0]; + I1 = x[1] ^ k[1]; + + I0 = ((uint32_t) SBOX1((I0 >> 24) & 0xFF) << 24) | + ((uint32_t) SBOX2((I0 >> 16) & 0xFF) << 16) | + ((uint32_t) SBOX3((I0 >> 8) & 0xFF) << 8) | + ((uint32_t) SBOX4((I0 ) & 0xFF) ); + I1 = ((uint32_t) SBOX2((I1 >> 24) & 0xFF) << 24) | + ((uint32_t) SBOX3((I1 >> 16) & 0xFF) << 16) | + ((uint32_t) SBOX4((I1 >> 8) & 0xFF) << 8) | + ((uint32_t) SBOX1((I1 ) & 0xFF) ); + + I0 ^= (I1 << 8) | (I1 >> 24); + I1 ^= (I0 << 16) | (I0 >> 16); + I0 ^= (I1 >> 8) | (I1 << 24); + I1 ^= (I0 >> 8) | (I0 << 24); + + z[0] ^= I1; + z[1] ^= I0; +} + +void mbedtls_camellia_init( mbedtls_camellia_context *ctx ) +{ + memset( ctx, 0, sizeof( mbedtls_camellia_context ) ); +} + +void mbedtls_camellia_free( mbedtls_camellia_context *ctx ) +{ + if( ctx == NULL ) + return; + + mbedtls_zeroize( ctx, sizeof( mbedtls_camellia_context ) ); +} + +/* + * Camellia key schedule (encryption) + */ +int mbedtls_camellia_setkey_enc( mbedtls_camellia_context *ctx, const unsigned char *key, + unsigned int keybits ) +{ + int idx; + size_t i; + uint32_t *RK; + unsigned char t[64]; + uint32_t SIGMA[6][2]; + uint32_t KC[16]; + uint32_t TK[20]; + + RK = ctx->rk; + + memset( t, 0, 64 ); + memset( RK, 0, sizeof(ctx->rk) ); + + switch( keybits ) + { + case 128: ctx->nr = 3; idx = 0; break; + case 192: + case 256: ctx->nr = 4; idx = 1; break; + default : return( MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH ); + } + + for( i = 0; i < keybits / 8; ++i ) + t[i] = key[i]; + + if( keybits == 192 ) { + for( i = 0; i < 8; i++ ) + t[24 + i] = ~t[16 + i]; + } + + /* + * Prepare SIGMA values + */ + for( i = 0; i < 6; i++ ) { + GET_UINT32_BE( SIGMA[i][0], SIGMA_CHARS[i], 0 ); + GET_UINT32_BE( SIGMA[i][1], SIGMA_CHARS[i], 4 ); + } + + /* + * Key storage in KC + * Order: KL, KR, KA, KB + */ + memset( KC, 0, sizeof(KC) ); + + /* Store KL, KR */ + for( i = 0; i < 8; i++ ) + GET_UINT32_BE( KC[i], t, i * 4 ); + + /* Generate KA */ + for( i = 0; i < 4; ++i ) + KC[8 + i] = KC[i] ^ KC[4 + i]; + + camellia_feistel( KC + 8, SIGMA[0], KC + 10 ); + camellia_feistel( KC + 10, SIGMA[1], KC + 8 ); + + for( i = 0; i < 4; ++i ) + KC[8 + i] ^= KC[i]; + + camellia_feistel( KC + 8, SIGMA[2], KC + 10 ); + camellia_feistel( KC + 10, SIGMA[3], KC + 8 ); + + if( keybits > 128 ) { + /* Generate KB */ + for( i = 0; i < 4; ++i ) + KC[12 + i] = KC[4 + i] ^ KC[8 + i]; + + camellia_feistel( KC + 12, SIGMA[4], KC + 14 ); + camellia_feistel( KC + 14, SIGMA[5], KC + 12 ); + } + + /* + * Generating subkeys + */ + + /* Manipulating KL */ + SHIFT_AND_PLACE( idx, 0 ); + + /* Manipulating KR */ + if( keybits > 128 ) { + SHIFT_AND_PLACE( idx, 1 ); + } + + /* Manipulating KA */ + SHIFT_AND_PLACE( idx, 2 ); + + /* Manipulating KB */ + if( keybits > 128 ) { + SHIFT_AND_PLACE( idx, 3 ); + } + + /* Do transpositions */ + for( i = 0; i < 20; i++ ) { + if( transposes[idx][i] != -1 ) { + RK[32 + 12 * idx + i] = RK[transposes[idx][i]]; + } + } + + return( 0 ); +} + +/* + * Camellia key schedule (decryption) + */ +int mbedtls_camellia_setkey_dec( mbedtls_camellia_context *ctx, const unsigned char *key, + unsigned int keybits ) +{ + int idx, ret; + size_t i; + mbedtls_camellia_context cty; + uint32_t *RK; + uint32_t *SK; + + mbedtls_camellia_init( &cty ); + + /* Also checks keybits */ + if( ( ret = mbedtls_camellia_setkey_enc( &cty, key, keybits ) ) != 0 ) + goto exit; + + ctx->nr = cty.nr; + idx = ( ctx->nr == 4 ); + + RK = ctx->rk; + SK = cty.rk + 24 * 2 + 8 * idx * 2; + + *RK++ = *SK++; + *RK++ = *SK++; + *RK++ = *SK++; + *RK++ = *SK++; + + for( i = 22 + 8 * idx, SK -= 6; i > 0; i--, SK -= 4 ) + { + *RK++ = *SK++; + *RK++ = *SK++; + } + + SK -= 2; + + *RK++ = *SK++; + *RK++ = *SK++; + *RK++ = *SK++; + *RK++ = *SK++; + +exit: + mbedtls_camellia_free( &cty ); + + return( ret ); +} + +/* + * Camellia-ECB block encryption/decryption + */ +int mbedtls_camellia_crypt_ecb( mbedtls_camellia_context *ctx, + int mode, + const unsigned char input[16], + unsigned char output[16] ) +{ + int NR; + uint32_t *RK, X[4]; + + ( (void) mode ); + + NR = ctx->nr; + RK = ctx->rk; + + GET_UINT32_BE( X[0], input, 0 ); + GET_UINT32_BE( X[1], input, 4 ); + GET_UINT32_BE( X[2], input, 8 ); + GET_UINT32_BE( X[3], input, 12 ); + + X[0] ^= *RK++; + X[1] ^= *RK++; + X[2] ^= *RK++; + X[3] ^= *RK++; + + while( NR ) { + --NR; + camellia_feistel( X, RK, X + 2 ); + RK += 2; + camellia_feistel( X + 2, RK, X ); + RK += 2; + camellia_feistel( X, RK, X + 2 ); + RK += 2; + camellia_feistel( X + 2, RK, X ); + RK += 2; + camellia_feistel( X, RK, X + 2 ); + RK += 2; + camellia_feistel( X + 2, RK, X ); + RK += 2; + + if( NR ) { + FL(X[0], X[1], RK[0], RK[1]); + RK += 2; + FLInv(X[2], X[3], RK[0], RK[1]); + RK += 2; + } + } + + X[2] ^= *RK++; + X[3] ^= *RK++; + X[0] ^= *RK++; + X[1] ^= *RK++; + + PUT_UINT32_BE( X[2], output, 0 ); + PUT_UINT32_BE( X[3], output, 4 ); + PUT_UINT32_BE( X[0], output, 8 ); + PUT_UINT32_BE( X[1], output, 12 ); + + return( 0 ); +} + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +/* + * Camellia-CBC buffer encryption/decryption + */ +int mbedtls_camellia_crypt_cbc( mbedtls_camellia_context *ctx, + int mode, + size_t length, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ) +{ + int i; + unsigned char temp[16]; + + if( length % 16 ) + return( MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH ); + + if( mode == MBEDTLS_CAMELLIA_DECRYPT ) + { + while( length > 0 ) + { + memcpy( temp, input, 16 ); + mbedtls_camellia_crypt_ecb( ctx, mode, input, output ); + + for( i = 0; i < 16; i++ ) + output[i] = (unsigned char)( output[i] ^ iv[i] ); + + memcpy( iv, temp, 16 ); + + input += 16; + output += 16; + length -= 16; + } + } + else + { + while( length > 0 ) + { + for( i = 0; i < 16; i++ ) + output[i] = (unsigned char)( input[i] ^ iv[i] ); + + mbedtls_camellia_crypt_ecb( ctx, mode, output, output ); + memcpy( iv, output, 16 ); + + input += 16; + output += 16; + length -= 16; + } + } + + return( 0 ); +} +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +/* + * Camellia-CFB128 buffer encryption/decryption + */ +int mbedtls_camellia_crypt_cfb128( mbedtls_camellia_context *ctx, + int mode, + size_t length, + size_t *iv_off, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ) +{ + int c; + size_t n = *iv_off; + + if( mode == MBEDTLS_CAMELLIA_DECRYPT ) + { + while( length-- ) + { + if( n == 0 ) + mbedtls_camellia_crypt_ecb( ctx, MBEDTLS_CAMELLIA_ENCRYPT, iv, iv ); + + c = *input++; + *output++ = (unsigned char)( c ^ iv[n] ); + iv[n] = (unsigned char) c; + + n = ( n + 1 ) & 0x0F; + } + } + else + { + while( length-- ) + { + if( n == 0 ) + mbedtls_camellia_crypt_ecb( ctx, MBEDTLS_CAMELLIA_ENCRYPT, iv, iv ); + + iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ ); + + n = ( n + 1 ) & 0x0F; + } + } + + *iv_off = n; + + return( 0 ); +} +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +/* + * Camellia-CTR buffer encryption/decryption + */ +int mbedtls_camellia_crypt_ctr( mbedtls_camellia_context *ctx, + size_t length, + size_t *nc_off, + unsigned char nonce_counter[16], + unsigned char stream_block[16], + const unsigned char *input, + unsigned char *output ) +{ + int c, i; + size_t n = *nc_off; + + while( length-- ) + { + if( n == 0 ) { + mbedtls_camellia_crypt_ecb( ctx, MBEDTLS_CAMELLIA_ENCRYPT, nonce_counter, + stream_block ); + + for( i = 16; i > 0; i-- ) + if( ++nonce_counter[i - 1] != 0 ) + break; + } + c = *input++; + *output++ = (unsigned char)( c ^ stream_block[n] ); + + n = ( n + 1 ) & 0x0F; + } + + *nc_off = n; + + return( 0 ); +} +#endif /* MBEDTLS_CIPHER_MODE_CTR */ +#endif /* !MBEDTLS_CAMELLIA_ALT */ + +#if defined(MBEDTLS_SELF_TEST) + +/* + * Camellia test vectors from: + * + * http://info.isl.ntt.co.jp/crypt/eng/camellia/technology.html: + * http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/cryptrec/intermediate.txt + * http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/cryptrec/t_camellia.txt + * (For each bitlength: Key 0, Nr 39) + */ +#define CAMELLIA_TESTS_ECB 2 + +static const unsigned char camellia_test_ecb_key[3][CAMELLIA_TESTS_ECB][32] = +{ + { + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } + }, + { + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } + }, + { + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } + }, +}; + +static const unsigned char camellia_test_ecb_plain[CAMELLIA_TESTS_ECB][16] = +{ + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, + { 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } +}; + +static const unsigned char camellia_test_ecb_cipher[3][CAMELLIA_TESTS_ECB][16] = +{ + { + { 0x67, 0x67, 0x31, 0x38, 0x54, 0x96, 0x69, 0x73, + 0x08, 0x57, 0x06, 0x56, 0x48, 0xea, 0xbe, 0x43 }, + { 0x38, 0x3C, 0x6C, 0x2A, 0xAB, 0xEF, 0x7F, 0xDE, + 0x25, 0xCD, 0x47, 0x0B, 0xF7, 0x74, 0xA3, 0x31 } + }, + { + { 0xb4, 0x99, 0x34, 0x01, 0xb3, 0xe9, 0x96, 0xf8, + 0x4e, 0xe5, 0xce, 0xe7, 0xd7, 0x9b, 0x09, 0xb9 }, + { 0xD1, 0x76, 0x3F, 0xC0, 0x19, 0xD7, 0x7C, 0xC9, + 0x30, 0xBF, 0xF2, 0xA5, 0x6F, 0x7C, 0x93, 0x64 } + }, + { + { 0x9a, 0xcc, 0x23, 0x7d, 0xff, 0x16, 0xd7, 0x6c, + 0x20, 0xef, 0x7c, 0x91, 0x9e, 0x3a, 0x75, 0x09 }, + { 0x05, 0x03, 0xFB, 0x10, 0xAB, 0x24, 0x1E, 0x7C, + 0xF4, 0x5D, 0x8C, 0xDE, 0xEE, 0x47, 0x43, 0x35 } + } +}; + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#define CAMELLIA_TESTS_CBC 3 + +static const unsigned char camellia_test_cbc_key[3][32] = +{ + { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, + 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C } + , + { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52, + 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5, + 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B } + , + { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, + 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81, + 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, + 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 } +}; + +static const unsigned char camellia_test_cbc_iv[16] = + + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F } +; + +static const unsigned char camellia_test_cbc_plain[CAMELLIA_TESTS_CBC][16] = +{ + { 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, + 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A }, + { 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C, + 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51 }, + { 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11, + 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF } + +}; + +static const unsigned char camellia_test_cbc_cipher[3][CAMELLIA_TESTS_CBC][16] = +{ + { + { 0x16, 0x07, 0xCF, 0x49, 0x4B, 0x36, 0xBB, 0xF0, + 0x0D, 0xAE, 0xB0, 0xB5, 0x03, 0xC8, 0x31, 0xAB }, + { 0xA2, 0xF2, 0xCF, 0x67, 0x16, 0x29, 0xEF, 0x78, + 0x40, 0xC5, 0xA5, 0xDF, 0xB5, 0x07, 0x48, 0x87 }, + { 0x0F, 0x06, 0x16, 0x50, 0x08, 0xCF, 0x8B, 0x8B, + 0x5A, 0x63, 0x58, 0x63, 0x62, 0x54, 0x3E, 0x54 } + }, + { + { 0x2A, 0x48, 0x30, 0xAB, 0x5A, 0xC4, 0xA1, 0xA2, + 0x40, 0x59, 0x55, 0xFD, 0x21, 0x95, 0xCF, 0x93 }, + { 0x5D, 0x5A, 0x86, 0x9B, 0xD1, 0x4C, 0xE5, 0x42, + 0x64, 0xF8, 0x92, 0xA6, 0xDD, 0x2E, 0xC3, 0xD5 }, + { 0x37, 0xD3, 0x59, 0xC3, 0x34, 0x98, 0x36, 0xD8, + 0x84, 0xE3, 0x10, 0xAD, 0xDF, 0x68, 0xC4, 0x49 } + }, + { + { 0xE6, 0xCF, 0xA3, 0x5F, 0xC0, 0x2B, 0x13, 0x4A, + 0x4D, 0x2C, 0x0B, 0x67, 0x37, 0xAC, 0x3E, 0xDA }, + { 0x36, 0xCB, 0xEB, 0x73, 0xBD, 0x50, 0x4B, 0x40, + 0x70, 0xB1, 0xB7, 0xDE, 0x2B, 0x21, 0xEB, 0x50 }, + { 0xE3, 0x1A, 0x60, 0x55, 0x29, 0x7D, 0x96, 0xCA, + 0x33, 0x30, 0xCD, 0xF1, 0xB1, 0x86, 0x0A, 0x83 } + } +}; +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +/* + * Camellia-CTR test vectors from: + * + * http://www.faqs.org/rfcs/rfc5528.html + */ + +static const unsigned char camellia_test_ctr_key[3][16] = +{ + { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC, + 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E }, + { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7, + 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 }, + { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8, + 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC } +}; + +static const unsigned char camellia_test_ctr_nonce_counter[3][16] = +{ + { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, + { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59, + 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 }, + { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F, + 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 } +}; + +static const unsigned char camellia_test_ctr_pt[3][48] = +{ + { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62, + 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 }, + + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F }, + + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, + 0x20, 0x21, 0x22, 0x23 } +}; + +static const unsigned char camellia_test_ctr_ct[3][48] = +{ + { 0xD0, 0x9D, 0xC2, 0x9A, 0x82, 0x14, 0x61, 0x9A, + 0x20, 0x87, 0x7C, 0x76, 0xDB, 0x1F, 0x0B, 0x3F }, + { 0xDB, 0xF3, 0xC7, 0x8D, 0xC0, 0x83, 0x96, 0xD4, + 0xDA, 0x7C, 0x90, 0x77, 0x65, 0xBB, 0xCB, 0x44, + 0x2B, 0x8E, 0x8E, 0x0F, 0x31, 0xF0, 0xDC, 0xA7, + 0x2C, 0x74, 0x17, 0xE3, 0x53, 0x60, 0xE0, 0x48 }, + { 0xB1, 0x9D, 0x1F, 0xCD, 0xCB, 0x75, 0xEB, 0x88, + 0x2F, 0x84, 0x9C, 0xE2, 0x4D, 0x85, 0xCF, 0x73, + 0x9C, 0xE6, 0x4B, 0x2B, 0x5C, 0x9D, 0x73, 0xF1, + 0x4F, 0x2D, 0x5D, 0x9D, 0xCE, 0x98, 0x89, 0xCD, + 0xDF, 0x50, 0x86, 0x96 } +}; + +static const int camellia_test_ctr_len[3] = + { 16, 32, 36 }; +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +/* + * Checkup routine + */ +int mbedtls_camellia_self_test( int verbose ) +{ + int i, j, u, v; + unsigned char key[32]; + unsigned char buf[64]; + unsigned char src[16]; + unsigned char dst[16]; +#if defined(MBEDTLS_CIPHER_MODE_CBC) + unsigned char iv[16]; +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + size_t offset, len; + unsigned char nonce_counter[16]; + unsigned char stream_block[16]; +#endif + + mbedtls_camellia_context ctx; + + memset( key, 0, 32 ); + + for( j = 0; j < 6; j++ ) { + u = j >> 1; + v = j & 1; + + if( verbose != 0 ) + mbedtls_printf( " CAMELLIA-ECB-%3d (%s): ", 128 + u * 64, + (v == MBEDTLS_CAMELLIA_DECRYPT) ? "dec" : "enc"); + + for( i = 0; i < CAMELLIA_TESTS_ECB; i++ ) { + memcpy( key, camellia_test_ecb_key[u][i], 16 + 8 * u ); + + if( v == MBEDTLS_CAMELLIA_DECRYPT ) { + mbedtls_camellia_setkey_dec( &ctx, key, 128 + u * 64 ); + memcpy( src, camellia_test_ecb_cipher[u][i], 16 ); + memcpy( dst, camellia_test_ecb_plain[i], 16 ); + } else { /* MBEDTLS_CAMELLIA_ENCRYPT */ + mbedtls_camellia_setkey_enc( &ctx, key, 128 + u * 64 ); + memcpy( src, camellia_test_ecb_plain[i], 16 ); + memcpy( dst, camellia_test_ecb_cipher[u][i], 16 ); + } + + mbedtls_camellia_crypt_ecb( &ctx, v, src, buf ); + + if( memcmp( buf, dst, 16 ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + return( 1 ); + } + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + } + + if( verbose != 0 ) + mbedtls_printf( "\n" ); + +#if defined(MBEDTLS_CIPHER_MODE_CBC) + /* + * CBC mode + */ + for( j = 0; j < 6; j++ ) + { + u = j >> 1; + v = j & 1; + + if( verbose != 0 ) + mbedtls_printf( " CAMELLIA-CBC-%3d (%s): ", 128 + u * 64, + ( v == MBEDTLS_CAMELLIA_DECRYPT ) ? "dec" : "enc" ); + + memcpy( src, camellia_test_cbc_iv, 16 ); + memcpy( dst, camellia_test_cbc_iv, 16 ); + memcpy( key, camellia_test_cbc_key[u], 16 + 8 * u ); + + if( v == MBEDTLS_CAMELLIA_DECRYPT ) { + mbedtls_camellia_setkey_dec( &ctx, key, 128 + u * 64 ); + } else { + mbedtls_camellia_setkey_enc( &ctx, key, 128 + u * 64 ); + } + + for( i = 0; i < CAMELLIA_TESTS_CBC; i++ ) { + + if( v == MBEDTLS_CAMELLIA_DECRYPT ) { + memcpy( iv , src, 16 ); + memcpy( src, camellia_test_cbc_cipher[u][i], 16 ); + memcpy( dst, camellia_test_cbc_plain[i], 16 ); + } else { /* MBEDTLS_CAMELLIA_ENCRYPT */ + memcpy( iv , dst, 16 ); + memcpy( src, camellia_test_cbc_plain[i], 16 ); + memcpy( dst, camellia_test_cbc_cipher[u][i], 16 ); + } + + mbedtls_camellia_crypt_cbc( &ctx, v, 16, iv, src, buf ); + + if( memcmp( buf, dst, 16 ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + return( 1 ); + } + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + } +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + + if( verbose != 0 ) + mbedtls_printf( "\n" ); + +#if defined(MBEDTLS_CIPHER_MODE_CTR) + /* + * CTR mode + */ + for( i = 0; i < 6; i++ ) + { + u = i >> 1; + v = i & 1; + + if( verbose != 0 ) + mbedtls_printf( " CAMELLIA-CTR-128 (%s): ", + ( v == MBEDTLS_CAMELLIA_DECRYPT ) ? "dec" : "enc" ); + + memcpy( nonce_counter, camellia_test_ctr_nonce_counter[u], 16 ); + memcpy( key, camellia_test_ctr_key[u], 16 ); + + offset = 0; + mbedtls_camellia_setkey_enc( &ctx, key, 128 ); + + if( v == MBEDTLS_CAMELLIA_DECRYPT ) + { + len = camellia_test_ctr_len[u]; + memcpy( buf, camellia_test_ctr_ct[u], len ); + + mbedtls_camellia_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block, + buf, buf ); + + if( memcmp( buf, camellia_test_ctr_pt[u], len ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + return( 1 ); + } + } + else + { + len = camellia_test_ctr_len[u]; + memcpy( buf, camellia_test_ctr_pt[u], len ); + + mbedtls_camellia_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block, + buf, buf ); + + if( memcmp( buf, camellia_test_ctr_ct[u], len ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + return( 1 ); + } + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + } + + if( verbose != 0 ) + mbedtls_printf( "\n" ); +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + + return( 0 ); +} + +#endif /* MBEDTLS_SELF_TEST */ + +#endif /* MBEDTLS_CAMELLIA_C */ diff --git a/APP_Framework/Framework/security/mbedtls/camellia.h b/APP_Framework/Framework/security/mbedtls/camellia.h index 3eeb66366..cf07629d9 100644 --- a/APP_Framework/Framework/security/mbedtls/camellia.h +++ b/APP_Framework/Framework/security/mbedtls/camellia.h @@ -33,107 +33,78 @@ #include #include -#include "platform_util.h" - #define MBEDTLS_CAMELLIA_ENCRYPT 1 #define MBEDTLS_CAMELLIA_DECRYPT 0 -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -#define MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( -0x0024 ) -#endif /* !MBEDTLS_DEPRECATED_REMOVED */ -#define MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA -0x0024 /**< Bad input data. */ - -#define MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH -0x0026 /**< Invalid data input length. */ - -/* MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED is deprecated and should not be used. - */ +#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_HW_ACCEL_FAILED -0x0027 /**< Camellia hardware accelerator failed. */ -#ifdef __cplusplus -extern "C" { -#endif - #if !defined(MBEDTLS_CAMELLIA_ALT) // Regular implementation // +#ifdef __cplusplus +extern "C" { +#endif + /** * \brief CAMELLIA context structure */ -typedef struct mbedtls_camellia_context +typedef struct { int nr; /*!< number of rounds */ uint32_t rk[68]; /*!< CAMELLIA round keys */ } mbedtls_camellia_context; -#else /* MBEDTLS_CAMELLIA_ALT */ -#include "camellia_alt.h" -#endif /* MBEDTLS_CAMELLIA_ALT */ - /** - * \brief Initialize a CAMELLIA context. + * \brief Initialize CAMELLIA context * - * \param ctx The CAMELLIA context to be initialized. - * This must not be \c NULL. + * \param ctx CAMELLIA context to be initialized */ void mbedtls_camellia_init( mbedtls_camellia_context *ctx ); /** - * \brief Clear a CAMELLIA context. + * \brief Clear CAMELLIA context * - * \param ctx The CAMELLIA context to be cleared. This may be \c NULL, - * in which case this function returns immediately. If it is not - * \c NULL, it must be initialized. + * \param ctx CAMELLIA context to be cleared */ void mbedtls_camellia_free( mbedtls_camellia_context *ctx ); /** - * \brief Perform a CAMELLIA key schedule operation for encryption. + * \brief CAMELLIA key schedule (encryption) * - * \param ctx The CAMELLIA context to use. This must be initialized. - * \param key The encryption key to use. This must be a readable buffer - * of size \p keybits Bits. - * \param keybits The length of \p key in Bits. This must be either \c 128, - * \c 192 or \c 256. + * \param ctx CAMELLIA context to be initialized + * \param key encryption key + * \param keybits must be 128, 192 or 256 * - * \return \c 0 if successful. - * \return A negative error code on failure. + * \return 0 if successful, or MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH */ -int mbedtls_camellia_setkey_enc( mbedtls_camellia_context *ctx, - const unsigned char *key, - unsigned int keybits ); +int mbedtls_camellia_setkey_enc( mbedtls_camellia_context *ctx, const unsigned char *key, + unsigned int keybits ); /** - * \brief Perform a CAMELLIA key schedule operation for decryption. + * \brief CAMELLIA key schedule (decryption) * - * \param ctx The CAMELLIA context to use. This must be initialized. - * \param key The decryption key. This must be a readable buffer - * of size \p keybits Bits. - * \param keybits The length of \p key in Bits. This must be either \c 128, - * \c 192 or \c 256. + * \param ctx CAMELLIA context to be initialized + * \param key decryption key + * \param keybits must be 128, 192 or 256 * - * \return \c 0 if successful. - * \return A negative error code on failure. + * \return 0 if successful, or MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH */ -int mbedtls_camellia_setkey_dec( mbedtls_camellia_context *ctx, - const unsigned char *key, - unsigned int keybits ); +int mbedtls_camellia_setkey_dec( mbedtls_camellia_context *ctx, const unsigned char *key, + unsigned int keybits ); /** - * \brief Perform a CAMELLIA-ECB block encryption/decryption operation. + * \brief CAMELLIA-ECB block encryption/decryption * - * \param ctx The CAMELLIA context to use. This must be initialized - * and bound to a key. - * \param mode The mode of operation. This must be either - * #MBEDTLS_CAMELLIA_ENCRYPT or #MBEDTLS_CAMELLIA_DECRYPT. - * \param input The input block. This must be a readable buffer - * of size \c 16 Bytes. - * \param output The output block. This must be a writable buffer - * of size \c 16 Bytes. + * \param ctx CAMELLIA context + * \param mode MBEDTLS_CAMELLIA_ENCRYPT or MBEDTLS_CAMELLIA_DECRYPT + * \param input 16-byte input block + * \param output 16-byte output block * - * \return \c 0 if successful. - * \return A negative error code on failure. + * \return 0 if successful */ int mbedtls_camellia_crypt_ecb( mbedtls_camellia_context *ctx, int mode, @@ -142,7 +113,9 @@ int mbedtls_camellia_crypt_ecb( mbedtls_camellia_context *ctx, #if defined(MBEDTLS_CIPHER_MODE_CBC) /** - * \brief Perform a CAMELLIA-CBC buffer encryption/decryption operation. + * \brief CAMELLIA-CBC buffer encryption/decryption + * Length should be a multiple of the block + * size (16 bytes) * * \note Upon exit, the content of the IV is updated so that you can * call the function same function again on the following @@ -152,22 +125,15 @@ int mbedtls_camellia_crypt_ecb( mbedtls_camellia_context *ctx, * IV, you should either save it manually or use the cipher * module instead. * - * \param ctx The CAMELLIA context to use. This must be initialized - * and bound to a key. - * \param mode The mode of operation. This must be either - * #MBEDTLS_CAMELLIA_ENCRYPT or #MBEDTLS_CAMELLIA_DECRYPT. - * \param length The length in Bytes of the input data \p input. - * This must be a multiple of \c 16 Bytes. - * \param iv The initialization vector. This must be a read/write buffer - * of length \c 16 Bytes. It is updated to allow streaming - * use as explained above. - * \param input The buffer holding the input data. This must point to a - * readable buffer of length \p length Bytes. - * \param output The buffer holding the output data. This must point to a - * writable buffer of length \p length Bytes. + * \param ctx CAMELLIA context + * \param mode MBEDTLS_CAMELLIA_ENCRYPT or MBEDTLS_CAMELLIA_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 \c 0 if successful. - * \return A negative error code on failure. + * \return 0 if successful, or + * MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH */ int mbedtls_camellia_crypt_cbc( mbedtls_camellia_context *ctx, int mode, @@ -179,14 +145,11 @@ int mbedtls_camellia_crypt_cbc( mbedtls_camellia_context *ctx, #if defined(MBEDTLS_CIPHER_MODE_CFB) /** - * \brief Perform a CAMELLIA-CFB128 buffer encryption/decryption - * operation. + * \brief CAMELLIA-CFB128 buffer encryption/decryption * - * \note Due to the nature of CFB mode, you should use the same - * key for both encryption and decryption. In particular, calls - * to this function should be preceded by a key-schedule via - * mbedtls_camellia_setkey_enc() regardless of whether \p mode - * is #MBEDTLS_CAMELLIA_ENCRYPT or #MBEDTLS_CAMELLIA_DECRYPT. + * Note: Due to the nature of CFB you should use the same key schedule for + * both encryption and decryption. So a context initialized with + * mbedtls_camellia_setkey_enc() for both MBEDTLS_CAMELLIA_ENCRYPT and CAMELLIE_DECRYPT. * * \note Upon exit, the content of the IV is updated so that you can * call the function same function again on the following @@ -196,24 +159,16 @@ int mbedtls_camellia_crypt_cbc( mbedtls_camellia_context *ctx, * IV, you should either save it manually or use the cipher * module instead. * - * \param ctx The CAMELLIA context to use. This must be initialized - * and bound to a key. - * \param mode The mode of operation. This must be either - * #MBEDTLS_CAMELLIA_ENCRYPT or #MBEDTLS_CAMELLIA_DECRYPT. - * \param length The length of the input data \p input. Any value is allowed. - * \param iv_off The current offset in the IV. This must be smaller - * than \c 16 Bytes. It is updated after this call to allow - * the aforementioned streaming usage. - * \param iv The initialization vector. This must be a read/write buffer - * of length \c 16 Bytes. It is updated after this call to - * allow the aforementioned streaming usage. - * \param input The buffer holding the input data. This must be a readable - * buffer of size \p length Bytes. - * \param output The buffer to hold the output data. This must be a writable - * buffer of length \p length Bytes. + * \param ctx CAMELLIA context + * \param mode MBEDTLS_CAMELLIA_ENCRYPT or MBEDTLS_CAMELLIA_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 \c 0 if successful. - * \return A negative error code on failure. + * \return 0 if successful, or + * MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH */ int mbedtls_camellia_crypt_cfb128( mbedtls_camellia_context *ctx, int mode, @@ -226,78 +181,26 @@ int mbedtls_camellia_crypt_cfb128( mbedtls_camellia_context *ctx, #if defined(MBEDTLS_CIPHER_MODE_CTR) /** - * \brief Perform a CAMELLIA-CTR buffer encryption/decryption operation. + * \brief CAMELLIA-CTR buffer encryption/decryption * - * *note Due to the nature of CTR mode, you should use the same - * key for both encryption and decryption. In particular, calls - * to this function should be preceded by a key-schedule via - * mbedtls_camellia_setkey_enc() regardless of whether \p mode - * is #MBEDTLS_CAMELLIA_ENCRYPT or #MBEDTLS_CAMELLIA_DECRYPT. + * Warning: You have to keep the maximum use of your counter in mind! * - * \warning You must never reuse a nonce value with the same key. Doing so - * would void the encryption for the two messages encrypted with - * the same nonce and key. + * Note: Due to the nature of CTR you should use the same key schedule for + * both encryption and decryption. So a context initialized with + * mbedtls_camellia_setkey_enc() for both MBEDTLS_CAMELLIA_ENCRYPT and MBEDTLS_CAMELLIA_DECRYPT. * - * There are two common strategies for managing nonces with CTR: - * - * 1. You can handle everything as a single message processed over - * successive calls to this function. In that case, you want to - * set \p nonce_counter and \p nc_off to 0 for the first call, and - * then preserve the values of \p nonce_counter, \p nc_off and \p - * stream_block across calls to this function as they will be - * updated by this function. - * - * With this strategy, you must not encrypt more than 2**128 - * blocks of data with the same key. - * - * 2. You can encrypt separate messages by dividing the \p - * nonce_counter buffer in two areas: the first one used for a - * per-message nonce, handled by yourself, and the second one - * updated by this function internally. - * - * For example, you might reserve the first \c 12 Bytes for the - * per-message nonce, and the last \c 4 Bytes for internal use. - * In that case, before calling this function on a new message you - * need to set the first \c 12 Bytes of \p nonce_counter to your - * chosen nonce value, the last four to \c 0, and \p nc_off to \c 0 - * (which will cause \p stream_block to be ignored). That way, you - * can encrypt at most \c 2**96 messages of up to \c 2**32 blocks - * each with the same key. - * - * The per-message nonce (or information sufficient to reconstruct - * it) needs to be communicated with the ciphertext and must be - * unique. The recommended way to ensure uniqueness is to use a - * message counter. An alternative is to generate random nonces, - * but this limits the number of messages that can be securely - * encrypted: for example, with 96-bit random nonces, you should - * not encrypt more than 2**32 messages with the same key. - * - * Note that for both stategies, sizes are measured in blocks and - * that a CAMELLIA block is \c 16 Bytes. - * - * \warning Upon return, \p stream_block contains sensitive data. Its - * content must not be written to insecure storage and should be - * securely discarded as soon as it's no longer needed. - * - * \param ctx The CAMELLIA context to use. This must be initialized - * and bound to a key. - * \param length The length of the input data \p input in Bytes. - * Any value is allowed. - * \param nc_off The offset in the current \p stream_block (for resuming + * \param ctx CAMELLIA context + * \param length The length of the data + * \param nc_off The offset in the current stream_block (for resuming * within current cipher stream). The offset pointer to - * should be \c 0 at the start of a stream. It is updated - * at the end of this call. - * \param nonce_counter The 128-bit nonce and counter. This must be a read/write - * buffer of length \c 16 Bytes. - * \param stream_block The saved stream-block for resuming. This must be a - * read/write buffer of length \c 16 Bytes. - * \param input The input data stream. This must be a readable buffer of - * size \p length Bytes. - * \param output The output data stream. This must be a writable buffer - * of size \p length Bytes. + * should be 0 at the start of a stream. + * \param nonce_counter The 128-bit nonce and counter. + * \param stream_block The saved stream-block for resuming. Is overwritten + * by the function. + * \param input The input data stream + * \param output The output data stream * - * \return \c 0 if successful. - * \return A negative error code on failure. + * \return 0 if successful */ int mbedtls_camellia_crypt_ctr( mbedtls_camellia_context *ctx, size_t length, @@ -308,7 +211,17 @@ int mbedtls_camellia_crypt_ctr( mbedtls_camellia_context *ctx, unsigned char *output ); #endif /* MBEDTLS_CIPHER_MODE_CTR */ -#if defined(MBEDTLS_SELF_TEST) +#ifdef __cplusplus +} +#endif + +#else /* MBEDTLS_CAMELLIA_ALT */ +#include "camellia_alt.h" +#endif /* MBEDTLS_CAMELLIA_ALT */ + +#ifdef __cplusplus +extern "C" { +#endif /** * \brief Checkup routine @@ -317,8 +230,6 @@ int mbedtls_camellia_crypt_ctr( mbedtls_camellia_context *ctx, */ int mbedtls_camellia_self_test( int verbose ); -#endif /* MBEDTLS_SELF_TEST */ - #ifdef __cplusplus } #endif diff --git a/APP_Framework/Framework/security/mbedtls/ccm.c b/APP_Framework/Framework/security/mbedtls/ccm.c new file mode 100644 index 000000000..626b1bfed --- /dev/null +++ b/APP_Framework/Framework/security/mbedtls/ccm.c @@ -0,0 +1,479 @@ +/* + * NIST SP800-38C compliant CCM implementation + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +/* + * Definition of CCM: + * http://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C_updated-July20_2007.pdf + * RFC 3610 "Counter with CBC-MAC (CCM)" + * + * Related: + * RFC 5116 "An Interface and Algorithms for Authenticated Encryption" + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_CCM_C) + +#include "ccm.h" + +#include + +#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) +#if defined(MBEDTLS_PLATFORM_C) +#include "platform.h" +#else +#include +#define mbedtls_printf printf +#endif /* MBEDTLS_PLATFORM_C */ +#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ + +#if !defined(MBEDTLS_CCM_ALT) + +/* 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; +} + +#define CCM_ENCRYPT 0 +#define CCM_DECRYPT 1 + +/* + * Initialize context + */ +void mbedtls_ccm_init( mbedtls_ccm_context *ctx ) +{ + memset( ctx, 0, sizeof( mbedtls_ccm_context ) ); +} + +int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx, + mbedtls_cipher_id_t cipher, + const unsigned char *key, + unsigned int keybits ) +{ + int ret; + const mbedtls_cipher_info_t *cipher_info; + + cipher_info = mbedtls_cipher_info_from_values( cipher, keybits, MBEDTLS_MODE_ECB ); + if( cipher_info == NULL ) + return( MBEDTLS_ERR_CCM_BAD_INPUT ); + + if( cipher_info->block_size != 16 ) + return( MBEDTLS_ERR_CCM_BAD_INPUT ); + + mbedtls_cipher_free( &ctx->cipher_ctx ); + + if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 ) + return( ret ); + + if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits, + MBEDTLS_ENCRYPT ) ) != 0 ) + { + return( ret ); + } + + return( 0 ); +} + +/* + * Free context + */ +void mbedtls_ccm_free( mbedtls_ccm_context *ctx ) +{ + mbedtls_cipher_free( &ctx->cipher_ctx ); + mbedtls_zeroize( ctx, sizeof( mbedtls_ccm_context ) ); +} + +/* + * Macros for common operations. + * Results in smaller compiled code than static inline functions. + */ + +/* + * Update the CBC-MAC state in y using a block in b + * (Always using b as the source helps the compiler optimise a bit better.) + */ +#define UPDATE_CBC_MAC \ + for( i = 0; i < 16; i++ ) \ + y[i] ^= b[i]; \ + \ + if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, y, 16, y, &olen ) ) != 0 ) \ + return( ret ); + +/* + * Encrypt or decrypt a partial block with CTR + * Warning: using b for temporary storage! src and dst must not be b! + * This avoids allocating one more 16 bytes buffer while allowing src == dst. + */ +#define CTR_CRYPT( dst, src, len ) \ + if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctr, 16, b, &olen ) ) != 0 ) \ + return( ret ); \ + \ + for( i = 0; i < len; i++ ) \ + dst[i] = src[i] ^ b[i]; + +/* + * Authenticated encryption or decryption + */ +static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length, + const unsigned char *iv, size_t iv_len, + const unsigned char *add, size_t add_len, + const unsigned char *input, unsigned char *output, + unsigned char *tag, size_t tag_len ) +{ + int ret; + unsigned char i; + unsigned char q; + size_t len_left, olen; + unsigned char b[16]; + unsigned char y[16]; + unsigned char ctr[16]; + const unsigned char *src; + unsigned char *dst; + + /* + * Check length requirements: SP800-38C A.1 + * Additional requirement: a < 2^16 - 2^8 to simplify the code. + * 'length' checked later (when writing it to the first block) + */ + if( tag_len < 4 || tag_len > 16 || tag_len % 2 != 0 ) + return( MBEDTLS_ERR_CCM_BAD_INPUT ); + + /* Also implies q is within bounds */ + if( iv_len < 7 || iv_len > 13 ) + return( MBEDTLS_ERR_CCM_BAD_INPUT ); + + if( add_len > 0xFF00 ) + return( MBEDTLS_ERR_CCM_BAD_INPUT ); + + q = 16 - 1 - (unsigned char) iv_len; + + /* + * First block B_0: + * 0 .. 0 flags + * 1 .. iv_len nonce (aka iv) + * iv_len+1 .. 15 length + * + * With flags as (bits): + * 7 0 + * 6 add present? + * 5 .. 3 (t - 2) / 2 + * 2 .. 0 q - 1 + */ + b[0] = 0; + b[0] |= ( add_len > 0 ) << 6; + b[0] |= ( ( tag_len - 2 ) / 2 ) << 3; + b[0] |= q - 1; + + memcpy( b + 1, iv, iv_len ); + + for( i = 0, len_left = length; i < q; i++, len_left >>= 8 ) + b[15-i] = (unsigned char)( len_left & 0xFF ); + + if( len_left > 0 ) + return( MBEDTLS_ERR_CCM_BAD_INPUT ); + + + /* Start CBC-MAC with first block */ + memset( y, 0, 16 ); + UPDATE_CBC_MAC; + + /* + * If there is additional data, update CBC-MAC with + * add_len, add, 0 (padding to a block boundary) + */ + if( add_len > 0 ) + { + size_t use_len; + len_left = add_len; + src = add; + + memset( b, 0, 16 ); + b[0] = (unsigned char)( ( add_len >> 8 ) & 0xFF ); + b[1] = (unsigned char)( ( add_len ) & 0xFF ); + + use_len = len_left < 16 - 2 ? len_left : 16 - 2; + memcpy( b + 2, src, use_len ); + len_left -= use_len; + src += use_len; + + UPDATE_CBC_MAC; + + while( len_left > 0 ) + { + use_len = len_left > 16 ? 16 : len_left; + + memset( b, 0, 16 ); + memcpy( b, src, use_len ); + UPDATE_CBC_MAC; + + len_left -= use_len; + src += use_len; + } + } + + /* + * Prepare counter block for encryption: + * 0 .. 0 flags + * 1 .. iv_len nonce (aka iv) + * iv_len+1 .. 15 counter (initially 1) + * + * With flags as (bits): + * 7 .. 3 0 + * 2 .. 0 q - 1 + */ + ctr[0] = q - 1; + memcpy( ctr + 1, iv, iv_len ); + memset( ctr + 1 + iv_len, 0, q ); + ctr[15] = 1; + + /* + * Authenticate and {en,de}crypt the message. + * + * The only difference between encryption and decryption is + * the respective order of authentication and {en,de}cryption. + */ + len_left = length; + src = input; + dst = output; + + while( len_left > 0 ) + { + size_t use_len = len_left > 16 ? 16 : len_left; + + if( mode == CCM_ENCRYPT ) + { + memset( b, 0, 16 ); + memcpy( b, src, use_len ); + UPDATE_CBC_MAC; + } + + CTR_CRYPT( dst, src, use_len ); + + if( mode == CCM_DECRYPT ) + { + memset( b, 0, 16 ); + memcpy( b, dst, use_len ); + UPDATE_CBC_MAC; + } + + dst += use_len; + src += use_len; + len_left -= use_len; + + /* + * Increment counter. + * No need to check for overflow thanks to the length check above. + */ + for( i = 0; i < q; i++ ) + if( ++ctr[15-i] != 0 ) + break; + } + + /* + * Authentication: reset counter and crypt/mask internal tag + */ + for( i = 0; i < q; i++ ) + ctr[15-i] = 0; + + CTR_CRYPT( y, y, 16 ); + memcpy( tag, y, tag_len ); + + return( 0 ); +} + +/* + * Authenticated encryption + */ +int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, + const unsigned char *iv, size_t iv_len, + const unsigned char *add, size_t add_len, + const unsigned char *input, unsigned char *output, + unsigned char *tag, size_t tag_len ) +{ + return( ccm_auth_crypt( ctx, CCM_ENCRYPT, length, iv, iv_len, + add, add_len, input, output, tag, tag_len ) ); +} + +/* + * Authenticated decryption + */ +int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length, + const unsigned char *iv, size_t iv_len, + const unsigned char *add, size_t add_len, + const unsigned char *input, unsigned char *output, + const unsigned char *tag, size_t tag_len ) +{ + int ret; + unsigned char check_tag[16]; + unsigned char i; + int diff; + + if( ( ret = ccm_auth_crypt( ctx, CCM_DECRYPT, length, + iv, iv_len, add, add_len, + input, output, check_tag, tag_len ) ) != 0 ) + { + return( ret ); + } + + /* Check tag in "constant-time" */ + for( diff = 0, i = 0; i < tag_len; i++ ) + diff |= tag[i] ^ check_tag[i]; + + if( diff != 0 ) + { + mbedtls_zeroize( output, length ); + return( MBEDTLS_ERR_CCM_AUTH_FAILED ); + } + + return( 0 ); +} + +#endif /* !MBEDTLS_CCM_ALT */ + +#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) +/* + * Examples 1 to 3 from SP800-38C Appendix C + */ + +#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 + */ +static const unsigned char key[] = { + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f +}; + +static const unsigned char iv[] = { + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b +}; + +static const unsigned char ad[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13 +}; + +static const unsigned char msg[CCM_SELFTEST_PT_MAX_LEN] = { + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, +}; + +static const size_t iv_len [NB_TESTS] = { 7, 8, 12 }; +static const size_t add_len[NB_TESTS] = { 8, 16, 20 }; +static const size_t msg_len[NB_TESTS] = { 4, 16, 24 }; +static const size_t tag_len[NB_TESTS] = { 4, 6, 8 }; + +static const unsigned char res[NB_TESTS][CCM_SELFTEST_CT_MAX_LEN] = { + { 0x71, 0x62, 0x01, 0x5b, 0x4d, 0xac, 0x25, 0x5d }, + { 0xd2, 0xa1, 0xf0, 0xe0, 0x51, 0xea, 0x5f, 0x62, + 0x08, 0x1a, 0x77, 0x92, 0x07, 0x3d, 0x59, 0x3d, + 0x1f, 0xc6, 0x4f, 0xbf, 0xac, 0xcd }, + { 0xe3, 0xb2, 0x01, 0xa9, 0xf5, 0xb7, 0x1a, 0x7a, + 0x9b, 0x1c, 0xea, 0xec, 0xcd, 0x97, 0xe7, 0x0b, + 0x61, 0x76, 0xaa, 0xd9, 0xa4, 0x42, 0x8a, 0xa5, + 0x48, 0x43, 0x92, 0xfb, 0xc1, 0xb0, 0x99, 0x51 } +}; + +int mbedtls_ccm_self_test( int verbose ) +{ + mbedtls_ccm_context ctx; + /* + * 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; + int ret; + + mbedtls_ccm_init( &ctx ); + + if( mbedtls_ccm_setkey( &ctx, MBEDTLS_CIPHER_ID_AES, key, 8 * sizeof key ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( " CCM: setup failed" ); + + return( 1 ); + } + + for( i = 0; i < NB_TESTS; i++ ) + { + if( verbose != 0 ) + 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], + iv, iv_len[i], ad, add_len[i], + plaintext, ciphertext, + ciphertext + msg_len[i], tag_len[i] ); + + if( ret != 0 || + memcmp( ciphertext, res[i], msg_len[i] + tag_len[i] ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + return( 1 ); + } + memset( plaintext, 0, CCM_SELFTEST_PT_MAX_LEN ); + + ret = mbedtls_ccm_auth_decrypt( &ctx, msg_len[i], + iv, iv_len[i], ad, add_len[i], + ciphertext, plaintext, + ciphertext + msg_len[i], tag_len[i] ); + + if( ret != 0 || + memcmp( plaintext, msg, msg_len[i] ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + } + + mbedtls_ccm_free( &ctx ); + + if( verbose != 0 ) + mbedtls_printf( "\n" ); + + return( 0 ); +} + +#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ + +#endif /* MBEDTLS_CCM_C */ diff --git a/APP_Framework/Framework/security/mbedtls/ccm.h b/APP_Framework/Framework/security/mbedtls/ccm.h index f03e3b580..e311e751d 100644 --- a/APP_Framework/Framework/security/mbedtls/ccm.h +++ b/APP_Framework/Framework/security/mbedtls/ccm.h @@ -1,11 +1,8 @@ /** * \file ccm.h * - * \brief This file provides an API for the CCM authenticated encryption - * mode for block ciphers. - * - * CCM combines Counter mode encryption with CBC-MAC authentication - * for 128-bit block ciphers. + * \brief CCM combines Counter mode encryption with CBC-MAC authentication + * for 128-bit block ciphers. * * Input to CCM includes the following elements: *
    • Payload - data that is both authenticated and encrypted.
    • @@ -14,18 +11,6 @@ *
    • Nonce - A unique value that is assigned to the payload and the * associated data.
    * - * Definition of CCM: - * http://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C_updated-July20_2007.pdf - * RFC 3610 "Counter with CBC-MAC (CCM)" - * - * Related: - * RFC 5116 "An Interface and Algorithms for Authenticated Encryption" - * - * Definition of CCM*: - * IEEE 802.15.4 - IEEE Standard for Local and metropolitan area networks - * Integer representation is fixed most-significant-octet-first order and - * the representation of octets is most-significant-bit-first order. This is - * consistent with RFC 3610. */ /* * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved @@ -59,38 +44,31 @@ #define MBEDTLS_ERR_CCM_BAD_INPUT -0x000D /**< Bad input parameters to the function. */ #define MBEDTLS_ERR_CCM_AUTH_FAILED -0x000F /**< Authenticated decryption failed. */ - -/* MBEDTLS_ERR_CCM_HW_ACCEL_FAILED is deprecated and should not be used. */ #define MBEDTLS_ERR_CCM_HW_ACCEL_FAILED -0x0011 /**< CCM hardware accelerator failed. */ -#ifdef __cplusplus -extern "C" { -#endif - #if !defined(MBEDTLS_CCM_ALT) // Regular implementation // +#ifdef __cplusplus +extern "C" { +#endif + /** * \brief The CCM context-type definition. The CCM context is passed * to the APIs called. */ -typedef struct mbedtls_ccm_context -{ +typedef struct { mbedtls_cipher_context_t cipher_ctx; /*!< The cipher context used. */ } mbedtls_ccm_context; -#else /* MBEDTLS_CCM_ALT */ -#include "ccm_alt.h" -#endif /* MBEDTLS_CCM_ALT */ - /** * \brief This function initializes the specified CCM context, * to make references valid, and prepare the context * for mbedtls_ccm_setkey() or mbedtls_ccm_free(). * - * \param ctx The CCM context to initialize. This must not be \c NULL. + * \param ctx The CCM context to initialize. */ void mbedtls_ccm_init( mbedtls_ccm_context *ctx ); @@ -98,14 +76,12 @@ void mbedtls_ccm_init( mbedtls_ccm_context *ctx ); * \brief This function initializes the CCM context set in the * \p ctx parameter and sets the encryption key. * - * \param ctx The CCM context to initialize. This must be an initialized - * context. + * \param ctx The CCM context to initialize. * \param cipher The 128-bit block cipher to use. - * \param key The encryption key. This must not be \c NULL. + * \param key The encryption key. * \param keybits The key size in bits. This must be acceptable by the cipher. * - * \return \c 0 on success. - * \return A CCM or cipher-specific error code on failure. + * \return \c 0 on success, or a cipher-specific error code. */ int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx, mbedtls_cipher_id_t cipher, @@ -116,96 +92,36 @@ int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx, * \brief This function releases and clears the specified CCM context * and underlying cipher sub-context. * - * \param ctx The CCM context to clear. If this is \c NULL, the function - * has no effect. Otherwise, this must be initialized. + * \param ctx The CCM context to clear. */ void mbedtls_ccm_free( mbedtls_ccm_context *ctx ); /** * \brief This function encrypts a buffer using CCM. * - * \note The tag is written to a separate buffer. To concatenate - * the \p tag with the \p output, as done in RFC-3610: - * Counter with CBC-MAC (CCM), use - * \p tag = \p output + \p length, and make sure that the - * output buffer is at least \p length + \p tag_len wide. - * - * \param ctx The CCM context to use for encryption. This must be - * initialized and bound to a key. + * \param ctx The CCM context to use for encryption. * \param length The length of the input data in Bytes. - * \param iv The initialization vector (nonce). This must be a readable - * buffer of at least \p iv_len Bytes. - * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, - * or 13. The length L of the message length field is - * 15 - \p iv_len. - * \param add The additional data field. If \p add_len is greater than - * zero, \p add must be a readable buffer of at least that - * length. + * \param iv Initialization vector (nonce). + * \param iv_len The length of the IV in Bytes: 7, 8, 9, 10, 11, 12, or 13. + * \param add The additional data field. * \param add_len The length of additional data in Bytes. - * This must be less than `2^16 - 2^8`. - * \param input The buffer holding the input data. If \p length is greater - * than zero, \p input must be a readable buffer of at least - * that length. - * \param output The buffer holding the output data. If \p length is greater - * than zero, \p output must be a writable buffer of at least - * that length. - * \param tag The buffer holding the authentication field. This must be a - * readable buffer of at least \p tag_len Bytes. - * \param tag_len The length of the authentication field to generate in Bytes: + * Must be less than 2^16 - 2^8. + * \param input The buffer holding the input data. + * \param output The buffer holding the output data. + * Must be at least \p length Bytes wide. + * \param tag The buffer holding the tag. + * \param tag_len The length of the tag to generate in Bytes: * 4, 6, 8, 10, 12, 14 or 16. * - * \return \c 0 on success. - * \return A CCM or cipher-specific error code on failure. - */ -int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, - const unsigned char *iv, size_t iv_len, - const unsigned char *add, size_t add_len, - const unsigned char *input, unsigned char *output, - unsigned char *tag, size_t tag_len ); - -/** - * \brief This function encrypts a buffer using CCM*. - * * \note The tag is written to a separate buffer. To concatenate * the \p tag with the \p output, as done in RFC-3610: * Counter with CBC-MAC (CCM), use * \p tag = \p output + \p length, and make sure that the * output buffer is at least \p length + \p tag_len wide. * - * \note When using this function in a variable tag length context, - * the tag length has to be encoded into the \p iv passed to - * this function. - * - * \param ctx The CCM context to use for encryption. This must be - * initialized and bound to a key. - * \param length The length of the input data in Bytes. - * \param iv The initialization vector (nonce). This must be a readable - * buffer of at least \p iv_len Bytes. - * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, - * or 13. The length L of the message length field is - * 15 - \p iv_len. - * \param add The additional data field. This must be a readable buffer of - * at least \p add_len Bytes. - * \param add_len The length of additional data in Bytes. - * This must be less than 2^16 - 2^8. - * \param input The buffer holding the input data. If \p length is greater - * than zero, \p input must be a readable buffer of at least - * that length. - * \param output The buffer holding the output data. If \p length is greater - * than zero, \p output must be a writable buffer of at least - * that length. - * \param tag The buffer holding the authentication field. This must be a - * readable buffer of at least \p tag_len Bytes. - * \param tag_len The length of the authentication field to generate in Bytes: - * 0, 4, 6, 8, 10, 12, 14 or 16. - * - * \warning Passing \c 0 as \p tag_len means that the message is no - * longer authenticated. - * * \return \c 0 on success. - * \return A CCM or cipher-specific error code on failure. */ -int mbedtls_ccm_star_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 *add, size_t add_len, const unsigned char *input, unsigned char *output, @@ -215,32 +131,22 @@ int mbedtls_ccm_star_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, * \brief This function performs a CCM authenticated decryption of a * buffer. * - * \param ctx The CCM context to use for decryption. This must be - * initialized and bound to a key. + * \param ctx The CCM context to use for decryption. * \param length The length of the input data in Bytes. - * \param iv The initialization vector (nonce). This must be a readable - * buffer of at least \p iv_len Bytes. - * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, - * or 13. The length L of the message length field is - * 15 - \p iv_len. - * \param add The additional data field. This must be a readable buffer - * of at least that \p add_len Bytes.. + * \param iv Initialization vector. + * \param iv_len The length of the IV in Bytes: 7, 8, 9, 10, 11, 12, or 13. + * \param add The additional data field. * \param add_len The length of additional data in Bytes. - * This must be less than 2^16 - 2^8. - * \param input The buffer holding the input data. If \p length is greater - * than zero, \p input must be a readable buffer of at least - * that length. - * \param output The buffer holding the output data. If \p length is greater - * than zero, \p output must be a writable buffer of at least - * that length. - * \param tag The buffer holding the authentication field. This must be a - * readable buffer of at least \p tag_len Bytes. - * \param tag_len The length of the authentication field to generate in Bytes: + * Must be less than 2^16 - 2^8. + * \param input The buffer holding the input data. + * \param output The buffer holding the output data. + * 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 \c 0 on success. This indicates that the message is authentic. - * \return #MBEDTLS_ERR_CCM_AUTH_FAILED if the tag does not match. - * \return A cipher-specific error code on calculation failure. + * \return 0 if successful and authenticated, or + * #MBEDTLS_ERR_CCM_AUTH_FAILED if the tag does not match. */ int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length, const unsigned char *iv, size_t iv_len, @@ -248,57 +154,23 @@ int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length, const unsigned char *input, unsigned char *output, const unsigned char *tag, size_t tag_len ); -/** - * \brief This function performs a CCM* authenticated decryption of a - * buffer. - * - * \note When using this function in a variable tag length context, - * the tag length has to be decoded from \p iv and passed to - * this function as \p tag_len. (\p tag needs to be adjusted - * accordingly.) - * - * \param ctx The CCM context to use for decryption. This must be - * initialized and bound to a key. - * \param length The length of the input data in Bytes. - * \param iv The initialization vector (nonce). This must be a readable - * buffer of at least \p iv_len Bytes. - * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, - * or 13. The length L of the message length field is - * 15 - \p iv_len. - * \param add The additional data field. This must be a readable buffer of - * at least that \p add_len Bytes. - * \param add_len The length of additional data in Bytes. - * This must be less than 2^16 - 2^8. - * \param input The buffer holding the input data. If \p length is greater - * than zero, \p input must be a readable buffer of at least - * that length. - * \param output The buffer holding the output data. If \p length is greater - * than zero, \p output must be a writable buffer of at least - * that length. - * \param tag The buffer holding the authentication field. This must be a - * readable buffer of at least \p tag_len Bytes. - * \param tag_len The length of the authentication field in Bytes. - * 0, 4, 6, 8, 10, 12, 14 or 16. - * - * \warning Passing \c 0 as \p tag_len means that the message is nos - * longer authenticated. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CCM_AUTH_FAILED if the tag does not match. - * \return A cipher-specific error code on calculation failure. - */ -int mbedtls_ccm_star_auth_decrypt( mbedtls_ccm_context *ctx, size_t length, - const unsigned char *iv, size_t iv_len, - const unsigned char *add, size_t add_len, - const unsigned char *input, unsigned char *output, - 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) /** * \brief The CCM checkup routine. * - * \return \c 0 on success. - * \return \c 1 on failure. + * \return \c 0 on success, or \c 1 on failure. */ int mbedtls_ccm_self_test( int verbose ); #endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ diff --git a/APP_Framework/Framework/security/mbedtls/certs.c b/APP_Framework/Framework/security/mbedtls/certs.c index 0d7710f50..7cf6ab589 100644 --- a/APP_Framework/Framework/security/mbedtls/certs.c +++ b/APP_Framework/Framework/security/mbedtls/certs.c @@ -29,2017 +29,375 @@ #if defined(MBEDTLS_CERTS_C) -/* - * Test CA Certificates - * - * We define test CA certificates for each choice of the following parameters: - * - PEM or DER encoding - * - SHA-1 or SHA-256 hash - * - RSA or EC key - * - * Things to add: - * - multiple EC curve types - * - */ - -/* Use CRTs with Secp256r1-only if Secp384r1 is disabled. - * Otherwise, fall back to previous test CRTs using both - * Secp256r1 and Secp384r1. */ -#if !defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) - -/* This is taken from tests/data_files/test-ca3.crt.pem */ -/* BEGIN FILE string macro TEST_CA_CRT_EC_PEM tests/data_files/test-ca3.crt.pem */ -#define TEST_CA_CRT_EC_PEM \ - "-----BEGIN CERTIFICATE-----\r\n" \ - "MIIBuTCCAV2gAwIBAgIBATAMBggqhkjOPQQDAgUAMDsxGjAYBgNVBAMMEVRlc3Qg\r\n" \ - "Q0EgU2VjcDI1NnIxMRAwDgYDVQQKDAdNYmVkVExTMQswCQYDVQQGEwJVSzAeFw0w\r\n" \ - "MTAxMDEwMDAwMDBaFw0zMDEyMzEyMzU5NTlaMDsxGjAYBgNVBAMMEVRlc3QgQ0Eg\r\n" \ - "U2VjcDI1NnIxMRAwDgYDVQQKDAdNYmVkVExTMQswCQYDVQQGEwJVSzBZMBMGByqG\r\n" \ - "SM49AgEGCCqGSM49AwEHA0IABLZIHgilzw/iCx1r09kyZsZfarzztX4y1km0S5Mx\r\n" \ - "rsFB67NjUhXE6/YY3W38oxeY4eIvEb516BOR/g3e3OL7Q8WjUDBOMAwGA1UdEwQF\r\n" \ - "MAMBAf8wHQYDVR0OBBYEFEpepGEzSxZIDDF4IjXW+85Q5yASMB8GA1UdIwQYMBaA\r\n" \ - "FEpepGEzSxZIDDF4IjXW+85Q5yASMAwGCCqGSM49BAMCBQADSAAwRQIhAKejV1jK\r\n" \ - "vPH1vIsZAr6/VmSvjXkxmT2rpzEP9iJvJAteAiBhCPtV7LdSF1ZUqphAK3DYh2m7\r\n" \ - "l1eSxSKXB29adbF96g==\r\n" \ - "-----END CERTIFICATE-----\r\n" -/* END FILE */ - -/* This is generated from tests/data_files/test-ca3.crt.der using `xxd -i`. */ -/* BEGIN FILE binary macro TEST_CA_CRT_EC_DER tests/data_files/test-ca3.crt.der */ -#define TEST_CA_CRT_EC_DER { \ - 0x30, 0x82, 0x01, 0xb9, 0x30, 0x82, 0x01, 0x5d, 0xa0, 0x03, 0x02, 0x01, \ - 0x02, 0x02, 0x01, 0x01, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, \ - 0x3d, 0x04, 0x03, 0x02, 0x05, 0x00, 0x30, 0x3b, 0x31, 0x1a, 0x30, 0x18, \ - 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x11, 0x54, 0x65, 0x73, 0x74, 0x20, \ - 0x43, 0x41, 0x20, 0x53, 0x65, 0x63, 0x70, 0x32, 0x35, 0x36, 0x72, 0x31, \ - 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x07, 0x4d, \ - 0x62, 0x65, 0x64, 0x54, 0x4c, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, \ - 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x4b, 0x30, 0x1e, 0x17, 0x0d, 0x30, \ - 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, \ - 0x17, 0x0d, 0x33, 0x30, 0x31, 0x32, 0x33, 0x31, 0x32, 0x33, 0x35, 0x39, \ - 0x35, 0x39, 0x5a, 0x30, 0x3b, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, \ - 0x04, 0x03, 0x0c, 0x11, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x20, \ - 0x53, 0x65, 0x63, 0x70, 0x32, 0x35, 0x36, 0x72, 0x31, 0x31, 0x10, 0x30, \ - 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x07, 0x4d, 0x62, 0x65, 0x64, \ - 0x54, 0x4c, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, \ - 0x13, 0x02, 0x55, 0x4b, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, \ - 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, \ - 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0xb6, 0x48, 0x1e, 0x08, 0xa5, \ - 0xcf, 0x0f, 0xe2, 0x0b, 0x1d, 0x6b, 0xd3, 0xd9, 0x32, 0x66, 0xc6, 0x5f, \ - 0x6a, 0xbc, 0xf3, 0xb5, 0x7e, 0x32, 0xd6, 0x49, 0xb4, 0x4b, 0x93, 0x31, \ - 0xae, 0xc1, 0x41, 0xeb, 0xb3, 0x63, 0x52, 0x15, 0xc4, 0xeb, 0xf6, 0x18, \ - 0xdd, 0x6d, 0xfc, 0xa3, 0x17, 0x98, 0xe1, 0xe2, 0x2f, 0x11, 0xbe, 0x75, \ - 0xe8, 0x13, 0x91, 0xfe, 0x0d, 0xde, 0xdc, 0xe2, 0xfb, 0x43, 0xc5, 0xa3, \ - 0x50, 0x30, 0x4e, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, \ - 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, \ - 0x04, 0x16, 0x04, 0x14, 0x4a, 0x5e, 0xa4, 0x61, 0x33, 0x4b, 0x16, 0x48, \ - 0x0c, 0x31, 0x78, 0x22, 0x35, 0xd6, 0xfb, 0xce, 0x50, 0xe7, 0x20, 0x12, \ - 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, \ - 0x14, 0x4a, 0x5e, 0xa4, 0x61, 0x33, 0x4b, 0x16, 0x48, 0x0c, 0x31, 0x78, \ - 0x22, 0x35, 0xd6, 0xfb, 0xce, 0x50, 0xe7, 0x20, 0x12, 0x30, 0x0c, 0x06, \ - 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x05, 0x00, 0x03, \ - 0x48, 0x00, 0x30, 0x45, 0x02, 0x21, 0x00, 0xa7, 0xa3, 0x57, 0x58, 0xca, \ - 0xbc, 0xf1, 0xf5, 0xbc, 0x8b, 0x19, 0x02, 0xbe, 0xbf, 0x56, 0x64, 0xaf, \ - 0x8d, 0x79, 0x31, 0x99, 0x3d, 0xab, 0xa7, 0x31, 0x0f, 0xf6, 0x22, 0x6f, \ - 0x24, 0x0b, 0x5e, 0x02, 0x20, 0x61, 0x08, 0xfb, 0x55, 0xec, 0xb7, 0x52, \ - 0x17, 0x56, 0x54, 0xaa, 0x98, 0x40, 0x2b, 0x70, 0xd8, 0x87, 0x69, 0xbb, \ - 0x97, 0x57, 0x92, 0xc5, 0x22, 0x97, 0x07, 0x6f, 0x5a, 0x75, 0xb1, 0x7d, \ - 0xea \ -} -/* END FILE */ - -/* This is taken from tests/data_files/test-ca3.key.pem */ -/* BEGIN FILE string macro TEST_CA_KEY_EC_PEM tests/data_files/test-ca3.key.pem */ -#define TEST_CA_KEY_EC_PEM \ - "-----BEGIN EC PRIVATE KEY-----\r\n" \ - "MHcCAQEEIDlfIVA04pd23r9UJhLf0kt6SkROecrhPbNWtawigBCkoAoGCCqGSM49\r\n" \ - "AwEHoUQDQgAEtkgeCKXPD+ILHWvT2TJmxl9qvPO1fjLWSbRLkzGuwUHrs2NSFcTr\r\n" \ - "9hjdbfyjF5jh4i8RvnXoE5H+Dd7c4vtDxQ==\r\n" \ - "-----END EC PRIVATE KEY-----\r\n" -/* END FILE */ - -/* This is generated from tests/data_files/test-ca3.key.der using `xxd -i`. */ -/* BEGIN FILE binary macro TEST_CA_KEY_EC_DER tests/data_files/test-ca3.key.der */ -#define TEST_CA_KEY_EC_DER { \ - 0x30, 0x77, 0x02, 0x01, 0x01, 0x04, 0x20, 0x39, 0x5f, 0x21, 0x50, 0x34, \ - 0xe2, 0x97, 0x76, 0xde, 0xbf, 0x54, 0x26, 0x12, 0xdf, 0xd2, 0x4b, 0x7a, \ - 0x4a, 0x44, 0x4e, 0x79, 0xca, 0xe1, 0x3d, 0xb3, 0x56, 0xb5, 0xac, 0x22, \ - 0x80, 0x10, 0xa4, 0xa0, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, \ - 0x03, 0x01, 0x07, 0xa1, 0x44, 0x03, 0x42, 0x00, 0x04, 0xb6, 0x48, 0x1e, \ - 0x08, 0xa5, 0xcf, 0x0f, 0xe2, 0x0b, 0x1d, 0x6b, 0xd3, 0xd9, 0x32, 0x66, \ - 0xc6, 0x5f, 0x6a, 0xbc, 0xf3, 0xb5, 0x7e, 0x32, 0xd6, 0x49, 0xb4, 0x4b, \ - 0x93, 0x31, 0xae, 0xc1, 0x41, 0xeb, 0xb3, 0x63, 0x52, 0x15, 0xc4, 0xeb, \ - 0xf6, 0x18, 0xdd, 0x6d, 0xfc, 0xa3, 0x17, 0x98, 0xe1, 0xe2, 0x2f, 0x11, \ - 0xbe, 0x75, 0xe8, 0x13, 0x91, 0xfe, 0x0d, 0xde, 0xdc, 0xe2, 0xfb, 0x43, \ - 0xc5 \ -} -/* END FILE */ - -#else /* !MBEDTLS_ECP_DP_SECP384R1_ENABLED */ - -/* This is taken from tests/data_files/test-ca2.crt */ -/* BEGIN FILE string macro TEST_CA_CRT_EC_PEM tests/data_files/test-ca2.crt */ -#define TEST_CA_CRT_EC_PEM \ - "-----BEGIN CERTIFICATE-----\r\n" \ - "MIICBDCCAYigAwIBAgIJAMFD4n5iQ8zoMAwGCCqGSM49BAMCBQAwPjELMAkGA1UE\r\n" \ - "BhMCTkwxETAPBgNVBAoMCFBvbGFyU1NMMRwwGgYDVQQDDBNQb2xhcnNzbCBUZXN0\r\n" \ - "IEVDIENBMB4XDTE5MDIxMDE0NDQwMFoXDTI5MDIxMDE0NDQwMFowPjELMAkGA1UE\r\n" \ - "BhMCTkwxETAPBgNVBAoMCFBvbGFyU1NMMRwwGgYDVQQDDBNQb2xhcnNzbCBUZXN0\r\n" \ - "IEVDIENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEw9orNEE3WC+HVv78ibopQ0tO\r\n" \ - "4G7DDldTMzlY1FK0kZU5CyPfXxckYkj8GpUpziwth8KIUoCv1mqrId240xxuWLjK\r\n" \ - "6LJpjvNBrSnDtF91p0dv1RkpVWmaUzsgtGYWYDMeo1AwTjAMBgNVHRMEBTADAQH/\r\n" \ - "MB0GA1UdDgQWBBSdbSAkSQE/K8t4tRm8fiTJ2/s2fDAfBgNVHSMEGDAWgBSdbSAk\r\n" \ - "SQE/K8t4tRm8fiTJ2/s2fDAMBggqhkjOPQQDAgUAA2gAMGUCMFHKrjAPpHB0BN1a\r\n" \ - "LH8TwcJ3vh0AxeKZj30mRdOKBmg/jLS3rU3g8VQBHpn8sOTTBwIxANxPO5AerimZ\r\n" \ - "hCjMe0d4CTHf1gFZMF70+IqEP+o5VHsIp2Cqvflb0VGWFC5l9a4cQg==\r\n" \ - "-----END CERTIFICATE-----\r\n" -/* END FILE */ - -/* This is generated from tests/data_files/test-ca2.crt.der using `xxd -i`. */ -/* BEGIN FILE binary macro TEST_CA_CRT_EC_DER tests/data_files/test-ca2.crt.der */ -#define TEST_CA_CRT_EC_DER { \ - 0x30, 0x82, 0x02, 0x04, 0x30, 0x82, 0x01, 0x88, 0xa0, 0x03, 0x02, 0x01, \ - 0x02, 0x02, 0x09, 0x00, 0xc1, 0x43, 0xe2, 0x7e, 0x62, 0x43, 0xcc, 0xe8, \ - 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, \ - 0x05, 0x00, 0x30, 0x3e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, \ - 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, \ - 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, \ - 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x13, 0x50, \ - 0x6f, 0x6c, 0x61, 0x72, 0x73, 0x73, 0x6c, 0x20, 0x54, 0x65, 0x73, 0x74, \ - 0x20, 0x45, 0x43, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x39, \ - 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, 0x34, 0x30, 0x30, 0x5a, 0x17, \ - 0x0d, 0x32, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, 0x34, 0x30, \ - 0x30, 0x5a, 0x30, 0x3e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, \ - 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, \ - 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, \ - 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x13, 0x50, \ - 0x6f, 0x6c, 0x61, 0x72, 0x73, 0x73, 0x6c, 0x20, 0x54, 0x65, 0x73, 0x74, \ - 0x20, 0x45, 0x43, 0x20, 0x43, 0x41, 0x30, 0x76, 0x30, 0x10, 0x06, 0x07, \ - 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x05, 0x2b, 0x81, 0x04, \ - 0x00, 0x22, 0x03, 0x62, 0x00, 0x04, 0xc3, 0xda, 0x2b, 0x34, 0x41, 0x37, \ - 0x58, 0x2f, 0x87, 0x56, 0xfe, 0xfc, 0x89, 0xba, 0x29, 0x43, 0x4b, 0x4e, \ - 0xe0, 0x6e, 0xc3, 0x0e, 0x57, 0x53, 0x33, 0x39, 0x58, 0xd4, 0x52, 0xb4, \ - 0x91, 0x95, 0x39, 0x0b, 0x23, 0xdf, 0x5f, 0x17, 0x24, 0x62, 0x48, 0xfc, \ - 0x1a, 0x95, 0x29, 0xce, 0x2c, 0x2d, 0x87, 0xc2, 0x88, 0x52, 0x80, 0xaf, \ - 0xd6, 0x6a, 0xab, 0x21, 0xdd, 0xb8, 0xd3, 0x1c, 0x6e, 0x58, 0xb8, 0xca, \ - 0xe8, 0xb2, 0x69, 0x8e, 0xf3, 0x41, 0xad, 0x29, 0xc3, 0xb4, 0x5f, 0x75, \ - 0xa7, 0x47, 0x6f, 0xd5, 0x19, 0x29, 0x55, 0x69, 0x9a, 0x53, 0x3b, 0x20, \ - 0xb4, 0x66, 0x16, 0x60, 0x33, 0x1e, 0xa3, 0x50, 0x30, 0x4e, 0x30, 0x0c, \ - 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, \ - 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x9d, \ - 0x6d, 0x20, 0x24, 0x49, 0x01, 0x3f, 0x2b, 0xcb, 0x78, 0xb5, 0x19, 0xbc, \ - 0x7e, 0x24, 0xc9, 0xdb, 0xfb, 0x36, 0x7c, 0x30, 0x1f, 0x06, 0x03, 0x55, \ - 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x9d, 0x6d, 0x20, 0x24, \ - 0x49, 0x01, 0x3f, 0x2b, 0xcb, 0x78, 0xb5, 0x19, 0xbc, 0x7e, 0x24, 0xc9, \ - 0xdb, 0xfb, 0x36, 0x7c, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, \ - 0x3d, 0x04, 0x03, 0x02, 0x05, 0x00, 0x03, 0x68, 0x00, 0x30, 0x65, 0x02, \ - 0x30, 0x51, 0xca, 0xae, 0x30, 0x0f, 0xa4, 0x70, 0x74, 0x04, 0xdd, 0x5a, \ - 0x2c, 0x7f, 0x13, 0xc1, 0xc2, 0x77, 0xbe, 0x1d, 0x00, 0xc5, 0xe2, 0x99, \ - 0x8f, 0x7d, 0x26, 0x45, 0xd3, 0x8a, 0x06, 0x68, 0x3f, 0x8c, 0xb4, 0xb7, \ - 0xad, 0x4d, 0xe0, 0xf1, 0x54, 0x01, 0x1e, 0x99, 0xfc, 0xb0, 0xe4, 0xd3, \ - 0x07, 0x02, 0x31, 0x00, 0xdc, 0x4f, 0x3b, 0x90, 0x1e, 0xae, 0x29, 0x99, \ - 0x84, 0x28, 0xcc, 0x7b, 0x47, 0x78, 0x09, 0x31, 0xdf, 0xd6, 0x01, 0x59, \ - 0x30, 0x5e, 0xf4, 0xf8, 0x8a, 0x84, 0x3f, 0xea, 0x39, 0x54, 0x7b, 0x08, \ - 0xa7, 0x60, 0xaa, 0xbd, 0xf9, 0x5b, 0xd1, 0x51, 0x96, 0x14, 0x2e, 0x65, \ - 0xf5, 0xae, 0x1c, 0x42 \ -} -/* END FILE */ - -/* This is taken from tests/data_files/test-ca2.key.enc */ -/* BEGIN FILE string macro TEST_CA_KEY_EC_PEM tests/data_files/test-ca2.key.enc */ -#define TEST_CA_KEY_EC_PEM \ - "-----BEGIN EC PRIVATE KEY-----\r\n" \ - "Proc-Type: 4,ENCRYPTED\r\n" \ - "DEK-Info: DES-EDE3-CBC,307EAB469933D64E\r\n" \ - "\r\n" \ - "IxbrRmKcAzctJqPdTQLA4SWyBYYGYJVkYEna+F7Pa5t5Yg/gKADrFKcm6B72e7DG\r\n" \ - "ihExtZI648s0zdYw6qSJ74vrPSuWDe5qm93BqsfVH9svtCzWHW0pm1p0KTBCFfUq\r\n" \ - "UsuWTITwJImcnlAs1gaRZ3sAWm7cOUidL0fo2G0fYUFNcYoCSLffCFTEHBuPnagb\r\n" \ - "a77x/sY1Bvii8S9/XhDTb6pTMx06wzrm\r\n" \ - "-----END EC PRIVATE KEY-----\r\n" -/* END FILE */ - -#define TEST_CA_PWD_EC_PEM "PolarSSLTest" - -/* This is generated from tests/data_files/test-ca2.key.der using `xxd -i`. */ -/* BEGIN FILE binary macro TEST_CA_KEY_EC_DER tests/data_files/test-ca2.key.der */ -#define TEST_CA_KEY_EC_DER { \ - 0x30, 0x81, 0xa4, 0x02, 0x01, 0x01, 0x04, 0x30, 0x83, 0xd9, 0x15, 0x0e, \ - 0xa0, 0x71, 0xf0, 0x57, 0x10, 0x33, 0xa3, 0x38, 0xb8, 0x86, 0xc1, 0xa6, \ - 0x11, 0x5d, 0x6d, 0xb4, 0x03, 0xe1, 0x29, 0x76, 0x45, 0xd7, 0x87, 0x6f, \ - 0x23, 0xab, 0x44, 0x20, 0xea, 0x64, 0x7b, 0x85, 0xb1, 0x76, 0xe7, 0x85, \ - 0x95, 0xaa, 0x74, 0xd6, 0xd1, 0xa4, 0x5e, 0xea, 0xa0, 0x07, 0x06, 0x05, \ - 0x2b, 0x81, 0x04, 0x00, 0x22, 0xa1, 0x64, 0x03, 0x62, 0x00, 0x04, 0xc3, \ - 0xda, 0x2b, 0x34, 0x41, 0x37, 0x58, 0x2f, 0x87, 0x56, 0xfe, 0xfc, 0x89, \ - 0xba, 0x29, 0x43, 0x4b, 0x4e, 0xe0, 0x6e, 0xc3, 0x0e, 0x57, 0x53, 0x33, \ - 0x39, 0x58, 0xd4, 0x52, 0xb4, 0x91, 0x95, 0x39, 0x0b, 0x23, 0xdf, 0x5f, \ - 0x17, 0x24, 0x62, 0x48, 0xfc, 0x1a, 0x95, 0x29, 0xce, 0x2c, 0x2d, 0x87, \ - 0xc2, 0x88, 0x52, 0x80, 0xaf, 0xd6, 0x6a, 0xab, 0x21, 0xdd, 0xb8, 0xd3, \ - 0x1c, 0x6e, 0x58, 0xb8, 0xca, 0xe8, 0xb2, 0x69, 0x8e, 0xf3, 0x41, 0xad, \ - 0x29, 0xc3, 0xb4, 0x5f, 0x75, 0xa7, 0x47, 0x6f, 0xd5, 0x19, 0x29, 0x55, \ - 0x69, 0x9a, 0x53, 0x3b, 0x20, 0xb4, 0x66, 0x16, 0x60, 0x33, 0x1e \ -} -/* END FILE */ - -#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */ - -#define TEST_CA_PWD_EC_PEM "PolarSSLTest" - -/* This is taken from tests/data_files/test-ca-sha256.crt. */ -/* BEGIN FILE string macro TEST_CA_CRT_RSA_SHA256_PEM tests/data_files/test-ca-sha256.crt */ -#define TEST_CA_CRT_RSA_SHA256_PEM \ - "-----BEGIN CERTIFICATE-----\r\n" \ - "MIIDQTCCAimgAwIBAgIBAzANBgkqhkiG9w0BAQsFADA7MQswCQYDVQQGEwJOTDER\r\n" \ - "MA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n" \ - "MTkwMjEwMTQ0NDAwWhcNMjkwMjEwMTQ0NDAwWjA7MQswCQYDVQQGEwJOTDERMA8G\r\n" \ - "A1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwggEiMA0G\r\n" \ - "CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDA3zf8F7vglp0/ht6WMn1EpRagzSHx\r\n" \ - "mdTs6st8GFgIlKXsm8WL3xoemTiZhx57wI053zhdcHgH057Zk+i5clHFzqMwUqny\r\n" \ - "50BwFMtEonILwuVA+T7lpg6z+exKY8C4KQB0nFc7qKUEkHHxvYPZP9al4jwqj+8n\r\n" \ - "YMPGn8u67GB9t+aEMr5P+1gmIgNb1LTV+/Xjli5wwOQuvfwu7uJBVcA0Ln0kcmnL\r\n" \ - "R7EUQIN9Z/SG9jGr8XmksrUuEvmEF/Bibyc+E1ixVA0hmnM3oTDPb5Lc9un8rNsu\r\n" \ - "KNF+AksjoBXyOGVkCeoMbo4bF6BxyLObyavpw/LPh5aPgAIynplYb6LVAgMBAAGj\r\n" \ - "UDBOMAwGA1UdEwQFMAMBAf8wHQYDVR0OBBYEFLRa5KWz3tJS9rnVppUP6z68x/3/\r\n" \ - "MB8GA1UdIwQYMBaAFLRa5KWz3tJS9rnVppUP6z68x/3/MA0GCSqGSIb3DQEBCwUA\r\n" \ - "A4IBAQA4qFSCth2q22uJIdE4KGHJsJjVEfw2/xn+MkTvCMfxVrvmRvqCtjE4tKDl\r\n" \ - "oK4MxFOek07oDZwvtAT9ijn1hHftTNS7RH9zd/fxNpfcHnMZXVC4w4DNA1fSANtW\r\n" \ - "5sY1JB5Je9jScrsLSS+mAjyv0Ow3Hb2Bix8wu7xNNrV5fIf7Ubm+wt6SqEBxu3Kb\r\n" \ - "+EfObAT4huf3czznhH3C17ed6NSbXwoXfby7stWUDeRJv08RaFOykf/Aae7bY5PL\r\n" \ - "yTVrkAnikMntJ9YI+hNNYt3inqq11A5cN0+rVTst8UKCxzQ4GpvroSwPKTFkbMw4\r\n" \ - "/anT1dVxr/BtwJfiESoK3/4CeXR1\r\n" \ - "-----END CERTIFICATE-----\r\n" -/* END FILE */ - -/* This is generated from tests/data_files/test-ca-sha256.crt.der - * using `xxd -i`. */ -/* BEGIN FILE binary macro TEST_CA_CRT_RSA_SHA256_DER tests/data_files/test-ca-sha256.crt.der */ -#define TEST_CA_CRT_RSA_SHA256_DER { \ - 0x30, 0x82, 0x03, 0x41, 0x30, 0x82, 0x02, 0x29, 0xa0, 0x03, 0x02, 0x01, \ - 0x02, 0x02, 0x01, 0x03, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, \ - 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x3b, 0x31, 0x0b, 0x30, \ - 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, \ - 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, \ - 0x61, 0x72, 0x53, 0x53, 0x4c, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, \ - 0x04, 0x03, 0x0c, 0x10, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, \ - 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, \ - 0x31, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, 0x34, 0x30, 0x30, \ - 0x5a, 0x17, 0x0d, 0x32, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, \ - 0x34, 0x30, 0x30, 0x5a, 0x30, 0x3b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, \ - 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, 0x0f, 0x06, \ - 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, \ - 0x53, 0x4c, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, \ - 0x10, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, 0x20, 0x54, 0x65, \ - 0x73, 0x74, 0x20, 0x43, 0x41, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, \ - 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, \ - 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, \ - 0x01, 0x00, 0xc0, 0xdf, 0x37, 0xfc, 0x17, 0xbb, 0xe0, 0x96, 0x9d, 0x3f, \ - 0x86, 0xde, 0x96, 0x32, 0x7d, 0x44, 0xa5, 0x16, 0xa0, 0xcd, 0x21, 0xf1, \ - 0x99, 0xd4, 0xec, 0xea, 0xcb, 0x7c, 0x18, 0x58, 0x08, 0x94, 0xa5, 0xec, \ - 0x9b, 0xc5, 0x8b, 0xdf, 0x1a, 0x1e, 0x99, 0x38, 0x99, 0x87, 0x1e, 0x7b, \ - 0xc0, 0x8d, 0x39, 0xdf, 0x38, 0x5d, 0x70, 0x78, 0x07, 0xd3, 0x9e, 0xd9, \ - 0x93, 0xe8, 0xb9, 0x72, 0x51, 0xc5, 0xce, 0xa3, 0x30, 0x52, 0xa9, 0xf2, \ - 0xe7, 0x40, 0x70, 0x14, 0xcb, 0x44, 0xa2, 0x72, 0x0b, 0xc2, 0xe5, 0x40, \ - 0xf9, 0x3e, 0xe5, 0xa6, 0x0e, 0xb3, 0xf9, 0xec, 0x4a, 0x63, 0xc0, 0xb8, \ - 0x29, 0x00, 0x74, 0x9c, 0x57, 0x3b, 0xa8, 0xa5, 0x04, 0x90, 0x71, 0xf1, \ - 0xbd, 0x83, 0xd9, 0x3f, 0xd6, 0xa5, 0xe2, 0x3c, 0x2a, 0x8f, 0xef, 0x27, \ - 0x60, 0xc3, 0xc6, 0x9f, 0xcb, 0xba, 0xec, 0x60, 0x7d, 0xb7, 0xe6, 0x84, \ - 0x32, 0xbe, 0x4f, 0xfb, 0x58, 0x26, 0x22, 0x03, 0x5b, 0xd4, 0xb4, 0xd5, \ - 0xfb, 0xf5, 0xe3, 0x96, 0x2e, 0x70, 0xc0, 0xe4, 0x2e, 0xbd, 0xfc, 0x2e, \ - 0xee, 0xe2, 0x41, 0x55, 0xc0, 0x34, 0x2e, 0x7d, 0x24, 0x72, 0x69, 0xcb, \ - 0x47, 0xb1, 0x14, 0x40, 0x83, 0x7d, 0x67, 0xf4, 0x86, 0xf6, 0x31, 0xab, \ - 0xf1, 0x79, 0xa4, 0xb2, 0xb5, 0x2e, 0x12, 0xf9, 0x84, 0x17, 0xf0, 0x62, \ - 0x6f, 0x27, 0x3e, 0x13, 0x58, 0xb1, 0x54, 0x0d, 0x21, 0x9a, 0x73, 0x37, \ - 0xa1, 0x30, 0xcf, 0x6f, 0x92, 0xdc, 0xf6, 0xe9, 0xfc, 0xac, 0xdb, 0x2e, \ - 0x28, 0xd1, 0x7e, 0x02, 0x4b, 0x23, 0xa0, 0x15, 0xf2, 0x38, 0x65, 0x64, \ - 0x09, 0xea, 0x0c, 0x6e, 0x8e, 0x1b, 0x17, 0xa0, 0x71, 0xc8, 0xb3, 0x9b, \ - 0xc9, 0xab, 0xe9, 0xc3, 0xf2, 0xcf, 0x87, 0x96, 0x8f, 0x80, 0x02, 0x32, \ - 0x9e, 0x99, 0x58, 0x6f, 0xa2, 0xd5, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, \ - 0x50, 0x30, 0x4e, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, \ - 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, \ - 0x04, 0x16, 0x04, 0x14, 0xb4, 0x5a, 0xe4, 0xa5, 0xb3, 0xde, 0xd2, 0x52, \ - 0xf6, 0xb9, 0xd5, 0xa6, 0x95, 0x0f, 0xeb, 0x3e, 0xbc, 0xc7, 0xfd, 0xff, \ - 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, \ - 0x14, 0xb4, 0x5a, 0xe4, 0xa5, 0xb3, 0xde, 0xd2, 0x52, 0xf6, 0xb9, 0xd5, \ - 0xa6, 0x95, 0x0f, 0xeb, 0x3e, 0xbc, 0xc7, 0xfd, 0xff, 0x30, 0x0d, 0x06, \ - 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, \ - 0x03, 0x82, 0x01, 0x01, 0x00, 0x38, 0xa8, 0x54, 0x82, 0xb6, 0x1d, 0xaa, \ - 0xdb, 0x6b, 0x89, 0x21, 0xd1, 0x38, 0x28, 0x61, 0xc9, 0xb0, 0x98, 0xd5, \ - 0x11, 0xfc, 0x36, 0xff, 0x19, 0xfe, 0x32, 0x44, 0xef, 0x08, 0xc7, 0xf1, \ - 0x56, 0xbb, 0xe6, 0x46, 0xfa, 0x82, 0xb6, 0x31, 0x38, 0xb4, 0xa0, 0xe5, \ - 0xa0, 0xae, 0x0c, 0xc4, 0x53, 0x9e, 0x93, 0x4e, 0xe8, 0x0d, 0x9c, 0x2f, \ - 0xb4, 0x04, 0xfd, 0x8a, 0x39, 0xf5, 0x84, 0x77, 0xed, 0x4c, 0xd4, 0xbb, \ - 0x44, 0x7f, 0x73, 0x77, 0xf7, 0xf1, 0x36, 0x97, 0xdc, 0x1e, 0x73, 0x19, \ - 0x5d, 0x50, 0xb8, 0xc3, 0x80, 0xcd, 0x03, 0x57, 0xd2, 0x00, 0xdb, 0x56, \ - 0xe6, 0xc6, 0x35, 0x24, 0x1e, 0x49, 0x7b, 0xd8, 0xd2, 0x72, 0xbb, 0x0b, \ - 0x49, 0x2f, 0xa6, 0x02, 0x3c, 0xaf, 0xd0, 0xec, 0x37, 0x1d, 0xbd, 0x81, \ - 0x8b, 0x1f, 0x30, 0xbb, 0xbc, 0x4d, 0x36, 0xb5, 0x79, 0x7c, 0x87, 0xfb, \ - 0x51, 0xb9, 0xbe, 0xc2, 0xde, 0x92, 0xa8, 0x40, 0x71, 0xbb, 0x72, 0x9b, \ - 0xf8, 0x47, 0xce, 0x6c, 0x04, 0xf8, 0x86, 0xe7, 0xf7, 0x73, 0x3c, 0xe7, \ - 0x84, 0x7d, 0xc2, 0xd7, 0xb7, 0x9d, 0xe8, 0xd4, 0x9b, 0x5f, 0x0a, 0x17, \ - 0x7d, 0xbc, 0xbb, 0xb2, 0xd5, 0x94, 0x0d, 0xe4, 0x49, 0xbf, 0x4f, 0x11, \ - 0x68, 0x53, 0xb2, 0x91, 0xff, 0xc0, 0x69, 0xee, 0xdb, 0x63, 0x93, 0xcb, \ - 0xc9, 0x35, 0x6b, 0x90, 0x09, 0xe2, 0x90, 0xc9, 0xed, 0x27, 0xd6, 0x08, \ - 0xfa, 0x13, 0x4d, 0x62, 0xdd, 0xe2, 0x9e, 0xaa, 0xb5, 0xd4, 0x0e, 0x5c, \ - 0x37, 0x4f, 0xab, 0x55, 0x3b, 0x2d, 0xf1, 0x42, 0x82, 0xc7, 0x34, 0x38, \ - 0x1a, 0x9b, 0xeb, 0xa1, 0x2c, 0x0f, 0x29, 0x31, 0x64, 0x6c, 0xcc, 0x38, \ - 0xfd, 0xa9, 0xd3, 0xd5, 0xd5, 0x71, 0xaf, 0xf0, 0x6d, 0xc0, 0x97, 0xe2, \ - 0x11, 0x2a, 0x0a, 0xdf, 0xfe, 0x02, 0x79, 0x74, 0x75 \ -} -/* END FILE */ - -/* This is taken from tests/data_files/test-ca-sha1.crt. */ -/* BEGIN FILE string macro TEST_CA_CRT_RSA_SHA1_PEM tests/data_files/test-ca-sha1.crt */ -#define TEST_CA_CRT_RSA_SHA1_PEM \ - "-----BEGIN CERTIFICATE-----\r\n" \ - "MIIDQTCCAimgAwIBAgIBAzANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER\r\n" \ - "MA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n" \ - "MTkwMjEwMTQ0NDAwWhcNMjkwMjEwMTQ0NDAwWjA7MQswCQYDVQQGEwJOTDERMA8G\r\n" \ - "A1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwggEiMA0G\r\n" \ - "CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDA3zf8F7vglp0/ht6WMn1EpRagzSHx\r\n" \ - "mdTs6st8GFgIlKXsm8WL3xoemTiZhx57wI053zhdcHgH057Zk+i5clHFzqMwUqny\r\n" \ - "50BwFMtEonILwuVA+T7lpg6z+exKY8C4KQB0nFc7qKUEkHHxvYPZP9al4jwqj+8n\r\n" \ - "YMPGn8u67GB9t+aEMr5P+1gmIgNb1LTV+/Xjli5wwOQuvfwu7uJBVcA0Ln0kcmnL\r\n" \ - "R7EUQIN9Z/SG9jGr8XmksrUuEvmEF/Bibyc+E1ixVA0hmnM3oTDPb5Lc9un8rNsu\r\n" \ - "KNF+AksjoBXyOGVkCeoMbo4bF6BxyLObyavpw/LPh5aPgAIynplYb6LVAgMBAAGj\r\n" \ - "UDBOMAwGA1UdEwQFMAMBAf8wHQYDVR0OBBYEFLRa5KWz3tJS9rnVppUP6z68x/3/\r\n" \ - "MB8GA1UdIwQYMBaAFLRa5KWz3tJS9rnVppUP6z68x/3/MA0GCSqGSIb3DQEBBQUA\r\n" \ - "A4IBAQB0ZiNRFdia6kskaPnhrqejIRq8YMEGAf2oIPnyZ78xoyERgc35lHGyMtsL\r\n" \ - "hWicNjP4d/hS9As4j5KA2gdNGi5ETA1X7SowWOGsryivSpMSHVy1+HdfWlsYQOzm\r\n" \ - "8o+faQNUm8XzPVmttfAVspxeHSxJZ36Oo+QWZ5wZlCIEyjEdLUId+Tm4Bz3B5jRD\r\n" \ - "zZa/SaqDokq66N2zpbgKKAl3GU2O++fBqP2dSkdQykmTxhLLWRN8FJqhYATyQntZ\r\n" \ - "0QSi3W9HfSZPnFTcPIXeoiPd2pLlxt1hZu8dws2LTXE63uP6MM4LHvWxiuJaWkP/\r\n" \ - "mtxyUALj2pQxRitopORFQdn7AOY5\r\n" \ - "-----END CERTIFICATE-----\r\n" -/* END FILE */ - -/* This is taken from tests/data_files/test-ca-sha1.crt.der. */ -/* BEGIN FILE binary macro TEST_CA_CRT_RSA_SHA1_DER tests/data_files/test-ca-sha1.crt.der */ -#define TEST_CA_CRT_RSA_SHA1_DER { \ - 0x30, 0x82, 0x03, 0x41, 0x30, 0x82, 0x02, 0x29, 0xa0, 0x03, 0x02, 0x01, \ - 0x02, 0x02, 0x01, 0x03, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, \ - 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x3b, 0x31, 0x0b, 0x30, \ - 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, \ - 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, \ - 0x61, 0x72, 0x53, 0x53, 0x4c, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, \ - 0x04, 0x03, 0x0c, 0x10, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, \ - 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, \ - 0x31, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, 0x34, 0x30, 0x30, \ - 0x5a, 0x17, 0x0d, 0x32, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, \ - 0x34, 0x30, 0x30, 0x5a, 0x30, 0x3b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, \ - 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, 0x0f, 0x06, \ - 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, \ - 0x53, 0x4c, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, \ - 0x10, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, 0x20, 0x54, 0x65, \ - 0x73, 0x74, 0x20, 0x43, 0x41, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, \ - 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, \ - 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, \ - 0x01, 0x00, 0xc0, 0xdf, 0x37, 0xfc, 0x17, 0xbb, 0xe0, 0x96, 0x9d, 0x3f, \ - 0x86, 0xde, 0x96, 0x32, 0x7d, 0x44, 0xa5, 0x16, 0xa0, 0xcd, 0x21, 0xf1, \ - 0x99, 0xd4, 0xec, 0xea, 0xcb, 0x7c, 0x18, 0x58, 0x08, 0x94, 0xa5, 0xec, \ - 0x9b, 0xc5, 0x8b, 0xdf, 0x1a, 0x1e, 0x99, 0x38, 0x99, 0x87, 0x1e, 0x7b, \ - 0xc0, 0x8d, 0x39, 0xdf, 0x38, 0x5d, 0x70, 0x78, 0x07, 0xd3, 0x9e, 0xd9, \ - 0x93, 0xe8, 0xb9, 0x72, 0x51, 0xc5, 0xce, 0xa3, 0x30, 0x52, 0xa9, 0xf2, \ - 0xe7, 0x40, 0x70, 0x14, 0xcb, 0x44, 0xa2, 0x72, 0x0b, 0xc2, 0xe5, 0x40, \ - 0xf9, 0x3e, 0xe5, 0xa6, 0x0e, 0xb3, 0xf9, 0xec, 0x4a, 0x63, 0xc0, 0xb8, \ - 0x29, 0x00, 0x74, 0x9c, 0x57, 0x3b, 0xa8, 0xa5, 0x04, 0x90, 0x71, 0xf1, \ - 0xbd, 0x83, 0xd9, 0x3f, 0xd6, 0xa5, 0xe2, 0x3c, 0x2a, 0x8f, 0xef, 0x27, \ - 0x60, 0xc3, 0xc6, 0x9f, 0xcb, 0xba, 0xec, 0x60, 0x7d, 0xb7, 0xe6, 0x84, \ - 0x32, 0xbe, 0x4f, 0xfb, 0x58, 0x26, 0x22, 0x03, 0x5b, 0xd4, 0xb4, 0xd5, \ - 0xfb, 0xf5, 0xe3, 0x96, 0x2e, 0x70, 0xc0, 0xe4, 0x2e, 0xbd, 0xfc, 0x2e, \ - 0xee, 0xe2, 0x41, 0x55, 0xc0, 0x34, 0x2e, 0x7d, 0x24, 0x72, 0x69, 0xcb, \ - 0x47, 0xb1, 0x14, 0x40, 0x83, 0x7d, 0x67, 0xf4, 0x86, 0xf6, 0x31, 0xab, \ - 0xf1, 0x79, 0xa4, 0xb2, 0xb5, 0x2e, 0x12, 0xf9, 0x84, 0x17, 0xf0, 0x62, \ - 0x6f, 0x27, 0x3e, 0x13, 0x58, 0xb1, 0x54, 0x0d, 0x21, 0x9a, 0x73, 0x37, \ - 0xa1, 0x30, 0xcf, 0x6f, 0x92, 0xdc, 0xf6, 0xe9, 0xfc, 0xac, 0xdb, 0x2e, \ - 0x28, 0xd1, 0x7e, 0x02, 0x4b, 0x23, 0xa0, 0x15, 0xf2, 0x38, 0x65, 0x64, \ - 0x09, 0xea, 0x0c, 0x6e, 0x8e, 0x1b, 0x17, 0xa0, 0x71, 0xc8, 0xb3, 0x9b, \ - 0xc9, 0xab, 0xe9, 0xc3, 0xf2, 0xcf, 0x87, 0x96, 0x8f, 0x80, 0x02, 0x32, \ - 0x9e, 0x99, 0x58, 0x6f, 0xa2, 0xd5, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, \ - 0x50, 0x30, 0x4e, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, \ - 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, \ - 0x04, 0x16, 0x04, 0x14, 0xb4, 0x5a, 0xe4, 0xa5, 0xb3, 0xde, 0xd2, 0x52, \ - 0xf6, 0xb9, 0xd5, 0xa6, 0x95, 0x0f, 0xeb, 0x3e, 0xbc, 0xc7, 0xfd, 0xff, \ - 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, \ - 0x14, 0xb4, 0x5a, 0xe4, 0xa5, 0xb3, 0xde, 0xd2, 0x52, 0xf6, 0xb9, 0xd5, \ - 0xa6, 0x95, 0x0f, 0xeb, 0x3e, 0xbc, 0xc7, 0xfd, 0xff, 0x30, 0x0d, 0x06, \ - 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, \ - 0x03, 0x82, 0x01, 0x01, 0x00, 0x74, 0x66, 0x23, 0x51, 0x15, 0xd8, 0x9a, \ - 0xea, 0x4b, 0x24, 0x68, 0xf9, 0xe1, 0xae, 0xa7, 0xa3, 0x21, 0x1a, 0xbc, \ - 0x60, 0xc1, 0x06, 0x01, 0xfd, 0xa8, 0x20, 0xf9, 0xf2, 0x67, 0xbf, 0x31, \ - 0xa3, 0x21, 0x11, 0x81, 0xcd, 0xf9, 0x94, 0x71, 0xb2, 0x32, 0xdb, 0x0b, \ - 0x85, 0x68, 0x9c, 0x36, 0x33, 0xf8, 0x77, 0xf8, 0x52, 0xf4, 0x0b, 0x38, \ - 0x8f, 0x92, 0x80, 0xda, 0x07, 0x4d, 0x1a, 0x2e, 0x44, 0x4c, 0x0d, 0x57, \ - 0xed, 0x2a, 0x30, 0x58, 0xe1, 0xac, 0xaf, 0x28, 0xaf, 0x4a, 0x93, 0x12, \ - 0x1d, 0x5c, 0xb5, 0xf8, 0x77, 0x5f, 0x5a, 0x5b, 0x18, 0x40, 0xec, 0xe6, \ - 0xf2, 0x8f, 0x9f, 0x69, 0x03, 0x54, 0x9b, 0xc5, 0xf3, 0x3d, 0x59, 0xad, \ - 0xb5, 0xf0, 0x15, 0xb2, 0x9c, 0x5e, 0x1d, 0x2c, 0x49, 0x67, 0x7e, 0x8e, \ - 0xa3, 0xe4, 0x16, 0x67, 0x9c, 0x19, 0x94, 0x22, 0x04, 0xca, 0x31, 0x1d, \ - 0x2d, 0x42, 0x1d, 0xf9, 0x39, 0xb8, 0x07, 0x3d, 0xc1, 0xe6, 0x34, 0x43, \ - 0xcd, 0x96, 0xbf, 0x49, 0xaa, 0x83, 0xa2, 0x4a, 0xba, 0xe8, 0xdd, 0xb3, \ - 0xa5, 0xb8, 0x0a, 0x28, 0x09, 0x77, 0x19, 0x4d, 0x8e, 0xfb, 0xe7, 0xc1, \ - 0xa8, 0xfd, 0x9d, 0x4a, 0x47, 0x50, 0xca, 0x49, 0x93, 0xc6, 0x12, 0xcb, \ - 0x59, 0x13, 0x7c, 0x14, 0x9a, 0xa1, 0x60, 0x04, 0xf2, 0x42, 0x7b, 0x59, \ - 0xd1, 0x04, 0xa2, 0xdd, 0x6f, 0x47, 0x7d, 0x26, 0x4f, 0x9c, 0x54, 0xdc, \ - 0x3c, 0x85, 0xde, 0xa2, 0x23, 0xdd, 0xda, 0x92, 0xe5, 0xc6, 0xdd, 0x61, \ - 0x66, 0xef, 0x1d, 0xc2, 0xcd, 0x8b, 0x4d, 0x71, 0x3a, 0xde, 0xe3, 0xfa, \ - 0x30, 0xce, 0x0b, 0x1e, 0xf5, 0xb1, 0x8a, 0xe2, 0x5a, 0x5a, 0x43, 0xff, \ - 0x9a, 0xdc, 0x72, 0x50, 0x02, 0xe3, 0xda, 0x94, 0x31, 0x46, 0x2b, 0x68, \ - 0xa4, 0xe4, 0x45, 0x41, 0xd9, 0xfb, 0x00, 0xe6, 0x39 \ -} -/* END FILE */ - -/* This is taken from tests/data_files/test-ca.key */ -/* BEGIN FILE string macro TEST_CA_KEY_RSA_PEM tests/data_files/test-ca.key */ -#define TEST_CA_KEY_RSA_PEM \ - "-----BEGIN RSA PRIVATE KEY-----\r\n" \ - "Proc-Type: 4,ENCRYPTED\r\n" \ - "DEK-Info: DES-EDE3-CBC,A8A95B05D5B7206B\r\n" \ - "\r\n" \ - "9Qd9GeArejl1GDVh2lLV1bHt0cPtfbh5h/5zVpAVaFpqtSPMrElp50Rntn9et+JA\r\n" \ - "7VOyboR+Iy2t/HU4WvA687k3Bppe9GwKHjHhtl//8xFKwZr3Xb5yO5JUP8AUctQq\r\n" \ - "Nb8CLlZyuUC+52REAAthdWgsX+7dJO4yabzUcQ22Tp9JSD0hiL43BlkWYUNK3dAo\r\n" \ - "PZlmiptjnzVTjg1MxsBSydZinWOLBV8/JQgxSPo2yD4uEfig28qbvQ2wNIn0pnAb\r\n" \ - "GxnSAOazkongEGfvcjIIs+LZN9gXFhxcOh6kc4Q/c99B7QWETwLLkYgZ+z1a9VY9\r\n" \ - "gEU7CwCxYCD+h9hY6FPmsK0/lC4O7aeRKpYq00rPPxs6i7phiexg6ax6yTMmArQq\r\n" \ - "QmK3TAsJm8V/J5AWpLEV6jAFgRGymGGHnof0DXzVWZidrcZJWTNuGEX90nB3ee2w\r\n" \ - "PXJEFWKoD3K3aFcSLdHYr3mLGxP7H9ThQai9VsycxZKS5kwvBKQ//YMrmFfwPk8x\r\n" \ - "vTeY4KZMaUrveEel5tWZC94RSMKgxR6cyE1nBXyTQnDOGbfpNNgBKxyKbINWoOJU\r\n" \ - "WJZAwlsQn+QzCDwpri7+sV1mS3gBE6UY7aQmnmiiaC2V3Hbphxct/en5QsfDOt1X\r\n" \ - "JczSfpRWLlbPznZg8OQh/VgCMA58N5DjOzTIK7sJJ5r+94ZBTCpgAMbF588f0NTR\r\n" \ - "KCe4yrxGJR7X02M4nvD4IwOlpsQ8xQxZtOSgXv4LkxvdU9XJJKWZ/XNKJeWztxSe\r\n" \ - "Z1vdTc2YfsDBA2SEv33vxHx2g1vqtw8SjDRT2RaQSS0QuSaMJimdOX6mTOCBKk1J\r\n" \ - "9Q5mXTrER+/LnK0jEmXsBXWA5bqqVZIyahXSx4VYZ7l7w/PHiUDtDgyRhMMKi4n2\r\n" \ - "iQvQcWSQTjrpnlJbca1/DkpRt3YwrvJwdqb8asZU2VrNETh5x0QVefDRLFiVpif/\r\n" \ - "tUaeAe/P1F8OkS7OIZDs1SUbv/sD2vMbhNkUoCms3/PvNtdnvgL4F0zhaDpKCmlT\r\n" \ - "P8vx49E7v5CyRNmED9zZg4o3wmMqrQO93PtTug3Eu9oVx1zPQM1NVMyBa2+f29DL\r\n" \ - "1nuTCeXdo9+ni45xx+jAI4DCwrRdhJ9uzZyC6962H37H6D+5naNvClFR1s6li1Gb\r\n" \ - "nqPoiy/OBsEx9CaDGcqQBp5Wme/3XW+6z1ISOx+igwNTVCT14mHdBMbya0eIKft5\r\n" \ - "X+GnwtgEMyCYyyWuUct8g4RzErcY9+yW9Om5Hzpx4zOuW4NPZgPDTgK+t2RSL/Yq\r\n" \ - "rE1njrgeGYcVeG3f+OftH4s6fPbq7t1A5ZgUscbLMBqr9tK+OqygR4EgKBPsH6Cz\r\n" \ - "L6zlv/2RV0qAHvVuDJcIDIgwY5rJtINEm32rhOeFNJwZS5MNIC1czXZx5//ugX7l\r\n" \ - "I4sy5nbVhwSjtAk8Xg5dZbdTZ6mIrb7xqH+fdakZor1khG7bC2uIwibD3cSl2XkR\r\n" \ - "wN48lslbHnqqagr6Xm1nNOSVl8C/6kbJEsMpLhAezfRtGwvOucoaE+WbeUNolGde\r\n" \ - "P/eQiddSf0brnpiLJRh7qZrl9XuqYdpUqnoEdMAfotDOID8OtV7gt8a48ad8VPW2\r\n" \ - "-----END RSA PRIVATE KEY-----\r\n" -/* END FILE */ - -#define TEST_CA_PWD_RSA_PEM "PolarSSLTest" - -/* This was generated from test-ca.key.der using `xxd -i`. */ -/* BEGIN FILE binary macro TEST_CA_KEY_RSA_DER tests/data_files/test-ca.key.der */ -#define TEST_CA_KEY_RSA_DER { \ - 0x30, 0x82, 0x04, 0xa4, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, \ - 0xc0, 0xdf, 0x37, 0xfc, 0x17, 0xbb, 0xe0, 0x96, 0x9d, 0x3f, 0x86, 0xde, \ - 0x96, 0x32, 0x7d, 0x44, 0xa5, 0x16, 0xa0, 0xcd, 0x21, 0xf1, 0x99, 0xd4, \ - 0xec, 0xea, 0xcb, 0x7c, 0x18, 0x58, 0x08, 0x94, 0xa5, 0xec, 0x9b, 0xc5, \ - 0x8b, 0xdf, 0x1a, 0x1e, 0x99, 0x38, 0x99, 0x87, 0x1e, 0x7b, 0xc0, 0x8d, \ - 0x39, 0xdf, 0x38, 0x5d, 0x70, 0x78, 0x07, 0xd3, 0x9e, 0xd9, 0x93, 0xe8, \ - 0xb9, 0x72, 0x51, 0xc5, 0xce, 0xa3, 0x30, 0x52, 0xa9, 0xf2, 0xe7, 0x40, \ - 0x70, 0x14, 0xcb, 0x44, 0xa2, 0x72, 0x0b, 0xc2, 0xe5, 0x40, 0xf9, 0x3e, \ - 0xe5, 0xa6, 0x0e, 0xb3, 0xf9, 0xec, 0x4a, 0x63, 0xc0, 0xb8, 0x29, 0x00, \ - 0x74, 0x9c, 0x57, 0x3b, 0xa8, 0xa5, 0x04, 0x90, 0x71, 0xf1, 0xbd, 0x83, \ - 0xd9, 0x3f, 0xd6, 0xa5, 0xe2, 0x3c, 0x2a, 0x8f, 0xef, 0x27, 0x60, 0xc3, \ - 0xc6, 0x9f, 0xcb, 0xba, 0xec, 0x60, 0x7d, 0xb7, 0xe6, 0x84, 0x32, 0xbe, \ - 0x4f, 0xfb, 0x58, 0x26, 0x22, 0x03, 0x5b, 0xd4, 0xb4, 0xd5, 0xfb, 0xf5, \ - 0xe3, 0x96, 0x2e, 0x70, 0xc0, 0xe4, 0x2e, 0xbd, 0xfc, 0x2e, 0xee, 0xe2, \ - 0x41, 0x55, 0xc0, 0x34, 0x2e, 0x7d, 0x24, 0x72, 0x69, 0xcb, 0x47, 0xb1, \ - 0x14, 0x40, 0x83, 0x7d, 0x67, 0xf4, 0x86, 0xf6, 0x31, 0xab, 0xf1, 0x79, \ - 0xa4, 0xb2, 0xb5, 0x2e, 0x12, 0xf9, 0x84, 0x17, 0xf0, 0x62, 0x6f, 0x27, \ - 0x3e, 0x13, 0x58, 0xb1, 0x54, 0x0d, 0x21, 0x9a, 0x73, 0x37, 0xa1, 0x30, \ - 0xcf, 0x6f, 0x92, 0xdc, 0xf6, 0xe9, 0xfc, 0xac, 0xdb, 0x2e, 0x28, 0xd1, \ - 0x7e, 0x02, 0x4b, 0x23, 0xa0, 0x15, 0xf2, 0x38, 0x65, 0x64, 0x09, 0xea, \ - 0x0c, 0x6e, 0x8e, 0x1b, 0x17, 0xa0, 0x71, 0xc8, 0xb3, 0x9b, 0xc9, 0xab, \ - 0xe9, 0xc3, 0xf2, 0xcf, 0x87, 0x96, 0x8f, 0x80, 0x02, 0x32, 0x9e, 0x99, \ - 0x58, 0x6f, 0xa2, 0xd5, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x82, 0x01, \ - 0x00, 0x3f, 0xf7, 0x07, 0xd3, 0x34, 0x6f, 0xdb, 0xc9, 0x37, 0xb7, 0x84, \ - 0xdc, 0x37, 0x45, 0xe1, 0x63, 0xad, 0xb8, 0xb6, 0x75, 0xb1, 0xc7, 0x35, \ - 0xb4, 0x77, 0x2a, 0x5b, 0x77, 0xf9, 0x7e, 0xe0, 0xc1, 0xa3, 0xd1, 0xb7, \ - 0xcb, 0xa9, 0x5a, 0xc1, 0x87, 0xda, 0x5a, 0xfa, 0x17, 0xe4, 0xd5, 0x38, \ - 0x03, 0xde, 0x68, 0x98, 0x81, 0xec, 0xb5, 0xf2, 0x2a, 0x8d, 0xe9, 0x2c, \ - 0xf3, 0xa6, 0xe5, 0x32, 0x17, 0x7f, 0x33, 0x81, 0xe8, 0x38, 0x72, 0xd5, \ - 0x9c, 0xfa, 0x4e, 0xfb, 0x26, 0xf5, 0x15, 0x0b, 0xaf, 0x84, 0x66, 0xab, \ - 0x02, 0xe0, 0x18, 0xd5, 0x91, 0x7c, 0xd6, 0x8f, 0xc9, 0x4b, 0x76, 0x08, \ - 0x2b, 0x1d, 0x81, 0x68, 0x30, 0xe1, 0xfa, 0x70, 0x6c, 0x13, 0x4e, 0x10, \ - 0x03, 0x35, 0x3e, 0xc5, 0xca, 0x58, 0x20, 0x8a, 0x21, 0x18, 0x38, 0xa0, \ - 0x0f, 0xed, 0xc4, 0xbb, 0x45, 0x6f, 0xf5, 0x84, 0x5b, 0xb0, 0xcf, 0x4e, \ - 0x9d, 0x58, 0x13, 0x6b, 0x35, 0x35, 0x69, 0xa1, 0xd2, 0xc4, 0xf2, 0xc1, \ - 0x48, 0x04, 0x20, 0x51, 0xb9, 0x6b, 0xa4, 0x5d, 0xa5, 0x4b, 0x84, 0x88, \ - 0x43, 0x48, 0x99, 0x2c, 0xbb, 0xa4, 0x97, 0xd6, 0xd6, 0x18, 0xf6, 0xec, \ - 0x5c, 0xd1, 0x31, 0x49, 0xc9, 0xf2, 0x8f, 0x0b, 0x4d, 0xef, 0x09, 0x02, \ - 0xfe, 0x7d, 0xfd, 0xbb, 0xaf, 0x2b, 0x83, 0x94, 0x22, 0xc4, 0xa7, 0x3e, \ - 0x66, 0xf5, 0xe0, 0x57, 0xdc, 0xf2, 0xed, 0x2c, 0x3e, 0x81, 0x74, 0x76, \ - 0x1e, 0x96, 0x6f, 0x74, 0x1e, 0x32, 0x0e, 0x14, 0x31, 0xd0, 0x74, 0xf0, \ - 0xf4, 0x07, 0xbd, 0xc3, 0xd1, 0x22, 0xc2, 0xa8, 0x95, 0x92, 0x06, 0x7f, \ - 0x43, 0x02, 0x91, 0xbc, 0xdd, 0x23, 0x01, 0x89, 0x94, 0x20, 0x44, 0x64, \ - 0xf5, 0x1d, 0x67, 0xd2, 0x8f, 0xe8, 0x69, 0xa5, 0x29, 0x25, 0xe6, 0x50, \ - 0x9c, 0xe3, 0xe9, 0xcb, 0x75, 0x02, 0x81, 0x81, 0x00, 0xe2, 0x29, 0x3e, \ - 0xaa, 0x6b, 0xd5, 0x59, 0x1e, 0x9c, 0xe6, 0x47, 0xd5, 0xb6, 0xd7, 0xe3, \ - 0xf1, 0x8e, 0x9e, 0xe9, 0x83, 0x5f, 0x10, 0x9f, 0x63, 0xec, 0x04, 0x44, \ - 0xcc, 0x3f, 0xf8, 0xd9, 0x3a, 0x17, 0xe0, 0x4f, 0xfe, 0xd8, 0x4d, 0xcd, \ - 0x46, 0x54, 0x74, 0xbf, 0x0a, 0xc4, 0x67, 0x9c, 0xa7, 0xd8, 0x89, 0x65, \ - 0x4c, 0xfd, 0x58, 0x2a, 0x47, 0x0f, 0xf4, 0x37, 0xb6, 0x55, 0xb0, 0x1d, \ - 0xed, 0xa7, 0x39, 0xfc, 0x4f, 0xa3, 0xc4, 0x75, 0x3a, 0xa3, 0x98, 0xa7, \ - 0x45, 0xf5, 0x66, 0xcb, 0x7c, 0x65, 0xfb, 0x80, 0x23, 0xe6, 0xff, 0xfd, \ - 0x99, 0x1f, 0x8e, 0x6b, 0xff, 0x5e, 0x93, 0x66, 0xdf, 0x6c, 0x6f, 0xc3, \ - 0xf6, 0x38, 0x2e, 0xff, 0x69, 0xb5, 0xac, 0xae, 0xbb, 0xc6, 0x71, 0x16, \ - 0x6b, 0xd0, 0xf8, 0x22, 0xd9, 0xf8, 0xa2, 0x72, 0x20, 0xd2, 0xe2, 0x3a, \ - 0x70, 0x4b, 0xde, 0xab, 0x2f, 0x02, 0x81, 0x81, 0x00, 0xda, 0x51, 0x9b, \ - 0xb8, 0xb2, 0x2a, 0x14, 0x75, 0x58, 0x40, 0x8d, 0x27, 0x70, 0xfa, 0x31, \ - 0x48, 0xb0, 0x20, 0x21, 0x34, 0xfa, 0x4c, 0x57, 0xa8, 0x11, 0x88, 0xf3, \ - 0xa7, 0xae, 0x21, 0xe9, 0xb6, 0x2b, 0xd1, 0xcd, 0xa7, 0xf8, 0xd8, 0x0c, \ - 0x8a, 0x76, 0x22, 0x35, 0x44, 0xce, 0x3f, 0x25, 0x29, 0x83, 0x7d, 0x79, \ - 0xa7, 0x31, 0xd6, 0xec, 0xb2, 0xbf, 0xda, 0x34, 0xb6, 0xf6, 0xb2, 0x3b, \ - 0xf3, 0x78, 0x5a, 0x04, 0x83, 0x33, 0x3e, 0xa2, 0xe2, 0x81, 0x82, 0x13, \ - 0xd4, 0x35, 0x17, 0x63, 0x9b, 0x9e, 0xc4, 0x8d, 0x91, 0x4c, 0x03, 0x77, \ - 0xc7, 0x71, 0x5b, 0xee, 0x83, 0x6d, 0xd5, 0x78, 0x88, 0xf6, 0x2c, 0x79, \ - 0xc2, 0x4a, 0xb4, 0x79, 0x90, 0x70, 0xbf, 0xdf, 0x34, 0x56, 0x96, 0x71, \ - 0xe3, 0x0e, 0x68, 0x91, 0xbc, 0xea, 0xcb, 0x33, 0xc0, 0xbe, 0x45, 0xd7, \ - 0xfc, 0x30, 0xfd, 0x01, 0x3b, 0x02, 0x81, 0x81, 0x00, 0xd2, 0x9f, 0x2a, \ - 0xb7, 0x38, 0x19, 0xc7, 0x17, 0x95, 0x73, 0x78, 0xae, 0xf5, 0xcb, 0x75, \ - 0x83, 0x7f, 0x19, 0x4b, 0xcb, 0x86, 0xfb, 0x4a, 0x15, 0x9a, 0xb6, 0x17, \ - 0x04, 0x49, 0x07, 0x8d, 0xf6, 0x66, 0x4a, 0x06, 0xf6, 0x05, 0xa7, 0xdf, \ - 0x66, 0x82, 0x3c, 0xff, 0xb6, 0x1d, 0x57, 0x89, 0x33, 0x5f, 0x9c, 0x05, \ - 0x75, 0x7f, 0xf3, 0x5d, 0xdc, 0x34, 0x65, 0x72, 0x85, 0x22, 0xa4, 0x14, \ - 0x1b, 0x41, 0xc3, 0xe4, 0xd0, 0x9e, 0x69, 0xd5, 0xeb, 0x38, 0x74, 0x70, \ - 0x43, 0xdc, 0xd9, 0x50, 0xe4, 0x97, 0x6d, 0x73, 0xd6, 0xfb, 0xc8, 0xa7, \ - 0xfa, 0xb4, 0xc2, 0xc4, 0x9d, 0x5d, 0x0c, 0xd5, 0x9f, 0x79, 0xb3, 0x54, \ - 0xc2, 0xb7, 0x6c, 0x3d, 0x7d, 0xcb, 0x2d, 0xf8, 0xc4, 0xf3, 0x78, 0x5a, \ - 0x33, 0x2a, 0xb8, 0x0c, 0x6d, 0x06, 0xfa, 0xf2, 0x62, 0xd3, 0x42, 0xd0, \ - 0xbd, 0xc8, 0x4a, 0xa5, 0x0d, 0x02, 0x81, 0x81, 0x00, 0xd4, 0xa9, 0x90, \ - 0x15, 0xde, 0xbf, 0x2c, 0xc4, 0x8d, 0x9d, 0xfb, 0xa1, 0xc2, 0xe4, 0x83, \ - 0xe3, 0x79, 0x65, 0x22, 0xd3, 0xb7, 0x49, 0x6c, 0x4d, 0x94, 0x1f, 0x22, \ - 0xb1, 0x60, 0xe7, 0x3a, 0x00, 0xb1, 0x38, 0xa2, 0xab, 0x0f, 0xb4, 0x6c, \ - 0xaa, 0xe7, 0x9e, 0x34, 0xe3, 0x7c, 0x40, 0x78, 0x53, 0xb2, 0xf9, 0x23, \ - 0xea, 0xa0, 0x9a, 0xea, 0x60, 0xc8, 0x8f, 0xa6, 0xaf, 0xdf, 0x29, 0x09, \ - 0x4b, 0x06, 0x1e, 0x31, 0xad, 0x17, 0xda, 0xd8, 0xd1, 0xe9, 0x33, 0xab, \ - 0x5b, 0x18, 0x08, 0x5b, 0x87, 0xf8, 0xa5, 0x1f, 0xfd, 0xbb, 0xdc, 0xd8, \ - 0xed, 0x97, 0x57, 0xe4, 0xc3, 0x73, 0xd6, 0xf0, 0x9e, 0x01, 0xa6, 0x9b, \ - 0x48, 0x8e, 0x7a, 0xb4, 0xbb, 0xe5, 0x88, 0x91, 0xc5, 0x2a, 0xdf, 0x4b, \ - 0xba, 0xd0, 0x8b, 0x3e, 0x03, 0x97, 0x77, 0x2f, 0x47, 0x7e, 0x51, 0x0c, \ - 0xae, 0x65, 0x8d, 0xde, 0x87, 0x02, 0x81, 0x80, 0x20, 0x24, 0x0f, 0xd2, \ - 0xaf, 0xc2, 0x28, 0x3b, 0x97, 0x20, 0xb2, 0x92, 0x49, 0xeb, 0x09, 0x68, \ - 0x40, 0xb2, 0xbe, 0xd1, 0xc3, 0x83, 0x94, 0x34, 0x38, 0xd6, 0xc9, 0xec, \ - 0x34, 0x09, 0xf9, 0x41, 0x6d, 0x5c, 0x42, 0x94, 0xf7, 0x04, 0xfc, 0x32, \ - 0x39, 0x69, 0xbc, 0x1c, 0xfb, 0x3e, 0x61, 0x98, 0xc0, 0x80, 0xd8, 0x36, \ - 0x47, 0xc3, 0x6d, 0xc2, 0x2e, 0xe7, 0x81, 0x2a, 0x17, 0x34, 0x64, 0x30, \ - 0x4e, 0x96, 0xbb, 0x26, 0x16, 0xb9, 0x41, 0x36, 0xfe, 0x8a, 0xd6, 0x53, \ - 0x7c, 0xaa, 0xec, 0x39, 0x42, 0x50, 0xef, 0xe3, 0xb3, 0x01, 0x28, 0x32, \ - 0xca, 0x6d, 0xf5, 0x9a, 0x1e, 0x9f, 0x37, 0xbe, 0xfe, 0x38, 0x20, 0x22, \ - 0x91, 0x8c, 0xcd, 0x95, 0x02, 0xf2, 0x4d, 0x6f, 0x1a, 0xb4, 0x43, 0xf0, \ - 0x19, 0xdf, 0x65, 0xc0, 0x92, 0xe7, 0x9d, 0x2f, 0x09, 0xe7, 0xec, 0x69, \ - 0xa8, 0xc2, 0x8f, 0x0d \ -} -/* END FILE */ - -/* - * Test server Certificates - * - * Test server certificates are defined for each choice - * of the following parameters: - * - PEM or DER encoding - * - SHA-1 or SHA-256 hash - * - RSA or EC key - * - * Things to add: - * - multiple EC curve types - */ - -/* Use CRTs with Secp256r1-only if Secp384r1 is disabled. - * Otherwise, fall back to previous test CRTs using both - * Secp256r1 and Secp384r1. */ -#if !defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) - -/* This is taken from tests/data_files/server11.crt.pem. */ -/* BEGIN FILE string macro TEST_SRV_CRT_EC_PEM tests/data_files/server11.crt.pem */ -#define TEST_SRV_CRT_EC_PEM \ - "-----BEGIN CERTIFICATE-----\r\n" \ - "MIIBrzCCAVKgAwIBAgIBATAMBggqhkjOPQQDAgUAMDsxGjAYBgNVBAMMEVRlc3Qg\r\n" \ - "Q0EgU2VjcDI1NnIxMRAwDgYDVQQKDAdNYmVkVExTMQswCQYDVQQGEwJVSzAeFw0w\r\n" \ - "MTAxMDEwMDAwMDBaFw0zMDEyMzEyMzU5NTlaMDMxEjAQBgNVBAMMCWxvY2FsaG9z\r\n" \ - "dDEQMA4GA1UECgwHTWJlZFRMUzELMAkGA1UEBhMCVUswWTATBgcqhkjOPQIBBggq\r\n" \ - "hkjOPQMBBwNCAATH4k2I+9HG/2AM4cN0pPkfO62ddKWwtDsdFezZoKxwXYm0ClZe\r\n" \ - "zZYmfpl8x5Q7+V2oGg3TXoC8TOmXjAtabfDNo00wSzAJBgNVHRMEAjAAMB0GA1Ud\r\n" \ - "DgQWBBQjXj0e2wlEVpSCbySpu2oDJgn7sjAfBgNVHSMEGDAWgBRKXqRhM0sWSAwx\r\n" \ - "eCI11vvOUOcgEjAMBggqhkjOPQQDAgUAA0kAMEYCIQCN7/F5DbM4Ug5NcKHeKFbb\r\n" \ - "3EHpsBjg0//gXa9mJ7Q4jAIhAIzio6vwCYnzrslzsTbPpmtU+6Op6SlzdGO/iR77\r\n" \ - "bcfp\r\n" \ - "-----END CERTIFICATE-----\r\n" -/* END FILE */ - -/* This is generated from tests/data_files/server11.crt.der using `xxd -i`. */ -/* BEGIN FILE binary macro TEST_SRV_CRT_EC_DER tests/data_files/server11.crt.der */ -#define TEST_SRV_CRT_EC_DER { \ - 0x30, 0x82, 0x01, 0xaf, 0x30, 0x82, 0x01, 0x52, 0xa0, 0x03, 0x02, 0x01, \ - 0x02, 0x02, 0x01, 0x01, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, \ - 0x3d, 0x04, 0x03, 0x02, 0x05, 0x00, 0x30, 0x3b, 0x31, 0x1a, 0x30, 0x18, \ - 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x11, 0x54, 0x65, 0x73, 0x74, 0x20, \ - 0x43, 0x41, 0x20, 0x53, 0x65, 0x63, 0x70, 0x32, 0x35, 0x36, 0x72, 0x31, \ - 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x07, 0x4d, \ - 0x62, 0x65, 0x64, 0x54, 0x4c, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, \ - 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x4b, 0x30, 0x1e, 0x17, 0x0d, 0x30, \ - 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, \ - 0x17, 0x0d, 0x33, 0x30, 0x31, 0x32, 0x33, 0x31, 0x32, 0x33, 0x35, 0x39, \ - 0x35, 0x39, 0x5a, 0x30, 0x33, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, \ - 0x04, 0x03, 0x0c, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, \ - 0x74, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x07, \ - 0x4d, 0x62, 0x65, 0x64, 0x54, 0x4c, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, \ - 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x4b, 0x30, 0x59, 0x30, 0x13, \ - 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, \ - 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0xc7, \ - 0xe2, 0x4d, 0x88, 0xfb, 0xd1, 0xc6, 0xff, 0x60, 0x0c, 0xe1, 0xc3, 0x74, \ - 0xa4, 0xf9, 0x1f, 0x3b, 0xad, 0x9d, 0x74, 0xa5, 0xb0, 0xb4, 0x3b, 0x1d, \ - 0x15, 0xec, 0xd9, 0xa0, 0xac, 0x70, 0x5d, 0x89, 0xb4, 0x0a, 0x56, 0x5e, \ - 0xcd, 0x96, 0x26, 0x7e, 0x99, 0x7c, 0xc7, 0x94, 0x3b, 0xf9, 0x5d, 0xa8, \ - 0x1a, 0x0d, 0xd3, 0x5e, 0x80, 0xbc, 0x4c, 0xe9, 0x97, 0x8c, 0x0b, 0x5a, \ - 0x6d, 0xf0, 0xcd, 0xa3, 0x4d, 0x30, 0x4b, 0x30, 0x09, 0x06, 0x03, 0x55, \ - 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, \ - 0x0e, 0x04, 0x16, 0x04, 0x14, 0x23, 0x5e, 0x3d, 0x1e, 0xdb, 0x09, 0x44, \ - 0x56, 0x94, 0x82, 0x6f, 0x24, 0xa9, 0xbb, 0x6a, 0x03, 0x26, 0x09, 0xfb, \ - 0xb2, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, \ - 0x80, 0x14, 0x4a, 0x5e, 0xa4, 0x61, 0x33, 0x4b, 0x16, 0x48, 0x0c, 0x31, \ - 0x78, 0x22, 0x35, 0xd6, 0xfb, 0xce, 0x50, 0xe7, 0x20, 0x12, 0x30, 0x0c, \ - 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x05, 0x00, \ - 0x03, 0x49, 0x00, 0x30, 0x46, 0x02, 0x21, 0x00, 0x8d, 0xef, 0xf1, 0x79, \ - 0x0d, 0xb3, 0x38, 0x52, 0x0e, 0x4d, 0x70, 0xa1, 0xde, 0x28, 0x56, 0xdb, \ - 0xdc, 0x41, 0xe9, 0xb0, 0x18, 0xe0, 0xd3, 0xff, 0xe0, 0x5d, 0xaf, 0x66, \ - 0x27, 0xb4, 0x38, 0x8c, 0x02, 0x21, 0x00, 0x8c, 0xe2, 0xa3, 0xab, 0xf0, \ - 0x09, 0x89, 0xf3, 0xae, 0xc9, 0x73, 0xb1, 0x36, 0xcf, 0xa6, 0x6b, 0x54, \ - 0xfb, 0xa3, 0xa9, 0xe9, 0x29, 0x73, 0x74, 0x63, 0xbf, 0x89, 0x1e, 0xfb, \ - 0x6d, 0xc7, 0xe9 \ -} -/* END FILE */ - -/* This is taken from tests/data_files/server11.key.pem. */ -/* BEGIN FILE string macro TEST_SRV_KEY_EC_PEM tests/data_files/server11.key.pem */ -#define TEST_SRV_KEY_EC_PEM \ - "-----BEGIN EC PRIVATE KEY-----\r\n" \ - "MHcCAQEEIGEWs7/9cQHgEI5v2qeQRGLoFhjrNK4lul6tmcqDACKuoAoGCCqGSM49\r\n" \ - "AwEHoUQDQgAEx+JNiPvRxv9gDOHDdKT5HzutnXSlsLQ7HRXs2aCscF2JtApWXs2W\r\n" \ - "Jn6ZfMeUO/ldqBoN016AvEzpl4wLWm3wzQ==\r\n" \ - "-----END EC PRIVATE KEY-----\r\n" -/* END FILE */ - -/* This is generated from tests/data_files/server11.key.der using `xxd -i`. */ -/* BEGIN FILE binary macro TEST_SRV_KEY_EC_DER tests/data_files/server11.key.der */ -#define TEST_SRV_KEY_EC_DER { \ - 0x30, 0x77, 0x02, 0x01, 0x01, 0x04, 0x20, 0x61, 0x16, 0xb3, 0xbf, 0xfd, \ - 0x71, 0x01, 0xe0, 0x10, 0x8e, 0x6f, 0xda, 0xa7, 0x90, 0x44, 0x62, 0xe8, \ - 0x16, 0x18, 0xeb, 0x34, 0xae, 0x25, 0xba, 0x5e, 0xad, 0x99, 0xca, 0x83, \ - 0x00, 0x22, 0xae, 0xa0, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, \ - 0x03, 0x01, 0x07, 0xa1, 0x44, 0x03, 0x42, 0x00, 0x04, 0xc7, 0xe2, 0x4d, \ - 0x88, 0xfb, 0xd1, 0xc6, 0xff, 0x60, 0x0c, 0xe1, 0xc3, 0x74, 0xa4, 0xf9, \ - 0x1f, 0x3b, 0xad, 0x9d, 0x74, 0xa5, 0xb0, 0xb4, 0x3b, 0x1d, 0x15, 0xec, \ - 0xd9, 0xa0, 0xac, 0x70, 0x5d, 0x89, 0xb4, 0x0a, 0x56, 0x5e, 0xcd, 0x96, \ - 0x26, 0x7e, 0x99, 0x7c, 0xc7, 0x94, 0x3b, 0xf9, 0x5d, 0xa8, 0x1a, 0x0d, \ - 0xd3, 0x5e, 0x80, 0xbc, 0x4c, 0xe9, 0x97, 0x8c, 0x0b, 0x5a, 0x6d, 0xf0, \ - 0xcd \ -} -/* END FILE */ - -#else /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */ - -/* This is taken from tests/data_files/server5.crt. */ -/* BEGIN FILE string macro TEST_SRV_CRT_EC_PEM tests/data_files/server5.crt */ -#define TEST_SRV_CRT_EC_PEM \ - "-----BEGIN CERTIFICATE-----\r\n" \ - "MIICHzCCAaWgAwIBAgIBCTAKBggqhkjOPQQDAjA+MQswCQYDVQQGEwJOTDERMA8G\r\n" \ - "A1UEChMIUG9sYXJTU0wxHDAaBgNVBAMTE1BvbGFyc3NsIFRlc3QgRUMgQ0EwHhcN\r\n" \ - "MTMwOTI0MTU1MjA0WhcNMjMwOTIyMTU1MjA0WjA0MQswCQYDVQQGEwJOTDERMA8G\r\n" \ - "A1UEChMIUG9sYXJTU0wxEjAQBgNVBAMTCWxvY2FsaG9zdDBZMBMGByqGSM49AgEG\r\n" \ - "CCqGSM49AwEHA0IABDfMVtl2CR5acj7HWS3/IG7ufPkGkXTQrRS192giWWKSTuUA\r\n" \ - "2CMR/+ov0jRdXRa9iojCa3cNVc2KKg76Aci07f+jgZ0wgZowCQYDVR0TBAIwADAd\r\n" \ - "BgNVHQ4EFgQUUGGlj9QH2deCAQzlZX+MY0anE74wbgYDVR0jBGcwZYAUnW0gJEkB\r\n" \ - "PyvLeLUZvH4kydv7NnyhQqRAMD4xCzAJBgNVBAYTAk5MMREwDwYDVQQKEwhQb2xh\r\n" \ - "clNTTDEcMBoGA1UEAxMTUG9sYXJzc2wgVGVzdCBFQyBDQYIJAMFD4n5iQ8zoMAoG\r\n" \ - "CCqGSM49BAMCA2gAMGUCMQCaLFzXptui5WQN8LlO3ddh1hMxx6tzgLvT03MTVK2S\r\n" \ - "C12r0Lz3ri/moSEpNZWqPjkCMCE2f53GXcYLqyfyJR078c/xNSUU5+Xxl7VZ414V\r\n" \ - "fGa5kHvHARBPc8YAIVIqDvHH1Q==\r\n" \ - "-----END CERTIFICATE-----\r\n" -/* END FILE */ - -/* This is generated from tests/data_files/server5.crt.der using `xxd -i`. */ -/* BEGIN FILE binary macro TEST_SRV_CRT_EC_DER tests/data_files/server5.crt.der */ -#define TEST_SRV_CRT_EC_DER { \ - 0x30, 0x82, 0x02, 0x1f, 0x30, 0x82, 0x01, 0xa5, 0xa0, 0x03, 0x02, 0x01, \ - 0x02, 0x02, 0x01, 0x09, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, \ - 0x3d, 0x04, 0x03, 0x02, 0x30, 0x3e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, \ - 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, 0x0f, 0x06, \ - 0x03, 0x55, 0x04, 0x0a, 0x13, 0x08, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, \ - 0x53, 0x4c, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, \ - 0x13, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x73, 0x73, 0x6c, 0x20, 0x54, 0x65, \ - 0x73, 0x74, 0x20, 0x45, 0x43, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, \ - 0x31, 0x33, 0x30, 0x39, 0x32, 0x34, 0x31, 0x35, 0x35, 0x32, 0x30, 0x34, \ - 0x5a, 0x17, 0x0d, 0x32, 0x33, 0x30, 0x39, 0x32, 0x32, 0x31, 0x35, 0x35, \ - 0x32, 0x30, 0x34, 0x5a, 0x30, 0x34, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, \ - 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, 0x0f, 0x06, \ - 0x03, 0x55, 0x04, 0x0a, 0x13, 0x08, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, \ - 0x53, 0x4c, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, \ - 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x30, 0x59, \ - 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, \ - 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, \ - 0x04, 0x37, 0xcc, 0x56, 0xd9, 0x76, 0x09, 0x1e, 0x5a, 0x72, 0x3e, 0xc7, \ - 0x59, 0x2d, 0xff, 0x20, 0x6e, 0xee, 0x7c, 0xf9, 0x06, 0x91, 0x74, 0xd0, \ - 0xad, 0x14, 0xb5, 0xf7, 0x68, 0x22, 0x59, 0x62, 0x92, 0x4e, 0xe5, 0x00, \ - 0xd8, 0x23, 0x11, 0xff, 0xea, 0x2f, 0xd2, 0x34, 0x5d, 0x5d, 0x16, 0xbd, \ - 0x8a, 0x88, 0xc2, 0x6b, 0x77, 0x0d, 0x55, 0xcd, 0x8a, 0x2a, 0x0e, 0xfa, \ - 0x01, 0xc8, 0xb4, 0xed, 0xff, 0xa3, 0x81, 0x9d, 0x30, 0x81, 0x9a, 0x30, \ - 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1d, \ - 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x50, 0x61, 0xa5, \ - 0x8f, 0xd4, 0x07, 0xd9, 0xd7, 0x82, 0x01, 0x0c, 0xe5, 0x65, 0x7f, 0x8c, \ - 0x63, 0x46, 0xa7, 0x13, 0xbe, 0x30, 0x6e, 0x06, 0x03, 0x55, 0x1d, 0x23, \ - 0x04, 0x67, 0x30, 0x65, 0x80, 0x14, 0x9d, 0x6d, 0x20, 0x24, 0x49, 0x01, \ - 0x3f, 0x2b, 0xcb, 0x78, 0xb5, 0x19, 0xbc, 0x7e, 0x24, 0xc9, 0xdb, 0xfb, \ - 0x36, 0x7c, 0xa1, 0x42, 0xa4, 0x40, 0x30, 0x3e, 0x31, 0x0b, 0x30, 0x09, \ - 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, \ - 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x08, 0x50, 0x6f, 0x6c, 0x61, \ - 0x72, 0x53, 0x53, 0x4c, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, \ - 0x03, 0x13, 0x13, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x73, 0x73, 0x6c, 0x20, \ - 0x54, 0x65, 0x73, 0x74, 0x20, 0x45, 0x43, 0x20, 0x43, 0x41, 0x82, 0x09, \ - 0x00, 0xc1, 0x43, 0xe2, 0x7e, 0x62, 0x43, 0xcc, 0xe8, 0x30, 0x0a, 0x06, \ - 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x68, 0x00, \ - 0x30, 0x65, 0x02, 0x31, 0x00, 0x9a, 0x2c, 0x5c, 0xd7, 0xa6, 0xdb, 0xa2, \ - 0xe5, 0x64, 0x0d, 0xf0, 0xb9, 0x4e, 0xdd, 0xd7, 0x61, 0xd6, 0x13, 0x31, \ - 0xc7, 0xab, 0x73, 0x80, 0xbb, 0xd3, 0xd3, 0x73, 0x13, 0x54, 0xad, 0x92, \ - 0x0b, 0x5d, 0xab, 0xd0, 0xbc, 0xf7, 0xae, 0x2f, 0xe6, 0xa1, 0x21, 0x29, \ - 0x35, 0x95, 0xaa, 0x3e, 0x39, 0x02, 0x30, 0x21, 0x36, 0x7f, 0x9d, 0xc6, \ - 0x5d, 0xc6, 0x0b, 0xab, 0x27, 0xf2, 0x25, 0x1d, 0x3b, 0xf1, 0xcf, 0xf1, \ - 0x35, 0x25, 0x14, 0xe7, 0xe5, 0xf1, 0x97, 0xb5, 0x59, 0xe3, 0x5e, 0x15, \ - 0x7c, 0x66, 0xb9, 0x90, 0x7b, 0xc7, 0x01, 0x10, 0x4f, 0x73, 0xc6, 0x00, \ - 0x21, 0x52, 0x2a, 0x0e, 0xf1, 0xc7, 0xd5 \ -} -/* END FILE */ - -/* This is taken from tests/data_files/server5.key. */ -/* BEGIN FILE string macro TEST_SRV_KEY_EC_PEM tests/data_files/server5.key */ -#define TEST_SRV_KEY_EC_PEM \ - "-----BEGIN EC PRIVATE KEY-----\r\n" \ - "MHcCAQEEIPEqEyB2AnCoPL/9U/YDHvdqXYbIogTywwyp6/UfDw6noAoGCCqGSM49\r\n" \ - "AwEHoUQDQgAEN8xW2XYJHlpyPsdZLf8gbu58+QaRdNCtFLX3aCJZYpJO5QDYIxH/\r\n" \ - "6i/SNF1dFr2KiMJrdw1VzYoqDvoByLTt/w==\r\n" \ - "-----END EC PRIVATE KEY-----\r\n" -/* END FILE */ - -/* This is generated from tests/data_files/server5.key.der using `xxd -i`. */ -/* BEGIN FILE binary macro TEST_SRV_KEY_EC_DER tests/data_files/server5.key.der */ -#define TEST_SRV_KEY_EC_DER { \ - 0x30, 0x77, 0x02, 0x01, 0x01, 0x04, 0x20, 0xf1, 0x2a, 0x13, 0x20, 0x76, \ - 0x02, 0x70, 0xa8, 0x3c, 0xbf, 0xfd, 0x53, 0xf6, 0x03, 0x1e, 0xf7, 0x6a, \ - 0x5d, 0x86, 0xc8, 0xa2, 0x04, 0xf2, 0xc3, 0x0c, 0xa9, 0xeb, 0xf5, 0x1f, \ - 0x0f, 0x0e, 0xa7, 0xa0, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, \ - 0x03, 0x01, 0x07, 0xa1, 0x44, 0x03, 0x42, 0x00, 0x04, 0x37, 0xcc, 0x56, \ - 0xd9, 0x76, 0x09, 0x1e, 0x5a, 0x72, 0x3e, 0xc7, 0x59, 0x2d, 0xff, 0x20, \ - 0x6e, 0xee, 0x7c, 0xf9, 0x06, 0x91, 0x74, 0xd0, 0xad, 0x14, 0xb5, 0xf7, \ - 0x68, 0x22, 0x59, 0x62, 0x92, 0x4e, 0xe5, 0x00, 0xd8, 0x23, 0x11, 0xff, \ - 0xea, 0x2f, 0xd2, 0x34, 0x5d, 0x5d, 0x16, 0xbd, 0x8a, 0x88, 0xc2, 0x6b, \ - 0x77, 0x0d, 0x55, 0xcd, 0x8a, 0x2a, 0x0e, 0xfa, 0x01, 0xc8, 0xb4, 0xed, \ - 0xff \ -} -/* END FILE */ - -#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */ - -/* This is taken from tests/data_files/server2-sha256.crt. */ -/* BEGIN FILE string macro TEST_SRV_CRT_RSA_SHA256_PEM tests/data_files/server2-sha256.crt */ -#define TEST_SRV_CRT_RSA_SHA256_PEM \ - "-----BEGIN CERTIFICATE-----\r\n" \ - "MIIDNzCCAh+gAwIBAgIBAjANBgkqhkiG9w0BAQsFADA7MQswCQYDVQQGEwJOTDER\r\n" \ - "MA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n" \ - "MTkwMjEwMTQ0NDA2WhcNMjkwMjEwMTQ0NDA2WjA0MQswCQYDVQQGEwJOTDERMA8G\r\n" \ - "A1UECgwIUG9sYXJTU0wxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcN\r\n" \ - "AQEBBQADggEPADCCAQoCggEBAMFNo93nzR3RBNdJcriZrA545Do8Ss86ExbQWuTN\r\n" \ - "owCIp+4ea5anUrSQ7y1yej4kmvy2NKwk9XfgJmSMnLAofaHa6ozmyRyWvP7BBFKz\r\n" \ - "NtSj+uGxdtiQwWG0ZlI2oiZTqqt0Xgd9GYLbKtgfoNkNHC1JZvdbJXNG6AuKT2kM\r\n" \ - "tQCQ4dqCEGZ9rlQri2V5kaHiYcPNQEkI7mgM8YuG0ka/0LiqEQMef1aoGh5EGA8P\r\n" \ - "hYvai0Re4hjGYi/HZo36Xdh98yeJKQHFkA4/J/EwyEoO79bex8cna8cFPXrEAjya\r\n" \ - "HT4P6DSYW8tzS1KW2BGiLICIaTla0w+w3lkvEcf36hIBMJcCAwEAAaNNMEswCQYD\r\n" \ - "VR0TBAIwADAdBgNVHQ4EFgQUpQXoZLjc32APUBJNYKhkr02LQ5MwHwYDVR0jBBgw\r\n" \ - "FoAUtFrkpbPe0lL2udWmlQ/rPrzH/f8wDQYJKoZIhvcNAQELBQADggEBAC465FJh\r\n" \ - "Pqel7zJngHIHJrqj/wVAxGAFOTF396XKATGAp+HRCqJ81Ry60CNK1jDzk8dv6M6U\r\n" \ - "HoS7RIFiM/9rXQCbJfiPD5xMTejZp5n5UYHAmxsxDaazfA5FuBhkfokKK6jD4Eq9\r\n" \ - "1C94xGKb6X4/VkaPF7cqoBBw/bHxawXc0UEPjqayiBpCYU/rJoVZgLqFVP7Px3sv\r\n" \ - "a1nOrNx8rPPI1hJ+ZOg8maiPTxHZnBVLakSSLQy/sWeWyazO1RnrbxjrbgQtYKz0\r\n" \ - "e3nwGpu1w13vfckFmUSBhHXH7AAS/HpKC4IH7G2GAk3+n8iSSN71sZzpxonQwVbo\r\n" \ - "pMZqLmbBm/7WPLc=\r\n" \ - "-----END CERTIFICATE-----\r\n" -/* END FILE */ - -/* This is taken from tests/data_files/server2-sha256.crt.der. */ -/* BEGIN FILE binary macro TEST_SRV_CRT_RSA_SHA256_DER tests/data_files/server2-sha256.crt.der */ -#define TEST_SRV_CRT_RSA_SHA256_DER { \ - 0x30, 0x82, 0x03, 0x37, 0x30, 0x82, 0x02, 0x1f, 0xa0, 0x03, 0x02, 0x01, \ - 0x02, 0x02, 0x01, 0x02, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, \ - 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x3b, 0x31, 0x0b, 0x30, \ - 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, \ - 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, \ - 0x61, 0x72, 0x53, 0x53, 0x4c, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, \ - 0x04, 0x03, 0x0c, 0x10, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, \ - 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, \ - 0x31, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, 0x34, 0x30, 0x36, \ - 0x5a, 0x17, 0x0d, 0x32, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, \ - 0x34, 0x30, 0x36, 0x5a, 0x30, 0x34, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, \ - 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, 0x0f, 0x06, \ - 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, \ - 0x53, 0x4c, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, \ - 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x30, 0x82, \ - 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, \ - 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, \ - 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xc1, 0x4d, 0xa3, 0xdd, 0xe7, \ - 0xcd, 0x1d, 0xd1, 0x04, 0xd7, 0x49, 0x72, 0xb8, 0x99, 0xac, 0x0e, 0x78, \ - 0xe4, 0x3a, 0x3c, 0x4a, 0xcf, 0x3a, 0x13, 0x16, 0xd0, 0x5a, 0xe4, 0xcd, \ - 0xa3, 0x00, 0x88, 0xa7, 0xee, 0x1e, 0x6b, 0x96, 0xa7, 0x52, 0xb4, 0x90, \ - 0xef, 0x2d, 0x72, 0x7a, 0x3e, 0x24, 0x9a, 0xfc, 0xb6, 0x34, 0xac, 0x24, \ - 0xf5, 0x77, 0xe0, 0x26, 0x64, 0x8c, 0x9c, 0xb0, 0x28, 0x7d, 0xa1, 0xda, \ - 0xea, 0x8c, 0xe6, 0xc9, 0x1c, 0x96, 0xbc, 0xfe, 0xc1, 0x04, 0x52, 0xb3, \ - 0x36, 0xd4, 0xa3, 0xfa, 0xe1, 0xb1, 0x76, 0xd8, 0x90, 0xc1, 0x61, 0xb4, \ - 0x66, 0x52, 0x36, 0xa2, 0x26, 0x53, 0xaa, 0xab, 0x74, 0x5e, 0x07, 0x7d, \ - 0x19, 0x82, 0xdb, 0x2a, 0xd8, 0x1f, 0xa0, 0xd9, 0x0d, 0x1c, 0x2d, 0x49, \ - 0x66, 0xf7, 0x5b, 0x25, 0x73, 0x46, 0xe8, 0x0b, 0x8a, 0x4f, 0x69, 0x0c, \ - 0xb5, 0x00, 0x90, 0xe1, 0xda, 0x82, 0x10, 0x66, 0x7d, 0xae, 0x54, 0x2b, \ - 0x8b, 0x65, 0x79, 0x91, 0xa1, 0xe2, 0x61, 0xc3, 0xcd, 0x40, 0x49, 0x08, \ - 0xee, 0x68, 0x0c, 0xf1, 0x8b, 0x86, 0xd2, 0x46, 0xbf, 0xd0, 0xb8, 0xaa, \ - 0x11, 0x03, 0x1e, 0x7f, 0x56, 0xa8, 0x1a, 0x1e, 0x44, 0x18, 0x0f, 0x0f, \ - 0x85, 0x8b, 0xda, 0x8b, 0x44, 0x5e, 0xe2, 0x18, 0xc6, 0x62, 0x2f, 0xc7, \ - 0x66, 0x8d, 0xfa, 0x5d, 0xd8, 0x7d, 0xf3, 0x27, 0x89, 0x29, 0x01, 0xc5, \ - 0x90, 0x0e, 0x3f, 0x27, 0xf1, 0x30, 0xc8, 0x4a, 0x0e, 0xef, 0xd6, 0xde, \ - 0xc7, 0xc7, 0x27, 0x6b, 0xc7, 0x05, 0x3d, 0x7a, 0xc4, 0x02, 0x3c, 0x9a, \ - 0x1d, 0x3e, 0x0f, 0xe8, 0x34, 0x98, 0x5b, 0xcb, 0x73, 0x4b, 0x52, 0x96, \ - 0xd8, 0x11, 0xa2, 0x2c, 0x80, 0x88, 0x69, 0x39, 0x5a, 0xd3, 0x0f, 0xb0, \ - 0xde, 0x59, 0x2f, 0x11, 0xc7, 0xf7, 0xea, 0x12, 0x01, 0x30, 0x97, 0x02, \ - 0x03, 0x01, 0x00, 0x01, 0xa3, 0x4d, 0x30, 0x4b, 0x30, 0x09, 0x06, 0x03, \ - 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, \ - 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xa5, 0x05, 0xe8, 0x64, 0xb8, 0xdc, \ - 0xdf, 0x60, 0x0f, 0x50, 0x12, 0x4d, 0x60, 0xa8, 0x64, 0xaf, 0x4d, 0x8b, \ - 0x43, 0x93, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, \ - 0x16, 0x80, 0x14, 0xb4, 0x5a, 0xe4, 0xa5, 0xb3, 0xde, 0xd2, 0x52, 0xf6, \ - 0xb9, 0xd5, 0xa6, 0x95, 0x0f, 0xeb, 0x3e, 0xbc, 0xc7, 0xfd, 0xff, 0x30, \ - 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, \ - 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x2e, 0x3a, 0xe4, 0x52, 0x61, \ - 0x3e, 0xa7, 0xa5, 0xef, 0x32, 0x67, 0x80, 0x72, 0x07, 0x26, 0xba, 0xa3, \ - 0xff, 0x05, 0x40, 0xc4, 0x60, 0x05, 0x39, 0x31, 0x77, 0xf7, 0xa5, 0xca, \ - 0x01, 0x31, 0x80, 0xa7, 0xe1, 0xd1, 0x0a, 0xa2, 0x7c, 0xd5, 0x1c, 0xba, \ - 0xd0, 0x23, 0x4a, 0xd6, 0x30, 0xf3, 0x93, 0xc7, 0x6f, 0xe8, 0xce, 0x94, \ - 0x1e, 0x84, 0xbb, 0x44, 0x81, 0x62, 0x33, 0xff, 0x6b, 0x5d, 0x00, 0x9b, \ - 0x25, 0xf8, 0x8f, 0x0f, 0x9c, 0x4c, 0x4d, 0xe8, 0xd9, 0xa7, 0x99, 0xf9, \ - 0x51, 0x81, 0xc0, 0x9b, 0x1b, 0x31, 0x0d, 0xa6, 0xb3, 0x7c, 0x0e, 0x45, \ - 0xb8, 0x18, 0x64, 0x7e, 0x89, 0x0a, 0x2b, 0xa8, 0xc3, 0xe0, 0x4a, 0xbd, \ - 0xd4, 0x2f, 0x78, 0xc4, 0x62, 0x9b, 0xe9, 0x7e, 0x3f, 0x56, 0x46, 0x8f, \ - 0x17, 0xb7, 0x2a, 0xa0, 0x10, 0x70, 0xfd, 0xb1, 0xf1, 0x6b, 0x05, 0xdc, \ - 0xd1, 0x41, 0x0f, 0x8e, 0xa6, 0xb2, 0x88, 0x1a, 0x42, 0x61, 0x4f, 0xeb, \ - 0x26, 0x85, 0x59, 0x80, 0xba, 0x85, 0x54, 0xfe, 0xcf, 0xc7, 0x7b, 0x2f, \ - 0x6b, 0x59, 0xce, 0xac, 0xdc, 0x7c, 0xac, 0xf3, 0xc8, 0xd6, 0x12, 0x7e, \ - 0x64, 0xe8, 0x3c, 0x99, 0xa8, 0x8f, 0x4f, 0x11, 0xd9, 0x9c, 0x15, 0x4b, \ - 0x6a, 0x44, 0x92, 0x2d, 0x0c, 0xbf, 0xb1, 0x67, 0x96, 0xc9, 0xac, 0xce, \ - 0xd5, 0x19, 0xeb, 0x6f, 0x18, 0xeb, 0x6e, 0x04, 0x2d, 0x60, 0xac, 0xf4, \ - 0x7b, 0x79, 0xf0, 0x1a, 0x9b, 0xb5, 0xc3, 0x5d, 0xef, 0x7d, 0xc9, 0x05, \ - 0x99, 0x44, 0x81, 0x84, 0x75, 0xc7, 0xec, 0x00, 0x12, 0xfc, 0x7a, 0x4a, \ - 0x0b, 0x82, 0x07, 0xec, 0x6d, 0x86, 0x02, 0x4d, 0xfe, 0x9f, 0xc8, 0x92, \ - 0x48, 0xde, 0xf5, 0xb1, 0x9c, 0xe9, 0xc6, 0x89, 0xd0, 0xc1, 0x56, 0xe8, \ - 0xa4, 0xc6, 0x6a, 0x2e, 0x66, 0xc1, 0x9b, 0xfe, 0xd6, 0x3c, 0xb7 \ -} -/* END FILE */ - -/* This is taken from tests/data_files/server2.crt. */ -/* BEGIN FILE string macro TEST_SRV_CRT_RSA_SHA1_PEM tests/data_files/server2.crt */ -#define TEST_SRV_CRT_RSA_SHA1_PEM \ - "-----BEGIN CERTIFICATE-----\r\n" \ - "MIIDNzCCAh+gAwIBAgIBAjANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER\r\n" \ - "MA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n" \ - "MTkwMjEwMTQ0NDA2WhcNMjkwMjEwMTQ0NDA2WjA0MQswCQYDVQQGEwJOTDERMA8G\r\n" \ - "A1UECgwIUG9sYXJTU0wxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcN\r\n" \ - "AQEBBQADggEPADCCAQoCggEBAMFNo93nzR3RBNdJcriZrA545Do8Ss86ExbQWuTN\r\n" \ - "owCIp+4ea5anUrSQ7y1yej4kmvy2NKwk9XfgJmSMnLAofaHa6ozmyRyWvP7BBFKz\r\n" \ - "NtSj+uGxdtiQwWG0ZlI2oiZTqqt0Xgd9GYLbKtgfoNkNHC1JZvdbJXNG6AuKT2kM\r\n" \ - "tQCQ4dqCEGZ9rlQri2V5kaHiYcPNQEkI7mgM8YuG0ka/0LiqEQMef1aoGh5EGA8P\r\n" \ - "hYvai0Re4hjGYi/HZo36Xdh98yeJKQHFkA4/J/EwyEoO79bex8cna8cFPXrEAjya\r\n" \ - "HT4P6DSYW8tzS1KW2BGiLICIaTla0w+w3lkvEcf36hIBMJcCAwEAAaNNMEswCQYD\r\n" \ - "VR0TBAIwADAdBgNVHQ4EFgQUpQXoZLjc32APUBJNYKhkr02LQ5MwHwYDVR0jBBgw\r\n" \ - "FoAUtFrkpbPe0lL2udWmlQ/rPrzH/f8wDQYJKoZIhvcNAQEFBQADggEBAJklg3Q4\r\n" \ - "cB7v7BzsxM/vLyKccO6op0/gZzM4ghuLq2Y32kl0sM6kSNUUmduuq3u/+GmUZN2A\r\n" \ - "O/7c+Hw7hDFEIvZk98aBGjCLqn3DmgHIv8ToQ67nellQxx2Uj309PdgjNi/r9HOc\r\n" \ - "KNAYPbBcg6MJGWWj2TI6vNaceios/DhOYx5V0j5nfqSJ/pnU0g9Ign2LAhgYpGJE\r\n" \ - "iEM9wW7hEMkwmk0h/sqZsrJsGH5YsF/VThSq/JVO1e2mZH2vruyZKJVBq+8tDNYp\r\n" \ - "HkK6tSyVYQhzIt3StMJWKMl/o5k2AYz6tSC164+1oG+ML3LWg8XrGKa91H4UOKap\r\n" \ - "Awgk0+4m0T25cNs=\r\n" \ - "-----END CERTIFICATE-----\r\n" -/* END FILE */ - -/* This is taken from tests/data_files/server2.crt.der. */ -/* BEGIN FILE binary macro TEST_SRV_CRT_RSA_SHA1_DER tests/data_files/server2.crt.der */ -#define TEST_SRV_CRT_RSA_SHA1_DER { \ - 0x30, 0x82, 0x03, 0x37, 0x30, 0x82, 0x02, 0x1f, 0xa0, 0x03, 0x02, 0x01, \ - 0x02, 0x02, 0x01, 0x02, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, \ - 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x3b, 0x31, 0x0b, 0x30, \ - 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, \ - 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, \ - 0x61, 0x72, 0x53, 0x53, 0x4c, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, \ - 0x04, 0x03, 0x0c, 0x10, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, \ - 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, \ - 0x31, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, 0x34, 0x30, 0x36, \ - 0x5a, 0x17, 0x0d, 0x32, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, \ - 0x34, 0x30, 0x36, 0x5a, 0x30, 0x34, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, \ - 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, 0x0f, 0x06, \ - 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, \ - 0x53, 0x4c, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, \ - 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x30, 0x82, \ - 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, \ - 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, \ - 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xc1, 0x4d, 0xa3, 0xdd, 0xe7, \ - 0xcd, 0x1d, 0xd1, 0x04, 0xd7, 0x49, 0x72, 0xb8, 0x99, 0xac, 0x0e, 0x78, \ - 0xe4, 0x3a, 0x3c, 0x4a, 0xcf, 0x3a, 0x13, 0x16, 0xd0, 0x5a, 0xe4, 0xcd, \ - 0xa3, 0x00, 0x88, 0xa7, 0xee, 0x1e, 0x6b, 0x96, 0xa7, 0x52, 0xb4, 0x90, \ - 0xef, 0x2d, 0x72, 0x7a, 0x3e, 0x24, 0x9a, 0xfc, 0xb6, 0x34, 0xac, 0x24, \ - 0xf5, 0x77, 0xe0, 0x26, 0x64, 0x8c, 0x9c, 0xb0, 0x28, 0x7d, 0xa1, 0xda, \ - 0xea, 0x8c, 0xe6, 0xc9, 0x1c, 0x96, 0xbc, 0xfe, 0xc1, 0x04, 0x52, 0xb3, \ - 0x36, 0xd4, 0xa3, 0xfa, 0xe1, 0xb1, 0x76, 0xd8, 0x90, 0xc1, 0x61, 0xb4, \ - 0x66, 0x52, 0x36, 0xa2, 0x26, 0x53, 0xaa, 0xab, 0x74, 0x5e, 0x07, 0x7d, \ - 0x19, 0x82, 0xdb, 0x2a, 0xd8, 0x1f, 0xa0, 0xd9, 0x0d, 0x1c, 0x2d, 0x49, \ - 0x66, 0xf7, 0x5b, 0x25, 0x73, 0x46, 0xe8, 0x0b, 0x8a, 0x4f, 0x69, 0x0c, \ - 0xb5, 0x00, 0x90, 0xe1, 0xda, 0x82, 0x10, 0x66, 0x7d, 0xae, 0x54, 0x2b, \ - 0x8b, 0x65, 0x79, 0x91, 0xa1, 0xe2, 0x61, 0xc3, 0xcd, 0x40, 0x49, 0x08, \ - 0xee, 0x68, 0x0c, 0xf1, 0x8b, 0x86, 0xd2, 0x46, 0xbf, 0xd0, 0xb8, 0xaa, \ - 0x11, 0x03, 0x1e, 0x7f, 0x56, 0xa8, 0x1a, 0x1e, 0x44, 0x18, 0x0f, 0x0f, \ - 0x85, 0x8b, 0xda, 0x8b, 0x44, 0x5e, 0xe2, 0x18, 0xc6, 0x62, 0x2f, 0xc7, \ - 0x66, 0x8d, 0xfa, 0x5d, 0xd8, 0x7d, 0xf3, 0x27, 0x89, 0x29, 0x01, 0xc5, \ - 0x90, 0x0e, 0x3f, 0x27, 0xf1, 0x30, 0xc8, 0x4a, 0x0e, 0xef, 0xd6, 0xde, \ - 0xc7, 0xc7, 0x27, 0x6b, 0xc7, 0x05, 0x3d, 0x7a, 0xc4, 0x02, 0x3c, 0x9a, \ - 0x1d, 0x3e, 0x0f, 0xe8, 0x34, 0x98, 0x5b, 0xcb, 0x73, 0x4b, 0x52, 0x96, \ - 0xd8, 0x11, 0xa2, 0x2c, 0x80, 0x88, 0x69, 0x39, 0x5a, 0xd3, 0x0f, 0xb0, \ - 0xde, 0x59, 0x2f, 0x11, 0xc7, 0xf7, 0xea, 0x12, 0x01, 0x30, 0x97, 0x02, \ - 0x03, 0x01, 0x00, 0x01, 0xa3, 0x4d, 0x30, 0x4b, 0x30, 0x09, 0x06, 0x03, \ - 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, \ - 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xa5, 0x05, 0xe8, 0x64, 0xb8, 0xdc, \ - 0xdf, 0x60, 0x0f, 0x50, 0x12, 0x4d, 0x60, 0xa8, 0x64, 0xaf, 0x4d, 0x8b, \ - 0x43, 0x93, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, \ - 0x16, 0x80, 0x14, 0xb4, 0x5a, 0xe4, 0xa5, 0xb3, 0xde, 0xd2, 0x52, 0xf6, \ - 0xb9, 0xd5, 0xa6, 0x95, 0x0f, 0xeb, 0x3e, 0xbc, 0xc7, 0xfd, 0xff, 0x30, \ - 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, \ - 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x99, 0x25, 0x83, 0x74, 0x38, \ - 0x70, 0x1e, 0xef, 0xec, 0x1c, 0xec, 0xc4, 0xcf, 0xef, 0x2f, 0x22, 0x9c, \ - 0x70, 0xee, 0xa8, 0xa7, 0x4f, 0xe0, 0x67, 0x33, 0x38, 0x82, 0x1b, 0x8b, \ - 0xab, 0x66, 0x37, 0xda, 0x49, 0x74, 0xb0, 0xce, 0xa4, 0x48, 0xd5, 0x14, \ - 0x99, 0xdb, 0xae, 0xab, 0x7b, 0xbf, 0xf8, 0x69, 0x94, 0x64, 0xdd, 0x80, \ - 0x3b, 0xfe, 0xdc, 0xf8, 0x7c, 0x3b, 0x84, 0x31, 0x44, 0x22, 0xf6, 0x64, \ - 0xf7, 0xc6, 0x81, 0x1a, 0x30, 0x8b, 0xaa, 0x7d, 0xc3, 0x9a, 0x01, 0xc8, \ - 0xbf, 0xc4, 0xe8, 0x43, 0xae, 0xe7, 0x7a, 0x59, 0x50, 0xc7, 0x1d, 0x94, \ - 0x8f, 0x7d, 0x3d, 0x3d, 0xd8, 0x23, 0x36, 0x2f, 0xeb, 0xf4, 0x73, 0x9c, \ - 0x28, 0xd0, 0x18, 0x3d, 0xb0, 0x5c, 0x83, 0xa3, 0x09, 0x19, 0x65, 0xa3, \ - 0xd9, 0x32, 0x3a, 0xbc, 0xd6, 0x9c, 0x7a, 0x2a, 0x2c, 0xfc, 0x38, 0x4e, \ - 0x63, 0x1e, 0x55, 0xd2, 0x3e, 0x67, 0x7e, 0xa4, 0x89, 0xfe, 0x99, 0xd4, \ - 0xd2, 0x0f, 0x48, 0x82, 0x7d, 0x8b, 0x02, 0x18, 0x18, 0xa4, 0x62, 0x44, \ - 0x88, 0x43, 0x3d, 0xc1, 0x6e, 0xe1, 0x10, 0xc9, 0x30, 0x9a, 0x4d, 0x21, \ - 0xfe, 0xca, 0x99, 0xb2, 0xb2, 0x6c, 0x18, 0x7e, 0x58, 0xb0, 0x5f, 0xd5, \ - 0x4e, 0x14, 0xaa, 0xfc, 0x95, 0x4e, 0xd5, 0xed, 0xa6, 0x64, 0x7d, 0xaf, \ - 0xae, 0xec, 0x99, 0x28, 0x95, 0x41, 0xab, 0xef, 0x2d, 0x0c, 0xd6, 0x29, \ - 0x1e, 0x42, 0xba, 0xb5, 0x2c, 0x95, 0x61, 0x08, 0x73, 0x22, 0xdd, 0xd2, \ - 0xb4, 0xc2, 0x56, 0x28, 0xc9, 0x7f, 0xa3, 0x99, 0x36, 0x01, 0x8c, 0xfa, \ - 0xb5, 0x20, 0xb5, 0xeb, 0x8f, 0xb5, 0xa0, 0x6f, 0x8c, 0x2f, 0x72, 0xd6, \ - 0x83, 0xc5, 0xeb, 0x18, 0xa6, 0xbd, 0xd4, 0x7e, 0x14, 0x38, 0xa6, 0xa9, \ - 0x03, 0x08, 0x24, 0xd3, 0xee, 0x26, 0xd1, 0x3d, 0xb9, 0x70, 0xdb \ -} -/* END FILE */ - -/* This is taken from tests/data_files/server2.key. */ -/* BEGIN FILE string macro TEST_SRV_KEY_RSA_PEM tests/data_files/server2.key */ -#define TEST_SRV_KEY_RSA_PEM \ - "-----BEGIN RSA PRIVATE KEY-----\r\n" \ - "MIIEpAIBAAKCAQEAwU2j3efNHdEE10lyuJmsDnjkOjxKzzoTFtBa5M2jAIin7h5r\r\n" \ - "lqdStJDvLXJ6PiSa/LY0rCT1d+AmZIycsCh9odrqjObJHJa8/sEEUrM21KP64bF2\r\n" \ - "2JDBYbRmUjaiJlOqq3ReB30Zgtsq2B+g2Q0cLUlm91slc0boC4pPaQy1AJDh2oIQ\r\n" \ - "Zn2uVCuLZXmRoeJhw81ASQjuaAzxi4bSRr/QuKoRAx5/VqgaHkQYDw+Fi9qLRF7i\r\n" \ - "GMZiL8dmjfpd2H3zJ4kpAcWQDj8n8TDISg7v1t7HxydrxwU9esQCPJodPg/oNJhb\r\n" \ - "y3NLUpbYEaIsgIhpOVrTD7DeWS8Rx/fqEgEwlwIDAQABAoIBAQCXR0S8EIHFGORZ\r\n" \ - "++AtOg6eENxD+xVs0f1IeGz57Tjo3QnXX7VBZNdj+p1ECvhCE/G7XnkgU5hLZX+G\r\n" \ - "Z0jkz/tqJOI0vRSdLBbipHnWouyBQ4e/A1yIJdlBtqXxJ1KE/ituHRbNc4j4kL8Z\r\n" \ - "/r6pvwnTI0PSx2Eqs048YdS92LT6qAv4flbNDxMn2uY7s4ycS4Q8w1JXnCeaAnYm\r\n" \ - "WYI5wxO+bvRELR2Mcz5DmVnL8jRyml6l6582bSv5oufReFIbyPZbQWlXgYnpu6He\r\n" \ - "GTc7E1zKYQGG/9+DQUl/1vQuCPqQwny0tQoX2w5tdYpdMdVm+zkLtbajzdTviJJa\r\n" \ - "TWzL6lt5AoGBAN86+SVeJDcmQJcv4Eq6UhtRr4QGMiQMz0Sod6ettYxYzMgxtw28\r\n" \ - "CIrgpozCc+UaZJLo7UxvC6an85r1b2nKPCLQFaggJ0H4Q0J/sZOhBIXaoBzWxveK\r\n" \ - "nupceKdVxGsFi8CDy86DBfiyFivfBj+47BbaQzPBj7C4rK7UlLjab2rDAoGBAN2u\r\n" \ - "AM2gchoFiu4v1HFL8D7lweEpi6ZnMJjnEu/dEgGQJFjwdpLnPbsj4c75odQ4Gz8g\r\n" \ - "sw9lao9VVzbusoRE/JGI4aTdO0pATXyG7eG1Qu+5Yc1YGXcCrliA2xM9xx+d7f+s\r\n" \ - "mPzN+WIEg5GJDYZDjAzHG5BNvi/FfM1C9dOtjv2dAoGAF0t5KmwbjWHBhcVqO4Ic\r\n" \ - "BVvN3BIlc1ue2YRXEDlxY5b0r8N4XceMgKmW18OHApZxfl8uPDauWZLXOgl4uepv\r\n" \ - "whZC3EuWrSyyICNhLY21Ah7hbIEBPF3L3ZsOwC+UErL+dXWLdB56Jgy3gZaBeW7b\r\n" \ - "vDrEnocJbqCm7IukhXHOBK8CgYEAwqdHB0hqyNSzIOGY7v9abzB6pUdA3BZiQvEs\r\n" \ - "3LjHVd4HPJ2x0N8CgrBIWOE0q8+0hSMmeE96WW/7jD3fPWwCR5zlXknxBQsfv0gP\r\n" \ - "3BC5PR0Qdypz+d+9zfMf625kyit4T/hzwhDveZUzHnk1Cf+IG7Q+TOEnLnWAWBED\r\n" \ - "ISOWmrUCgYAFEmRxgwAc/u+D6t0syCwAYh6POtscq9Y0i9GyWk89NzgC4NdwwbBH\r\n" \ - "4AgahOxIxXx2gxJnq3yfkJfIjwf0s2DyP0kY2y6Ua1OeomPeY9mrIS4tCuDQ6LrE\r\n" \ - "TB6l9VGoxJL4fyHnZb8L5gGvnB1bbD8cL6YPaDiOhcRseC9vBiEuVg==\r\n" \ - "-----END RSA PRIVATE KEY-----\r\n" -/* END FILE */ - -/* This was generated from tests/data_files/server2.key.der using `xxd -i`. */ -/* BEGIN FILE binary macro TEST_SRV_KEY_RSA_DER tests/data_files/server2.key.der */ -#define TEST_SRV_KEY_RSA_DER { \ - 0x30, 0x82, 0x04, 0xa4, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, \ - 0xc1, 0x4d, 0xa3, 0xdd, 0xe7, 0xcd, 0x1d, 0xd1, 0x04, 0xd7, 0x49, 0x72, \ - 0xb8, 0x99, 0xac, 0x0e, 0x78, 0xe4, 0x3a, 0x3c, 0x4a, 0xcf, 0x3a, 0x13, \ - 0x16, 0xd0, 0x5a, 0xe4, 0xcd, 0xa3, 0x00, 0x88, 0xa7, 0xee, 0x1e, 0x6b, \ - 0x96, 0xa7, 0x52, 0xb4, 0x90, 0xef, 0x2d, 0x72, 0x7a, 0x3e, 0x24, 0x9a, \ - 0xfc, 0xb6, 0x34, 0xac, 0x24, 0xf5, 0x77, 0xe0, 0x26, 0x64, 0x8c, 0x9c, \ - 0xb0, 0x28, 0x7d, 0xa1, 0xda, 0xea, 0x8c, 0xe6, 0xc9, 0x1c, 0x96, 0xbc, \ - 0xfe, 0xc1, 0x04, 0x52, 0xb3, 0x36, 0xd4, 0xa3, 0xfa, 0xe1, 0xb1, 0x76, \ - 0xd8, 0x90, 0xc1, 0x61, 0xb4, 0x66, 0x52, 0x36, 0xa2, 0x26, 0x53, 0xaa, \ - 0xab, 0x74, 0x5e, 0x07, 0x7d, 0x19, 0x82, 0xdb, 0x2a, 0xd8, 0x1f, 0xa0, \ - 0xd9, 0x0d, 0x1c, 0x2d, 0x49, 0x66, 0xf7, 0x5b, 0x25, 0x73, 0x46, 0xe8, \ - 0x0b, 0x8a, 0x4f, 0x69, 0x0c, 0xb5, 0x00, 0x90, 0xe1, 0xda, 0x82, 0x10, \ - 0x66, 0x7d, 0xae, 0x54, 0x2b, 0x8b, 0x65, 0x79, 0x91, 0xa1, 0xe2, 0x61, \ - 0xc3, 0xcd, 0x40, 0x49, 0x08, 0xee, 0x68, 0x0c, 0xf1, 0x8b, 0x86, 0xd2, \ - 0x46, 0xbf, 0xd0, 0xb8, 0xaa, 0x11, 0x03, 0x1e, 0x7f, 0x56, 0xa8, 0x1a, \ - 0x1e, 0x44, 0x18, 0x0f, 0x0f, 0x85, 0x8b, 0xda, 0x8b, 0x44, 0x5e, 0xe2, \ - 0x18, 0xc6, 0x62, 0x2f, 0xc7, 0x66, 0x8d, 0xfa, 0x5d, 0xd8, 0x7d, 0xf3, \ - 0x27, 0x89, 0x29, 0x01, 0xc5, 0x90, 0x0e, 0x3f, 0x27, 0xf1, 0x30, 0xc8, \ - 0x4a, 0x0e, 0xef, 0xd6, 0xde, 0xc7, 0xc7, 0x27, 0x6b, 0xc7, 0x05, 0x3d, \ - 0x7a, 0xc4, 0x02, 0x3c, 0x9a, 0x1d, 0x3e, 0x0f, 0xe8, 0x34, 0x98, 0x5b, \ - 0xcb, 0x73, 0x4b, 0x52, 0x96, 0xd8, 0x11, 0xa2, 0x2c, 0x80, 0x88, 0x69, \ - 0x39, 0x5a, 0xd3, 0x0f, 0xb0, 0xde, 0x59, 0x2f, 0x11, 0xc7, 0xf7, 0xea, \ - 0x12, 0x01, 0x30, 0x97, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x82, 0x01, \ - 0x01, 0x00, 0x97, 0x47, 0x44, 0xbc, 0x10, 0x81, 0xc5, 0x18, 0xe4, 0x59, \ - 0xfb, 0xe0, 0x2d, 0x3a, 0x0e, 0x9e, 0x10, 0xdc, 0x43, 0xfb, 0x15, 0x6c, \ - 0xd1, 0xfd, 0x48, 0x78, 0x6c, 0xf9, 0xed, 0x38, 0xe8, 0xdd, 0x09, 0xd7, \ - 0x5f, 0xb5, 0x41, 0x64, 0xd7, 0x63, 0xfa, 0x9d, 0x44, 0x0a, 0xf8, 0x42, \ - 0x13, 0xf1, 0xbb, 0x5e, 0x79, 0x20, 0x53, 0x98, 0x4b, 0x65, 0x7f, 0x86, \ - 0x67, 0x48, 0xe4, 0xcf, 0xfb, 0x6a, 0x24, 0xe2, 0x34, 0xbd, 0x14, 0x9d, \ - 0x2c, 0x16, 0xe2, 0xa4, 0x79, 0xd6, 0xa2, 0xec, 0x81, 0x43, 0x87, 0xbf, \ - 0x03, 0x5c, 0x88, 0x25, 0xd9, 0x41, 0xb6, 0xa5, 0xf1, 0x27, 0x52, 0x84, \ - 0xfe, 0x2b, 0x6e, 0x1d, 0x16, 0xcd, 0x73, 0x88, 0xf8, 0x90, 0xbf, 0x19, \ - 0xfe, 0xbe, 0xa9, 0xbf, 0x09, 0xd3, 0x23, 0x43, 0xd2, 0xc7, 0x61, 0x2a, \ - 0xb3, 0x4e, 0x3c, 0x61, 0xd4, 0xbd, 0xd8, 0xb4, 0xfa, 0xa8, 0x0b, 0xf8, \ - 0x7e, 0x56, 0xcd, 0x0f, 0x13, 0x27, 0xda, 0xe6, 0x3b, 0xb3, 0x8c, 0x9c, \ - 0x4b, 0x84, 0x3c, 0xc3, 0x52, 0x57, 0x9c, 0x27, 0x9a, 0x02, 0x76, 0x26, \ - 0x59, 0x82, 0x39, 0xc3, 0x13, 0xbe, 0x6e, 0xf4, 0x44, 0x2d, 0x1d, 0x8c, \ - 0x73, 0x3e, 0x43, 0x99, 0x59, 0xcb, 0xf2, 0x34, 0x72, 0x9a, 0x5e, 0xa5, \ - 0xeb, 0x9f, 0x36, 0x6d, 0x2b, 0xf9, 0xa2, 0xe7, 0xd1, 0x78, 0x52, 0x1b, \ - 0xc8, 0xf6, 0x5b, 0x41, 0x69, 0x57, 0x81, 0x89, 0xe9, 0xbb, 0xa1, 0xde, \ - 0x19, 0x37, 0x3b, 0x13, 0x5c, 0xca, 0x61, 0x01, 0x86, 0xff, 0xdf, 0x83, \ - 0x41, 0x49, 0x7f, 0xd6, 0xf4, 0x2e, 0x08, 0xfa, 0x90, 0xc2, 0x7c, 0xb4, \ - 0xb5, 0x0a, 0x17, 0xdb, 0x0e, 0x6d, 0x75, 0x8a, 0x5d, 0x31, 0xd5, 0x66, \ - 0xfb, 0x39, 0x0b, 0xb5, 0xb6, 0xa3, 0xcd, 0xd4, 0xef, 0x88, 0x92, 0x5a, \ - 0x4d, 0x6c, 0xcb, 0xea, 0x5b, 0x79, 0x02, 0x81, 0x81, 0x00, 0xdf, 0x3a, \ - 0xf9, 0x25, 0x5e, 0x24, 0x37, 0x26, 0x40, 0x97, 0x2f, 0xe0, 0x4a, 0xba, \ - 0x52, 0x1b, 0x51, 0xaf, 0x84, 0x06, 0x32, 0x24, 0x0c, 0xcf, 0x44, 0xa8, \ - 0x77, 0xa7, 0xad, 0xb5, 0x8c, 0x58, 0xcc, 0xc8, 0x31, 0xb7, 0x0d, 0xbc, \ - 0x08, 0x8a, 0xe0, 0xa6, 0x8c, 0xc2, 0x73, 0xe5, 0x1a, 0x64, 0x92, 0xe8, \ - 0xed, 0x4c, 0x6f, 0x0b, 0xa6, 0xa7, 0xf3, 0x9a, 0xf5, 0x6f, 0x69, 0xca, \ - 0x3c, 0x22, 0xd0, 0x15, 0xa8, 0x20, 0x27, 0x41, 0xf8, 0x43, 0x42, 0x7f, \ - 0xb1, 0x93, 0xa1, 0x04, 0x85, 0xda, 0xa0, 0x1c, 0xd6, 0xc6, 0xf7, 0x8a, \ - 0x9e, 0xea, 0x5c, 0x78, 0xa7, 0x55, 0xc4, 0x6b, 0x05, 0x8b, 0xc0, 0x83, \ - 0xcb, 0xce, 0x83, 0x05, 0xf8, 0xb2, 0x16, 0x2b, 0xdf, 0x06, 0x3f, 0xb8, \ - 0xec, 0x16, 0xda, 0x43, 0x33, 0xc1, 0x8f, 0xb0, 0xb8, 0xac, 0xae, 0xd4, \ - 0x94, 0xb8, 0xda, 0x6f, 0x6a, 0xc3, 0x02, 0x81, 0x81, 0x00, 0xdd, 0xae, \ - 0x00, 0xcd, 0xa0, 0x72, 0x1a, 0x05, 0x8a, 0xee, 0x2f, 0xd4, 0x71, 0x4b, \ - 0xf0, 0x3e, 0xe5, 0xc1, 0xe1, 0x29, 0x8b, 0xa6, 0x67, 0x30, 0x98, 0xe7, \ - 0x12, 0xef, 0xdd, 0x12, 0x01, 0x90, 0x24, 0x58, 0xf0, 0x76, 0x92, 0xe7, \ - 0x3d, 0xbb, 0x23, 0xe1, 0xce, 0xf9, 0xa1, 0xd4, 0x38, 0x1b, 0x3f, 0x20, \ - 0xb3, 0x0f, 0x65, 0x6a, 0x8f, 0x55, 0x57, 0x36, 0xee, 0xb2, 0x84, 0x44, \ - 0xfc, 0x91, 0x88, 0xe1, 0xa4, 0xdd, 0x3b, 0x4a, 0x40, 0x4d, 0x7c, 0x86, \ - 0xed, 0xe1, 0xb5, 0x42, 0xef, 0xb9, 0x61, 0xcd, 0x58, 0x19, 0x77, 0x02, \ - 0xae, 0x58, 0x80, 0xdb, 0x13, 0x3d, 0xc7, 0x1f, 0x9d, 0xed, 0xff, 0xac, \ - 0x98, 0xfc, 0xcd, 0xf9, 0x62, 0x04, 0x83, 0x91, 0x89, 0x0d, 0x86, 0x43, \ - 0x8c, 0x0c, 0xc7, 0x1b, 0x90, 0x4d, 0xbe, 0x2f, 0xc5, 0x7c, 0xcd, 0x42, \ - 0xf5, 0xd3, 0xad, 0x8e, 0xfd, 0x9d, 0x02, 0x81, 0x80, 0x17, 0x4b, 0x79, \ - 0x2a, 0x6c, 0x1b, 0x8d, 0x61, 0xc1, 0x85, 0xc5, 0x6a, 0x3b, 0x82, 0x1c, \ - 0x05, 0x5b, 0xcd, 0xdc, 0x12, 0x25, 0x73, 0x5b, 0x9e, 0xd9, 0x84, 0x57, \ - 0x10, 0x39, 0x71, 0x63, 0x96, 0xf4, 0xaf, 0xc3, 0x78, 0x5d, 0xc7, 0x8c, \ - 0x80, 0xa9, 0x96, 0xd7, 0xc3, 0x87, 0x02, 0x96, 0x71, 0x7e, 0x5f, 0x2e, \ - 0x3c, 0x36, 0xae, 0x59, 0x92, 0xd7, 0x3a, 0x09, 0x78, 0xb9, 0xea, 0x6f, \ - 0xc2, 0x16, 0x42, 0xdc, 0x4b, 0x96, 0xad, 0x2c, 0xb2, 0x20, 0x23, 0x61, \ - 0x2d, 0x8d, 0xb5, 0x02, 0x1e, 0xe1, 0x6c, 0x81, 0x01, 0x3c, 0x5d, 0xcb, \ - 0xdd, 0x9b, 0x0e, 0xc0, 0x2f, 0x94, 0x12, 0xb2, 0xfe, 0x75, 0x75, 0x8b, \ - 0x74, 0x1e, 0x7a, 0x26, 0x0c, 0xb7, 0x81, 0x96, 0x81, 0x79, 0x6e, 0xdb, \ - 0xbc, 0x3a, 0xc4, 0x9e, 0x87, 0x09, 0x6e, 0xa0, 0xa6, 0xec, 0x8b, 0xa4, \ - 0x85, 0x71, 0xce, 0x04, 0xaf, 0x02, 0x81, 0x81, 0x00, 0xc2, 0xa7, 0x47, \ - 0x07, 0x48, 0x6a, 0xc8, 0xd4, 0xb3, 0x20, 0xe1, 0x98, 0xee, 0xff, 0x5a, \ - 0x6f, 0x30, 0x7a, 0xa5, 0x47, 0x40, 0xdc, 0x16, 0x62, 0x42, 0xf1, 0x2c, \ - 0xdc, 0xb8, 0xc7, 0x55, 0xde, 0x07, 0x3c, 0x9d, 0xb1, 0xd0, 0xdf, 0x02, \ - 0x82, 0xb0, 0x48, 0x58, 0xe1, 0x34, 0xab, 0xcf, 0xb4, 0x85, 0x23, 0x26, \ - 0x78, 0x4f, 0x7a, 0x59, 0x6f, 0xfb, 0x8c, 0x3d, 0xdf, 0x3d, 0x6c, 0x02, \ - 0x47, 0x9c, 0xe5, 0x5e, 0x49, 0xf1, 0x05, 0x0b, 0x1f, 0xbf, 0x48, 0x0f, \ - 0xdc, 0x10, 0xb9, 0x3d, 0x1d, 0x10, 0x77, 0x2a, 0x73, 0xf9, 0xdf, 0xbd, \ - 0xcd, 0xf3, 0x1f, 0xeb, 0x6e, 0x64, 0xca, 0x2b, 0x78, 0x4f, 0xf8, 0x73, \ - 0xc2, 0x10, 0xef, 0x79, 0x95, 0x33, 0x1e, 0x79, 0x35, 0x09, 0xff, 0x88, \ - 0x1b, 0xb4, 0x3e, 0x4c, 0xe1, 0x27, 0x2e, 0x75, 0x80, 0x58, 0x11, 0x03, \ - 0x21, 0x23, 0x96, 0x9a, 0xb5, 0x02, 0x81, 0x80, 0x05, 0x12, 0x64, 0x71, \ - 0x83, 0x00, 0x1c, 0xfe, 0xef, 0x83, 0xea, 0xdd, 0x2c, 0xc8, 0x2c, 0x00, \ - 0x62, 0x1e, 0x8f, 0x3a, 0xdb, 0x1c, 0xab, 0xd6, 0x34, 0x8b, 0xd1, 0xb2, \ - 0x5a, 0x4f, 0x3d, 0x37, 0x38, 0x02, 0xe0, 0xd7, 0x70, 0xc1, 0xb0, 0x47, \ - 0xe0, 0x08, 0x1a, 0x84, 0xec, 0x48, 0xc5, 0x7c, 0x76, 0x83, 0x12, 0x67, \ - 0xab, 0x7c, 0x9f, 0x90, 0x97, 0xc8, 0x8f, 0x07, 0xf4, 0xb3, 0x60, 0xf2, \ - 0x3f, 0x49, 0x18, 0xdb, 0x2e, 0x94, 0x6b, 0x53, 0x9e, 0xa2, 0x63, 0xde, \ - 0x63, 0xd9, 0xab, 0x21, 0x2e, 0x2d, 0x0a, 0xe0, 0xd0, 0xe8, 0xba, 0xc4, \ - 0x4c, 0x1e, 0xa5, 0xf5, 0x51, 0xa8, 0xc4, 0x92, 0xf8, 0x7f, 0x21, 0xe7, \ - 0x65, 0xbf, 0x0b, 0xe6, 0x01, 0xaf, 0x9c, 0x1d, 0x5b, 0x6c, 0x3f, 0x1c, \ - 0x2f, 0xa6, 0x0f, 0x68, 0x38, 0x8e, 0x85, 0xc4, 0x6c, 0x78, 0x2f, 0x6f, \ - 0x06, 0x21, 0x2e, 0x56 \ -} -/* END FILE */ - -/* - * Test client Certificates - * - * Test client certificates are defined for each choice - * of the following parameters: - * - PEM or DER encoding - * - RSA or EC key - * - * Things to add: - * - hash type - * - multiple EC curve types - */ - -/* Use CRTs with Secp256r1-only if Secp384r1 is disabled. - * Otherwise, fall back to previous test CRTs using both - * Secp256r1 and Secp384r1. */ -#if !defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) - -/* This is taken from tests/data_files/cli3.crt. */ -/* BEGIN FILE string macro TEST_CLI_CRT_EC_PEM tests/data_files/cli3.crt.pem */ -#define TEST_CLI_CRT_EC_PEM \ - "-----BEGIN CERTIFICATE-----\r\n" \ - "MIIBuTCCAVygAwIBAgIBATAMBggqhkjOPQQDAgUAMDsxGjAYBgNVBAMMEVRlc3Qg\r\n" \ - "Q0EgU2VjcDI1NnIxMRAwDgYDVQQKDAdNYmVkVExTMQswCQYDVQQGEwJVSzAeFw0w\r\n" \ - "MTAxMDEwMDAwMDBaFw0zMDEyMzEyMzU5NTlaMD0xHDAaBgNVBAMME1Rlc3QgQ1JU\r\n" \ - "MiBTZWNwMjU2cjExEDAOBgNVBAoMB01iZWRUTFMxCzAJBgNVBAYTAlVLMFkwEwYH\r\n" \ - "KoZIzj0CAQYIKoZIzj0DAQcDQgAEEm+TJ4LBB85IBjWNcNIodr2L06CZqLbVClmH\r\n" \ - "uxPqiZafsAZDl0lqgL6cCigF/ML2EqFyKW+Oext3uAmNkemj6aNNMEswCQYDVR0T\r\n" \ - "BAIwADAdBgNVHQ4EFgQUF9Yq9UkoSClnXwrdghuhrokH/hIwHwYDVR0jBBgwFoAU\r\n" \ - "Sl6kYTNLFkgMMXgiNdb7zlDnIBIwDAYIKoZIzj0EAwIFAANJADBGAiEAg3UsTyLd\r\n" \ - "vCPRG13gbf1R8gb85g4K1VbZ+CKl58HW2VgCIQDXk/8WFrt7vA+m3L1xJxj8iln9\r\n" \ - "wMR16i9Fqykw7cqsRw==\r\n" \ - "-----END CERTIFICATE-----\r\n" -/* END FILE */ - -/* This is generated from tests/data_files/cli3.crt.der using `xxd -i`. */ -/* BEGIN FILE binary macro TEST_CLI_CRT_EC_DER tests/data_files/cli3.crt.der */ -#define TEST_CLI_CRT_EC_DER { \ - 0x30, 0x82, 0x01, 0xb9, 0x30, 0x82, 0x01, 0x5c, 0xa0, 0x03, 0x02, 0x01, \ - 0x02, 0x02, 0x01, 0x01, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, \ - 0x3d, 0x04, 0x03, 0x02, 0x05, 0x00, 0x30, 0x3b, 0x31, 0x1a, 0x30, 0x18, \ - 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x11, 0x54, 0x65, 0x73, 0x74, 0x20, \ - 0x43, 0x41, 0x20, 0x53, 0x65, 0x63, 0x70, 0x32, 0x35, 0x36, 0x72, 0x31, \ - 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x07, 0x4d, \ - 0x62, 0x65, 0x64, 0x54, 0x4c, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, \ - 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x4b, 0x30, 0x1e, 0x17, 0x0d, 0x30, \ - 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, \ - 0x17, 0x0d, 0x33, 0x30, 0x31, 0x32, 0x33, 0x31, 0x32, 0x33, 0x35, 0x39, \ - 0x35, 0x39, 0x5a, 0x30, 0x3d, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, \ - 0x04, 0x03, 0x0c, 0x13, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x52, 0x54, \ - 0x32, 0x20, 0x53, 0x65, 0x63, 0x70, 0x32, 0x35, 0x36, 0x72, 0x31, 0x31, \ - 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x07, 0x4d, 0x62, \ - 0x65, 0x64, 0x54, 0x4c, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, \ - 0x04, 0x06, 0x13, 0x02, 0x55, 0x4b, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, \ - 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, \ - 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x12, 0x6f, 0x93, \ - 0x27, 0x82, 0xc1, 0x07, 0xce, 0x48, 0x06, 0x35, 0x8d, 0x70, 0xd2, 0x28, \ - 0x76, 0xbd, 0x8b, 0xd3, 0xa0, 0x99, 0xa8, 0xb6, 0xd5, 0x0a, 0x59, 0x87, \ - 0xbb, 0x13, 0xea, 0x89, 0x96, 0x9f, 0xb0, 0x06, 0x43, 0x97, 0x49, 0x6a, \ - 0x80, 0xbe, 0x9c, 0x0a, 0x28, 0x05, 0xfc, 0xc2, 0xf6, 0x12, 0xa1, 0x72, \ - 0x29, 0x6f, 0x8e, 0x7b, 0x1b, 0x77, 0xb8, 0x09, 0x8d, 0x91, 0xe9, 0xa3, \ - 0xe9, 0xa3, 0x4d, 0x30, 0x4b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, \ - 0x04, 0x02, 0x30, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, \ - 0x16, 0x04, 0x14, 0x17, 0xd6, 0x2a, 0xf5, 0x49, 0x28, 0x48, 0x29, 0x67, \ - 0x5f, 0x0a, 0xdd, 0x82, 0x1b, 0xa1, 0xae, 0x89, 0x07, 0xfe, 0x12, 0x30, \ - 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, \ - 0x4a, 0x5e, 0xa4, 0x61, 0x33, 0x4b, 0x16, 0x48, 0x0c, 0x31, 0x78, 0x22, \ - 0x35, 0xd6, 0xfb, 0xce, 0x50, 0xe7, 0x20, 0x12, 0x30, 0x0c, 0x06, 0x08, \ - 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x05, 0x00, 0x03, 0x49, \ - 0x00, 0x30, 0x46, 0x02, 0x21, 0x00, 0x83, 0x75, 0x2c, 0x4f, 0x22, 0xdd, \ - 0xbc, 0x23, 0xd1, 0x1b, 0x5d, 0xe0, 0x6d, 0xfd, 0x51, 0xf2, 0x06, 0xfc, \ - 0xe6, 0x0e, 0x0a, 0xd5, 0x56, 0xd9, 0xf8, 0x22, 0xa5, 0xe7, 0xc1, 0xd6, \ - 0xd9, 0x58, 0x02, 0x21, 0x00, 0xd7, 0x93, 0xff, 0x16, 0x16, 0xbb, 0x7b, \ - 0xbc, 0x0f, 0xa6, 0xdc, 0xbd, 0x71, 0x27, 0x18, 0xfc, 0x8a, 0x59, 0xfd, \ - 0xc0, 0xc4, 0x75, 0xea, 0x2f, 0x45, 0xab, 0x29, 0x30, 0xed, 0xca, 0xac, \ - 0x47 \ -} -/* END FILE */ - -/* This is taken from tests/data_files/cli3.key.pem. */ -/* BEGIN FILE string macro TEST_CLI_KEY_EC_PEM tests/data_files/cli3.key.pem */ -#define TEST_CLI_KEY_EC_PEM \ - "-----BEGIN EC PRIVATE KEY-----\r\n" \ - "MHcCAQEEIGFE8JJMBKeo1BnPGgzGae1stIrWdEaUvjo9xO8OTC5QoAoGCCqGSM49\r\n" \ - "AwEHoUQDQgAEEm+TJ4LBB85IBjWNcNIodr2L06CZqLbVClmHuxPqiZafsAZDl0lq\r\n" \ - "gL6cCigF/ML2EqFyKW+Oext3uAmNkemj6Q==\r\n" \ - "-----END EC PRIVATE KEY-----\r\n" -/* END FILE */ - -/* This is generated from tests/data_files/cli3.key.der using `xxd -i`. */ -/* BEGIN FILE binary macro TEST_CLI_KEY_EC_DER tests/data_files/cli3.key.der */ -#define TEST_CLI_KEY_EC_DER { \ - 0x30, 0x77, 0x02, 0x01, 0x01, 0x04, 0x20, 0x61, 0x44, 0xf0, 0x92, 0x4c, \ - 0x04, 0xa7, 0xa8, 0xd4, 0x19, 0xcf, 0x1a, 0x0c, 0xc6, 0x69, 0xed, 0x6c, \ - 0xb4, 0x8a, 0xd6, 0x74, 0x46, 0x94, 0xbe, 0x3a, 0x3d, 0xc4, 0xef, 0x0e, \ - 0x4c, 0x2e, 0x50, 0xa0, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, \ - 0x03, 0x01, 0x07, 0xa1, 0x44, 0x03, 0x42, 0x00, 0x04, 0x12, 0x6f, 0x93, \ - 0x27, 0x82, 0xc1, 0x07, 0xce, 0x48, 0x06, 0x35, 0x8d, 0x70, 0xd2, 0x28, \ - 0x76, 0xbd, 0x8b, 0xd3, 0xa0, 0x99, 0xa8, 0xb6, 0xd5, 0x0a, 0x59, 0x87, \ - 0xbb, 0x13, 0xea, 0x89, 0x96, 0x9f, 0xb0, 0x06, 0x43, 0x97, 0x49, 0x6a, \ - 0x80, 0xbe, 0x9c, 0x0a, 0x28, 0x05, 0xfc, 0xc2, 0xf6, 0x12, 0xa1, 0x72, \ - 0x29, 0x6f, 0x8e, 0x7b, 0x1b, 0x77, 0xb8, 0x09, 0x8d, 0x91, 0xe9, 0xa3, \ - 0xe9 \ -} -/* END FILE */ - -#else /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */ - -/* This is taken from tests/data_files/cli2.crt. */ -/* BEGIN FILE string macro TEST_CLI_CRT_EC_PEM tests/data_files/cli2.crt */ -#define TEST_CLI_CRT_EC_PEM \ - "-----BEGIN CERTIFICATE-----\r\n" \ - "MIIB3zCCAWOgAwIBAgIBDTAMBggqhkjOPQQDAgUAMD4xCzAJBgNVBAYTAk5MMREw\r\n" \ - "DwYDVQQKDAhQb2xhclNTTDEcMBoGA1UEAwwTUG9sYXJTU0wgVGVzdCBFQyBDQTAe\r\n" \ - "Fw0xOTAyMTAxNDQ0MDBaFw0yOTAyMTAxNDQ0MDBaMEExCzAJBgNVBAYTAk5MMREw\r\n" \ - "DwYDVQQKDAhQb2xhclNTTDEfMB0GA1UEAwwWUG9sYXJTU0wgVGVzdCBDbGllbnQg\r\n" \ - "MjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABFflrrFz39Osu5O4gf8Sru7mU6zO\r\n" \ - "VVP2NA7MLuNjJQvfmOLzXGA2lsDVGBRw5X+f1UtFGOWwbNVc+JaPh3Cj5MejTTBL\r\n" \ - "MAkGA1UdEwQCMAAwHQYDVR0OBBYEFHoAX4Zk/OBd5REQO7LmO8QmP8/iMB8GA1Ud\r\n" \ - "IwQYMBaAFJ1tICRJAT8ry3i1Gbx+JMnb+zZ8MAwGCCqGSM49BAMCBQADaAAwZQIx\r\n" \ - "AMqme4DKMldUlplDET9Q6Eptre7uUWKhsLOF+zPkKDlfzpIkJYEFgcloDHGYw80u\r\n" \ - "IgIwNftyPXsabTqMM7iEHgVpX/GRozKklY9yQI/5eoA6gGW7Y+imuGR/oao5ySOb\r\n" \ - "a9Vk\r\n" \ - "-----END CERTIFICATE-----\r\n" -/* END FILE */ - -/* This is generated from tests/data_files/cli2.crt.der using `xxd -i`. */ -/* BEGIN FILE binary macro TEST_CLI_CRT_EC_DER tests/data_files/cli2.crt.der */ -#define TEST_CLI_CRT_EC_DER { \ - 0x30, 0x82, 0x01, 0xdf, 0x30, 0x82, 0x01, 0x63, 0xa0, 0x03, 0x02, 0x01, \ - 0x02, 0x02, 0x01, 0x0d, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, \ - 0x3d, 0x04, 0x03, 0x02, 0x05, 0x00, 0x30, 0x3e, 0x31, 0x0b, 0x30, 0x09, \ - 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, \ - 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, 0x61, \ - 0x72, 0x53, 0x53, 0x4c, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, \ - 0x03, 0x0c, 0x13, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, 0x20, \ - 0x54, 0x65, 0x73, 0x74, 0x20, 0x45, 0x43, 0x20, 0x43, 0x41, 0x30, 0x1e, \ - 0x17, 0x0d, 0x31, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, 0x34, \ - 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, \ - 0x34, 0x34, 0x34, 0x30, 0x30, 0x5a, 0x30, 0x41, 0x31, 0x0b, 0x30, 0x09, \ - 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, \ - 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, 0x61, \ - 0x72, 0x53, 0x53, 0x4c, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, \ - 0x03, 0x0c, 0x16, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, 0x20, \ - 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, \ - 0x32, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, \ - 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, \ - 0x03, 0x42, 0x00, 0x04, 0x57, 0xe5, 0xae, 0xb1, 0x73, 0xdf, 0xd3, 0xac, \ - 0xbb, 0x93, 0xb8, 0x81, 0xff, 0x12, 0xae, 0xee, 0xe6, 0x53, 0xac, 0xce, \ - 0x55, 0x53, 0xf6, 0x34, 0x0e, 0xcc, 0x2e, 0xe3, 0x63, 0x25, 0x0b, 0xdf, \ - 0x98, 0xe2, 0xf3, 0x5c, 0x60, 0x36, 0x96, 0xc0, 0xd5, 0x18, 0x14, 0x70, \ - 0xe5, 0x7f, 0x9f, 0xd5, 0x4b, 0x45, 0x18, 0xe5, 0xb0, 0x6c, 0xd5, 0x5c, \ - 0xf8, 0x96, 0x8f, 0x87, 0x70, 0xa3, 0xe4, 0xc7, 0xa3, 0x4d, 0x30, 0x4b, \ - 0x30, 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, \ - 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x7a, 0x00, \ - 0x5f, 0x86, 0x64, 0xfc, 0xe0, 0x5d, 0xe5, 0x11, 0x10, 0x3b, 0xb2, 0xe6, \ - 0x3b, 0xc4, 0x26, 0x3f, 0xcf, 0xe2, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, \ - 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x9d, 0x6d, 0x20, 0x24, 0x49, \ - 0x01, 0x3f, 0x2b, 0xcb, 0x78, 0xb5, 0x19, 0xbc, 0x7e, 0x24, 0xc9, 0xdb, \ - 0xfb, 0x36, 0x7c, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, \ - 0x04, 0x03, 0x02, 0x05, 0x00, 0x03, 0x68, 0x00, 0x30, 0x65, 0x02, 0x31, \ - 0x00, 0xca, 0xa6, 0x7b, 0x80, 0xca, 0x32, 0x57, 0x54, 0x96, 0x99, 0x43, \ - 0x11, 0x3f, 0x50, 0xe8, 0x4a, 0x6d, 0xad, 0xee, 0xee, 0x51, 0x62, 0xa1, \ - 0xb0, 0xb3, 0x85, 0xfb, 0x33, 0xe4, 0x28, 0x39, 0x5f, 0xce, 0x92, 0x24, \ - 0x25, 0x81, 0x05, 0x81, 0xc9, 0x68, 0x0c, 0x71, 0x98, 0xc3, 0xcd, 0x2e, \ - 0x22, 0x02, 0x30, 0x35, 0xfb, 0x72, 0x3d, 0x7b, 0x1a, 0x6d, 0x3a, 0x8c, \ - 0x33, 0xb8, 0x84, 0x1e, 0x05, 0x69, 0x5f, 0xf1, 0x91, 0xa3, 0x32, 0xa4, \ - 0x95, 0x8f, 0x72, 0x40, 0x8f, 0xf9, 0x7a, 0x80, 0x3a, 0x80, 0x65, 0xbb, \ - 0x63, 0xe8, 0xa6, 0xb8, 0x64, 0x7f, 0xa1, 0xaa, 0x39, 0xc9, 0x23, 0x9b, \ - 0x6b, 0xd5, 0x64 \ -} -/* END FILE */ - -/* This is taken from tests/data_files/cli2.key. */ -/* BEGIN FILE string macro TEST_CLI_KEY_EC_PEM tests/data_files/cli2.key */ -#define TEST_CLI_KEY_EC_PEM \ - "-----BEGIN EC PRIVATE KEY-----\r\n" \ - "MHcCAQEEIPb3hmTxZ3/mZI3vyk7p3U3wBf+WIop6hDhkFzJhmLcqoAoGCCqGSM49\r\n" \ - "AwEHoUQDQgAEV+WusXPf06y7k7iB/xKu7uZTrM5VU/Y0Dswu42MlC9+Y4vNcYDaW\r\n" \ - "wNUYFHDlf5/VS0UY5bBs1Vz4lo+HcKPkxw==\r\n" \ - "-----END EC PRIVATE KEY-----\r\n" -/* END FILE */ - -/* This is generated from tests/data_files/cli2.key.der using `xxd -i`. */ -/* BEGIN FILE binary macro TEST_CLI_KEY_EC_DER tests/data_files/cli2.key.der */ -#define TEST_CLI_KEY_EC_DER { \ - 0x30, 0x77, 0x02, 0x01, 0x01, 0x04, 0x20, 0xf6, 0xf7, 0x86, 0x64, 0xf1, \ - 0x67, 0x7f, 0xe6, 0x64, 0x8d, 0xef, 0xca, 0x4e, 0xe9, 0xdd, 0x4d, 0xf0, \ - 0x05, 0xff, 0x96, 0x22, 0x8a, 0x7a, 0x84, 0x38, 0x64, 0x17, 0x32, 0x61, \ - 0x98, 0xb7, 0x2a, 0xa0, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, \ - 0x03, 0x01, 0x07, 0xa1, 0x44, 0x03, 0x42, 0x00, 0x04, 0x57, 0xe5, 0xae, \ - 0xb1, 0x73, 0xdf, 0xd3, 0xac, 0xbb, 0x93, 0xb8, 0x81, 0xff, 0x12, 0xae, \ - 0xee, 0xe6, 0x53, 0xac, 0xce, 0x55, 0x53, 0xf6, 0x34, 0x0e, 0xcc, 0x2e, \ - 0xe3, 0x63, 0x25, 0x0b, 0xdf, 0x98, 0xe2, 0xf3, 0x5c, 0x60, 0x36, 0x96, \ - 0xc0, 0xd5, 0x18, 0x14, 0x70, 0xe5, 0x7f, 0x9f, 0xd5, 0x4b, 0x45, 0x18, \ - 0xe5, 0xb0, 0x6c, 0xd5, 0x5c, 0xf8, 0x96, 0x8f, 0x87, 0x70, 0xa3, 0xe4, \ - 0xc7 \ -} -/* END FILE */ - -#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */ - -/* This is taken from tests/data_files/cli-rsa-sha256.crt. */ -/* BEGIN FILE string macro TEST_CLI_CRT_RSA_PEM tests/data_files/cli-rsa-sha256.crt */ -#define TEST_CLI_CRT_RSA_PEM \ - "-----BEGIN CERTIFICATE-----\r\n" \ - "MIIDPzCCAiegAwIBAgIBBDANBgkqhkiG9w0BAQsFADA7MQswCQYDVQQGEwJOTDER\r\n" \ - "MA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n" \ - "MTkwMjEwMTQ0NDA2WhcNMjkwMjEwMTQ0NDA2WjA8MQswCQYDVQQGEwJOTDERMA8G\r\n" \ - "A1UECgwIUG9sYXJTU0wxGjAYBgNVBAMMEVBvbGFyU1NMIENsaWVudCAyMIIBIjAN\r\n" \ - "BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyHTEzLn5tXnpRdkUYLB9u5Pyax6f\r\n" \ - "M60Nj4o8VmXl3ETZzGaFB9X4J7BKNdBjngpuG7fa8H6r7gwQk4ZJGDTzqCrSV/Uu\r\n" \ - "1C93KYRhTYJQj6eVSHD1bk2y1RPD0hrt5kPqQhTrdOrA7R/UV06p86jt0uDBMHEw\r\n" \ - "MjDV0/YI0FZPRo7yX/k9Z5GIMC5Cst99++UMd//sMcB4j7/Cf8qtbCHWjdmLao5v\r\n" \ - "4Jv4EFbMs44TFeY0BGbH7vk2DmqV9gmaBmf0ZXH4yqSxJeD+PIs1BGe64E92hfx/\r\n" \ - "/DZrtenNLQNiTrM9AM+vdqBpVoNq0qjU51Bx5rU2BXcFbXvI5MT9TNUhXwIDAQAB\r\n" \ - "o00wSzAJBgNVHRMEAjAAMB0GA1UdDgQWBBRxoQBzckAvVHZeM/xSj7zx3WtGITAf\r\n" \ - "BgNVHSMEGDAWgBS0WuSls97SUva51aaVD+s+vMf9/zANBgkqhkiG9w0BAQsFAAOC\r\n" \ - "AQEAXidv1d4pLlBiKWED95rMycBdgDcgyNqJxakFkRfRyA2y1mlyTn7uBXRkNLY5\r\n" \ - "ZFzK82GCjk2Q2OD4RZSCPAJJqLpHHU34t71ciffvy2KK81YvrxczRhMAE64i+qna\r\n" \ - "yP3Td2XuWJR05PVPoSemsNELs9gWttdnYy3ce+EY2Y0n7Rsi7982EeLIAA7H6ca4\r\n" \ - "2Es/NUH//JZJT32OP0doMxeDRA+vplkKqTLLWf7dX26LIriBkBaRCgR5Yv9LBPFc\r\n" \ - "NOtpzu/LbrY7QFXKJMI+JXDudCsOn8KCmiA4d6Emisqfh3V3485l7HEQNcvLTxlD\r\n" \ - "6zDQyi0/ykYUYZkwQTK1N2Nvlw==\r\n" \ - "-----END CERTIFICATE-----\r\n" -/* END FILE */ - -/* This was generated from tests/data_files/cli-rsa-sha256.crt.der - using `xxd -i.` */ -/* BEGIN FILE binary macro TEST_CLI_CRT_RSA_DER tests/data_files/cli-rsa-sha256.crt.der */ -#define TEST_CLI_CRT_RSA_DER { \ - 0x30, 0x82, 0x03, 0x3f, 0x30, 0x82, 0x02, 0x27, 0xa0, 0x03, 0x02, 0x01, \ - 0x02, 0x02, 0x01, 0x04, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, \ - 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x3b, 0x31, 0x0b, 0x30, \ - 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, \ - 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, \ - 0x61, 0x72, 0x53, 0x53, 0x4c, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, \ - 0x04, 0x03, 0x0c, 0x10, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, \ - 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, \ - 0x31, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, 0x34, 0x30, 0x36, \ - 0x5a, 0x17, 0x0d, 0x32, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, \ - 0x34, 0x30, 0x36, 0x5a, 0x30, 0x3c, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, \ - 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, 0x0f, 0x06, \ - 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, \ - 0x53, 0x4c, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, \ - 0x11, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, 0x20, 0x43, 0x6c, \ - 0x69, 0x65, 0x6e, 0x74, 0x20, 0x32, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, \ - 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, \ - 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, \ - 0x01, 0x01, 0x00, 0xc8, 0x74, 0xc4, 0xcc, 0xb9, 0xf9, 0xb5, 0x79, 0xe9, \ - 0x45, 0xd9, 0x14, 0x60, 0xb0, 0x7d, 0xbb, 0x93, 0xf2, 0x6b, 0x1e, 0x9f, \ - 0x33, 0xad, 0x0d, 0x8f, 0x8a, 0x3c, 0x56, 0x65, 0xe5, 0xdc, 0x44, 0xd9, \ - 0xcc, 0x66, 0x85, 0x07, 0xd5, 0xf8, 0x27, 0xb0, 0x4a, 0x35, 0xd0, 0x63, \ - 0x9e, 0x0a, 0x6e, 0x1b, 0xb7, 0xda, 0xf0, 0x7e, 0xab, 0xee, 0x0c, 0x10, \ - 0x93, 0x86, 0x49, 0x18, 0x34, 0xf3, 0xa8, 0x2a, 0xd2, 0x57, 0xf5, 0x2e, \ - 0xd4, 0x2f, 0x77, 0x29, 0x84, 0x61, 0x4d, 0x82, 0x50, 0x8f, 0xa7, 0x95, \ - 0x48, 0x70, 0xf5, 0x6e, 0x4d, 0xb2, 0xd5, 0x13, 0xc3, 0xd2, 0x1a, 0xed, \ - 0xe6, 0x43, 0xea, 0x42, 0x14, 0xeb, 0x74, 0xea, 0xc0, 0xed, 0x1f, 0xd4, \ - 0x57, 0x4e, 0xa9, 0xf3, 0xa8, 0xed, 0xd2, 0xe0, 0xc1, 0x30, 0x71, 0x30, \ - 0x32, 0x30, 0xd5, 0xd3, 0xf6, 0x08, 0xd0, 0x56, 0x4f, 0x46, 0x8e, 0xf2, \ - 0x5f, 0xf9, 0x3d, 0x67, 0x91, 0x88, 0x30, 0x2e, 0x42, 0xb2, 0xdf, 0x7d, \ - 0xfb, 0xe5, 0x0c, 0x77, 0xff, 0xec, 0x31, 0xc0, 0x78, 0x8f, 0xbf, 0xc2, \ - 0x7f, 0xca, 0xad, 0x6c, 0x21, 0xd6, 0x8d, 0xd9, 0x8b, 0x6a, 0x8e, 0x6f, \ - 0xe0, 0x9b, 0xf8, 0x10, 0x56, 0xcc, 0xb3, 0x8e, 0x13, 0x15, 0xe6, 0x34, \ - 0x04, 0x66, 0xc7, 0xee, 0xf9, 0x36, 0x0e, 0x6a, 0x95, 0xf6, 0x09, 0x9a, \ - 0x06, 0x67, 0xf4, 0x65, 0x71, 0xf8, 0xca, 0xa4, 0xb1, 0x25, 0xe0, 0xfe, \ - 0x3c, 0x8b, 0x35, 0x04, 0x67, 0xba, 0xe0, 0x4f, 0x76, 0x85, 0xfc, 0x7f, \ - 0xfc, 0x36, 0x6b, 0xb5, 0xe9, 0xcd, 0x2d, 0x03, 0x62, 0x4e, 0xb3, 0x3d, \ - 0x00, 0xcf, 0xaf, 0x76, 0xa0, 0x69, 0x56, 0x83, 0x6a, 0xd2, 0xa8, 0xd4, \ - 0xe7, 0x50, 0x71, 0xe6, 0xb5, 0x36, 0x05, 0x77, 0x05, 0x6d, 0x7b, 0xc8, \ - 0xe4, 0xc4, 0xfd, 0x4c, 0xd5, 0x21, 0x5f, 0x02, 0x03, 0x01, 0x00, 0x01, \ - 0xa3, 0x4d, 0x30, 0x4b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, \ - 0x02, 0x30, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, \ - 0x04, 0x14, 0x71, 0xa1, 0x00, 0x73, 0x72, 0x40, 0x2f, 0x54, 0x76, 0x5e, \ - 0x33, 0xfc, 0x52, 0x8f, 0xbc, 0xf1, 0xdd, 0x6b, 0x46, 0x21, 0x30, 0x1f, \ - 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xb4, \ - 0x5a, 0xe4, 0xa5, 0xb3, 0xde, 0xd2, 0x52, 0xf6, 0xb9, 0xd5, 0xa6, 0x95, \ - 0x0f, 0xeb, 0x3e, 0xbc, 0xc7, 0xfd, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, \ - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, \ - 0x01, 0x01, 0x00, 0x5e, 0x27, 0x6f, 0xd5, 0xde, 0x29, 0x2e, 0x50, 0x62, \ - 0x29, 0x61, 0x03, 0xf7, 0x9a, 0xcc, 0xc9, 0xc0, 0x5d, 0x80, 0x37, 0x20, \ - 0xc8, 0xda, 0x89, 0xc5, 0xa9, 0x05, 0x91, 0x17, 0xd1, 0xc8, 0x0d, 0xb2, \ - 0xd6, 0x69, 0x72, 0x4e, 0x7e, 0xee, 0x05, 0x74, 0x64, 0x34, 0xb6, 0x39, \ - 0x64, 0x5c, 0xca, 0xf3, 0x61, 0x82, 0x8e, 0x4d, 0x90, 0xd8, 0xe0, 0xf8, \ - 0x45, 0x94, 0x82, 0x3c, 0x02, 0x49, 0xa8, 0xba, 0x47, 0x1d, 0x4d, 0xf8, \ - 0xb7, 0xbd, 0x5c, 0x89, 0xf7, 0xef, 0xcb, 0x62, 0x8a, 0xf3, 0x56, 0x2f, \ - 0xaf, 0x17, 0x33, 0x46, 0x13, 0x00, 0x13, 0xae, 0x22, 0xfa, 0xa9, 0xda, \ - 0xc8, 0xfd, 0xd3, 0x77, 0x65, 0xee, 0x58, 0x94, 0x74, 0xe4, 0xf5, 0x4f, \ - 0xa1, 0x27, 0xa6, 0xb0, 0xd1, 0x0b, 0xb3, 0xd8, 0x16, 0xb6, 0xd7, 0x67, \ - 0x63, 0x2d, 0xdc, 0x7b, 0xe1, 0x18, 0xd9, 0x8d, 0x27, 0xed, 0x1b, 0x22, \ - 0xef, 0xdf, 0x36, 0x11, 0xe2, 0xc8, 0x00, 0x0e, 0xc7, 0xe9, 0xc6, 0xb8, \ - 0xd8, 0x4b, 0x3f, 0x35, 0x41, 0xff, 0xfc, 0x96, 0x49, 0x4f, 0x7d, 0x8e, \ - 0x3f, 0x47, 0x68, 0x33, 0x17, 0x83, 0x44, 0x0f, 0xaf, 0xa6, 0x59, 0x0a, \ - 0xa9, 0x32, 0xcb, 0x59, 0xfe, 0xdd, 0x5f, 0x6e, 0x8b, 0x22, 0xb8, 0x81, \ - 0x90, 0x16, 0x91, 0x0a, 0x04, 0x79, 0x62, 0xff, 0x4b, 0x04, 0xf1, 0x5c, \ - 0x34, 0xeb, 0x69, 0xce, 0xef, 0xcb, 0x6e, 0xb6, 0x3b, 0x40, 0x55, 0xca, \ - 0x24, 0xc2, 0x3e, 0x25, 0x70, 0xee, 0x74, 0x2b, 0x0e, 0x9f, 0xc2, 0x82, \ - 0x9a, 0x20, 0x38, 0x77, 0xa1, 0x26, 0x8a, 0xca, 0x9f, 0x87, 0x75, 0x77, \ - 0xe3, 0xce, 0x65, 0xec, 0x71, 0x10, 0x35, 0xcb, 0xcb, 0x4f, 0x19, 0x43, \ - 0xeb, 0x30, 0xd0, 0xca, 0x2d, 0x3f, 0xca, 0x46, 0x14, 0x61, 0x99, 0x30, \ - 0x41, 0x32, 0xb5, 0x37, 0x63, 0x6f, 0x97 \ -} -/* END FILE */ - -/* This is taken from tests/data_files/cli-rsa.key. */ -/* BEGIN FILE string macro TEST_CLI_KEY_RSA_PEM tests/data_files/cli-rsa.key */ -#define TEST_CLI_KEY_RSA_PEM \ - "-----BEGIN RSA PRIVATE KEY-----\r\n" \ - "MIIEpAIBAAKCAQEAyHTEzLn5tXnpRdkUYLB9u5Pyax6fM60Nj4o8VmXl3ETZzGaF\r\n" \ - "B9X4J7BKNdBjngpuG7fa8H6r7gwQk4ZJGDTzqCrSV/Uu1C93KYRhTYJQj6eVSHD1\r\n" \ - "bk2y1RPD0hrt5kPqQhTrdOrA7R/UV06p86jt0uDBMHEwMjDV0/YI0FZPRo7yX/k9\r\n" \ - "Z5GIMC5Cst99++UMd//sMcB4j7/Cf8qtbCHWjdmLao5v4Jv4EFbMs44TFeY0BGbH\r\n" \ - "7vk2DmqV9gmaBmf0ZXH4yqSxJeD+PIs1BGe64E92hfx//DZrtenNLQNiTrM9AM+v\r\n" \ - "dqBpVoNq0qjU51Bx5rU2BXcFbXvI5MT9TNUhXwIDAQABAoIBAGdNtfYDiap6bzst\r\n" \ - "yhCiI8m9TtrhZw4MisaEaN/ll3XSjaOG2dvV6xMZCMV+5TeXDHOAZnY18Yi18vzz\r\n" \ - "4Ut2TnNFzizCECYNaA2fST3WgInnxUkV3YXAyP6CNxJaCmv2aA0yFr2kFVSeaKGt\r\n" \ - "ymvljNp2NVkvm7Th8fBQBO7I7AXhz43k0mR7XmPgewe8ApZOG3hstkOaMvbWAvWA\r\n" \ - "zCZupdDjZYjOJqlA4eEA4H8/w7F83r5CugeBE8LgEREjLPiyejrU5H1fubEY+h0d\r\n" \ - "l5HZBJ68ybTXfQ5U9o/QKA3dd0toBEhhdRUDGzWtjvwkEQfqF1reGWj/tod/gCpf\r\n" \ - "DFi6X0ECgYEA4wOv/pjSC3ty6TuOvKX2rOUiBrLXXv2JSxZnMoMiWI5ipLQt+RYT\r\n" \ - "VPafL/m7Dn6MbwjayOkcZhBwk5CNz5A6Q4lJ64Mq/lqHznRCQQ2Mc1G8eyDF/fYL\r\n" \ - "Ze2pLvwP9VD5jTc2miDfw+MnvJhywRRLcemDFP8k4hQVtm8PMp3ZmNECgYEA4gz7\r\n" \ - "wzObR4gn8ibe617uQPZjWzUj9dUHYd+in1gwBCIrtNnaRn9I9U/Q6tegRYpii4ys\r\n" \ - "c176NmU+umy6XmuSKV5qD9bSpZWG2nLFnslrN15Lm3fhZxoeMNhBaEDTnLT26yoi\r\n" \ - "33gp0mSSWy94ZEqipms+ULF6sY1ZtFW6tpGFoy8CgYAQHhnnvJflIs2ky4q10B60\r\n" \ - "ZcxFp3rtDpkp0JxhFLhiizFrujMtZSjYNm5U7KkgPVHhLELEUvCmOnKTt4ap/vZ0\r\n" \ - "BxJNe1GZH3pW6SAvGDQpl9sG7uu/vTFP+lCxukmzxB0DrrDcvorEkKMom7ZCCRvW\r\n" \ - "KZsZ6YeH2Z81BauRj218kQKBgQCUV/DgKP2985xDTT79N08jUo3hTP5MVYCCuj/+\r\n" \ - "UeEw1TvZcx3LJby7P6Xad6a1/BqveaGyFKIfEFIaBUBItk801sDDpDaYc4gL00Xc\r\n" \ - "7lFuBHOZkxJYlss5QrGpuOEl9ZwUt5IrFLBdYaKqNHzNVC1pCPfb/JyH6Dr2HUxq\r\n" \ - "gxUwAQKBgQCcU6G2L8AG9d9c0UpOyL1tMvFe5Ttw0KjlQVdsh1MP6yigYo9DYuwu\r\n" \ - "bHFVW2r0dBTqegP2/KTOxKzaHfC1qf0RGDsUoJCNJrd1cwoCLG8P2EF4w3OBrKqv\r\n" \ - "8u4ytY0F+Vlanj5lm3TaoHSVF1+NWPyOTiwevIECGKwSxvlki4fDAA==\r\n" \ - "-----END RSA PRIVATE KEY-----\r\n"/* END FILE */ - -/* This was generated from tests/data_files/cli-rsa.key.der using `xxd -i`. */ -/* BEGIN FILE binary macro TEST_CLI_KEY_RSA_DER tests/data_files/cli-rsa.key.der */ -#define TEST_CLI_KEY_RSA_DER { \ - 0x30, 0x82, 0x04, 0xa4, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, \ - 0xc8, 0x74, 0xc4, 0xcc, 0xb9, 0xf9, 0xb5, 0x79, 0xe9, 0x45, 0xd9, 0x14, \ - 0x60, 0xb0, 0x7d, 0xbb, 0x93, 0xf2, 0x6b, 0x1e, 0x9f, 0x33, 0xad, 0x0d, \ - 0x8f, 0x8a, 0x3c, 0x56, 0x65, 0xe5, 0xdc, 0x44, 0xd9, 0xcc, 0x66, 0x85, \ - 0x07, 0xd5, 0xf8, 0x27, 0xb0, 0x4a, 0x35, 0xd0, 0x63, 0x9e, 0x0a, 0x6e, \ - 0x1b, 0xb7, 0xda, 0xf0, 0x7e, 0xab, 0xee, 0x0c, 0x10, 0x93, 0x86, 0x49, \ - 0x18, 0x34, 0xf3, 0xa8, 0x2a, 0xd2, 0x57, 0xf5, 0x2e, 0xd4, 0x2f, 0x77, \ - 0x29, 0x84, 0x61, 0x4d, 0x82, 0x50, 0x8f, 0xa7, 0x95, 0x48, 0x70, 0xf5, \ - 0x6e, 0x4d, 0xb2, 0xd5, 0x13, 0xc3, 0xd2, 0x1a, 0xed, 0xe6, 0x43, 0xea, \ - 0x42, 0x14, 0xeb, 0x74, 0xea, 0xc0, 0xed, 0x1f, 0xd4, 0x57, 0x4e, 0xa9, \ - 0xf3, 0xa8, 0xed, 0xd2, 0xe0, 0xc1, 0x30, 0x71, 0x30, 0x32, 0x30, 0xd5, \ - 0xd3, 0xf6, 0x08, 0xd0, 0x56, 0x4f, 0x46, 0x8e, 0xf2, 0x5f, 0xf9, 0x3d, \ - 0x67, 0x91, 0x88, 0x30, 0x2e, 0x42, 0xb2, 0xdf, 0x7d, 0xfb, 0xe5, 0x0c, \ - 0x77, 0xff, 0xec, 0x31, 0xc0, 0x78, 0x8f, 0xbf, 0xc2, 0x7f, 0xca, 0xad, \ - 0x6c, 0x21, 0xd6, 0x8d, 0xd9, 0x8b, 0x6a, 0x8e, 0x6f, 0xe0, 0x9b, 0xf8, \ - 0x10, 0x56, 0xcc, 0xb3, 0x8e, 0x13, 0x15, 0xe6, 0x34, 0x04, 0x66, 0xc7, \ - 0xee, 0xf9, 0x36, 0x0e, 0x6a, 0x95, 0xf6, 0x09, 0x9a, 0x06, 0x67, 0xf4, \ - 0x65, 0x71, 0xf8, 0xca, 0xa4, 0xb1, 0x25, 0xe0, 0xfe, 0x3c, 0x8b, 0x35, \ - 0x04, 0x67, 0xba, 0xe0, 0x4f, 0x76, 0x85, 0xfc, 0x7f, 0xfc, 0x36, 0x6b, \ - 0xb5, 0xe9, 0xcd, 0x2d, 0x03, 0x62, 0x4e, 0xb3, 0x3d, 0x00, 0xcf, 0xaf, \ - 0x76, 0xa0, 0x69, 0x56, 0x83, 0x6a, 0xd2, 0xa8, 0xd4, 0xe7, 0x50, 0x71, \ - 0xe6, 0xb5, 0x36, 0x05, 0x77, 0x05, 0x6d, 0x7b, 0xc8, 0xe4, 0xc4, 0xfd, \ - 0x4c, 0xd5, 0x21, 0x5f, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x82, 0x01, \ - 0x00, 0x67, 0x4d, 0xb5, 0xf6, 0x03, 0x89, 0xaa, 0x7a, 0x6f, 0x3b, 0x2d, \ - 0xca, 0x10, 0xa2, 0x23, 0xc9, 0xbd, 0x4e, 0xda, 0xe1, 0x67, 0x0e, 0x0c, \ - 0x8a, 0xc6, 0x84, 0x68, 0xdf, 0xe5, 0x97, 0x75, 0xd2, 0x8d, 0xa3, 0x86, \ - 0xd9, 0xdb, 0xd5, 0xeb, 0x13, 0x19, 0x08, 0xc5, 0x7e, 0xe5, 0x37, 0x97, \ - 0x0c, 0x73, 0x80, 0x66, 0x76, 0x35, 0xf1, 0x88, 0xb5, 0xf2, 0xfc, 0xf3, \ - 0xe1, 0x4b, 0x76, 0x4e, 0x73, 0x45, 0xce, 0x2c, 0xc2, 0x10, 0x26, 0x0d, \ - 0x68, 0x0d, 0x9f, 0x49, 0x3d, 0xd6, 0x80, 0x89, 0xe7, 0xc5, 0x49, 0x15, \ - 0xdd, 0x85, 0xc0, 0xc8, 0xfe, 0x82, 0x37, 0x12, 0x5a, 0x0a, 0x6b, 0xf6, \ - 0x68, 0x0d, 0x32, 0x16, 0xbd, 0xa4, 0x15, 0x54, 0x9e, 0x68, 0xa1, 0xad, \ - 0xca, 0x6b, 0xe5, 0x8c, 0xda, 0x76, 0x35, 0x59, 0x2f, 0x9b, 0xb4, 0xe1, \ - 0xf1, 0xf0, 0x50, 0x04, 0xee, 0xc8, 0xec, 0x05, 0xe1, 0xcf, 0x8d, 0xe4, \ - 0xd2, 0x64, 0x7b, 0x5e, 0x63, 0xe0, 0x7b, 0x07, 0xbc, 0x02, 0x96, 0x4e, \ - 0x1b, 0x78, 0x6c, 0xb6, 0x43, 0x9a, 0x32, 0xf6, 0xd6, 0x02, 0xf5, 0x80, \ - 0xcc, 0x26, 0x6e, 0xa5, 0xd0, 0xe3, 0x65, 0x88, 0xce, 0x26, 0xa9, 0x40, \ - 0xe1, 0xe1, 0x00, 0xe0, 0x7f, 0x3f, 0xc3, 0xb1, 0x7c, 0xde, 0xbe, 0x42, \ - 0xba, 0x07, 0x81, 0x13, 0xc2, 0xe0, 0x11, 0x11, 0x23, 0x2c, 0xf8, 0xb2, \ - 0x7a, 0x3a, 0xd4, 0xe4, 0x7d, 0x5f, 0xb9, 0xb1, 0x18, 0xfa, 0x1d, 0x1d, \ - 0x97, 0x91, 0xd9, 0x04, 0x9e, 0xbc, 0xc9, 0xb4, 0xd7, 0x7d, 0x0e, 0x54, \ - 0xf6, 0x8f, 0xd0, 0x28, 0x0d, 0xdd, 0x77, 0x4b, 0x68, 0x04, 0x48, 0x61, \ - 0x75, 0x15, 0x03, 0x1b, 0x35, 0xad, 0x8e, 0xfc, 0x24, 0x11, 0x07, 0xea, \ - 0x17, 0x5a, 0xde, 0x19, 0x68, 0xff, 0xb6, 0x87, 0x7f, 0x80, 0x2a, 0x5f, \ - 0x0c, 0x58, 0xba, 0x5f, 0x41, 0x02, 0x81, 0x81, 0x00, 0xe3, 0x03, 0xaf, \ - 0xfe, 0x98, 0xd2, 0x0b, 0x7b, 0x72, 0xe9, 0x3b, 0x8e, 0xbc, 0xa5, 0xf6, \ - 0xac, 0xe5, 0x22, 0x06, 0xb2, 0xd7, 0x5e, 0xfd, 0x89, 0x4b, 0x16, 0x67, \ - 0x32, 0x83, 0x22, 0x58, 0x8e, 0x62, 0xa4, 0xb4, 0x2d, 0xf9, 0x16, 0x13, \ - 0x54, 0xf6, 0x9f, 0x2f, 0xf9, 0xbb, 0x0e, 0x7e, 0x8c, 0x6f, 0x08, 0xda, \ - 0xc8, 0xe9, 0x1c, 0x66, 0x10, 0x70, 0x93, 0x90, 0x8d, 0xcf, 0x90, 0x3a, \ - 0x43, 0x89, 0x49, 0xeb, 0x83, 0x2a, 0xfe, 0x5a, 0x87, 0xce, 0x74, 0x42, \ - 0x41, 0x0d, 0x8c, 0x73, 0x51, 0xbc, 0x7b, 0x20, 0xc5, 0xfd, 0xf6, 0x0b, \ - 0x65, 0xed, 0xa9, 0x2e, 0xfc, 0x0f, 0xf5, 0x50, 0xf9, 0x8d, 0x37, 0x36, \ - 0x9a, 0x20, 0xdf, 0xc3, 0xe3, 0x27, 0xbc, 0x98, 0x72, 0xc1, 0x14, 0x4b, \ - 0x71, 0xe9, 0x83, 0x14, 0xff, 0x24, 0xe2, 0x14, 0x15, 0xb6, 0x6f, 0x0f, \ - 0x32, 0x9d, 0xd9, 0x98, 0xd1, 0x02, 0x81, 0x81, 0x00, 0xe2, 0x0c, 0xfb, \ - 0xc3, 0x33, 0x9b, 0x47, 0x88, 0x27, 0xf2, 0x26, 0xde, 0xeb, 0x5e, 0xee, \ - 0x40, 0xf6, 0x63, 0x5b, 0x35, 0x23, 0xf5, 0xd5, 0x07, 0x61, 0xdf, 0xa2, \ - 0x9f, 0x58, 0x30, 0x04, 0x22, 0x2b, 0xb4, 0xd9, 0xda, 0x46, 0x7f, 0x48, \ - 0xf5, 0x4f, 0xd0, 0xea, 0xd7, 0xa0, 0x45, 0x8a, 0x62, 0x8b, 0x8c, 0xac, \ - 0x73, 0x5e, 0xfa, 0x36, 0x65, 0x3e, 0xba, 0x6c, 0xba, 0x5e, 0x6b, 0x92, \ - 0x29, 0x5e, 0x6a, 0x0f, 0xd6, 0xd2, 0xa5, 0x95, 0x86, 0xda, 0x72, 0xc5, \ - 0x9e, 0xc9, 0x6b, 0x37, 0x5e, 0x4b, 0x9b, 0x77, 0xe1, 0x67, 0x1a, 0x1e, \ - 0x30, 0xd8, 0x41, 0x68, 0x40, 0xd3, 0x9c, 0xb4, 0xf6, 0xeb, 0x2a, 0x22, \ - 0xdf, 0x78, 0x29, 0xd2, 0x64, 0x92, 0x5b, 0x2f, 0x78, 0x64, 0x4a, 0xa2, \ - 0xa6, 0x6b, 0x3e, 0x50, 0xb1, 0x7a, 0xb1, 0x8d, 0x59, 0xb4, 0x55, 0xba, \ - 0xb6, 0x91, 0x85, 0xa3, 0x2f, 0x02, 0x81, 0x80, 0x10, 0x1e, 0x19, 0xe7, \ - 0xbc, 0x97, 0xe5, 0x22, 0xcd, 0xa4, 0xcb, 0x8a, 0xb5, 0xd0, 0x1e, 0xb4, \ - 0x65, 0xcc, 0x45, 0xa7, 0x7a, 0xed, 0x0e, 0x99, 0x29, 0xd0, 0x9c, 0x61, \ - 0x14, 0xb8, 0x62, 0x8b, 0x31, 0x6b, 0xba, 0x33, 0x2d, 0x65, 0x28, 0xd8, \ - 0x36, 0x6e, 0x54, 0xec, 0xa9, 0x20, 0x3d, 0x51, 0xe1, 0x2c, 0x42, 0xc4, \ - 0x52, 0xf0, 0xa6, 0x3a, 0x72, 0x93, 0xb7, 0x86, 0xa9, 0xfe, 0xf6, 0x74, \ - 0x07, 0x12, 0x4d, 0x7b, 0x51, 0x99, 0x1f, 0x7a, 0x56, 0xe9, 0x20, 0x2f, \ - 0x18, 0x34, 0x29, 0x97, 0xdb, 0x06, 0xee, 0xeb, 0xbf, 0xbd, 0x31, 0x4f, \ - 0xfa, 0x50, 0xb1, 0xba, 0x49, 0xb3, 0xc4, 0x1d, 0x03, 0xae, 0xb0, 0xdc, \ - 0xbe, 0x8a, 0xc4, 0x90, 0xa3, 0x28, 0x9b, 0xb6, 0x42, 0x09, 0x1b, 0xd6, \ - 0x29, 0x9b, 0x19, 0xe9, 0x87, 0x87, 0xd9, 0x9f, 0x35, 0x05, 0xab, 0x91, \ - 0x8f, 0x6d, 0x7c, 0x91, 0x02, 0x81, 0x81, 0x00, 0x94, 0x57, 0xf0, 0xe0, \ - 0x28, 0xfd, 0xbd, 0xf3, 0x9c, 0x43, 0x4d, 0x3e, 0xfd, 0x37, 0x4f, 0x23, \ - 0x52, 0x8d, 0xe1, 0x4c, 0xfe, 0x4c, 0x55, 0x80, 0x82, 0xba, 0x3f, 0xfe, \ - 0x51, 0xe1, 0x30, 0xd5, 0x3b, 0xd9, 0x73, 0x1d, 0xcb, 0x25, 0xbc, 0xbb, \ - 0x3f, 0xa5, 0xda, 0x77, 0xa6, 0xb5, 0xfc, 0x1a, 0xaf, 0x79, 0xa1, 0xb2, \ - 0x14, 0xa2, 0x1f, 0x10, 0x52, 0x1a, 0x05, 0x40, 0x48, 0xb6, 0x4f, 0x34, \ - 0xd6, 0xc0, 0xc3, 0xa4, 0x36, 0x98, 0x73, 0x88, 0x0b, 0xd3, 0x45, 0xdc, \ - 0xee, 0x51, 0x6e, 0x04, 0x73, 0x99, 0x93, 0x12, 0x58, 0x96, 0xcb, 0x39, \ - 0x42, 0xb1, 0xa9, 0xb8, 0xe1, 0x25, 0xf5, 0x9c, 0x14, 0xb7, 0x92, 0x2b, \ - 0x14, 0xb0, 0x5d, 0x61, 0xa2, 0xaa, 0x34, 0x7c, 0xcd, 0x54, 0x2d, 0x69, \ - 0x08, 0xf7, 0xdb, 0xfc, 0x9c, 0x87, 0xe8, 0x3a, 0xf6, 0x1d, 0x4c, 0x6a, \ - 0x83, 0x15, 0x30, 0x01, 0x02, 0x81, 0x81, 0x00, 0x9c, 0x53, 0xa1, 0xb6, \ - 0x2f, 0xc0, 0x06, 0xf5, 0xdf, 0x5c, 0xd1, 0x4a, 0x4e, 0xc8, 0xbd, 0x6d, \ - 0x32, 0xf1, 0x5e, 0xe5, 0x3b, 0x70, 0xd0, 0xa8, 0xe5, 0x41, 0x57, 0x6c, \ - 0x87, 0x53, 0x0f, 0xeb, 0x28, 0xa0, 0x62, 0x8f, 0x43, 0x62, 0xec, 0x2e, \ - 0x6c, 0x71, 0x55, 0x5b, 0x6a, 0xf4, 0x74, 0x14, 0xea, 0x7a, 0x03, 0xf6, \ - 0xfc, 0xa4, 0xce, 0xc4, 0xac, 0xda, 0x1d, 0xf0, 0xb5, 0xa9, 0xfd, 0x11, \ - 0x18, 0x3b, 0x14, 0xa0, 0x90, 0x8d, 0x26, 0xb7, 0x75, 0x73, 0x0a, 0x02, \ - 0x2c, 0x6f, 0x0f, 0xd8, 0x41, 0x78, 0xc3, 0x73, 0x81, 0xac, 0xaa, 0xaf, \ - 0xf2, 0xee, 0x32, 0xb5, 0x8d, 0x05, 0xf9, 0x59, 0x5a, 0x9e, 0x3e, 0x65, \ - 0x9b, 0x74, 0xda, 0xa0, 0x74, 0x95, 0x17, 0x5f, 0x8d, 0x58, 0xfc, 0x8e, \ - 0x4e, 0x2c, 0x1e, 0xbc, 0x81, 0x02, 0x18, 0xac, 0x12, 0xc6, 0xf9, 0x64, \ - 0x8b, 0x87, 0xc3, 0x00 \ -} -/* END FILE */ - -/* - * - * Test certificates and keys as C variables - * - */ - -/* - * CA - */ - -const char mbedtls_test_ca_crt_ec_pem[] = TEST_CA_CRT_EC_PEM; -const char mbedtls_test_ca_key_ec_pem[] = TEST_CA_KEY_EC_PEM; -const char mbedtls_test_ca_pwd_ec_pem[] = TEST_CA_PWD_EC_PEM; -const char mbedtls_test_ca_key_rsa_pem[] = TEST_CA_KEY_RSA_PEM; -const char mbedtls_test_ca_pwd_rsa_pem[] = TEST_CA_PWD_RSA_PEM; -const char mbedtls_test_ca_crt_rsa_sha1_pem[] = TEST_CA_CRT_RSA_SHA1_PEM; -const char mbedtls_test_ca_crt_rsa_sha256_pem[] = TEST_CA_CRT_RSA_SHA256_PEM; - -const unsigned char mbedtls_test_ca_crt_ec_der[] = TEST_CA_CRT_EC_DER; -const unsigned char mbedtls_test_ca_key_ec_der[] = TEST_CA_KEY_EC_DER; -const unsigned char mbedtls_test_ca_key_rsa_der[] = TEST_CA_KEY_RSA_DER; -const unsigned char mbedtls_test_ca_crt_rsa_sha1_der[] = - TEST_CA_CRT_RSA_SHA1_DER; -const unsigned char mbedtls_test_ca_crt_rsa_sha256_der[] = - TEST_CA_CRT_RSA_SHA256_DER; - -const size_t mbedtls_test_ca_crt_ec_pem_len = - sizeof( mbedtls_test_ca_crt_ec_pem ); -const size_t mbedtls_test_ca_key_ec_pem_len = - sizeof( mbedtls_test_ca_key_ec_pem ); -const size_t mbedtls_test_ca_pwd_ec_pem_len = - sizeof( mbedtls_test_ca_pwd_ec_pem ) - 1; -const size_t mbedtls_test_ca_key_rsa_pem_len = - sizeof( mbedtls_test_ca_key_rsa_pem ); -const size_t mbedtls_test_ca_pwd_rsa_pem_len = - sizeof( mbedtls_test_ca_pwd_rsa_pem ) - 1; -const size_t mbedtls_test_ca_crt_rsa_sha1_pem_len = - sizeof( mbedtls_test_ca_crt_rsa_sha1_pem ); -const size_t mbedtls_test_ca_crt_rsa_sha256_pem_len = - sizeof( mbedtls_test_ca_crt_rsa_sha256_pem ); - -const size_t mbedtls_test_ca_crt_ec_der_len = - sizeof( mbedtls_test_ca_crt_ec_der ); -const size_t mbedtls_test_ca_key_ec_der_len = - sizeof( mbedtls_test_ca_key_ec_der ); -const size_t mbedtls_test_ca_pwd_ec_der_len = 0; -const size_t mbedtls_test_ca_key_rsa_der_len = - sizeof( mbedtls_test_ca_key_rsa_der ); -const size_t mbedtls_test_ca_pwd_rsa_der_len = 0; -const size_t mbedtls_test_ca_crt_rsa_sha1_der_len = - sizeof( mbedtls_test_ca_crt_rsa_sha1_der ); -const size_t mbedtls_test_ca_crt_rsa_sha256_der_len = - sizeof( mbedtls_test_ca_crt_rsa_sha256_der ); - -/* - * Server - */ - -const char mbedtls_test_srv_crt_ec_pem[] = TEST_SRV_CRT_EC_PEM; -const char mbedtls_test_srv_key_ec_pem[] = TEST_SRV_KEY_EC_PEM; -const char mbedtls_test_srv_pwd_ec_pem[] = ""; -const char mbedtls_test_srv_key_rsa_pem[] = TEST_SRV_KEY_RSA_PEM; -const char mbedtls_test_srv_pwd_rsa_pem[] = ""; -const char mbedtls_test_srv_crt_rsa_sha1_pem[] = TEST_SRV_CRT_RSA_SHA1_PEM; -const char mbedtls_test_srv_crt_rsa_sha256_pem[] = TEST_SRV_CRT_RSA_SHA256_PEM; - -const unsigned char mbedtls_test_srv_crt_ec_der[] = TEST_SRV_CRT_EC_DER; -const unsigned char mbedtls_test_srv_key_ec_der[] = TEST_SRV_KEY_EC_DER; -const unsigned char mbedtls_test_srv_key_rsa_der[] = TEST_SRV_KEY_RSA_DER; -const unsigned char mbedtls_test_srv_crt_rsa_sha1_der[] = - TEST_SRV_CRT_RSA_SHA1_DER; -const unsigned char mbedtls_test_srv_crt_rsa_sha256_der[] = - TEST_SRV_CRT_RSA_SHA256_DER; - -const size_t mbedtls_test_srv_crt_ec_pem_len = - sizeof( mbedtls_test_srv_crt_ec_pem ); -const size_t mbedtls_test_srv_key_ec_pem_len = - sizeof( mbedtls_test_srv_key_ec_pem ); -const size_t mbedtls_test_srv_pwd_ec_pem_len = - sizeof( mbedtls_test_srv_pwd_ec_pem ) - 1; -const size_t mbedtls_test_srv_key_rsa_pem_len = - sizeof( mbedtls_test_srv_key_rsa_pem ); -const size_t mbedtls_test_srv_pwd_rsa_pem_len = - sizeof( mbedtls_test_srv_pwd_rsa_pem ) - 1; -const size_t mbedtls_test_srv_crt_rsa_sha1_pem_len = - sizeof( mbedtls_test_srv_crt_rsa_sha1_pem ); -const size_t mbedtls_test_srv_crt_rsa_sha256_pem_len = - sizeof( mbedtls_test_srv_crt_rsa_sha256_pem ); - -const size_t mbedtls_test_srv_crt_ec_der_len = - sizeof( mbedtls_test_srv_crt_ec_der ); -const size_t mbedtls_test_srv_key_ec_der_len = - sizeof( mbedtls_test_srv_key_ec_der ); -const size_t mbedtls_test_srv_pwd_ec_der_len = 0; -const size_t mbedtls_test_srv_key_rsa_der_len = - sizeof( mbedtls_test_srv_key_rsa_der ); -const size_t mbedtls_test_srv_pwd_rsa_der_len = 0; -const size_t mbedtls_test_srv_crt_rsa_sha1_der_len = - sizeof( mbedtls_test_srv_crt_rsa_sha1_der ); -const size_t mbedtls_test_srv_crt_rsa_sha256_der_len = - sizeof( mbedtls_test_srv_crt_rsa_sha256_der ); - -/* - * Client - */ - -const char mbedtls_test_cli_crt_ec_pem[] = TEST_CLI_CRT_EC_PEM; -const char mbedtls_test_cli_key_ec_pem[] = TEST_CLI_KEY_EC_PEM; -const char mbedtls_test_cli_pwd_ec_pem[] = ""; -const char mbedtls_test_cli_key_rsa_pem[] = TEST_CLI_KEY_RSA_PEM; -const char mbedtls_test_cli_pwd_rsa_pem[] = ""; -const char mbedtls_test_cli_crt_rsa_pem[] = TEST_CLI_CRT_RSA_PEM; - -const unsigned char mbedtls_test_cli_crt_ec_der[] = TEST_CLI_CRT_EC_DER; -const unsigned char mbedtls_test_cli_key_ec_der[] = TEST_CLI_KEY_EC_DER; -const unsigned char mbedtls_test_cli_key_rsa_der[] = TEST_CLI_KEY_RSA_DER; -const unsigned char mbedtls_test_cli_crt_rsa_der[] = TEST_CLI_CRT_RSA_DER; - -const size_t mbedtls_test_cli_crt_ec_pem_len = - sizeof( mbedtls_test_cli_crt_ec_pem ); -const size_t mbedtls_test_cli_key_ec_pem_len = - sizeof( mbedtls_test_cli_key_ec_pem ); -const size_t mbedtls_test_cli_pwd_ec_pem_len = - sizeof( mbedtls_test_cli_pwd_ec_pem ) - 1; -const size_t mbedtls_test_cli_key_rsa_pem_len = - sizeof( mbedtls_test_cli_key_rsa_pem ); -const size_t mbedtls_test_cli_pwd_rsa_pem_len = - sizeof( mbedtls_test_cli_pwd_rsa_pem ) - 1; -const size_t mbedtls_test_cli_crt_rsa_pem_len = - sizeof( mbedtls_test_cli_crt_rsa_pem ); - -const size_t mbedtls_test_cli_crt_ec_der_len = - sizeof( mbedtls_test_cli_crt_ec_der ); -const size_t mbedtls_test_cli_key_ec_der_len = - sizeof( mbedtls_test_cli_key_ec_der ); -const size_t mbedtls_test_cli_key_rsa_der_len = - sizeof( mbedtls_test_cli_key_rsa_der ); -const size_t mbedtls_test_cli_crt_rsa_der_len = - sizeof( mbedtls_test_cli_crt_rsa_der ); - -/* - * - * Definitions of test CRTs without specification of all parameters, choosing - * them automatically according to the config. For example, mbedtls_test_ca_crt - * is one of mbedtls_test_ca_crt_{rsa|ec}_{sha1|sha256}_{pem|der}. - * - */ - -/* - * Dispatch between PEM and DER according to config - */ - -#if defined(MBEDTLS_PEM_PARSE_C) - -/* PEM encoded test CA certificates and keys */ - -#define TEST_CA_KEY_RSA TEST_CA_KEY_RSA_PEM -#define TEST_CA_PWD_RSA TEST_CA_PWD_RSA_PEM -#define TEST_CA_CRT_RSA_SHA256 TEST_CA_CRT_RSA_SHA256_PEM -#define TEST_CA_CRT_RSA_SHA1 TEST_CA_CRT_RSA_SHA1_PEM -#define TEST_CA_KEY_EC TEST_CA_KEY_EC_PEM -#define TEST_CA_PWD_EC TEST_CA_PWD_EC_PEM -#define TEST_CA_CRT_EC TEST_CA_CRT_EC_PEM - -/* PEM encoded test server certificates and keys */ - -#define TEST_SRV_KEY_RSA TEST_SRV_KEY_RSA_PEM -#define TEST_SRV_PWD_RSA "" -#define TEST_SRV_CRT_RSA_SHA256 TEST_SRV_CRT_RSA_SHA256_PEM -#define TEST_SRV_CRT_RSA_SHA1 TEST_SRV_CRT_RSA_SHA1_PEM -#define TEST_SRV_KEY_EC TEST_SRV_KEY_EC_PEM -#define TEST_SRV_PWD_EC "" -#define TEST_SRV_CRT_EC TEST_SRV_CRT_EC_PEM - -/* PEM encoded test client certificates and keys */ - -#define TEST_CLI_KEY_RSA TEST_CLI_KEY_RSA_PEM -#define TEST_CLI_PWD_RSA "" -#define TEST_CLI_CRT_RSA TEST_CLI_CRT_RSA_PEM -#define TEST_CLI_KEY_EC TEST_CLI_KEY_EC_PEM -#define TEST_CLI_PWD_EC "" -#define TEST_CLI_CRT_EC TEST_CLI_CRT_EC_PEM - -#else /* MBEDTLS_PEM_PARSE_C */ - -/* DER encoded test CA certificates and keys */ - -#define TEST_CA_KEY_RSA TEST_CA_KEY_RSA_DER -#define TEST_CA_PWD_RSA "" -#define TEST_CA_CRT_RSA_SHA256 TEST_CA_CRT_RSA_SHA256_DER -#define TEST_CA_CRT_RSA_SHA1 TEST_CA_CRT_RSA_SHA1_DER -#define TEST_CA_KEY_EC TEST_CA_KEY_EC_DER -#define TEST_CA_PWD_EC "" -#define TEST_CA_CRT_EC TEST_CA_CRT_EC_DER - -/* DER encoded test server certificates and keys */ - -#define TEST_SRV_KEY_RSA TEST_SRV_KEY_RSA_DER -#define TEST_SRV_PWD_RSA "" -#define TEST_SRV_CRT_RSA_SHA256 TEST_SRV_CRT_RSA_SHA256_DER -#define TEST_SRV_CRT_RSA_SHA1 TEST_SRV_CRT_RSA_SHA1_DER -#define TEST_SRV_KEY_EC TEST_SRV_KEY_EC_DER -#define TEST_SRV_PWD_EC "" -#define TEST_SRV_CRT_EC TEST_SRV_CRT_EC_DER - -/* DER encoded test client certificates and keys */ - -#define TEST_CLI_KEY_RSA TEST_CLI_KEY_RSA_DER -#define TEST_CLI_PWD_RSA "" -#define TEST_CLI_CRT_RSA TEST_CLI_CRT_RSA_DER -#define TEST_CLI_KEY_EC TEST_CLI_KEY_EC_DER -#define TEST_CLI_PWD_EC "" -#define TEST_CLI_CRT_EC TEST_CLI_CRT_EC_DER - -#endif /* MBEDTLS_PEM_PARSE_C */ - -const char mbedtls_test_ca_key_rsa[] = TEST_CA_KEY_RSA; -const char mbedtls_test_ca_pwd_rsa[] = TEST_CA_PWD_RSA; -const char mbedtls_test_ca_crt_rsa_sha256[] = TEST_CA_CRT_RSA_SHA256; -const char mbedtls_test_ca_crt_rsa_sha1[] = TEST_CA_CRT_RSA_SHA1; -const char mbedtls_test_ca_key_ec[] = TEST_CA_KEY_EC; -const char mbedtls_test_ca_pwd_ec[] = TEST_CA_PWD_EC; -const char mbedtls_test_ca_crt_ec[] = TEST_CA_CRT_EC; - -const char mbedtls_test_srv_key_rsa[] = TEST_SRV_KEY_RSA; -const char mbedtls_test_srv_pwd_rsa[] = TEST_SRV_PWD_RSA; -const char mbedtls_test_srv_crt_rsa_sha256[] = TEST_SRV_CRT_RSA_SHA256; -const char mbedtls_test_srv_crt_rsa_sha1[] = TEST_SRV_CRT_RSA_SHA1; -const char mbedtls_test_srv_key_ec[] = TEST_SRV_KEY_EC; -const char mbedtls_test_srv_pwd_ec[] = TEST_SRV_PWD_EC; -const char mbedtls_test_srv_crt_ec[] = TEST_SRV_CRT_EC; - -const char mbedtls_test_cli_key_rsa[] = TEST_CLI_KEY_RSA; -const char mbedtls_test_cli_pwd_rsa[] = TEST_CLI_PWD_RSA; -const char mbedtls_test_cli_crt_rsa[] = TEST_CLI_CRT_RSA; -const char mbedtls_test_cli_key_ec[] = TEST_CLI_KEY_EC; -const char mbedtls_test_cli_pwd_ec[] = TEST_CLI_PWD_EC; -const char mbedtls_test_cli_crt_ec[] = TEST_CLI_CRT_EC; - -const size_t mbedtls_test_ca_key_rsa_len = - sizeof( mbedtls_test_ca_key_rsa ); -const size_t mbedtls_test_ca_pwd_rsa_len = - sizeof( mbedtls_test_ca_pwd_rsa ) - 1; -const size_t mbedtls_test_ca_crt_rsa_sha256_len = - sizeof( mbedtls_test_ca_crt_rsa_sha256 ); -const size_t mbedtls_test_ca_crt_rsa_sha1_len = - sizeof( mbedtls_test_ca_crt_rsa_sha1 ); -const size_t mbedtls_test_ca_key_ec_len = - sizeof( mbedtls_test_ca_key_ec ); -const size_t mbedtls_test_ca_pwd_ec_len = - sizeof( mbedtls_test_ca_pwd_ec ) - 1; -const size_t mbedtls_test_ca_crt_ec_len = - sizeof( mbedtls_test_ca_crt_ec ); - -const size_t mbedtls_test_srv_key_rsa_len = - sizeof( mbedtls_test_srv_key_rsa ); -const size_t mbedtls_test_srv_pwd_rsa_len = - sizeof( mbedtls_test_srv_pwd_rsa ) -1; -const size_t mbedtls_test_srv_crt_rsa_sha256_len = - sizeof( mbedtls_test_srv_crt_rsa_sha256 ); -const size_t mbedtls_test_srv_crt_rsa_sha1_len = - sizeof( mbedtls_test_srv_crt_rsa_sha1 ); -const size_t mbedtls_test_srv_key_ec_len = - sizeof( mbedtls_test_srv_key_ec ); -const size_t mbedtls_test_srv_pwd_ec_len = - sizeof( mbedtls_test_srv_pwd_ec ) - 1; -const size_t mbedtls_test_srv_crt_ec_len = - sizeof( mbedtls_test_srv_crt_ec ); - -const size_t mbedtls_test_cli_key_rsa_len = - sizeof( mbedtls_test_cli_key_rsa ); -const size_t mbedtls_test_cli_pwd_rsa_len = - sizeof( mbedtls_test_cli_pwd_rsa ) - 1; -const size_t mbedtls_test_cli_crt_rsa_len = - sizeof( mbedtls_test_cli_crt_rsa ); -const size_t mbedtls_test_cli_key_ec_len = - sizeof( mbedtls_test_cli_key_ec ); -const size_t mbedtls_test_cli_pwd_ec_len = - sizeof( mbedtls_test_cli_pwd_ec ) - 1; -const size_t mbedtls_test_cli_crt_ec_len = - sizeof( mbedtls_test_cli_crt_ec ); - -/* - * Dispatch between SHA-1 and SHA-256 - */ - -#if defined(MBEDTLS_SHA256_C) -#define TEST_CA_CRT_RSA TEST_CA_CRT_RSA_SHA256 -#define TEST_SRV_CRT_RSA TEST_SRV_CRT_RSA_SHA256 -#else -#define TEST_CA_CRT_RSA TEST_CA_CRT_RSA_SHA1 -#define TEST_SRV_CRT_RSA TEST_SRV_CRT_RSA_SHA1 -#endif /* MBEDTLS_SHA256_C */ - -const char mbedtls_test_ca_crt_rsa[] = TEST_CA_CRT_RSA; -const char mbedtls_test_srv_crt_rsa[] = TEST_SRV_CRT_RSA; - -const size_t mbedtls_test_ca_crt_rsa_len = - sizeof( mbedtls_test_ca_crt_rsa ); -const size_t mbedtls_test_srv_crt_rsa_len = - sizeof( mbedtls_test_srv_crt_rsa ); - -/* - * Dispatch between RSA and EC - */ +#if defined(MBEDTLS_ECDSA_C) +#define TEST_CA_CRT_EC \ +"-----BEGIN CERTIFICATE-----\r\n" \ +"MIICUjCCAdegAwIBAgIJAMFD4n5iQ8zoMAoGCCqGSM49BAMCMD4xCzAJBgNVBAYT\r\n" \ +"Ak5MMREwDwYDVQQKEwhQb2xhclNTTDEcMBoGA1UEAxMTUG9sYXJzc2wgVGVzdCBF\r\n" \ +"QyBDQTAeFw0xMzA5MjQxNTQ5NDhaFw0yMzA5MjIxNTQ5NDhaMD4xCzAJBgNVBAYT\r\n" \ +"Ak5MMREwDwYDVQQKEwhQb2xhclNTTDEcMBoGA1UEAxMTUG9sYXJzc2wgVGVzdCBF\r\n" \ +"QyBDQTB2MBAGByqGSM49AgEGBSuBBAAiA2IABMPaKzRBN1gvh1b+/Im6KUNLTuBu\r\n" \ +"ww5XUzM5WNRStJGVOQsj318XJGJI/BqVKc4sLYfCiFKAr9ZqqyHduNMcbli4yuiy\r\n" \ +"aY7zQa0pw7RfdadHb9UZKVVpmlM7ILRmFmAzHqOBoDCBnTAdBgNVHQ4EFgQUnW0g\r\n" \ +"JEkBPyvLeLUZvH4kydv7NnwwbgYDVR0jBGcwZYAUnW0gJEkBPyvLeLUZvH4kydv7\r\n" \ +"NnyhQqRAMD4xCzAJBgNVBAYTAk5MMREwDwYDVQQKEwhQb2xhclNTTDEcMBoGA1UE\r\n" \ +"AxMTUG9sYXJzc2wgVGVzdCBFQyBDQYIJAMFD4n5iQ8zoMAwGA1UdEwQFMAMBAf8w\r\n" \ +"CgYIKoZIzj0EAwIDaQAwZgIxAMO0YnNWKJUAfXgSJtJxexn4ipg+kv4znuR50v56\r\n" \ +"t4d0PCu412mUC6Nnd7izvtE2MgIxAP1nnJQjZ8BWukszFQDG48wxCCyci9qpdSMv\r\n" \ +"uCjn8pwUOkABXK8Mss90fzCfCEOtIA==\r\n" \ +"-----END CERTIFICATE-----\r\n" +const char mbedtls_test_ca_crt_ec[] = TEST_CA_CRT_EC; +const size_t mbedtls_test_ca_crt_ec_len = sizeof( mbedtls_test_ca_crt_ec ); + +const char mbedtls_test_ca_key_ec[] = +"-----BEGIN EC PRIVATE KEY-----\r\n" +"Proc-Type: 4,ENCRYPTED\r\n" +"DEK-Info: DES-EDE3-CBC,307EAB469933D64E\r\n" +"\r\n" +"IxbrRmKcAzctJqPdTQLA4SWyBYYGYJVkYEna+F7Pa5t5Yg/gKADrFKcm6B72e7DG\r\n" +"ihExtZI648s0zdYw6qSJ74vrPSuWDe5qm93BqsfVH9svtCzWHW0pm1p0KTBCFfUq\r\n" +"UsuWTITwJImcnlAs1gaRZ3sAWm7cOUidL0fo2G0fYUFNcYoCSLffCFTEHBuPnagb\r\n" +"a77x/sY1Bvii8S9/XhDTb6pTMx06wzrm\r\n" +"-----END EC PRIVATE KEY-----\r\n"; +const size_t mbedtls_test_ca_key_ec_len = sizeof( mbedtls_test_ca_key_ec ); + +const char mbedtls_test_ca_pwd_ec[] = "PolarSSLTest"; +const size_t mbedtls_test_ca_pwd_ec_len = sizeof( mbedtls_test_ca_pwd_ec ) - 1; + +const char mbedtls_test_srv_crt_ec[] = +"-----BEGIN CERTIFICATE-----\r\n" +"MIICHzCCAaWgAwIBAgIBCTAKBggqhkjOPQQDAjA+MQswCQYDVQQGEwJOTDERMA8G\r\n" +"A1UEChMIUG9sYXJTU0wxHDAaBgNVBAMTE1BvbGFyc3NsIFRlc3QgRUMgQ0EwHhcN\r\n" +"MTMwOTI0MTU1MjA0WhcNMjMwOTIyMTU1MjA0WjA0MQswCQYDVQQGEwJOTDERMA8G\r\n" +"A1UEChMIUG9sYXJTU0wxEjAQBgNVBAMTCWxvY2FsaG9zdDBZMBMGByqGSM49AgEG\r\n" +"CCqGSM49AwEHA0IABDfMVtl2CR5acj7HWS3/IG7ufPkGkXTQrRS192giWWKSTuUA\r\n" +"2CMR/+ov0jRdXRa9iojCa3cNVc2KKg76Aci07f+jgZ0wgZowCQYDVR0TBAIwADAd\r\n" +"BgNVHQ4EFgQUUGGlj9QH2deCAQzlZX+MY0anE74wbgYDVR0jBGcwZYAUnW0gJEkB\r\n" +"PyvLeLUZvH4kydv7NnyhQqRAMD4xCzAJBgNVBAYTAk5MMREwDwYDVQQKEwhQb2xh\r\n" +"clNTTDEcMBoGA1UEAxMTUG9sYXJzc2wgVGVzdCBFQyBDQYIJAMFD4n5iQ8zoMAoG\r\n" +"CCqGSM49BAMCA2gAMGUCMQCaLFzXptui5WQN8LlO3ddh1hMxx6tzgLvT03MTVK2S\r\n" +"C12r0Lz3ri/moSEpNZWqPjkCMCE2f53GXcYLqyfyJR078c/xNSUU5+Xxl7VZ414V\r\n" +"fGa5kHvHARBPc8YAIVIqDvHH1Q==\r\n" +"-----END CERTIFICATE-----\r\n"; +const size_t mbedtls_test_srv_crt_ec_len = sizeof( mbedtls_test_srv_crt_ec ); + +const char mbedtls_test_srv_key_ec[] = +"-----BEGIN EC PRIVATE KEY-----\r\n" +"MHcCAQEEIPEqEyB2AnCoPL/9U/YDHvdqXYbIogTywwyp6/UfDw6noAoGCCqGSM49\r\n" +"AwEHoUQDQgAEN8xW2XYJHlpyPsdZLf8gbu58+QaRdNCtFLX3aCJZYpJO5QDYIxH/\r\n" +"6i/SNF1dFr2KiMJrdw1VzYoqDvoByLTt/w==\r\n" +"-----END EC PRIVATE KEY-----\r\n"; +const size_t mbedtls_test_srv_key_ec_len = sizeof( mbedtls_test_srv_key_ec ); + +const char mbedtls_test_cli_crt_ec[] = +"-----BEGIN CERTIFICATE-----\r\n" +"MIICLDCCAbKgAwIBAgIBDTAKBggqhkjOPQQDAjA+MQswCQYDVQQGEwJOTDERMA8G\r\n" +"A1UEChMIUG9sYXJTU0wxHDAaBgNVBAMTE1BvbGFyc3NsIFRlc3QgRUMgQ0EwHhcN\r\n" +"MTMwOTI0MTU1MjA0WhcNMjMwOTIyMTU1MjA0WjBBMQswCQYDVQQGEwJOTDERMA8G\r\n" +"A1UEChMIUG9sYXJTU0wxHzAdBgNVBAMTFlBvbGFyU1NMIFRlc3QgQ2xpZW50IDIw\r\n" +"WTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARX5a6xc9/TrLuTuIH/Eq7u5lOszlVT\r\n" +"9jQOzC7jYyUL35ji81xgNpbA1RgUcOV/n9VLRRjlsGzVXPiWj4dwo+THo4GdMIGa\r\n" +"MAkGA1UdEwQCMAAwHQYDVR0OBBYEFHoAX4Zk/OBd5REQO7LmO8QmP8/iMG4GA1Ud\r\n" +"IwRnMGWAFJ1tICRJAT8ry3i1Gbx+JMnb+zZ8oUKkQDA+MQswCQYDVQQGEwJOTDER\r\n" +"MA8GA1UEChMIUG9sYXJTU0wxHDAaBgNVBAMTE1BvbGFyc3NsIFRlc3QgRUMgQ0GC\r\n" +"CQDBQ+J+YkPM6DAKBggqhkjOPQQDAgNoADBlAjBKZQ17IIOimbmoD/yN7o89u3BM\r\n" +"lgOsjnhw3fIOoLIWy2WOGsk/LGF++DzvrRzuNiACMQCd8iem1XS4JK7haj8xocpU\r\n" +"LwjQje5PDGHfd3h9tP38Qknu5bJqws0md2KOKHyeV0U=\r\n" +"-----END CERTIFICATE-----\r\n"; +const size_t mbedtls_test_cli_crt_ec_len = sizeof( mbedtls_test_cli_crt_ec ); + +const char mbedtls_test_cli_key_ec[] = +"-----BEGIN EC PRIVATE KEY-----\r\n" +"MHcCAQEEIPb3hmTxZ3/mZI3vyk7p3U3wBf+WIop6hDhkFzJhmLcqoAoGCCqGSM49\r\n" +"AwEHoUQDQgAEV+WusXPf06y7k7iB/xKu7uZTrM5VU/Y0Dswu42MlC9+Y4vNcYDaW\r\n" +"wNUYFHDlf5/VS0UY5bBs1Vz4lo+HcKPkxw==\r\n" +"-----END EC PRIVATE KEY-----\r\n"; +const size_t mbedtls_test_cli_key_ec_len = sizeof( mbedtls_test_cli_key_ec ); +#endif /* MBEDTLS_ECDSA_C */ #if defined(MBEDTLS_RSA_C) -#define TEST_CA_KEY TEST_CA_KEY_RSA -#define TEST_CA_PWD TEST_CA_PWD_RSA -#define TEST_CA_CRT TEST_CA_CRT_RSA +#if defined(MBEDTLS_SHA256_C) +#define TEST_CA_CRT_RSA_SHA256 \ +"-----BEGIN CERTIFICATE-----\r\n" \ +"MIIDhzCCAm+gAwIBAgIBADANBgkqhkiG9w0BAQsFADA7MQswCQYDVQQGEwJOTDER\r\n" \ +"MA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n" \ +"MTcwNTA0MTY1NzAxWhcNMjcwNTA1MTY1NzAxWjA7MQswCQYDVQQGEwJOTDERMA8G\r\n" \ +"A1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwggEiMA0G\r\n" \ +"CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDA3zf8F7vglp0/ht6WMn1EpRagzSHx\r\n" \ +"mdTs6st8GFgIlKXsm8WL3xoemTiZhx57wI053zhdcHgH057Zk+i5clHFzqMwUqny\r\n" \ +"50BwFMtEonILwuVA+T7lpg6z+exKY8C4KQB0nFc7qKUEkHHxvYPZP9al4jwqj+8n\r\n" \ +"YMPGn8u67GB9t+aEMr5P+1gmIgNb1LTV+/Xjli5wwOQuvfwu7uJBVcA0Ln0kcmnL\r\n" \ +"R7EUQIN9Z/SG9jGr8XmksrUuEvmEF/Bibyc+E1ixVA0hmnM3oTDPb5Lc9un8rNsu\r\n" \ +"KNF+AksjoBXyOGVkCeoMbo4bF6BxyLObyavpw/LPh5aPgAIynplYb6LVAgMBAAGj\r\n" \ +"gZUwgZIwHQYDVR0OBBYEFLRa5KWz3tJS9rnVppUP6z68x/3/MGMGA1UdIwRcMFqA\r\n" \ +"FLRa5KWz3tJS9rnVppUP6z68x/3/oT+kPTA7MQswCQYDVQQGEwJOTDERMA8GA1UE\r\n" \ +"CgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0GCAQAwDAYDVR0T\r\n" \ +"BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAHK/HHrTZMnnVMpde1io+voAtql7j\r\n" \ +"4sRhLrjD7o3THtwRbDa2diCvpq0Sq23Ng2LMYoXsOxoL/RQK3iN7UKxV3MKPEr0w\r\n" \ +"XQS+kKQqiT2bsfrjnWMVHZtUOMpm6FNqcdGm/Rss3vKda2lcKl8kUnq/ylc1+QbB\r\n" \ +"G6A6tUvQcr2ZyWfVg+mM5XkhTrOOXus2OLikb4WwEtJTJRNE0f+yPODSUz0/vT57\r\n" \ +"ApH0CnB80bYJshYHPHHymOtleAB8KSYtqm75g/YNobjnjB6cm4HkW3OZRVIl6fYY\r\n" \ +"n20NRVA1Vjs6GAROr4NqW4k/+LofY9y0LLDE+p0oIEKXIsIvhPr39swxSA==\r\n" \ +"-----END CERTIFICATE-----\r\n" -#define TEST_SRV_KEY TEST_SRV_KEY_RSA -#define TEST_SRV_PWD TEST_SRV_PWD_RSA -#define TEST_SRV_CRT TEST_SRV_CRT_RSA +const char mbedtls_test_ca_crt_rsa[] = TEST_CA_CRT_RSA_SHA256; +const size_t mbedtls_test_ca_crt_rsa_len = sizeof( mbedtls_test_ca_crt_rsa ); +#define TEST_CA_CRT_RSA_SOME -#define TEST_CLI_KEY TEST_CLI_KEY_RSA -#define TEST_CLI_PWD TEST_CLI_PWD_RSA -#define TEST_CLI_CRT TEST_CLI_CRT_RSA +static const char mbedtls_test_ca_crt_rsa_sha256[] = TEST_CA_CRT_RSA_SHA256; -#else /* no RSA, so assume ECDSA */ +#endif -#define TEST_CA_KEY TEST_CA_KEY_EC -#define TEST_CA_PWD TEST_CA_PWD_EC -#define TEST_CA_CRT TEST_CA_CRT_EC +#if !defined(TEST_CA_CRT_RSA_SOME) || defined(MBEDTLS_SHA1_C) +#define TEST_CA_CRT_RSA_SHA1 \ +"-----BEGIN CERTIFICATE-----\r\n" \ +"MIIDhzCCAm+gAwIBAgIBADANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER\r\n" \ +"MA8GA1UEChMIUG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n" \ +"MTEwMjEyMTQ0NDAwWhcNMjEwMjEyMTQ0NDAwWjA7MQswCQYDVQQGEwJOTDERMA8G\r\n" \ +"A1UEChMIUG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EwggEiMA0G\r\n" \ +"CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDA3zf8F7vglp0/ht6WMn1EpRagzSHx\r\n" \ +"mdTs6st8GFgIlKXsm8WL3xoemTiZhx57wI053zhdcHgH057Zk+i5clHFzqMwUqny\r\n" \ +"50BwFMtEonILwuVA+T7lpg6z+exKY8C4KQB0nFc7qKUEkHHxvYPZP9al4jwqj+8n\r\n" \ +"YMPGn8u67GB9t+aEMr5P+1gmIgNb1LTV+/Xjli5wwOQuvfwu7uJBVcA0Ln0kcmnL\r\n" \ +"R7EUQIN9Z/SG9jGr8XmksrUuEvmEF/Bibyc+E1ixVA0hmnM3oTDPb5Lc9un8rNsu\r\n" \ +"KNF+AksjoBXyOGVkCeoMbo4bF6BxyLObyavpw/LPh5aPgAIynplYb6LVAgMBAAGj\r\n" \ +"gZUwgZIwDAYDVR0TBAUwAwEB/zAdBgNVHQ4EFgQUtFrkpbPe0lL2udWmlQ/rPrzH\r\n" \ +"/f8wYwYDVR0jBFwwWoAUtFrkpbPe0lL2udWmlQ/rPrzH/f+hP6Q9MDsxCzAJBgNV\r\n" \ +"BAYTAk5MMREwDwYDVQQKEwhQb2xhclNTTDEZMBcGA1UEAxMQUG9sYXJTU0wgVGVz\r\n" \ +"dCBDQYIBADANBgkqhkiG9w0BAQUFAAOCAQEAuP1U2ABUkIslsCfdlc2i94QHHYeJ\r\n" \ +"SsR4EdgHtdciUI5I62J6Mom+Y0dT/7a+8S6MVMCZP6C5NyNyXw1GWY/YR82XTJ8H\r\n" \ +"DBJiCTok5DbZ6SzaONBzdWHXwWwmi5vg1dxn7YxrM9d0IjxM27WNKs4sDQhZBQkF\r\n" \ +"pjmfs2cb4oPl4Y9T9meTx/lvdkRYEug61Jfn6cA+qHpyPYdTH+UshITnmp5/Ztkf\r\n" \ +"m/UTSLBNFNHesiTZeH31NcxYGdHSme9Nc/gfidRa0FLOCfWxRlFqAI47zG9jAQCZ\r\n" \ +"7Z2mCGDNMhjQc+BYcdnl0lPXjdDK6V0qCg1dVewhUBcW5gZKzV7e9+DpVA==\r\n" \ +"-----END CERTIFICATE-----\r\n" -#define TEST_SRV_KEY TEST_SRV_KEY_EC -#define TEST_SRV_PWD TEST_SRV_PWD_EC -#define TEST_SRV_CRT TEST_SRV_CRT_EC +#if !defined (TEST_CA_CRT_RSA_SOME) +const char mbedtls_test_ca_crt_rsa[] = TEST_CA_CRT_RSA_SHA1; +const size_t mbedtls_test_ca_crt_rsa_len = sizeof( mbedtls_test_ca_crt_rsa ); +#endif -#define TEST_CLI_KEY TEST_CLI_KEY_EC -#define TEST_CLI_PWD TEST_CLI_PWD_EC -#define TEST_CLI_CRT TEST_CLI_CRT_EC +static const char mbedtls_test_ca_crt_rsa_sha1[] = TEST_CA_CRT_RSA_SHA1; +#endif + +const char mbedtls_test_ca_key_rsa[] = +"-----BEGIN RSA PRIVATE KEY-----\r\n" +"Proc-Type: 4,ENCRYPTED\r\n" +"DEK-Info: DES-EDE3-CBC,A8A95B05D5B7206B\r\n" +"\r\n" +"9Qd9GeArejl1GDVh2lLV1bHt0cPtfbh5h/5zVpAVaFpqtSPMrElp50Rntn9et+JA\r\n" +"7VOyboR+Iy2t/HU4WvA687k3Bppe9GwKHjHhtl//8xFKwZr3Xb5yO5JUP8AUctQq\r\n" +"Nb8CLlZyuUC+52REAAthdWgsX+7dJO4yabzUcQ22Tp9JSD0hiL43BlkWYUNK3dAo\r\n" +"PZlmiptjnzVTjg1MxsBSydZinWOLBV8/JQgxSPo2yD4uEfig28qbvQ2wNIn0pnAb\r\n" +"GxnSAOazkongEGfvcjIIs+LZN9gXFhxcOh6kc4Q/c99B7QWETwLLkYgZ+z1a9VY9\r\n" +"gEU7CwCxYCD+h9hY6FPmsK0/lC4O7aeRKpYq00rPPxs6i7phiexg6ax6yTMmArQq\r\n" +"QmK3TAsJm8V/J5AWpLEV6jAFgRGymGGHnof0DXzVWZidrcZJWTNuGEX90nB3ee2w\r\n" +"PXJEFWKoD3K3aFcSLdHYr3mLGxP7H9ThQai9VsycxZKS5kwvBKQ//YMrmFfwPk8x\r\n" +"vTeY4KZMaUrveEel5tWZC94RSMKgxR6cyE1nBXyTQnDOGbfpNNgBKxyKbINWoOJU\r\n" +"WJZAwlsQn+QzCDwpri7+sV1mS3gBE6UY7aQmnmiiaC2V3Hbphxct/en5QsfDOt1X\r\n" +"JczSfpRWLlbPznZg8OQh/VgCMA58N5DjOzTIK7sJJ5r+94ZBTCpgAMbF588f0NTR\r\n" +"KCe4yrxGJR7X02M4nvD4IwOlpsQ8xQxZtOSgXv4LkxvdU9XJJKWZ/XNKJeWztxSe\r\n" +"Z1vdTc2YfsDBA2SEv33vxHx2g1vqtw8SjDRT2RaQSS0QuSaMJimdOX6mTOCBKk1J\r\n" +"9Q5mXTrER+/LnK0jEmXsBXWA5bqqVZIyahXSx4VYZ7l7w/PHiUDtDgyRhMMKi4n2\r\n" +"iQvQcWSQTjrpnlJbca1/DkpRt3YwrvJwdqb8asZU2VrNETh5x0QVefDRLFiVpif/\r\n" +"tUaeAe/P1F8OkS7OIZDs1SUbv/sD2vMbhNkUoCms3/PvNtdnvgL4F0zhaDpKCmlT\r\n" +"P8vx49E7v5CyRNmED9zZg4o3wmMqrQO93PtTug3Eu9oVx1zPQM1NVMyBa2+f29DL\r\n" +"1nuTCeXdo9+ni45xx+jAI4DCwrRdhJ9uzZyC6962H37H6D+5naNvClFR1s6li1Gb\r\n" +"nqPoiy/OBsEx9CaDGcqQBp5Wme/3XW+6z1ISOx+igwNTVCT14mHdBMbya0eIKft5\r\n" +"X+GnwtgEMyCYyyWuUct8g4RzErcY9+yW9Om5Hzpx4zOuW4NPZgPDTgK+t2RSL/Yq\r\n" +"rE1njrgeGYcVeG3f+OftH4s6fPbq7t1A5ZgUscbLMBqr9tK+OqygR4EgKBPsH6Cz\r\n" +"L6zlv/2RV0qAHvVuDJcIDIgwY5rJtINEm32rhOeFNJwZS5MNIC1czXZx5//ugX7l\r\n" +"I4sy5nbVhwSjtAk8Xg5dZbdTZ6mIrb7xqH+fdakZor1khG7bC2uIwibD3cSl2XkR\r\n" +"wN48lslbHnqqagr6Xm1nNOSVl8C/6kbJEsMpLhAezfRtGwvOucoaE+WbeUNolGde\r\n" +"P/eQiddSf0brnpiLJRh7qZrl9XuqYdpUqnoEdMAfotDOID8OtV7gt8a48ad8VPW2\r\n" +"-----END RSA PRIVATE KEY-----\r\n"; +const size_t mbedtls_test_ca_key_rsa_len = sizeof( mbedtls_test_ca_key_rsa ); + +const char mbedtls_test_ca_pwd_rsa[] = "PolarSSLTest"; +const size_t mbedtls_test_ca_pwd_rsa_len = sizeof( mbedtls_test_ca_pwd_rsa ) - 1; + +const char mbedtls_test_srv_crt_rsa[] = +"-----BEGIN CERTIFICATE-----\r\n" +"MIIDNzCCAh+gAwIBAgIBAjANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER\r\n" +"MA8GA1UEChMIUG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n" +"MTEwMjEyMTQ0NDA2WhcNMjEwMjEyMTQ0NDA2WjA0MQswCQYDVQQGEwJOTDERMA8G\r\n" +"A1UEChMIUG9sYXJTU0wxEjAQBgNVBAMTCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcN\r\n" +"AQEBBQADggEPADCCAQoCggEBAMFNo93nzR3RBNdJcriZrA545Do8Ss86ExbQWuTN\r\n" +"owCIp+4ea5anUrSQ7y1yej4kmvy2NKwk9XfgJmSMnLAofaHa6ozmyRyWvP7BBFKz\r\n" +"NtSj+uGxdtiQwWG0ZlI2oiZTqqt0Xgd9GYLbKtgfoNkNHC1JZvdbJXNG6AuKT2kM\r\n" +"tQCQ4dqCEGZ9rlQri2V5kaHiYcPNQEkI7mgM8YuG0ka/0LiqEQMef1aoGh5EGA8P\r\n" +"hYvai0Re4hjGYi/HZo36Xdh98yeJKQHFkA4/J/EwyEoO79bex8cna8cFPXrEAjya\r\n" +"HT4P6DSYW8tzS1KW2BGiLICIaTla0w+w3lkvEcf36hIBMJcCAwEAAaNNMEswCQYD\r\n" +"VR0TBAIwADAdBgNVHQ4EFgQUpQXoZLjc32APUBJNYKhkr02LQ5MwHwYDVR0jBBgw\r\n" +"FoAUtFrkpbPe0lL2udWmlQ/rPrzH/f8wDQYJKoZIhvcNAQEFBQADggEBAJxnXClY\r\n" +"oHkbp70cqBrsGXLybA74czbO5RdLEgFs7rHVS9r+c293luS/KdliLScZqAzYVylw\r\n" +"UfRWvKMoWhHYKp3dEIS4xTXk6/5zXxhv9Rw8SGc8qn6vITHk1S1mPevtekgasY5Y\r\n" +"iWQuM3h4YVlRH3HHEMAD1TnAexfXHHDFQGe+Bd1iAbz1/sH9H8l4StwX6egvTK3M\r\n" +"wXRwkKkvjKaEDA9ATbZx0mI8LGsxSuCqe9r9dyjmttd47J1p1Rulz3CLzaRcVIuS\r\n" +"RRQfaD8neM9c1S/iJ/amTVqJxA1KOdOS5780WhPfSArA+g4qAmSjelc3p4wWpha8\r\n" +"zhuYwjVuX6JHG0c=\r\n" +"-----END CERTIFICATE-----\r\n"; +const size_t mbedtls_test_srv_crt_rsa_len = sizeof( mbedtls_test_srv_crt_rsa ); + +const char mbedtls_test_srv_key_rsa[] = +"-----BEGIN RSA PRIVATE KEY-----\r\n" +"MIIEpAIBAAKCAQEAwU2j3efNHdEE10lyuJmsDnjkOjxKzzoTFtBa5M2jAIin7h5r\r\n" +"lqdStJDvLXJ6PiSa/LY0rCT1d+AmZIycsCh9odrqjObJHJa8/sEEUrM21KP64bF2\r\n" +"2JDBYbRmUjaiJlOqq3ReB30Zgtsq2B+g2Q0cLUlm91slc0boC4pPaQy1AJDh2oIQ\r\n" +"Zn2uVCuLZXmRoeJhw81ASQjuaAzxi4bSRr/QuKoRAx5/VqgaHkQYDw+Fi9qLRF7i\r\n" +"GMZiL8dmjfpd2H3zJ4kpAcWQDj8n8TDISg7v1t7HxydrxwU9esQCPJodPg/oNJhb\r\n" +"y3NLUpbYEaIsgIhpOVrTD7DeWS8Rx/fqEgEwlwIDAQABAoIBAQCXR0S8EIHFGORZ\r\n" +"++AtOg6eENxD+xVs0f1IeGz57Tjo3QnXX7VBZNdj+p1ECvhCE/G7XnkgU5hLZX+G\r\n" +"Z0jkz/tqJOI0vRSdLBbipHnWouyBQ4e/A1yIJdlBtqXxJ1KE/ituHRbNc4j4kL8Z\r\n" +"/r6pvwnTI0PSx2Eqs048YdS92LT6qAv4flbNDxMn2uY7s4ycS4Q8w1JXnCeaAnYm\r\n" +"WYI5wxO+bvRELR2Mcz5DmVnL8jRyml6l6582bSv5oufReFIbyPZbQWlXgYnpu6He\r\n" +"GTc7E1zKYQGG/9+DQUl/1vQuCPqQwny0tQoX2w5tdYpdMdVm+zkLtbajzdTviJJa\r\n" +"TWzL6lt5AoGBAN86+SVeJDcmQJcv4Eq6UhtRr4QGMiQMz0Sod6ettYxYzMgxtw28\r\n" +"CIrgpozCc+UaZJLo7UxvC6an85r1b2nKPCLQFaggJ0H4Q0J/sZOhBIXaoBzWxveK\r\n" +"nupceKdVxGsFi8CDy86DBfiyFivfBj+47BbaQzPBj7C4rK7UlLjab2rDAoGBAN2u\r\n" +"AM2gchoFiu4v1HFL8D7lweEpi6ZnMJjnEu/dEgGQJFjwdpLnPbsj4c75odQ4Gz8g\r\n" +"sw9lao9VVzbusoRE/JGI4aTdO0pATXyG7eG1Qu+5Yc1YGXcCrliA2xM9xx+d7f+s\r\n" +"mPzN+WIEg5GJDYZDjAzHG5BNvi/FfM1C9dOtjv2dAoGAF0t5KmwbjWHBhcVqO4Ic\r\n" +"BVvN3BIlc1ue2YRXEDlxY5b0r8N4XceMgKmW18OHApZxfl8uPDauWZLXOgl4uepv\r\n" +"whZC3EuWrSyyICNhLY21Ah7hbIEBPF3L3ZsOwC+UErL+dXWLdB56Jgy3gZaBeW7b\r\n" +"vDrEnocJbqCm7IukhXHOBK8CgYEAwqdHB0hqyNSzIOGY7v9abzB6pUdA3BZiQvEs\r\n" +"3LjHVd4HPJ2x0N8CgrBIWOE0q8+0hSMmeE96WW/7jD3fPWwCR5zlXknxBQsfv0gP\r\n" +"3BC5PR0Qdypz+d+9zfMf625kyit4T/hzwhDveZUzHnk1Cf+IG7Q+TOEnLnWAWBED\r\n" +"ISOWmrUCgYAFEmRxgwAc/u+D6t0syCwAYh6POtscq9Y0i9GyWk89NzgC4NdwwbBH\r\n" +"4AgahOxIxXx2gxJnq3yfkJfIjwf0s2DyP0kY2y6Ua1OeomPeY9mrIS4tCuDQ6LrE\r\n" +"TB6l9VGoxJL4fyHnZb8L5gGvnB1bbD8cL6YPaDiOhcRseC9vBiEuVg==\r\n" +"-----END RSA PRIVATE KEY-----\r\n"; +const size_t mbedtls_test_srv_key_rsa_len = sizeof( mbedtls_test_srv_key_rsa ); + +const char mbedtls_test_cli_crt_rsa[] = +"-----BEGIN CERTIFICATE-----\r\n" +"MIIDhTCCAm2gAwIBAgIBBDANBgkqhkiG9w0BAQsFADA7MQswCQYDVQQGEwJOTDER\r\n" +"MA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n" +"MTcwNTA1MTMwNzU5WhcNMjcwNTA2MTMwNzU5WjA8MQswCQYDVQQGEwJOTDERMA8G\r\n" +"A1UECgwIUG9sYXJTU0wxGjAYBgNVBAMMEVBvbGFyU1NMIENsaWVudCAyMIIBIjAN\r\n" +"BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyHTEzLn5tXnpRdkUYLB9u5Pyax6f\r\n" +"M60Nj4o8VmXl3ETZzGaFB9X4J7BKNdBjngpuG7fa8H6r7gwQk4ZJGDTzqCrSV/Uu\r\n" +"1C93KYRhTYJQj6eVSHD1bk2y1RPD0hrt5kPqQhTrdOrA7R/UV06p86jt0uDBMHEw\r\n" +"MjDV0/YI0FZPRo7yX/k9Z5GIMC5Cst99++UMd//sMcB4j7/Cf8qtbCHWjdmLao5v\r\n" +"4Jv4EFbMs44TFeY0BGbH7vk2DmqV9gmaBmf0ZXH4yqSxJeD+PIs1BGe64E92hfx/\r\n" +"/DZrtenNLQNiTrM9AM+vdqBpVoNq0qjU51Bx5rU2BXcFbXvI5MT9TNUhXwIDAQAB\r\n" +"o4GSMIGPMB0GA1UdDgQWBBRxoQBzckAvVHZeM/xSj7zx3WtGITBjBgNVHSMEXDBa\r\n" +"gBS0WuSls97SUva51aaVD+s+vMf9/6E/pD0wOzELMAkGA1UEBhMCTkwxETAPBgNV\r\n" +"BAoMCFBvbGFyU1NMMRkwFwYDVQQDDBBQb2xhclNTTCBUZXN0IENBggEAMAkGA1Ud\r\n" +"EwQCMAAwDQYJKoZIhvcNAQELBQADggEBAC7yO786NvcHpK8UovKIG9cB32oSQQom\r\n" +"LoR0eHDRzdqEkoq7yGZufHFiRAAzbMqJfogRtxlrWAeB4y/jGaMBV25IbFOIcH2W\r\n" +"iCEaMMbG+VQLKNvuC63kmw/Zewc9ThM6Pa1Hcy0axT0faf1B/U01j0FIcw/6mTfK\r\n" +"D8w48OIwc1yr0JtutCVjig5DC0yznGMt32RyseOLcUe+lfq005v2PAiCozr5X8rE\r\n" +"ofGZpiM2NqRPePgYy+Vc75Zk28xkRQq1ncprgQb3S4vTsZdScpM9hLf+eMlrgqlj\r\n" +"c5PLSkXBeLE5+fedkyfTaLxxQlgCpuoOhKBm04/R1pWNzUHyqagjO9Q=\r\n" +"-----END CERTIFICATE-----\r\n"; +const size_t mbedtls_test_cli_crt_rsa_len = sizeof( mbedtls_test_cli_crt_rsa ); + +const char mbedtls_test_cli_key_rsa[] = +"-----BEGIN RSA PRIVATE KEY-----\r\n" +"MIIEpAIBAAKCAQEAyHTEzLn5tXnpRdkUYLB9u5Pyax6fM60Nj4o8VmXl3ETZzGaF\r\n" +"B9X4J7BKNdBjngpuG7fa8H6r7gwQk4ZJGDTzqCrSV/Uu1C93KYRhTYJQj6eVSHD1\r\n" +"bk2y1RPD0hrt5kPqQhTrdOrA7R/UV06p86jt0uDBMHEwMjDV0/YI0FZPRo7yX/k9\r\n" +"Z5GIMC5Cst99++UMd//sMcB4j7/Cf8qtbCHWjdmLao5v4Jv4EFbMs44TFeY0BGbH\r\n" +"7vk2DmqV9gmaBmf0ZXH4yqSxJeD+PIs1BGe64E92hfx//DZrtenNLQNiTrM9AM+v\r\n" +"dqBpVoNq0qjU51Bx5rU2BXcFbXvI5MT9TNUhXwIDAQABAoIBAGdNtfYDiap6bzst\r\n" +"yhCiI8m9TtrhZw4MisaEaN/ll3XSjaOG2dvV6xMZCMV+5TeXDHOAZnY18Yi18vzz\r\n" +"4Ut2TnNFzizCECYNaA2fST3WgInnxUkV3YXAyP6CNxJaCmv2aA0yFr2kFVSeaKGt\r\n" +"ymvljNp2NVkvm7Th8fBQBO7I7AXhz43k0mR7XmPgewe8ApZOG3hstkOaMvbWAvWA\r\n" +"zCZupdDjZYjOJqlA4eEA4H8/w7F83r5CugeBE8LgEREjLPiyejrU5H1fubEY+h0d\r\n" +"l5HZBJ68ybTXfQ5U9o/QKA3dd0toBEhhdRUDGzWtjvwkEQfqF1reGWj/tod/gCpf\r\n" +"DFi6X0ECgYEA4wOv/pjSC3ty6TuOvKX2rOUiBrLXXv2JSxZnMoMiWI5ipLQt+RYT\r\n" +"VPafL/m7Dn6MbwjayOkcZhBwk5CNz5A6Q4lJ64Mq/lqHznRCQQ2Mc1G8eyDF/fYL\r\n" +"Ze2pLvwP9VD5jTc2miDfw+MnvJhywRRLcemDFP8k4hQVtm8PMp3ZmNECgYEA4gz7\r\n" +"wzObR4gn8ibe617uQPZjWzUj9dUHYd+in1gwBCIrtNnaRn9I9U/Q6tegRYpii4ys\r\n" +"c176NmU+umy6XmuSKV5qD9bSpZWG2nLFnslrN15Lm3fhZxoeMNhBaEDTnLT26yoi\r\n" +"33gp0mSSWy94ZEqipms+ULF6sY1ZtFW6tpGFoy8CgYAQHhnnvJflIs2ky4q10B60\r\n" +"ZcxFp3rtDpkp0JxhFLhiizFrujMtZSjYNm5U7KkgPVHhLELEUvCmOnKTt4ap/vZ0\r\n" +"BxJNe1GZH3pW6SAvGDQpl9sG7uu/vTFP+lCxukmzxB0DrrDcvorEkKMom7ZCCRvW\r\n" +"KZsZ6YeH2Z81BauRj218kQKBgQCUV/DgKP2985xDTT79N08jUo3hTP5MVYCCuj/+\r\n" +"UeEw1TvZcx3LJby7P6Xad6a1/BqveaGyFKIfEFIaBUBItk801sDDpDaYc4gL00Xc\r\n" +"7lFuBHOZkxJYlss5QrGpuOEl9ZwUt5IrFLBdYaKqNHzNVC1pCPfb/JyH6Dr2HUxq\r\n" +"gxUwAQKBgQCcU6G2L8AG9d9c0UpOyL1tMvFe5Ttw0KjlQVdsh1MP6yigYo9DYuwu\r\n" +"bHFVW2r0dBTqegP2/KTOxKzaHfC1qf0RGDsUoJCNJrd1cwoCLG8P2EF4w3OBrKqv\r\n" +"8u4ytY0F+Vlanj5lm3TaoHSVF1+NWPyOTiwevIECGKwSxvlki4fDAA==\r\n" +"-----END RSA PRIVATE KEY-----\r\n"; +const size_t mbedtls_test_cli_key_rsa_len = sizeof( mbedtls_test_cli_key_rsa ); #endif /* MBEDTLS_RSA_C */ -/* API stability forces us to declare - * mbedtls_test_{ca|srv|cli}_{key|pwd|crt} - * as pointers. */ -static const char test_ca_key[] = TEST_CA_KEY; -static const char test_ca_pwd[] = TEST_CA_PWD; -static const char test_ca_crt[] = TEST_CA_CRT; +#if defined(MBEDTLS_PEM_PARSE_C) +/* Concatenation of all available CA certificates */ +const char mbedtls_test_cas_pem[] = +#ifdef TEST_CA_CRT_RSA_SHA1 + TEST_CA_CRT_RSA_SHA1 +#endif +#ifdef TEST_CA_CRT_RSA_SHA256 + TEST_CA_CRT_RSA_SHA256 +#endif +#ifdef TEST_CA_CRT_EC + TEST_CA_CRT_EC +#endif + ""; +const size_t mbedtls_test_cas_pem_len = sizeof( mbedtls_test_cas_pem ); +#endif -static const char test_srv_key[] = TEST_SRV_KEY; -static const char test_srv_pwd[] = TEST_SRV_PWD; -static const char test_srv_crt[] = TEST_SRV_CRT; - -static const char test_cli_key[] = TEST_CLI_KEY; -static const char test_cli_pwd[] = TEST_CLI_PWD; -static const char test_cli_crt[] = TEST_CLI_CRT; - -const char *mbedtls_test_ca_key = test_ca_key; -const char *mbedtls_test_ca_pwd = test_ca_pwd; -const char *mbedtls_test_ca_crt = test_ca_crt; - -const char *mbedtls_test_srv_key = test_srv_key; -const char *mbedtls_test_srv_pwd = test_srv_pwd; -const char *mbedtls_test_srv_crt = test_srv_crt; - -const char *mbedtls_test_cli_key = test_cli_key; -const char *mbedtls_test_cli_pwd = test_cli_pwd; -const char *mbedtls_test_cli_crt = test_cli_crt; - -const size_t mbedtls_test_ca_key_len = - sizeof( test_ca_key ); -const size_t mbedtls_test_ca_pwd_len = - sizeof( test_ca_pwd ) - 1; -const size_t mbedtls_test_ca_crt_len = - sizeof( test_ca_crt ); - -const size_t mbedtls_test_srv_key_len = - sizeof( test_srv_key ); -const size_t mbedtls_test_srv_pwd_len = - sizeof( test_srv_pwd ) - 1; -const size_t mbedtls_test_srv_crt_len = - sizeof( test_srv_crt ); - -const size_t mbedtls_test_cli_key_len = - sizeof( test_cli_key ); -const size_t mbedtls_test_cli_pwd_len = - sizeof( test_cli_pwd ) - 1; -const size_t mbedtls_test_cli_crt_len = - sizeof( test_cli_crt ); - -/* - * - * Lists of certificates - * - */ - -/* List of CAs in PEM or DER, depending on config */ +/* List of all available CA certificates */ const char * mbedtls_test_cas[] = { -#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_SHA1_C) +#if defined(TEST_CA_CRT_RSA_SHA1) mbedtls_test_ca_crt_rsa_sha1, #endif -#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_SHA256_C) +#if defined(TEST_CA_CRT_RSA_SHA256) mbedtls_test_ca_crt_rsa_sha256, #endif -#if defined(MBEDTLS_ECDSA_C) || defined(MBEDTLS_USE_TINYCRYPT) +#if defined(MBEDTLS_ECDSA_C) mbedtls_test_ca_crt_ec, -#endif /* MBEDTLS_ECDSA_C || MBEDTLS_USE_TINYCRYPT */ +#endif NULL }; const size_t mbedtls_test_cas_len[] = { -#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_SHA1_C) +#if defined(TEST_CA_CRT_RSA_SHA1) sizeof( mbedtls_test_ca_crt_rsa_sha1 ), #endif -#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_SHA256_C) +#if defined(TEST_CA_CRT_RSA_SHA256) sizeof( mbedtls_test_ca_crt_rsa_sha256 ), #endif -#if defined(MBEDTLS_ECDSA_C) || defined(MBEDTLS_USE_TINYCRYPT) +#if defined(MBEDTLS_ECDSA_C) sizeof( mbedtls_test_ca_crt_ec ), -#endif /* MBEDTLS_ECDSA_C || MBEDTLS_USE_TINYCRYPT */ +#endif 0 }; -/* List of all available CA certificates in DER format */ -const unsigned char * mbedtls_test_cas_der[] = { #if defined(MBEDTLS_RSA_C) -#if defined(MBEDTLS_SHA256_C) - mbedtls_test_ca_crt_rsa_sha256_der, -#endif /* MBEDTLS_SHA256_C */ -#if defined(MBEDTLS_SHA1_C) - mbedtls_test_ca_crt_rsa_sha1_der, -#endif /* MBEDTLS_SHA1_C */ +const char *mbedtls_test_ca_crt = mbedtls_test_ca_crt_rsa; /* SHA1 or SHA256 */ +const char *mbedtls_test_ca_key = mbedtls_test_ca_key_rsa; +const char *mbedtls_test_ca_pwd = mbedtls_test_ca_pwd_rsa; +const char *mbedtls_test_srv_crt = mbedtls_test_srv_crt_rsa; +const char *mbedtls_test_srv_key = mbedtls_test_srv_key_rsa; +const char *mbedtls_test_cli_crt = mbedtls_test_cli_crt_rsa; +const char *mbedtls_test_cli_key = mbedtls_test_cli_key_rsa; +const size_t mbedtls_test_ca_crt_len = sizeof( mbedtls_test_ca_crt_rsa ); +const size_t mbedtls_test_ca_key_len = sizeof( mbedtls_test_ca_key_rsa ); +const size_t mbedtls_test_ca_pwd_len = sizeof( mbedtls_test_ca_pwd_rsa ) - 1; +const size_t mbedtls_test_srv_crt_len = sizeof( mbedtls_test_srv_crt_rsa ); +const size_t mbedtls_test_srv_key_len = sizeof( mbedtls_test_srv_key_rsa ); +const size_t mbedtls_test_cli_crt_len = sizeof( mbedtls_test_cli_crt_rsa ); +const size_t mbedtls_test_cli_key_len = sizeof( mbedtls_test_cli_key_rsa ); +#else /* ! MBEDTLS_RSA_C, so MBEDTLS_ECDSA_C */ +const char *mbedtls_test_ca_crt = mbedtls_test_ca_crt_ec; +const char *mbedtls_test_ca_key = mbedtls_test_ca_key_ec; +const char *mbedtls_test_ca_pwd = mbedtls_test_ca_pwd_ec; +const char *mbedtls_test_srv_crt = mbedtls_test_srv_crt_ec; +const char *mbedtls_test_srv_key = mbedtls_test_srv_key_ec; +const char *mbedtls_test_cli_crt = mbedtls_test_cli_crt_ec; +const char *mbedtls_test_cli_key = mbedtls_test_cli_key_ec; +const size_t mbedtls_test_ca_crt_len = sizeof( mbedtls_test_ca_crt_ec ); +const size_t mbedtls_test_ca_key_len = sizeof( mbedtls_test_ca_key_ec ); +const size_t mbedtls_test_ca_pwd_len = sizeof( mbedtls_test_ca_pwd_ec ) - 1; +const size_t mbedtls_test_srv_crt_len = sizeof( mbedtls_test_srv_crt_ec ); +const size_t mbedtls_test_srv_key_len = sizeof( mbedtls_test_srv_key_ec ); +const size_t mbedtls_test_cli_crt_len = sizeof( mbedtls_test_cli_crt_ec ); +const size_t mbedtls_test_cli_key_len = sizeof( mbedtls_test_cli_key_ec ); #endif /* MBEDTLS_RSA_C */ -#if defined(MBEDTLS_ECDSA_C) || defined(MBEDTLS_USE_TINYCRYPT) - mbedtls_test_ca_crt_ec_der, -#endif /* MBEDTLS_ECDSA_C || MBEDTLS_USE_TINYCRYPT */ - NULL -}; - -const size_t mbedtls_test_cas_der_len[] = { -#if defined(MBEDTLS_RSA_C) -#if defined(MBEDTLS_SHA256_C) - sizeof( mbedtls_test_ca_crt_rsa_sha256_der ), -#endif /* MBEDTLS_SHA256_C */ -#if defined(MBEDTLS_SHA1_C) - sizeof( mbedtls_test_ca_crt_rsa_sha1_der ), -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_RSA_C */ -#if defined(MBEDTLS_ECDSA_C) || defined(MBEDTLS_USE_TINYCRYPT) - sizeof( mbedtls_test_ca_crt_ec_der ), -#endif /* MBEDTLS_ECDSA_C || MBEDTLS_USE_TINYCRYPT */ - 0 -}; - -/* Concatenation of all available CA certificates in PEM format */ -#if defined(MBEDTLS_PEM_PARSE_C) -const char mbedtls_test_cas_pem[] = -#if defined(MBEDTLS_RSA_C) -#if defined(MBEDTLS_SHA256_C) - TEST_CA_CRT_RSA_SHA256_PEM -#endif /* MBEDTLS_SHA256_C */ -#if defined(MBEDTLS_SHA1_C) - TEST_CA_CRT_RSA_SHA1_PEM -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_RSA_C */ -#if defined(MBEDTLS_ECDSA_C) || defined(MBEDTLS_USE_TINYCRYPT) - TEST_CA_CRT_EC_PEM -#endif /* MBEDTLS_ECDSA_C || MBEDTLS_USE_TINYCRYPT */ - ""; -const size_t mbedtls_test_cas_pem_len = sizeof( mbedtls_test_cas_pem ); -#endif /* MBEDTLS_PEM_PARSE_C */ #endif /* MBEDTLS_CERTS_C */ diff --git a/APP_Framework/Framework/security/mbedtls/certs.h b/APP_Framework/Framework/security/mbedtls/certs.h index 179ebbbad..b7c5708f8 100644 --- a/APP_Framework/Framework/security/mbedtls/certs.h +++ b/APP_Framework/Framework/security/mbedtls/certs.h @@ -36,214 +36,68 @@ extern "C" { #endif -/* List of all PEM-encoded CA certificates, terminated by NULL; - * PEM encoded if MBEDTLS_PEM_PARSE_C is enabled, DER encoded - * otherwise. */ -extern const char * mbedtls_test_cas[]; -extern const size_t mbedtls_test_cas_len[]; - -/* List of all DER-encoded CA certificates, terminated by NULL */ -extern const unsigned char * mbedtls_test_cas_der[]; -extern const size_t mbedtls_test_cas_der_len[]; - #if defined(MBEDTLS_PEM_PARSE_C) /* Concatenation of all CA certificates in PEM format if available */ extern const char mbedtls_test_cas_pem[]; extern const size_t mbedtls_test_cas_pem_len; -#endif /* MBEDTLS_PEM_PARSE_C */ +#endif + +/* List of all CA certificates, terminated by NULL */ +extern const char * mbedtls_test_cas[]; +extern const size_t mbedtls_test_cas_len[]; /* - * CA test certificates + * Convenience for users who just want a certificate: + * RSA by default, or ECDSA if RSA is not available */ - -extern const char mbedtls_test_ca_crt_ec_pem[]; -extern const char mbedtls_test_ca_key_ec_pem[]; -extern const char mbedtls_test_ca_pwd_ec_pem[]; -extern const char mbedtls_test_ca_key_rsa_pem[]; -extern const char mbedtls_test_ca_pwd_rsa_pem[]; -extern const char mbedtls_test_ca_crt_rsa_sha1_pem[]; -extern const char mbedtls_test_ca_crt_rsa_sha256_pem[]; - -extern const unsigned char mbedtls_test_ca_crt_ec_der[]; -extern const unsigned char mbedtls_test_ca_key_ec_der[]; -extern const unsigned char mbedtls_test_ca_key_rsa_der[]; -extern const unsigned char mbedtls_test_ca_crt_rsa_sha1_der[]; -extern const unsigned char mbedtls_test_ca_crt_rsa_sha256_der[]; - -extern const size_t mbedtls_test_ca_crt_ec_pem_len; -extern const size_t mbedtls_test_ca_key_ec_pem_len; -extern const size_t mbedtls_test_ca_pwd_ec_pem_len; -extern const size_t mbedtls_test_ca_key_rsa_pem_len; -extern const size_t mbedtls_test_ca_pwd_rsa_pem_len; -extern const size_t mbedtls_test_ca_crt_rsa_sha1_pem_len; -extern const size_t mbedtls_test_ca_crt_rsa_sha256_pem_len; - -extern const size_t mbedtls_test_ca_crt_ec_der_len; -extern const size_t mbedtls_test_ca_key_ec_der_len; -extern const size_t mbedtls_test_ca_pwd_ec_der_len; -extern const size_t mbedtls_test_ca_key_rsa_der_len; -extern const size_t mbedtls_test_ca_pwd_rsa_der_len; -extern const size_t mbedtls_test_ca_crt_rsa_sha1_der_len; -extern const size_t mbedtls_test_ca_crt_rsa_sha256_der_len; - -/* Config-dependent dispatch between PEM and DER encoding - * (PEM if enabled, otherwise DER) */ - -extern const char mbedtls_test_ca_crt_ec[]; -extern const char mbedtls_test_ca_key_ec[]; -extern const char mbedtls_test_ca_pwd_ec[]; -extern const char mbedtls_test_ca_key_rsa[]; -extern const char mbedtls_test_ca_pwd_rsa[]; -extern const char mbedtls_test_ca_crt_rsa_sha1[]; -extern const char mbedtls_test_ca_crt_rsa_sha256[]; - -extern const size_t mbedtls_test_ca_crt_ec_len; -extern const size_t mbedtls_test_ca_key_ec_len; -extern const size_t mbedtls_test_ca_pwd_ec_len; -extern const size_t mbedtls_test_ca_key_rsa_len; -extern const size_t mbedtls_test_ca_pwd_rsa_len; -extern const size_t mbedtls_test_ca_crt_rsa_sha1_len; -extern const size_t mbedtls_test_ca_crt_rsa_sha256_len; - -/* Config-dependent dispatch between SHA-1 and SHA-256 - * (SHA-256 if enabled, otherwise SHA-1) */ - -extern const char mbedtls_test_ca_crt_rsa[]; -extern const size_t mbedtls_test_ca_crt_rsa_len; - -/* Config-dependent dispatch between EC and RSA - * (RSA if enabled, otherwise EC) */ - extern const char * mbedtls_test_ca_crt; -extern const char * mbedtls_test_ca_key; -extern const char * mbedtls_test_ca_pwd; extern const size_t mbedtls_test_ca_crt_len; +extern const char * mbedtls_test_ca_key; extern const size_t mbedtls_test_ca_key_len; +extern const char * mbedtls_test_ca_pwd; extern const size_t mbedtls_test_ca_pwd_len; - -/* - * Server test certificates - */ - -extern const char mbedtls_test_srv_crt_ec_pem[]; -extern const char mbedtls_test_srv_key_ec_pem[]; -extern const char mbedtls_test_srv_pwd_ec_pem[]; -extern const char mbedtls_test_srv_key_rsa_pem[]; -extern const char mbedtls_test_srv_pwd_rsa_pem[]; -extern const char mbedtls_test_srv_crt_rsa_sha1_pem[]; -extern const char mbedtls_test_srv_crt_rsa_sha256_pem[]; - -extern const unsigned char mbedtls_test_srv_crt_ec_der[]; -extern const unsigned char mbedtls_test_srv_key_ec_der[]; -extern const unsigned char mbedtls_test_srv_key_rsa_der[]; -extern const unsigned char mbedtls_test_srv_crt_rsa_sha1_der[]; -extern const unsigned char mbedtls_test_srv_crt_rsa_sha256_der[]; - -extern const size_t mbedtls_test_srv_crt_ec_pem_len; -extern const size_t mbedtls_test_srv_key_ec_pem_len; -extern const size_t mbedtls_test_srv_pwd_ec_pem_len; -extern const size_t mbedtls_test_srv_key_rsa_pem_len; -extern const size_t mbedtls_test_srv_pwd_rsa_pem_len; -extern const size_t mbedtls_test_srv_crt_rsa_sha1_pem_len; -extern const size_t mbedtls_test_srv_crt_rsa_sha256_pem_len; - -extern const size_t mbedtls_test_srv_crt_ec_der_len; -extern const size_t mbedtls_test_srv_key_ec_der_len; -extern const size_t mbedtls_test_srv_pwd_ec_der_len; -extern const size_t mbedtls_test_srv_key_rsa_der_len; -extern const size_t mbedtls_test_srv_pwd_rsa_der_len; -extern const size_t mbedtls_test_srv_crt_rsa_sha1_der_len; -extern const size_t mbedtls_test_srv_crt_rsa_sha256_der_len; - -/* Config-dependent dispatch between PEM and DER encoding - * (PEM if enabled, otherwise DER) */ - -extern const char mbedtls_test_srv_crt_ec[]; -extern const char mbedtls_test_srv_key_ec[]; -extern const char mbedtls_test_srv_pwd_ec[]; -extern const char mbedtls_test_srv_key_rsa[]; -extern const char mbedtls_test_srv_pwd_rsa[]; -extern const char mbedtls_test_srv_crt_rsa_sha1[]; -extern const char mbedtls_test_srv_crt_rsa_sha256[]; - -extern const size_t mbedtls_test_srv_crt_ec_len; -extern const size_t mbedtls_test_srv_key_ec_len; -extern const size_t mbedtls_test_srv_pwd_ec_len; -extern const size_t mbedtls_test_srv_key_rsa_len; -extern const size_t mbedtls_test_srv_pwd_rsa_len; -extern const size_t mbedtls_test_srv_crt_rsa_sha1_len; -extern const size_t mbedtls_test_srv_crt_rsa_sha256_len; - -/* Config-dependent dispatch between SHA-1 and SHA-256 - * (SHA-256 if enabled, otherwise SHA-1) */ - -extern const char mbedtls_test_srv_crt_rsa[]; -extern const size_t mbedtls_test_srv_crt_rsa_len; - -/* Config-dependent dispatch between EC and RSA - * (RSA if enabled, otherwise EC) */ - extern const char * mbedtls_test_srv_crt; -extern const char * mbedtls_test_srv_key; -extern const char * mbedtls_test_srv_pwd; extern const size_t mbedtls_test_srv_crt_len; +extern const char * mbedtls_test_srv_key; extern const size_t mbedtls_test_srv_key_len; -extern const size_t mbedtls_test_srv_pwd_len; - -/* - * Client test certificates - */ - -extern const char mbedtls_test_cli_crt_ec_pem[]; -extern const char mbedtls_test_cli_key_ec_pem[]; -extern const char mbedtls_test_cli_pwd_ec_pem[]; -extern const char mbedtls_test_cli_key_rsa_pem[]; -extern const char mbedtls_test_cli_pwd_rsa_pem[]; -extern const char mbedtls_test_cli_crt_rsa_pem[]; - -extern const unsigned char mbedtls_test_cli_crt_ec_der[]; -extern const unsigned char mbedtls_test_cli_key_ec_der[]; -extern const unsigned char mbedtls_test_cli_key_rsa_der[]; -extern const unsigned char mbedtls_test_cli_crt_rsa_der[]; - -extern const size_t mbedtls_test_cli_crt_ec_pem_len; -extern const size_t mbedtls_test_cli_key_ec_pem_len; -extern const size_t mbedtls_test_cli_pwd_ec_pem_len; -extern const size_t mbedtls_test_cli_key_rsa_pem_len; -extern const size_t mbedtls_test_cli_pwd_rsa_pem_len; -extern const size_t mbedtls_test_cli_crt_rsa_pem_len; - -extern const size_t mbedtls_test_cli_crt_ec_der_len; -extern const size_t mbedtls_test_cli_key_ec_der_len; -extern const size_t mbedtls_test_cli_key_rsa_der_len; -extern const size_t mbedtls_test_cli_crt_rsa_der_len; - -/* Config-dependent dispatch between PEM and DER encoding - * (PEM if enabled, otherwise DER) */ - -extern const char mbedtls_test_cli_crt_ec[]; -extern const char mbedtls_test_cli_key_ec[]; -extern const char mbedtls_test_cli_pwd_ec[]; -extern const char mbedtls_test_cli_key_rsa[]; -extern const char mbedtls_test_cli_pwd_rsa[]; -extern const char mbedtls_test_cli_crt_rsa[]; - -extern const size_t mbedtls_test_cli_crt_ec_len; -extern const size_t mbedtls_test_cli_key_ec_len; -extern const size_t mbedtls_test_cli_pwd_ec_len; -extern const size_t mbedtls_test_cli_key_rsa_len; -extern const size_t mbedtls_test_cli_pwd_rsa_len; -extern const size_t mbedtls_test_cli_crt_rsa_len; - -/* Config-dependent dispatch between EC and RSA - * (RSA if enabled, otherwise EC) */ - extern const char * mbedtls_test_cli_crt; -extern const char * mbedtls_test_cli_key; -extern const char * mbedtls_test_cli_pwd; extern const size_t mbedtls_test_cli_crt_len; +extern const char * mbedtls_test_cli_key; extern const size_t mbedtls_test_cli_key_len; -extern const size_t mbedtls_test_cli_pwd_len; + +#if defined(MBEDTLS_ECDSA_C) +extern const char mbedtls_test_ca_crt_ec[]; +extern const size_t mbedtls_test_ca_crt_ec_len; +extern const char mbedtls_test_ca_key_ec[]; +extern const size_t mbedtls_test_ca_key_ec_len; +extern const char mbedtls_test_ca_pwd_ec[]; +extern const size_t mbedtls_test_ca_pwd_ec_len; +extern const char mbedtls_test_srv_crt_ec[]; +extern const size_t mbedtls_test_srv_crt_ec_len; +extern const char mbedtls_test_srv_key_ec[]; +extern const size_t mbedtls_test_srv_key_ec_len; +extern const char mbedtls_test_cli_crt_ec[]; +extern const size_t mbedtls_test_cli_crt_ec_len; +extern const char mbedtls_test_cli_key_ec[]; +extern const size_t mbedtls_test_cli_key_ec_len; +#endif + +#if defined(MBEDTLS_RSA_C) +extern const char mbedtls_test_ca_crt_rsa[]; +extern const size_t mbedtls_test_ca_crt_rsa_len; +extern const char mbedtls_test_ca_key_rsa[]; +extern const size_t mbedtls_test_ca_key_rsa_len; +extern const char mbedtls_test_ca_pwd_rsa[]; +extern const size_t mbedtls_test_ca_pwd_rsa_len; +extern const char mbedtls_test_srv_crt_rsa[]; +extern const size_t mbedtls_test_srv_crt_rsa_len; +extern const char mbedtls_test_srv_key_rsa[]; +extern const size_t mbedtls_test_srv_key_rsa_len; +extern const char mbedtls_test_cli_crt_rsa[]; +extern const size_t mbedtls_test_cli_crt_rsa_len; +extern const char mbedtls_test_cli_key_rsa[]; +extern const size_t mbedtls_test_cli_key_rsa_len; +#endif #ifdef __cplusplus } diff --git a/APP_Framework/Framework/security/mbedtls/chacha20.h b/APP_Framework/Framework/security/mbedtls/chacha20.h deleted file mode 100644 index 2ae5e6e5f..000000000 --- a/APP_Framework/Framework/security/mbedtls/chacha20.h +++ /dev/null @@ -1,226 +0,0 @@ -/** - * \file chacha20.h - * - * \brief This file contains ChaCha20 definitions and functions. - * - * ChaCha20 is a stream cipher that can encrypt and decrypt - * information. ChaCha was created by Daniel Bernstein as a variant of - * its Salsa cipher https://cr.yp.to/chacha/chacha-20080128.pdf - * ChaCha20 is the variant with 20 rounds, that was also standardized - * in RFC 7539. - * - * \author Daniel King - */ - -/* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * This file is part of Mbed TLS (https://tls.mbed.org) - */ - -#ifndef MBEDTLS_CHACHA20_H -#define MBEDTLS_CHACHA20_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include -#include - -#define MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA -0x0051 /**< Invalid input parameter(s). */ - -/* MBEDTLS_ERR_CHACHA20_FEATURE_UNAVAILABLE is deprecated and should not be - * used. */ -#define MBEDTLS_ERR_CHACHA20_FEATURE_UNAVAILABLE -0x0053 /**< Feature not available. For example, s part of the API is not implemented. */ - -/* MBEDTLS_ERR_CHACHA20_HW_ACCEL_FAILED is deprecated and should not be used. - */ -#define MBEDTLS_ERR_CHACHA20_HW_ACCEL_FAILED -0x0055 /**< Chacha20 hardware accelerator failed. */ - -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined(MBEDTLS_CHACHA20_ALT) - -typedef struct mbedtls_chacha20_context -{ - uint32_t state[16]; /*! The state (before round operations). */ - uint8_t keystream8[64]; /*! Leftover keystream bytes. */ - size_t keystream_bytes_used; /*! Number of keystream bytes already used. */ -} -mbedtls_chacha20_context; - -#else /* MBEDTLS_CHACHA20_ALT */ -#include "chacha20_alt.h" -#endif /* MBEDTLS_CHACHA20_ALT */ - -/** - * \brief This function initializes the specified ChaCha20 context. - * - * It must be the first API called before using - * the context. - * - * It is usually followed by calls to - * \c mbedtls_chacha20_setkey() and - * \c mbedtls_chacha20_starts(), then one or more calls to - * to \c mbedtls_chacha20_update(), and finally to - * \c mbedtls_chacha20_free(). - * - * \param ctx The ChaCha20 context to initialize. - * This must not be \c NULL. - */ -void mbedtls_chacha20_init( mbedtls_chacha20_context *ctx ); - -/** - * \brief This function releases and clears the specified - * ChaCha20 context. - * - * \param ctx The ChaCha20 context to clear. This may be \c NULL, - * in which case this function is a no-op. If it is not - * \c NULL, it must point to an initialized context. - * - */ -void mbedtls_chacha20_free( mbedtls_chacha20_context *ctx ); - -/** - * \brief This function sets the encryption/decryption key. - * - * \note After using this function, you must also call - * \c mbedtls_chacha20_starts() to set a nonce before you - * start encrypting/decrypting data with - * \c mbedtls_chacha_update(). - * - * \param ctx The ChaCha20 context to which the key should be bound. - * It must be initialized. - * \param key The encryption/decryption key. This must be \c 32 Bytes - * in length. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA if ctx or key is NULL. - */ -int mbedtls_chacha20_setkey( mbedtls_chacha20_context *ctx, - const unsigned char key[32] ); - -/** - * \brief This function sets the nonce and initial counter value. - * - * \note A ChaCha20 context can be re-used with the same key by - * calling this function to change the nonce. - * - * \warning You must never use the same nonce twice with the same key. - * This would void any confidentiality guarantees for the - * messages encrypted with the same nonce and key. - * - * \param ctx The ChaCha20 context to which the nonce should be bound. - * It must be initialized and bound to a key. - * \param nonce The nonce. This must be \c 12 Bytes in size. - * \param counter The initial counter value. This is usually \c 0. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA if ctx or nonce is - * NULL. - */ -int mbedtls_chacha20_starts( mbedtls_chacha20_context* ctx, - const unsigned char nonce[12], - uint32_t counter ); - -/** - * \brief This function encrypts or decrypts data. - * - * Since ChaCha20 is a stream cipher, the same operation is - * used for encrypting and decrypting data. - * - * \note The \p input and \p output pointers must either be equal or - * point to non-overlapping buffers. - * - * \note \c mbedtls_chacha20_setkey() and - * \c mbedtls_chacha20_starts() must be called at least once - * to setup the context before this function can be called. - * - * \note This function can be called multiple times in a row in - * order to encrypt of decrypt data piecewise with the same - * key and nonce. - * - * \param ctx The ChaCha20 context to use for encryption or decryption. - * It must be initialized and bound to a key and nonce. - * \param size The length of the input data in Bytes. - * \param input The buffer holding the input data. - * This pointer can be \c NULL if `size == 0`. - * \param output The buffer holding the output data. - * This must be able to hold \p size Bytes. - * This pointer can be \c NULL if `size == 0`. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_chacha20_update( mbedtls_chacha20_context *ctx, - size_t size, - const unsigned char *input, - unsigned char *output ); - -/** - * \brief This function encrypts or decrypts data with ChaCha20 and - * the given key and nonce. - * - * Since ChaCha20 is a stream cipher, the same operation is - * used for encrypting and decrypting data. - * - * \warning You must never use the same (key, nonce) pair more than - * once. This would void any confidentiality guarantees for - * the messages encrypted with the same nonce and key. - * - * \note The \p input and \p output pointers must either be equal or - * point to non-overlapping buffers. - * - * \param key The encryption/decryption key. - * This must be \c 32 Bytes in length. - * \param nonce The nonce. This must be \c 12 Bytes in size. - * \param counter The initial counter value. This is usually \c 0. - * \param size The length of the input data in Bytes. - * \param input The buffer holding the input data. - * This pointer can be \c NULL if `size == 0`. - * \param output The buffer holding the output data. - * This must be able to hold \p size Bytes. - * This pointer can be \c NULL if `size == 0`. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_chacha20_crypt( const unsigned char key[32], - const unsigned char nonce[12], - uint32_t counter, - size_t size, - const unsigned char* input, - unsigned char* output ); - -#if defined(MBEDTLS_SELF_TEST) -/** - * \brief The ChaCha20 checkup routine. - * - * \return \c 0 on success. - * \return \c 1 on failure. - */ -int mbedtls_chacha20_self_test( int verbose ); -#endif /* MBEDTLS_SELF_TEST */ - -#ifdef __cplusplus -} -#endif - -#endif /* MBEDTLS_CHACHA20_H */ diff --git a/APP_Framework/Framework/security/mbedtls/chachapoly.h b/APP_Framework/Framework/security/mbedtls/chachapoly.h deleted file mode 100644 index 49e615d27..000000000 --- a/APP_Framework/Framework/security/mbedtls/chachapoly.h +++ /dev/null @@ -1,358 +0,0 @@ -/** - * \file chachapoly.h - * - * \brief This file contains the AEAD-ChaCha20-Poly1305 definitions and - * functions. - * - * ChaCha20-Poly1305 is an algorithm for Authenticated Encryption - * with Associated Data (AEAD) that can be used to encrypt and - * authenticate data. It is based on ChaCha20 and Poly1305 by Daniel - * Bernstein and was standardized in RFC 7539. - * - * \author Daniel King - */ - -/* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * This file is part of Mbed TLS (https://tls.mbed.org) - */ - -#ifndef MBEDTLS_CHACHAPOLY_H -#define MBEDTLS_CHACHAPOLY_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -/* for shared error codes */ -#include "poly1305.h" - -#define MBEDTLS_ERR_CHACHAPOLY_BAD_STATE -0x0054 /**< The requested operation is not permitted in the current state. */ -#define MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED -0x0056 /**< Authenticated decryption failed: data was not authentic. */ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum -{ - MBEDTLS_CHACHAPOLY_ENCRYPT, /**< The mode value for performing encryption. */ - MBEDTLS_CHACHAPOLY_DECRYPT /**< The mode value for performing decryption. */ -} -mbedtls_chachapoly_mode_t; - -#if !defined(MBEDTLS_CHACHAPOLY_ALT) - -#include "chacha20.h" - -typedef struct mbedtls_chachapoly_context -{ - mbedtls_chacha20_context chacha20_ctx; /**< The ChaCha20 context. */ - mbedtls_poly1305_context poly1305_ctx; /**< The Poly1305 context. */ - uint64_t aad_len; /**< The length (bytes) of the Additional Authenticated Data. */ - uint64_t ciphertext_len; /**< The length (bytes) of the ciphertext. */ - int state; /**< The current state of the context. */ - mbedtls_chachapoly_mode_t mode; /**< Cipher mode (encrypt or decrypt). */ -} -mbedtls_chachapoly_context; - -#else /* !MBEDTLS_CHACHAPOLY_ALT */ -#include "chachapoly_alt.h" -#endif /* !MBEDTLS_CHACHAPOLY_ALT */ - -/** - * \brief This function initializes the specified ChaCha20-Poly1305 context. - * - * It must be the first API called before using - * the context. It must be followed by a call to - * \c mbedtls_chachapoly_setkey() before any operation can be - * done, and to \c mbedtls_chachapoly_free() once all - * operations with that context have been finished. - * - * In order to encrypt or decrypt full messages at once, for - * each message you should make a single call to - * \c mbedtls_chachapoly_crypt_and_tag() or - * \c mbedtls_chachapoly_auth_decrypt(). - * - * In order to encrypt messages piecewise, for each - * message you should make a call to - * \c mbedtls_chachapoly_starts(), then 0 or more calls to - * \c mbedtls_chachapoly_update_aad(), then 0 or more calls to - * \c mbedtls_chachapoly_update(), then one call to - * \c mbedtls_chachapoly_finish(). - * - * \warning Decryption with the piecewise API is discouraged! Always - * use \c mbedtls_chachapoly_auth_decrypt() when possible! - * - * If however this is not possible because the data is too - * large to fit in memory, you need to: - * - * - call \c mbedtls_chachapoly_starts() and (if needed) - * \c mbedtls_chachapoly_update_aad() as above, - * - call \c mbedtls_chachapoly_update() multiple times and - * ensure its output (the plaintext) is NOT used in any other - * way than placing it in temporary storage at this point, - * - call \c mbedtls_chachapoly_finish() to compute the - * authentication tag and compared it in constant time to the - * tag received with the ciphertext. - * - * If the tags are not equal, you must immediately discard - * all previous outputs of \c mbedtls_chachapoly_update(), - * otherwise you can now safely use the plaintext. - * - * \param ctx The ChachaPoly context to initialize. Must not be \c NULL. - */ -void mbedtls_chachapoly_init( mbedtls_chachapoly_context *ctx ); - -/** - * \brief This function releases and clears the specified - * ChaCha20-Poly1305 context. - * - * \param ctx The ChachaPoly context to clear. This may be \c NULL, in which - * case this function is a no-op. - */ -void mbedtls_chachapoly_free( mbedtls_chachapoly_context *ctx ); - -/** - * \brief This function sets the ChaCha20-Poly1305 - * symmetric encryption key. - * - * \param ctx The ChaCha20-Poly1305 context to which the key should be - * bound. This must be initialized. - * \param key The \c 256 Bit (\c 32 Bytes) key. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_chachapoly_setkey( mbedtls_chachapoly_context *ctx, - const unsigned char key[32] ); - -/** - * \brief This function starts a ChaCha20-Poly1305 encryption or - * decryption operation. - * - * \warning You must never use the same nonce twice with the same key. - * This would void any confidentiality and authenticity - * guarantees for the messages encrypted with the same nonce - * and key. - * - * \note If the context is being used for AAD only (no data to - * encrypt or decrypt) then \p mode can be set to any value. - * - * \warning Decryption with the piecewise API is discouraged, see the - * warning on \c mbedtls_chachapoly_init(). - * - * \param ctx The ChaCha20-Poly1305 context. This must be initialized - * and bound to a key. - * \param nonce The nonce/IV to use for the message. - * This must be a redable buffer of length \c 12 Bytes. - * \param mode The operation to perform: #MBEDTLS_CHACHAPOLY_ENCRYPT or - * #MBEDTLS_CHACHAPOLY_DECRYPT (discouraged, see warning). - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_chachapoly_starts( mbedtls_chachapoly_context *ctx, - const unsigned char nonce[12], - mbedtls_chachapoly_mode_t mode ); - -/** - * \brief This function feeds additional data to be authenticated - * into an ongoing ChaCha20-Poly1305 operation. - * - * The Additional Authenticated Data (AAD), also called - * Associated Data (AD) is only authenticated but not - * encrypted nor included in the encrypted output. It is - * usually transmitted separately from the ciphertext or - * computed locally by each party. - * - * \note This function is called before data is encrypted/decrypted. - * I.e. call this function to process the AAD before calling - * \c mbedtls_chachapoly_update(). - * - * You may call this function multiple times to process - * an arbitrary amount of AAD. It is permitted to call - * this function 0 times, if no AAD is used. - * - * This function cannot be called any more if data has - * been processed by \c mbedtls_chachapoly_update(), - * or if the context has been finished. - * - * \warning Decryption with the piecewise API is discouraged, see the - * warning on \c mbedtls_chachapoly_init(). - * - * \param ctx The ChaCha20-Poly1305 context. This must be initialized - * and bound to a key. - * \param aad_len The length in Bytes of the AAD. The length has no - * restrictions. - * \param aad Buffer containing the AAD. - * This pointer can be \c NULL if `aad_len == 0`. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA - * if \p ctx or \p aad are NULL. - * \return #MBEDTLS_ERR_CHACHAPOLY_BAD_STATE - * if the operations has not been started or has been - * finished, or if the AAD has been finished. - */ -int mbedtls_chachapoly_update_aad( mbedtls_chachapoly_context *ctx, - const unsigned char *aad, - size_t aad_len ); - -/** - * \brief Thus function feeds data to be encrypted or decrypted - * into an on-going ChaCha20-Poly1305 - * operation. - * - * The direction (encryption or decryption) depends on the - * mode that was given when calling - * \c mbedtls_chachapoly_starts(). - * - * You may call this function multiple times to process - * an arbitrary amount of data. It is permitted to call - * this function 0 times, if no data is to be encrypted - * or decrypted. - * - * \warning Decryption with the piecewise API is discouraged, see the - * warning on \c mbedtls_chachapoly_init(). - * - * \param ctx The ChaCha20-Poly1305 context to use. This must be initialized. - * \param len The length (in bytes) of the data to encrypt or decrypt. - * \param input The buffer containing the data to encrypt or decrypt. - * This pointer can be \c NULL if `len == 0`. - * \param output The buffer to where the encrypted or decrypted data is - * written. This must be able to hold \p len bytes. - * This pointer can be \c NULL if `len == 0`. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CHACHAPOLY_BAD_STATE - * if the operation has not been started or has been - * finished. - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_chachapoly_update( mbedtls_chachapoly_context *ctx, - size_t len, - const unsigned char *input, - unsigned char *output ); - -/** - * \brief This function finished the ChaCha20-Poly1305 operation and - * generates the MAC (authentication tag). - * - * \param ctx The ChaCha20-Poly1305 context to use. This must be initialized. - * \param mac The buffer to where the 128-bit (16 bytes) MAC is written. - * - * \warning Decryption with the piecewise API is discouraged, see the - * warning on \c mbedtls_chachapoly_init(). - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CHACHAPOLY_BAD_STATE - * if the operation has not been started or has been - * finished. - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_chachapoly_finish( mbedtls_chachapoly_context *ctx, - unsigned char mac[16] ); - -/** - * \brief This function performs a complete ChaCha20-Poly1305 - * authenticated encryption with the previously-set key. - * - * \note Before using this function, you must set the key with - * \c mbedtls_chachapoly_setkey(). - * - * \warning You must never use the same nonce twice with the same key. - * This would void any confidentiality and authenticity - * guarantees for the messages encrypted with the same nonce - * and key. - * - * \param ctx The ChaCha20-Poly1305 context to use (holds the key). - * This must be initialized. - * \param length The length (in bytes) of the data to encrypt or decrypt. - * \param nonce The 96-bit (12 bytes) nonce/IV to use. - * \param aad The buffer containing the additional authenticated - * data (AAD). This pointer can be \c NULL if `aad_len == 0`. - * \param aad_len The length (in bytes) of the AAD data to process. - * \param input The buffer containing the data to encrypt or decrypt. - * This pointer can be \c NULL if `ilen == 0`. - * \param output The buffer to where the encrypted or decrypted data - * is written. This pointer can be \c NULL if `ilen == 0`. - * \param tag The buffer to where the computed 128-bit (16 bytes) MAC - * is written. This must not be \c NULL. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_chachapoly_encrypt_and_tag( mbedtls_chachapoly_context *ctx, - size_t length, - const unsigned char nonce[12], - const unsigned char *aad, - size_t aad_len, - const unsigned char *input, - unsigned char *output, - unsigned char tag[16] ); - -/** - * \brief This function performs a complete ChaCha20-Poly1305 - * authenticated decryption with the previously-set key. - * - * \note Before using this function, you must set the key with - * \c mbedtls_chachapoly_setkey(). - * - * \param ctx The ChaCha20-Poly1305 context to use (holds the key). - * \param length The length (in Bytes) of the data to decrypt. - * \param nonce The \c 96 Bit (\c 12 bytes) nonce/IV to use. - * \param aad The buffer containing the additional authenticated data (AAD). - * This pointer can be \c NULL if `aad_len == 0`. - * \param aad_len The length (in bytes) of the AAD data to process. - * \param tag The buffer holding the authentication tag. - * This must be a readable buffer of length \c 16 Bytes. - * \param input The buffer containing the data to decrypt. - * This pointer can be \c NULL if `ilen == 0`. - * \param output The buffer to where the decrypted data is written. - * This pointer can be \c NULL if `ilen == 0`. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED - * if the data was not authentic. - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_chachapoly_auth_decrypt( mbedtls_chachapoly_context *ctx, - size_t length, - const unsigned char nonce[12], - const unsigned char *aad, - size_t aad_len, - const unsigned char tag[16], - const unsigned char *input, - unsigned char *output ); - -#if defined(MBEDTLS_SELF_TEST) -/** - * \brief The ChaCha20-Poly1305 checkup routine. - * - * \return \c 0 on success. - * \return \c 1 on failure. - */ -int mbedtls_chachapoly_self_test( int verbose ); -#endif /* MBEDTLS_SELF_TEST */ - -#ifdef __cplusplus -} -#endif - -#endif /* MBEDTLS_CHACHAPOLY_H */ diff --git a/APP_Framework/Framework/security/mbedtls/check_config.h b/APP_Framework/Framework/security/mbedtls/check_config.h index 4c92954e9..fa7110fe9 100644 --- a/APP_Framework/Framework/security/mbedtls/check_config.h +++ b/APP_Framework/Framework/security/mbedtls/check_config.h @@ -4,7 +4,7 @@ * \brief Consistency checks for configuration options */ /* - * Copyright (C) 2006-2018, ARM Limited, All Rights Reserved + * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -74,16 +74,6 @@ #error "MBEDTLS_CTR_DRBG_C defined, but not all prerequisites" #endif -#if defined(MBEDTLS_CTR_DRBG_C) && defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) && !defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY) -#error "MBEDTLS_CTR_DRBG_C and MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH defined, but MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is not defined" -#endif - -#if defined(MBEDTLS_AES_128_BIT_MASKED) && ( !defined(MBEDTLS_AES_SCA_COUNTERMEASURES) || \ - !defined(MBEDTLS_AES_ONLY_ENCRYPT) || \ - !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) ) -#error "MBEDTLS_AES_128_BIT_MASKED defined, but not all prerequisites" -#endif - #if defined(MBEDTLS_DHM_C) && !defined(MBEDTLS_BIGNUM_C) #error "MBEDTLS_DHM_C defined, but not all prerequisites" #endif @@ -97,56 +87,6 @@ #error "MBEDTLS_CMAC_C defined, but not all prerequisites" #endif -#if defined(MBEDTLS_SSL_CONF_SINGLE_EC) && \ - ( !defined(MBEDTLS_SSL_CONF_SINGLE_EC_TLS_ID) || \ - ( defined(MBEDTLS_USE_TINYCRYPT) && \ - !defined(MBEDTLS_SSL_CONF_SINGLE_UECC_GRP_ID) ) || \ - ( defined(MBEDTLS_ECP_C) && \ - !defined(MBEDTLS_SSL_CONF_SINGLE_EC_GRP_ID) ) ) -#error "MBEDTLS_SSL_CONF_SINGLE_EC defined, but not all prerequesites" -#endif - -#if defined(MBEDTLS_SSL_CONF_SINGLE_SIG_HASH) && \ - ( !defined(MBEDTLS_SSL_CONF_SINGLE_SIG_HASH_MD_ID) || \ - !defined(MBEDTLS_SSL_CONF_SINGLE_SIG_HASH_TLS_ID) ) -#error "MBEDTLS_SSL_CONF_SINGLE_SIG_HASH defined, but not all prerequesites" -#endif - -#if defined(MBEDTLS_USE_TINYCRYPT) && defined(MBEDTLS_NO_64BIT_MULTIPLICATION) -#error "MBEDTLS_USE_TINYCRYPT defined, but it cannot be defined with MBEDTLS_NO_64BIT_MULTIPLICATION" -#endif - -#if defined(MBEDTLS_USE_TINYCRYPT) && !defined(MBEDTLS_SHA256_C) -#error "MBEDTLS_USE_TINYCRYPT defined, but not MBEDTLS_SHA256_C" -#endif - -#if defined(MBEDTLS_USE_TINYCRYPT) && \ - !( defined(MBEDTLS_SSL_CONF_SINGLE_EC) && \ - MBEDTLS_SSL_CONF_SINGLE_EC_TLS_ID == 23 && \ - MBEDTLS_SSL_CONF_SINGLE_UECC_GRP_ID == MBEDTLS_UECC_DP_SECP256R1 ) -#error "MBEDTLS_USE_TINYCRYPT requires the use of MBEDTLS_SSL_CONF_SINGLE_UECC_GRP_ID to hardcode the choice of Secp256r1" -#endif - -#if defined(MBEDTLS_USE_TINYCRYPT) && defined(MBEDTLS_ECP_C) -#error "MBEDTLS_USE_TINYCRYPT and MBEDTLS_ECP_C cannot be used simultaneously" -#endif - -#if defined(MBEDTLS_USE_TINYCRYPT) && \ - !defined(MBEDTLS_SSL_CONF_RNG) -#error "MBEDTLS_USE_TINYCRYPT defined, but not all prerequesites" -#endif - -#if defined(MBEDTLS_OPTIMIZE_TINYCRYPT_ASM) && \ - ( !defined(MBEDTLS_HAVE_ASM) || \ - !defined(MBEDTLS_USE_TINYCRYPT) ) -#error "MBEDTLS_OPTIMIZE_TINYCRYPT_ASM defined, but not all prerequesites" -#endif - -#if defined(MBEDTLS_NIST_KW_C) && \ - ( !defined(MBEDTLS_AES_C) || !defined(MBEDTLS_CIPHER_C) ) -#error "MBEDTLS_NIST_KW_C defined, but not all prerequisites" -#endif - #if defined(MBEDTLS_ECDH_C) && !defined(MBEDTLS_ECP_C) #error "MBEDTLS_ECDH_C defined, but not all prerequisites" #endif @@ -163,22 +103,11 @@ #error "MBEDTLS_ECJPAKE_C defined, but not all prerequisites" #endif -#if defined(MBEDTLS_ECP_RESTARTABLE) && \ - ( defined(MBEDTLS_ECDH_COMPUTE_SHARED_ALT) || \ - defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT) || \ - defined(MBEDTLS_ECDSA_SIGN_ALT) || \ - defined(MBEDTLS_ECDSA_VERIFY_ALT) || \ - defined(MBEDTLS_ECDSA_GENKEY_ALT) || \ - defined(MBEDTLS_ECP_INTERNAL_ALT) || \ - defined(MBEDTLS_ECP_ALT) ) -#error "MBEDTLS_ECP_RESTARTABLE defined, but it cannot coexist with an alternative ECP implementation" -#endif - #if defined(MBEDTLS_ECDSA_DETERMINISTIC) && !defined(MBEDTLS_HMAC_DRBG_C) #error "MBEDTLS_ECDSA_DETERMINISTIC defined, but not all prerequisites" #endif -#if defined(MBEDTLS_ECP_C) && ( !defined(MBEDTLS_BIGNUM_C) || ( \ +#if defined(MBEDTLS_ECP_C) && ( !defined(MBEDTLS_BIGNUM_C) || ( \ !defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) && \ !defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) && \ !defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) && \ @@ -189,27 +118,10 @@ !defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) && \ !defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) && \ !defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) && \ - !defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) && \ - !defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) && \ - !defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) ) ) + !defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) ) ) #error "MBEDTLS_ECP_C defined, but not all prerequisites" #endif -#if ( defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) ) && \ - !defined(MBEDTLS_ECP_C) -#error "At least one ECP curve enabled, but not all prerequesites" -#endif - #if defined(MBEDTLS_PK_PARSE_C) && !defined(MBEDTLS_ASN1_PARSE_C) #error "MBEDTLS_PK_PARSE_C defined, but not all prerequesites" #endif @@ -283,23 +195,17 @@ #error "MBEDTLS_HAVEGE_C defined, but not all prerequisites" #endif -#if defined(MBEDTLS_HKDF_C) && !defined(MBEDTLS_MD_C) -#error "MBEDTLS_HKDF_C defined, but not all prerequisites" -#endif - #if defined(MBEDTLS_HMAC_DRBG_C) && !defined(MBEDTLS_MD_C) #error "MBEDTLS_HMAC_DRBG_C defined, but not all prerequisites" #endif #if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) && \ - ( !( defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_USE_TINYCRYPT) ) || \ - !defined(MBEDTLS_X509_CRT_PARSE_C) ) + ( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) ) #error "MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED defined, but not all prerequisites" #endif -#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \ - ( !( defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_USE_TINYCRYPT) ) || \ - !defined(MBEDTLS_X509_CRT_PARSE_C) ) +#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \ + ( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) ) #error "MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED defined, but not all prerequisites" #endif @@ -308,7 +214,7 @@ #endif #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) && \ - !(defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_USE_TINYCRYPT) ) + !defined(MBEDTLS_ECDH_C) #error "MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED defined, but not all prerequisites" #endif @@ -318,17 +224,14 @@ #error "MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED defined, but not all prerequisites" #endif -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \ - ( !( defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_USE_TINYCRYPT) ) || \ - !defined(MBEDTLS_RSA_C) || \ - !defined(MBEDTLS_X509_CRT_PARSE_C) || \ - !defined(MBEDTLS_PKCS1_V15) ) +#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \ + ( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_RSA_C) || \ + !defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_PKCS1_V15) ) #error "MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED defined, but not all prerequisites" #endif #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) && \ - ( !( defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_USE_TINYCRYPT) ) || \ - !( defined(MBEDTLS_ECDSA_C) || defined(MBEDTLS_USE_TINYCRYPT) ) || \ + ( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_ECDSA_C) || \ !defined(MBEDTLS_X509_CRT_PARSE_C) ) #error "MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED defined, but not all prerequisites" #endif @@ -351,27 +254,11 @@ #error "MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED defined, but not all prerequisites" #endif -#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) && \ - !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) && \ - ( !defined(MBEDTLS_SHA256_C) && \ - !defined(MBEDTLS_SHA512_C) && \ - !defined(MBEDTLS_SHA1_C) ) -#error "MBEDTLS_SSL_KEEP_PEER_CERTIFICATE defined, but not all prerequesites" -#endif - #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) && \ ( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) ) #error "MBEDTLS_MEMORY_BUFFER_ALLOC_C defined, but not all prerequisites" #endif -#if defined(MBEDTLS_MEMORY_BACKTRACE) && !defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) -#error "MBEDTLS_MEMORY_BACKTRACE defined, but not all prerequesites" -#endif - -#if defined(MBEDTLS_MEMORY_DEBUG) && !defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) -#error "MBEDTLS_MEMORY_DEBUG defined, but not all prerequesites" -#endif - #if defined(MBEDTLS_PADLOCK_C) && !defined(MBEDTLS_HAVE_ASM) #error "MBEDTLS_PADLOCK_C defined, but not all prerequisites" #endif @@ -384,10 +271,8 @@ #error "MBEDTLS_PEM_WRITE_C defined, but not all prerequisites" #endif -#if defined(MBEDTLS_PK_C) && \ - ( !defined(MBEDTLS_RSA_C) && \ - !defined(MBEDTLS_ECP_C) && \ - !defined(MBEDTLS_USE_TINYCRYPT) ) +#if defined(MBEDTLS_PK_C) && \ + ( !defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_ECP_C) ) #error "MBEDTLS_PK_C defined, but not all prerequisites" #endif @@ -631,23 +516,6 @@ #error "MBEDTLS_SSL_PROTO_TLS1_2 defined, but not all prerequisites" #endif -#if (defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)) && \ - !(defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) ) -#error "One or more versions of the TLS protocol are enabled " \ - "but no key exchange methods defined with MBEDTLS_KEY_EXCHANGE_xxxx" -#endif - #if defined(MBEDTLS_SSL_PROTO_DTLS) && \ !defined(MBEDTLS_SSL_PROTO_TLS1_1) && \ !defined(MBEDTLS_SSL_PROTO_TLS1_2) @@ -670,28 +538,7 @@ #if defined(MBEDTLS_SSL_TLS_C) && (!defined(MBEDTLS_SSL_PROTO_SSL3) && \ !defined(MBEDTLS_SSL_PROTO_TLS1) && !defined(MBEDTLS_SSL_PROTO_TLS1_1) && \ !defined(MBEDTLS_SSL_PROTO_TLS1_2)) -#error "MBEDTLS_SSL_TLS_C defined, but no protocol version is active" -#endif - -/* PROTO_TLS is not a documented option so far, but still check for conflicts - * involving it, in preparation for making it the documented option later */ -#if defined(MBEDTLS_SSL_PROTO_TLS) && defined(MBEDTLS_SSL_PROTO_NO_TLS) -#error "MBEDTLS_SSL_PROTO_TLS and MBEDTLS_SSL_PROTO_NO_TLS both defined" -#endif - -#if defined(MBEDTLS_SSL_TLS_C) && \ - ( defined(MBEDTLS_SSL_PROTO_NO_TLS) && !defined(MBEDTLS_SSL_PROTO_DTLS) ) -#error "MBEDTLS_SSL_TLS_C defined, but neither TLS or DTLS is active" -#endif - -#if defined(MBEDTLS_SSL_TLS_C) && defined(MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS) && \ - defined(MBEDTLS_ARC4_C) -#error "MBEDTLS_ARC4_C cannot be defined with MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS on" -#endif - -#if defined(MBEDTLS_VALIDATE_SSL_KEYS_INTEGRITY) && !defined(MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS) && \ - defined(MBEDTLS_ARC4_C) -#error "MBEDTLS_VALIDATE_SSL_KEYS_INTEGRITY requires MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS to be defined." +#error "MBEDTLS_SSL_TLS_C defined, but no protocols are active" #endif #if defined(MBEDTLS_SSL_TLS_C) && (defined(MBEDTLS_SSL_PROTO_SSL3) && \ @@ -724,49 +571,6 @@ #error "MBEDTLS_SSL_DTLS_ANTI_REPLAY defined, but not all prerequisites" #endif -#if defined(MBEDTLS_SSL_CONF_MIN_MINOR_VER) || \ - defined(MBEDTLS_SSL_CONF_MAX_MINOR_VER) || \ - defined(MBEDTLS_SSL_CONF_MIN_MAJOR_VER) || \ - defined(MBEDTLS_SSL_CONF_MAX_MAJOR_VER) -#if !( defined(MBEDTLS_SSL_CONF_MIN_MINOR_VER) && \ - defined(MBEDTLS_SSL_CONF_MAX_MINOR_VER) && \ - defined(MBEDTLS_SSL_CONF_MIN_MAJOR_VER) && \ - defined(MBEDTLS_SSL_CONF_MAX_MAJOR_VER) ) -#error "MBEDTLS_SSL_CONF_MIN_MINOR_VER, MBEDTLS_SSL_CONF_MAX_MINOR_VER, MBEDTLS_SSL_CONF_MIN_MAJOR_VER, MBEDTLS_SSL_CONF_MAX_MAJOR_VER must be defined simultaneously" -#endif -#endif - -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \ - ( !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) ) -#error "MBEDTLS_SSL_DTLS_CONNECTION_ID defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \ - defined(MBEDTLS_SSL_CID_IN_LEN_MAX) && \ - MBEDTLS_SSL_CID_IN_LEN_MAX > 255 -#error "MBEDTLS_SSL_CID_IN_LEN_MAX too large (max 255)" -#endif - -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \ - defined(MBEDTLS_SSL_CID_OUT_LEN_MAX) && \ - MBEDTLS_SSL_CID_OUT_LEN_MAX > 255 -#error "MBEDTLS_SSL_CID_OUT_LEN_MAX too large (max 255)" -#endif - -#if ( defined(MBEDTLS_SSL_CONF_CID_LEN) && \ - !defined(MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID) ) || \ - ( !defined(MBEDTLS_SSL_CONF_CID_LEN) && \ - defined(MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID) ) -#error "MBEDTLS_SSL_CONF_CID_LEN and MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID must be defined simultaneously" -#endif - -#if ( defined(MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN) && \ - !defined(MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX) ) || \ - ( !defined(MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN) && \ - defined(MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX) ) -#error "MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN and MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX must be defined simultaneously" -#endif - #if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) && \ ( !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) ) #error "MBEDTLS_SSL_DTLS_BADMAC_LIMIT defined, but not all prerequisites" @@ -786,32 +590,6 @@ #error "MBEDTLS_SSL_EXTENDED_MASTER_SECRET defined, but not all prerequsites" #endif -#if ( defined(MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET) && \ - !defined(MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET) ) || \ - ( !defined(MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET) && \ - defined(MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET) ) -#error "MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET and MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET must be defined together." -#endif - -#if ( defined(MBEDTLS_SSL_CONF_SEND) && \ - !( defined(MBEDTLS_SSL_CONF_RECV) && \ - defined(MBEDTLS_SSL_CONF_RECV_TIMEOUT) ) ) || \ - ( defined(MBEDTLS_SSL_CONF_RECV) && \ - !( defined(MBEDTLS_SSL_CONF_SEND) && \ - defined(MBEDTLS_SSL_CONF_RECV_TIMEOUT) ) ) || \ - ( defined(MBEDTLS_SSL_CONF_RECV_TIMEOUT) && \ - !( defined(MBEDTLS_SSL_CONF_SEND) && \ - defined(MBEDTLS_SSL_CONF_RECV) ) ) -#error "MBEDTLS_SSL_CONF_SEND/RECV/RECV_TIMEOUT must be defined simultaneously" -#endif - -#if ( defined(MBEDTLS_SSL_CONF_GET_TIMER) && \ - !defined(MBEDTLS_SSL_CONF_SET_TIMER) ) || \ - ( !defined(MBEDTLS_SSL_CONF_GET_TIMER) && \ - defined(MBEDTLS_SSL_CONF_SET_TIMER) ) -#error "MBEDTLS_SSL_CONF_GET_TIMER and MBEDTLS_SSL_CONF_SET_TIMER must be defined together." -#endif - #if defined(MBEDTLS_SSL_TICKET_C) && !defined(MBEDTLS_CIPHER_C) #error "MBEDTLS_SSL_TICKET_C defined, but not all prerequisites" #endif @@ -826,16 +604,6 @@ #error "MBEDTLS_SSL_SERVER_NAME_INDICATION defined, but not all prerequisites" #endif -#if defined(MBEDTLS_SSL_SESSION_TICKETS) && \ - defined(MBEDTLS_SSL_NO_SESSION_RESUMPTION) -#error "MBEDTLS_SSL_SESSION_TICKETS cannot be defined with MBEDTLS_SSL_NO_SESSION_RESUMPTION" -#endif - -#if !defined(MBEDTLS_SSL_NO_SESSION_CACHE) && \ - defined(MBEDTLS_SSL_NO_SESSION_RESUMPTION) -#error "MBEDTLS_SSL_NO_SESSION_CACHE needs to be defined with MBEDTLS_SSL_NO_SESSION_RESUMPTION" -#endif - #if defined(MBEDTLS_THREADING_PTHREAD) #if !defined(MBEDTLS_THREADING_C) || defined(MBEDTLS_THREADING_IMPL) #error "MBEDTLS_THREADING_PTHREAD defined, but not all prerequisites" @@ -843,113 +611,6 @@ #define MBEDTLS_THREADING_IMPL #endif -/* Ensure that precisely one hash is enabled. */ -#if defined(MBEDTLS_MD_SINGLE_HASH) - -#if defined(MBEDTLS_SHA256_C) -#define MBEDTLS_SHA256_ENABLED 1 -#else -#define MBEDTLS_SHA256_ENABLED 0 -#endif /* MBEDTLS_SHA256_C */ - -#if defined(MBEDTLS_SHA256_C) && !defined(MBEDTLS_SHA256_NO_SHA224) -#define MBEDTLS_SHA224_ENABLED 1 -#else -#define MBEDTLS_SHA224_ENABLED 0 -#endif /* MBEDTLS_SHA256_C && !MBEDTLS_SHA256_NO_SHA224 */ - -#if defined(MBEDTLS_SHA512_C) -#define MBEDTLS_SHA512_ENABLED 2 -#else -#define MBEDTLS_SHA512_ENABLED 0 -#endif /* MBEDTLS_SHA512_C */ - -#if defined(MBEDTLS_SHA1_C) -#define MBEDTLS_SHA1_ENABLED 1 -#else -#define MBEDTLS_SHA1_ENABLED 0 -#endif /* MBEDTLS_SHA1_C */ - -#if defined(MBEDTLS_MD2_C) -#define MBEDTLS_MD2_ENABLED 1 -#else -#define MBEDTLS_MD2_ENABLED 0 -#endif /* MBEDTLS_MD2_C */ - -#if defined(MBEDTLS_MD4_C) -#define MBEDTLS_MD4_ENABLED 1 -#else -#define MBEDTLS_MD4_ENABLED 0 -#endif /* MBEDTLS_MD4_C */ - -#if defined(MBEDTLS_MD5_C) -#define MBEDTLS_MD5_ENABLED 1 -#else -#define MBEDTLS_MD5_ENABLED 0 -#endif /* MBEDTLS_MD5_C */ - -#if defined(MBEDTLS_RIPEMD160_C) -#define MBEDTLS_RIPEMD160_ENABLED 1 -#else -#define MBEDTLS_RIPEMD160_ENABLED 0 -#endif /* MBEDTLS_RIPEMD160_C */ - -#define MBEDTLS_HASHES_ENABLED \ - ( MBEDTLS_MD2_ENABLED + \ - MBEDTLS_MD4_ENABLED + \ - MBEDTLS_MD5_ENABLED + \ - MBEDTLS_RIPEMD160_ENABLED + \ - MBEDTLS_SHA1_ENABLED + \ - MBEDTLS_SHA256_ENABLED + \ - MBEDTLS_SHA512_ENABLED ) - -#if MBEDTLS_HASHES_ENABLED != 1 -#error "MBEDTLS_MD_SINGLE_HASH must be used with precisely one hash algorithm enabled." -#endif - -#undef MBEDTLS_HASHES_ENABLED -#endif /* MBEDTLS_MD_SINGLE_HASH */ - -#if defined(MBEDTLS_SSL_DELAYED_SERVER_CERT_VERIFICATION) && !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) -#error "MBEDTLS_SSL_DELAYED_SERVER_CERT_VERIFICATION can only be used with MBEDTLS_SSL_KEEP_PEER_CERTIFICATE" -#endif - - -#if defined(MBEDTLS_SSL_EARLY_KEY_COMPUTATION) && !defined(MBEDTLS_USE_TINYCRYPT) -#error "MBEDTLS_SSL_EARLY_KEY_COMPUTATION can only be used with MBEDTLS_USE_TINYCRYPT" -#endif - -/* - * Note: the dependency on TinyCrypt is reflected in several ways in the code: - * - * 1. We only define the various MBEDTLS_PK_INFO_{TYPE}_{FIELD} macros for - * TYPE == ECKEY, resolving to the TinyCrypt version. - * 2. In pk_init() and pk_free() we assume that zeroization is a proper way - * to init/free the context, which is true of mbedtls_uecc_keypair, but - * might not always hold otherwise (think hardware-accelerated ECP_ALT). - * 3. We rely on the fact that MBEDTLS_ECP_RESTARTABLE is disabled - code - * paths (and pk_info fields) that are guarded by this are currently not - * handled by the internal abstraction layers enabling PK_SINGLE_TYPE. - * - * If this dependency is ever removed, the above points need to be addressed - * in the code. - */ -#if defined(MBEDTLS_PK_SINGLE_TYPE) && !defined(MBEDTLS_USE_TINYCRYPT) -#error "MBEDTLS_PK_SINGLE_TYPE can only be used with MBEDTLS_USE_TINYCRYPT" -#endif - -/* Note: code paths that depend on MBEDTLS_PK_RSA_ALT_SUPPORT are not ported - * to the internal abstraction layers that enable PK_SINGLE_TYPE. */ -#if defined(MBEDTLS_PK_SINGLE_TYPE) && defined(MBEDTLS_PK_RSA_ALT_SUPPORT) -#error "MBEDTLS_PK_SINGLE_TYPE is not compatible with MBEDTLS_PK_RSA_ALT_SUPPORT" -#endif - -/* This is to avoid a situation where RSA is available, but not through the PK - * layer, which might surprise user code. */ -#if defined(MBEDTLS_PK_SINGLE_TYPE) && defined(MBEDTLS_RSA_C) -#error "MBEDTLS_PK_SINGLE_TYPE is not compatible with MBEDTLS_RSA_C" -#endif - #if defined(MBEDTLS_THREADING_ALT) #if !defined(MBEDTLS_THREADING_C) || defined(MBEDTLS_THREADING_IMPL) #error "MBEDTLS_THREADING_ALT defined, but not all prerequisites" @@ -966,10 +627,9 @@ #error "MBEDTLS_VERSION_FEATURES defined, but not all prerequisites" #endif -#if defined(MBEDTLS_X509_USE_C) && \ - ( !defined(MBEDTLS_OID_C) || \ - !defined(MBEDTLS_ASN1_PARSE_C) || \ - !defined(MBEDTLS_PK_PARSE_C) ) +#if defined(MBEDTLS_X509_USE_C) && ( !defined(MBEDTLS_BIGNUM_C) || \ + !defined(MBEDTLS_OID_C) || !defined(MBEDTLS_ASN1_PARSE_C) || \ + !defined(MBEDTLS_PK_PARSE_C) ) #error "MBEDTLS_X509_USE_C defined, but not all prerequisites" #endif @@ -979,10 +639,6 @@ #error "MBEDTLS_X509_CREATE_C defined, but not all prerequisites" #endif -#if defined(MBEDTLS_CERTS_C) && !defined(MBEDTLS_X509_USE_C) -#error "MBEDTLS_CERTS_C defined, but not all prerequisites" -#endif - #if defined(MBEDTLS_X509_CRT_PARSE_C) && ( !defined(MBEDTLS_X509_USE_C) ) #error "MBEDTLS_X509_CRT_PARSE_C defined, but not all prerequisites" #endif @@ -1003,11 +659,6 @@ #error "MBEDTLS_X509_CSR_WRITE_C defined, but not all prerequisites" #endif -#if defined(MBEDTLS_X509_CRT_REMOVE_TIME) && \ - defined(MBEDTLS_HAVE_TIME_DATE) -#error "MBEDTLS_X509_CRT_REMOVE_TIME and MBEDTLS_HAVE_TIME_DATE cannot be defined simultaneously" -#endif - #if defined(MBEDTLS_HAVE_INT32) && defined(MBEDTLS_HAVE_INT64) #error "MBEDTLS_HAVE_INT32 and MBEDTLS_HAVE_INT64 cannot be defined simultaneously" #endif /* MBEDTLS_HAVE_INT32 && MBEDTLS_HAVE_INT64 */ @@ -1020,7 +671,7 @@ /* * Avoid warning from -pedantic. This is a convenient place for this * workaround since this is included by every single file before the - * #if defined(MBEDTLS_xxx_C) that results in empty translation units. + * #if defined(MBEDTLS_xxx_C) that results in emtpy translation units. */ typedef int mbedtls_iso_c_forbids_empty_translation_units; diff --git a/APP_Framework/Framework/security/mbedtls/cipher.c b/APP_Framework/Framework/security/mbedtls/cipher.c index a1c536680..166c83ba9 100644 --- a/APP_Framework/Framework/security/mbedtls/cipher.c +++ b/APP_Framework/Framework/security/mbedtls/cipher.c @@ -33,16 +33,10 @@ #include "cipher.h" #include "cipher_internal.h" -#include "platform_util.h" #include -#include #include -#if defined(MBEDTLS_CHACHAPOLY_C) -#include "chachapoly.h" -#endif - #if defined(MBEDTLS_GCM_C) #include "gcm.h" #endif @@ -51,10 +45,6 @@ #include "ccm.h" #endif -#if defined(MBEDTLS_CHACHA20_C) -#include "chacha20.h" -#endif - #if defined(MBEDTLS_CMAC_C) #include "cmac.h" #endif @@ -66,30 +56,10 @@ #define mbedtls_free free #endif -#define CIPHER_VALIDATE_RET( cond ) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ) -#define CIPHER_VALIDATE( cond ) \ - MBEDTLS_INTERNAL_VALIDATE( cond ) - -#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) -/* Compare the contents of two buffers in constant time. - * Returns 0 if the contents are bitwise identical, otherwise returns - * a non-zero value. - * This is currently only used by GCM and ChaCha20+Poly1305. - */ -static int mbedtls_constant_time_memcmp( const void *v1, const void *v2, size_t len ) -{ - const unsigned char *p1 = (const unsigned char*) v1; - const unsigned char *p2 = (const unsigned char*) v2; - size_t i; - unsigned char diff; - - for( diff = 0, i = 0; i < len; i++ ) - diff |= p1[i] ^ p2[i]; - - return( (int)diff ); +/* 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 /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */ static int supported_init = 0; @@ -156,7 +126,6 @@ const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values( const mbedtls_ciph void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx ) { - CIPHER_VALIDATE( ctx != NULL ); memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) ); } @@ -168,8 +137,7 @@ void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx ) #if defined(MBEDTLS_CMAC_C) if( ctx->cmac_ctx ) { - mbedtls_platform_zeroize( ctx->cmac_ctx, - sizeof( mbedtls_cmac_context_t ) ); + mbedtls_zeroize( ctx->cmac_ctx, sizeof( mbedtls_cmac_context_t ) ); mbedtls_free( ctx->cmac_ctx ); } #endif @@ -177,17 +145,15 @@ void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx ) if( ctx->cipher_ctx ) ctx->cipher_info->base->ctx_free_func( ctx->cipher_ctx ); - mbedtls_platform_zeroize( ctx, sizeof(mbedtls_cipher_context_t) ); + mbedtls_zeroize( ctx, sizeof(mbedtls_cipher_context_t) ); } int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx, const mbedtls_cipher_info_t *cipher_info ) { - CIPHER_VALIDATE_RET( ctx != NULL ); - if( cipher_info == NULL ) + if( NULL == cipher_info || NULL == ctx ) return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - mbedtls_platform_memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) ); - ctx->operation = MBEDTLS_OPERATION_NONE; + memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) ); if( NULL == ( ctx->cipher_ctx = cipher_info->base->ctx_alloc_func() ) ) return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED ); @@ -208,16 +174,10 @@ int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx, const mbedtls_cipher_in return( 0 ); } -int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx, - const unsigned char *key, - int key_bitlen, - const mbedtls_operation_t operation ) +int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx, const unsigned char *key, + int key_bitlen, const mbedtls_operation_t operation ) { - CIPHER_VALIDATE_RET( ctx != NULL ); - CIPHER_VALIDATE_RET( key != NULL ); - CIPHER_VALIDATE_RET( operation == MBEDTLS_ENCRYPT || - operation == MBEDTLS_DECRYPT ); - if( ctx->cipher_info == NULL ) + if( NULL == ctx || NULL == ctx->cipher_info ) return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); if( ( ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_KEY_LEN ) == 0 && @@ -230,34 +190,34 @@ int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx, ctx->operation = operation; /* - * For OFB, CFB and CTR mode always use the encryption key schedule + * For CFB and CTR mode always use the encryption key schedule */ if( MBEDTLS_ENCRYPT == operation || MBEDTLS_MODE_CFB == ctx->cipher_info->mode || - MBEDTLS_MODE_OFB == ctx->cipher_info->mode || MBEDTLS_MODE_CTR == ctx->cipher_info->mode ) { - return( ctx->cipher_info->base->setkey_enc_func( ctx->cipher_ctx, key, - ctx->key_bitlen ) ); + return ctx->cipher_info->base->setkey_enc_func( ctx->cipher_ctx, key, + ctx->key_bitlen ); } if( MBEDTLS_DECRYPT == operation ) - return( ctx->cipher_info->base->setkey_dec_func( ctx->cipher_ctx, key, - ctx->key_bitlen ) ); + return ctx->cipher_info->base->setkey_dec_func( ctx->cipher_ctx, key, + ctx->key_bitlen ); return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); } int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx, - const unsigned char *iv, - size_t iv_len ) + const unsigned char *iv, size_t iv_len ) { size_t actual_iv_size; - - CIPHER_VALIDATE_RET( ctx != NULL ); - CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL ); - if( ctx->cipher_info == NULL ) + if( NULL == ctx || NULL == ctx->cipher_info ) return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + else if( NULL == iv && iv_len != 0 ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + if( NULL == iv && iv_len == 0 ) + ctx->iv_size = 0; /* avoid buffer overflow in ctx->iv */ if( iv_len > MBEDTLS_MAX_IV_LENGTH ) @@ -273,22 +233,9 @@ int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx, if( actual_iv_size > iv_len ) return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); } - -#if defined(MBEDTLS_CHACHA20_C) - if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20 ) - { - if ( 0 != mbedtls_chacha20_starts( (mbedtls_chacha20_context*)ctx->cipher_ctx, - iv, - 0U ) ) /* Initial counter value */ - { - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - } -#endif - if ( actual_iv_size != 0 ) { - mbedtls_platform_memcpy( ctx->iv, iv, actual_iv_size ); + memcpy( ctx->iv, iv, actual_iv_size ); ctx->iv_size = actual_iv_size; } @@ -297,8 +244,7 @@ int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx, int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx ) { - CIPHER_VALIDATE_RET( ctx != NULL ); - if( ctx->cipher_info == NULL ) + if( NULL == ctx || NULL == ctx->cipher_info ) return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); ctx->unprocessed_len = 0; @@ -306,67 +252,36 @@ int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx ) return( 0 ); } -#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) +#if defined(MBEDTLS_GCM_C) int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx, const unsigned char *ad, size_t ad_len ) { - CIPHER_VALIDATE_RET( ctx != NULL ); - CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL ); - if( ctx->cipher_info == NULL ) + if( NULL == ctx || NULL == ctx->cipher_info ) return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); -#if defined(MBEDTLS_GCM_C) if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) { - return( mbedtls_gcm_starts( (mbedtls_gcm_context *) ctx->cipher_ctx, ctx->operation, - ctx->iv, ctx->iv_size, ad, ad_len ) ); + return mbedtls_gcm_starts( (mbedtls_gcm_context *) ctx->cipher_ctx, ctx->operation, + ctx->iv, ctx->iv_size, ad, ad_len ); } -#endif - -#if defined(MBEDTLS_CHACHAPOLY_C) - if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) - { - int result; - mbedtls_chachapoly_mode_t mode; - - mode = ( ctx->operation == MBEDTLS_ENCRYPT ) - ? MBEDTLS_CHACHAPOLY_ENCRYPT - : MBEDTLS_CHACHAPOLY_DECRYPT; - - result = mbedtls_chachapoly_starts( (mbedtls_chachapoly_context *) ctx->cipher_ctx, - ctx->iv, - mode ); - if ( result != 0 ) - return( result ); - - return( mbedtls_chachapoly_update_aad( (mbedtls_chachapoly_context *) ctx->cipher_ctx, - ad, ad_len ) ); - } -#endif return( 0 ); } -#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */ +#endif /* MBEDTLS_GCM_C */ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *input, size_t ilen, unsigned char *output, size_t *olen ) { int ret; - size_t block_size; + size_t block_size = 0; - CIPHER_VALIDATE_RET( ctx != NULL ); - CIPHER_VALIDATE_RET( ilen == 0 || input != NULL ); - CIPHER_VALIDATE_RET( output != NULL ); - CIPHER_VALIDATE_RET( olen != NULL ); - if( ctx->cipher_info == NULL ) + if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen ) + { return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + } *olen = 0; block_size = mbedtls_cipher_get_block_size( ctx ); - if ( 0 == block_size ) - { - return( MBEDTLS_ERR_CIPHER_INVALID_CONTEXT ); - } if( ctx->cipher_info->mode == MBEDTLS_MODE_ECB ) { @@ -388,19 +303,15 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i if( ctx->cipher_info->mode == MBEDTLS_MODE_GCM ) { *olen = ilen; - return( mbedtls_gcm_update( (mbedtls_gcm_context *) ctx->cipher_ctx, ilen, input, - output ) ); + return mbedtls_gcm_update( (mbedtls_gcm_context *) ctx->cipher_ctx, ilen, input, + output ); } #endif -#if defined(MBEDTLS_CHACHAPOLY_C) - if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20_POLY1305 ) + if ( 0 == block_size ) { - *olen = ilen; - return( mbedtls_chachapoly_update( (mbedtls_chachapoly_context *) ctx->cipher_ctx, - ilen, input, output ) ); + return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT; } -#endif if( input == output && ( ctx->unprocessed_len != 0 || ilen % block_size ) ) @@ -423,7 +334,7 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i ( ctx->operation == MBEDTLS_ENCRYPT && ilen < block_size - ctx->unprocessed_len ) ) { - mbedtls_platform_memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input, + memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input, ilen ); ctx->unprocessed_len += ilen; @@ -437,7 +348,7 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i { copy_len = block_size - ctx->unprocessed_len; - mbedtls_platform_memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input, + memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input, copy_len ); if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx, @@ -460,6 +371,11 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i */ if( 0 != ilen ) { + if( 0 == block_size ) + { + 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 @@ -472,7 +388,7 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i copy_len = block_size; } - mbedtls_platform_memcpy( ctx->unprocessed_data, &( input[ilen - copy_len] ), + memcpy( ctx->unprocessed_data, &( input[ilen - copy_len] ), copy_len ); ctx->unprocessed_len += copy_len; @@ -513,21 +429,6 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i } #endif /* MBEDTLS_CIPHER_MODE_CFB */ -#if defined(MBEDTLS_CIPHER_MODE_OFB) - if( ctx->cipher_info->mode == MBEDTLS_MODE_OFB ) - { - if( 0 != ( ret = ctx->cipher_info->base->ofb_func( ctx->cipher_ctx, - ilen, &ctx->unprocessed_len, ctx->iv, input, output ) ) ) - { - return( ret ); - } - - *olen = ilen; - - return( 0 ); - } -#endif /* MBEDTLS_CIPHER_MODE_OFB */ - #if defined(MBEDTLS_CIPHER_MODE_CTR) if( ctx->cipher_info->mode == MBEDTLS_MODE_CTR ) { @@ -544,27 +445,6 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i } #endif /* MBEDTLS_CIPHER_MODE_CTR */ -#if defined(MBEDTLS_CIPHER_MODE_XTS) - if( ctx->cipher_info->mode == MBEDTLS_MODE_XTS ) - { - if( ctx->unprocessed_len > 0 ) { - /* We can only process an entire data unit at a time. */ - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); - } - - ret = ctx->cipher_info->base->xts_func( ctx->cipher_ctx, - ctx->operation, ilen, ctx->iv, input, output ); - if( ret != 0 ) - { - return( ret ); - } - - *olen = ilen; - - return( 0 ); - } -#endif /* MBEDTLS_CIPHER_MODE_XTS */ - #if defined(MBEDTLS_CIPHER_MODE_STREAM) if( ctx->cipher_info->mode == MBEDTLS_MODE_STREAM ) { @@ -592,7 +472,7 @@ static void add_pkcs_padding( unsigned char *output, size_t output_len, size_t data_len ) { size_t padding_len = output_len - data_len; - uint_fast8_t i; + unsigned char i; for( i = 0; i < padding_len; i++ ) output[data_len + i] = (unsigned char) padding_len; @@ -602,7 +482,7 @@ static int get_pkcs_padding( unsigned char *input, size_t input_len, size_t *data_len ) { size_t i, pad_idx; - uint_fast8_t padding_len, bad = 0; + unsigned char padding_len, bad = 0; if( NULL == input || NULL == data_len ) return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); @@ -632,7 +512,7 @@ static void add_one_and_zeros_padding( unsigned char *output, size_t output_len, size_t data_len ) { size_t padding_len = output_len - data_len; - uint_fast8_t i = 0; + unsigned char i = 0; output[data_len] = 0x80; for( i = 1; i < padding_len; i++ ) @@ -643,7 +523,7 @@ static int get_one_and_zeros_padding( unsigned char *input, size_t input_len, size_t *data_len ) { size_t i; - uint_fast8_t done = 0, prev_done, bad; + unsigned char done = 0, prev_done, bad; if( NULL == input || NULL == data_len ) return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); @@ -671,7 +551,7 @@ static void add_zeros_and_len_padding( unsigned char *output, size_t output_len, size_t data_len ) { size_t padding_len = output_len - data_len; - uint_fast8_t i = 0; + unsigned char i = 0; for( i = 1; i < padding_len; i++ ) output[data_len + i - 1] = 0x00; @@ -758,30 +638,19 @@ static int get_no_padding( unsigned char *input, size_t input_len, int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx, unsigned char *output, size_t *olen ) { - CIPHER_VALIDATE_RET( ctx != NULL ); - CIPHER_VALIDATE_RET( output != NULL ); - CIPHER_VALIDATE_RET( olen != NULL ); - if( ctx->cipher_info == NULL ) + if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen ) return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); *olen = 0; if( MBEDTLS_MODE_CFB == ctx->cipher_info->mode || - MBEDTLS_MODE_OFB == ctx->cipher_info->mode || MBEDTLS_MODE_CTR == ctx->cipher_info->mode || MBEDTLS_MODE_GCM == ctx->cipher_info->mode || - MBEDTLS_MODE_XTS == ctx->cipher_info->mode || MBEDTLS_MODE_STREAM == ctx->cipher_info->mode ) { return( 0 ); } - if ( ( MBEDTLS_CIPHER_CHACHA20 == ctx->cipher_info->type ) || - ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) ) - { - return( 0 ); - } - if( MBEDTLS_MODE_ECB == ctx->cipher_info->mode ) { if( ctx->unprocessed_len != 0 ) @@ -831,8 +700,8 @@ int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx, /* Set output size for decryption */ if( MBEDTLS_DECRYPT == ctx->operation ) - return( ctx->get_padding( output, mbedtls_cipher_get_block_size( ctx ), - olen ) ); + return ctx->get_padding( output, mbedtls_cipher_get_block_size( ctx ), + olen ); /* Set output size for encryption */ *olen = mbedtls_cipher_get_block_size( ctx ); @@ -846,12 +715,10 @@ int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx, } #if defined(MBEDTLS_CIPHER_MODE_WITH_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 ) { - CIPHER_VALIDATE_RET( ctx != NULL ); - - if( NULL == ctx->cipher_info || MBEDTLS_MODE_CBC != ctx->cipher_info->mode ) + if( NULL == ctx || + MBEDTLS_MODE_CBC != ctx->cipher_info->mode ) { return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); } @@ -895,35 +762,18 @@ int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx, } #endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ -#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) +#if defined(MBEDTLS_GCM_C) int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx, unsigned char *tag, size_t tag_len ) { - CIPHER_VALIDATE_RET( ctx != NULL ); - CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL ); - if( ctx->cipher_info == NULL ) + if( NULL == ctx || NULL == ctx->cipher_info || NULL == tag ) return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); if( MBEDTLS_ENCRYPT != ctx->operation ) return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); -#if defined(MBEDTLS_GCM_C) if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) - return( mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx, - tag, tag_len ) ); -#endif - -#if defined(MBEDTLS_CHACHAPOLY_C) - if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) - { - /* Don't allow truncated MAC for Poly1305 */ - if ( tag_len != 16U ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - return( mbedtls_chachapoly_finish( (mbedtls_chachapoly_context *) ctx->cipher_ctx, - tag ) ); - } -#endif + return mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx, tag, tag_len ); return( 0 ); } @@ -931,22 +781,20 @@ int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx, int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx, const unsigned char *tag, size_t tag_len ) { - unsigned char check_tag[16]; int ret; - CIPHER_VALIDATE_RET( ctx != NULL ); - CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL ); - if( ctx->cipher_info == NULL ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - if( MBEDTLS_DECRYPT != ctx->operation ) + if( NULL == ctx || NULL == ctx->cipher_info || + MBEDTLS_DECRYPT != ctx->operation ) { return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); } -#if defined(MBEDTLS_GCM_C) if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) { + unsigned char check_tag[16]; + size_t i; + int diff; + if( tag_len > sizeof( check_tag ) ) return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); @@ -957,38 +805,18 @@ int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx, } /* Check the tag in "constant-time" */ - if( mbedtls_constant_time_memcmp( tag, check_tag, tag_len ) != 0 ) + for( diff = 0, i = 0; i < tag_len; i++ ) + diff |= tag[i] ^ check_tag[i]; + + if( diff != 0 ) return( MBEDTLS_ERR_CIPHER_AUTH_FAILED ); return( 0 ); } -#endif /* MBEDTLS_GCM_C */ - -#if defined(MBEDTLS_CHACHAPOLY_C) - if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) - { - /* Don't allow truncated MAC for Poly1305 */ - if ( tag_len != sizeof( check_tag ) ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - ret = mbedtls_chachapoly_finish( (mbedtls_chachapoly_context *) ctx->cipher_ctx, - check_tag ); - if ( ret != 0 ) - { - return( ret ); - } - - /* Check the tag in "constant-time" */ - if( mbedtls_constant_time_memcmp( tag, check_tag, tag_len ) != 0 ) - return( MBEDTLS_ERR_CIPHER_AUTH_FAILED ); - - return( 0 ); - } -#endif /* MBEDTLS_CHACHAPOLY_C */ return( 0 ); } -#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */ +#endif /* MBEDTLS_GCM_C */ /* * Packet-oriented wrapper for non-AEAD modes @@ -1001,12 +829,6 @@ int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx, int ret; size_t finish_olen; - CIPHER_VALIDATE_RET( ctx != NULL ); - CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL ); - CIPHER_VALIDATE_RET( ilen == 0 || input != NULL ); - CIPHER_VALIDATE_RET( output != NULL ); - CIPHER_VALIDATE_RET( olen != NULL ); - if( ( ret = mbedtls_cipher_set_iv( ctx, iv, iv_len ) ) != 0 ) return( ret ); @@ -1035,14 +857,6 @@ int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx, unsigned char *output, size_t *olen, unsigned char *tag, size_t tag_len ) { - CIPHER_VALIDATE_RET( ctx != NULL ); - CIPHER_VALIDATE_RET( iv != NULL ); - CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL ); - CIPHER_VALIDATE_RET( ilen == 0 || input != NULL ); - CIPHER_VALIDATE_RET( output != NULL ); - CIPHER_VALIDATE_RET( olen != NULL ); - CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL ); - #if defined(MBEDTLS_GCM_C) if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) { @@ -1061,21 +875,6 @@ int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx, tag, tag_len ) ); } #endif /* MBEDTLS_CCM_C */ -#if defined(MBEDTLS_CHACHAPOLY_C) - if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) - { - /* ChachaPoly has fixed length nonce and MAC (tag) */ - if ( ( iv_len != ctx->cipher_info->iv_size ) || - ( tag_len != 16U ) ) - { - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - - *olen = ilen; - return( mbedtls_chachapoly_encrypt_and_tag( ctx->cipher_ctx, - ilen, iv, ad, ad_len, input, output, tag ) ); - } -#endif /* MBEDTLS_CHACHAPOLY_C */ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); } @@ -1090,14 +889,6 @@ int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx, unsigned char *output, size_t *olen, const unsigned char *tag, size_t tag_len ) { - CIPHER_VALIDATE_RET( ctx != NULL ); - CIPHER_VALIDATE_RET( iv != NULL ); - CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL ); - CIPHER_VALIDATE_RET( ilen == 0 || input != NULL ); - CIPHER_VALIDATE_RET( output != NULL ); - CIPHER_VALIDATE_RET( olen != NULL ); - CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL ); - #if defined(MBEDTLS_GCM_C) if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) { @@ -1130,28 +921,6 @@ int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx, return( ret ); } #endif /* MBEDTLS_CCM_C */ -#if defined(MBEDTLS_CHACHAPOLY_C) - if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) - { - int ret; - - /* ChachaPoly has fixed length nonce and MAC (tag) */ - if ( ( iv_len != ctx->cipher_info->iv_size ) || - ( tag_len != 16U ) ) - { - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - - *olen = ilen; - ret = mbedtls_chachapoly_auth_decrypt( ctx->cipher_ctx, ilen, - iv, ad, ad_len, tag, input, output ); - - if( ret == MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED ) - ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; - - return( ret ); - } -#endif /* MBEDTLS_CHACHAPOLY_C */ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); } diff --git a/APP_Framework/Framework/security/mbedtls/cipher.h b/APP_Framework/Framework/security/mbedtls/cipher.h index cb575213b..1c453a1d3 100644 --- a/APP_Framework/Framework/security/mbedtls/cipher.h +++ b/APP_Framework/Framework/security/mbedtls/cipher.h @@ -1,9 +1,7 @@ /** * \file cipher.h * - * \brief This file contains an abstraction interface for use with the cipher - * primitives provided by the library. It provides a common interface to all of - * the available cipher operations. + * \brief The generic cipher wrapper. * * \author Adriaan de Jong */ @@ -36,9 +34,8 @@ #endif #include -#include "platform_util.h" -#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C) || defined(MBEDTLS_CHACHAPOLY_C) +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C) #define MBEDTLS_CIPHER_MODE_AEAD #endif @@ -46,8 +43,7 @@ #define MBEDTLS_CIPHER_MODE_WITH_PADDING #endif -#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER) || \ - defined(MBEDTLS_CHACHA20_C) +#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER) #define MBEDTLS_CIPHER_MODE_STREAM #endif @@ -63,8 +59,6 @@ #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_INVALID_CONTEXT -0x6380 /**< The context is invalid. For example, because it was freed. */ - -/* MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED is deprecated and should not be used. */ #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. */ @@ -75,122 +69,93 @@ extern "C" { #endif /** - * \brief Supported cipher types. + * \brief An enumeration of supported ciphers. * - * \warning RC4 and DES are considered weak ciphers and their use - * constitutes a security risk. Arm recommends considering stronger + * \warning ARC4 and DES are considered weak ciphers and their use + * constitutes a security risk. We recommend considering stronger * ciphers instead. */ typedef enum { - MBEDTLS_CIPHER_ID_NONE = 0, /**< Placeholder to mark the end of cipher ID lists. */ - MBEDTLS_CIPHER_ID_NULL, /**< The identity cipher, treated as a stream cipher. */ - MBEDTLS_CIPHER_ID_AES, /**< The AES cipher. */ - MBEDTLS_CIPHER_ID_DES, /**< The DES cipher. */ - MBEDTLS_CIPHER_ID_3DES, /**< The Triple DES cipher. */ - MBEDTLS_CIPHER_ID_CAMELLIA, /**< The Camellia cipher. */ - MBEDTLS_CIPHER_ID_BLOWFISH, /**< The Blowfish cipher. */ - MBEDTLS_CIPHER_ID_ARC4, /**< The RC4 cipher. */ - MBEDTLS_CIPHER_ID_ARIA, /**< The Aria cipher. */ - MBEDTLS_CIPHER_ID_CHACHA20, /**< The ChaCha20 cipher. */ + MBEDTLS_CIPHER_ID_NONE = 0, + MBEDTLS_CIPHER_ID_NULL, + MBEDTLS_CIPHER_ID_AES, + MBEDTLS_CIPHER_ID_DES, + MBEDTLS_CIPHER_ID_3DES, + MBEDTLS_CIPHER_ID_CAMELLIA, + MBEDTLS_CIPHER_ID_BLOWFISH, + MBEDTLS_CIPHER_ID_ARC4, } mbedtls_cipher_id_t; /** - * \brief Supported {cipher type, cipher mode} pairs. + * \brief An enumeration of supported (cipher, mode) pairs. * - * \warning RC4 and DES are considered weak ciphers and their use - * constitutes a security risk. Arm recommends considering stronger + * \warning ARC4 and DES are considered weak ciphers and their use + * constitutes a security risk. We recommend considering stronger * ciphers instead. */ typedef enum { - MBEDTLS_CIPHER_NONE = 0, /**< Placeholder to mark the end of cipher-pair lists. */ - MBEDTLS_CIPHER_NULL, /**< The identity stream cipher. */ - MBEDTLS_CIPHER_AES_128_ECB, /**< AES cipher with 128-bit ECB mode. */ - MBEDTLS_CIPHER_AES_192_ECB, /**< AES cipher with 192-bit ECB mode. */ - MBEDTLS_CIPHER_AES_256_ECB, /**< AES cipher with 256-bit ECB mode. */ - MBEDTLS_CIPHER_AES_128_CBC, /**< AES cipher with 128-bit CBC mode. */ - MBEDTLS_CIPHER_AES_192_CBC, /**< AES cipher with 192-bit CBC mode. */ - MBEDTLS_CIPHER_AES_256_CBC, /**< AES cipher with 256-bit CBC mode. */ - MBEDTLS_CIPHER_AES_128_CFB128, /**< AES cipher with 128-bit CFB128 mode. */ - MBEDTLS_CIPHER_AES_192_CFB128, /**< AES cipher with 192-bit CFB128 mode. */ - MBEDTLS_CIPHER_AES_256_CFB128, /**< AES cipher with 256-bit CFB128 mode. */ - MBEDTLS_CIPHER_AES_128_CTR, /**< AES cipher with 128-bit CTR mode. */ - MBEDTLS_CIPHER_AES_192_CTR, /**< AES cipher with 192-bit CTR mode. */ - MBEDTLS_CIPHER_AES_256_CTR, /**< AES cipher with 256-bit CTR mode. */ - MBEDTLS_CIPHER_AES_128_GCM, /**< AES cipher with 128-bit GCM mode. */ - MBEDTLS_CIPHER_AES_192_GCM, /**< AES cipher with 192-bit GCM mode. */ - MBEDTLS_CIPHER_AES_256_GCM, /**< AES cipher with 256-bit GCM mode. */ - MBEDTLS_CIPHER_CAMELLIA_128_ECB, /**< Camellia cipher with 128-bit ECB mode. */ - MBEDTLS_CIPHER_CAMELLIA_192_ECB, /**< Camellia cipher with 192-bit ECB mode. */ - MBEDTLS_CIPHER_CAMELLIA_256_ECB, /**< Camellia cipher with 256-bit ECB mode. */ - MBEDTLS_CIPHER_CAMELLIA_128_CBC, /**< Camellia cipher with 128-bit CBC mode. */ - MBEDTLS_CIPHER_CAMELLIA_192_CBC, /**< Camellia cipher with 192-bit CBC mode. */ - MBEDTLS_CIPHER_CAMELLIA_256_CBC, /**< Camellia cipher with 256-bit CBC mode. */ - MBEDTLS_CIPHER_CAMELLIA_128_CFB128, /**< Camellia cipher with 128-bit CFB128 mode. */ - MBEDTLS_CIPHER_CAMELLIA_192_CFB128, /**< Camellia cipher with 192-bit CFB128 mode. */ - MBEDTLS_CIPHER_CAMELLIA_256_CFB128, /**< Camellia cipher with 256-bit CFB128 mode. */ - MBEDTLS_CIPHER_CAMELLIA_128_CTR, /**< Camellia cipher with 128-bit CTR mode. */ - MBEDTLS_CIPHER_CAMELLIA_192_CTR, /**< Camellia cipher with 192-bit CTR mode. */ - MBEDTLS_CIPHER_CAMELLIA_256_CTR, /**< Camellia cipher with 256-bit CTR mode. */ - MBEDTLS_CIPHER_CAMELLIA_128_GCM, /**< Camellia cipher with 128-bit GCM mode. */ - MBEDTLS_CIPHER_CAMELLIA_192_GCM, /**< Camellia cipher with 192-bit GCM mode. */ - MBEDTLS_CIPHER_CAMELLIA_256_GCM, /**< Camellia cipher with 256-bit GCM mode. */ - MBEDTLS_CIPHER_DES_ECB, /**< DES cipher with ECB mode. */ - MBEDTLS_CIPHER_DES_CBC, /**< DES cipher with CBC mode. */ - MBEDTLS_CIPHER_DES_EDE_ECB, /**< DES cipher with EDE ECB mode. */ - MBEDTLS_CIPHER_DES_EDE_CBC, /**< DES cipher with EDE CBC mode. */ - MBEDTLS_CIPHER_DES_EDE3_ECB, /**< DES cipher with EDE3 ECB mode. */ - MBEDTLS_CIPHER_DES_EDE3_CBC, /**< DES cipher with EDE3 CBC mode. */ - MBEDTLS_CIPHER_BLOWFISH_ECB, /**< Blowfish cipher with ECB mode. */ - MBEDTLS_CIPHER_BLOWFISH_CBC, /**< Blowfish cipher with CBC mode. */ - MBEDTLS_CIPHER_BLOWFISH_CFB64, /**< Blowfish cipher with CFB64 mode. */ - MBEDTLS_CIPHER_BLOWFISH_CTR, /**< Blowfish cipher with CTR mode. */ - MBEDTLS_CIPHER_ARC4_128, /**< RC4 cipher with 128-bit mode. */ - MBEDTLS_CIPHER_AES_128_CCM, /**< AES cipher with 128-bit CCM mode. */ - MBEDTLS_CIPHER_AES_192_CCM, /**< AES cipher with 192-bit CCM mode. */ - MBEDTLS_CIPHER_AES_256_CCM, /**< AES cipher with 256-bit CCM mode. */ - MBEDTLS_CIPHER_CAMELLIA_128_CCM, /**< Camellia cipher with 128-bit CCM mode. */ - MBEDTLS_CIPHER_CAMELLIA_192_CCM, /**< Camellia cipher with 192-bit CCM mode. */ - MBEDTLS_CIPHER_CAMELLIA_256_CCM, /**< Camellia cipher with 256-bit CCM mode. */ - MBEDTLS_CIPHER_ARIA_128_ECB, /**< Aria cipher with 128-bit key and ECB mode. */ - MBEDTLS_CIPHER_ARIA_192_ECB, /**< Aria cipher with 192-bit key and ECB mode. */ - MBEDTLS_CIPHER_ARIA_256_ECB, /**< Aria cipher with 256-bit key and ECB mode. */ - MBEDTLS_CIPHER_ARIA_128_CBC, /**< Aria cipher with 128-bit key and CBC mode. */ - MBEDTLS_CIPHER_ARIA_192_CBC, /**< Aria cipher with 192-bit key and CBC mode. */ - MBEDTLS_CIPHER_ARIA_256_CBC, /**< Aria cipher with 256-bit key and CBC mode. */ - MBEDTLS_CIPHER_ARIA_128_CFB128, /**< Aria cipher with 128-bit key and CFB-128 mode. */ - MBEDTLS_CIPHER_ARIA_192_CFB128, /**< Aria cipher with 192-bit key and CFB-128 mode. */ - MBEDTLS_CIPHER_ARIA_256_CFB128, /**< Aria cipher with 256-bit key and CFB-128 mode. */ - MBEDTLS_CIPHER_ARIA_128_CTR, /**< Aria cipher with 128-bit key and CTR mode. */ - MBEDTLS_CIPHER_ARIA_192_CTR, /**< Aria cipher with 192-bit key and CTR mode. */ - MBEDTLS_CIPHER_ARIA_256_CTR, /**< Aria cipher with 256-bit key and CTR mode. */ - MBEDTLS_CIPHER_ARIA_128_GCM, /**< Aria cipher with 128-bit key and GCM mode. */ - MBEDTLS_CIPHER_ARIA_192_GCM, /**< Aria cipher with 192-bit key and GCM mode. */ - MBEDTLS_CIPHER_ARIA_256_GCM, /**< Aria cipher with 256-bit key and GCM mode. */ - MBEDTLS_CIPHER_ARIA_128_CCM, /**< Aria cipher with 128-bit key and CCM mode. */ - MBEDTLS_CIPHER_ARIA_192_CCM, /**< Aria cipher with 192-bit key and CCM mode. */ - MBEDTLS_CIPHER_ARIA_256_CCM, /**< Aria cipher with 256-bit key and CCM mode. */ - MBEDTLS_CIPHER_AES_128_OFB, /**< AES 128-bit cipher in OFB mode. */ - MBEDTLS_CIPHER_AES_192_OFB, /**< AES 192-bit cipher in OFB mode. */ - MBEDTLS_CIPHER_AES_256_OFB, /**< AES 256-bit cipher in OFB mode. */ - MBEDTLS_CIPHER_AES_128_XTS, /**< AES 128-bit cipher in XTS block mode. */ - MBEDTLS_CIPHER_AES_256_XTS, /**< AES 256-bit cipher in XTS block mode. */ - MBEDTLS_CIPHER_CHACHA20, /**< ChaCha20 stream cipher. */ - MBEDTLS_CIPHER_CHACHA20_POLY1305, /**< ChaCha20-Poly1305 AEAD cipher. */ + MBEDTLS_CIPHER_NONE = 0, + MBEDTLS_CIPHER_NULL, + MBEDTLS_CIPHER_AES_128_ECB, + MBEDTLS_CIPHER_AES_192_ECB, + MBEDTLS_CIPHER_AES_256_ECB, + MBEDTLS_CIPHER_AES_128_CBC, + MBEDTLS_CIPHER_AES_192_CBC, + MBEDTLS_CIPHER_AES_256_CBC, + MBEDTLS_CIPHER_AES_128_CFB128, + MBEDTLS_CIPHER_AES_192_CFB128, + MBEDTLS_CIPHER_AES_256_CFB128, + MBEDTLS_CIPHER_AES_128_CTR, + MBEDTLS_CIPHER_AES_192_CTR, + MBEDTLS_CIPHER_AES_256_CTR, + MBEDTLS_CIPHER_AES_128_GCM, + MBEDTLS_CIPHER_AES_192_GCM, + MBEDTLS_CIPHER_AES_256_GCM, + MBEDTLS_CIPHER_CAMELLIA_128_ECB, + MBEDTLS_CIPHER_CAMELLIA_192_ECB, + MBEDTLS_CIPHER_CAMELLIA_256_ECB, + MBEDTLS_CIPHER_CAMELLIA_128_CBC, + MBEDTLS_CIPHER_CAMELLIA_192_CBC, + MBEDTLS_CIPHER_CAMELLIA_256_CBC, + MBEDTLS_CIPHER_CAMELLIA_128_CFB128, + MBEDTLS_CIPHER_CAMELLIA_192_CFB128, + MBEDTLS_CIPHER_CAMELLIA_256_CFB128, + MBEDTLS_CIPHER_CAMELLIA_128_CTR, + MBEDTLS_CIPHER_CAMELLIA_192_CTR, + MBEDTLS_CIPHER_CAMELLIA_256_CTR, + MBEDTLS_CIPHER_CAMELLIA_128_GCM, + MBEDTLS_CIPHER_CAMELLIA_192_GCM, + MBEDTLS_CIPHER_CAMELLIA_256_GCM, + MBEDTLS_CIPHER_DES_ECB, + MBEDTLS_CIPHER_DES_CBC, + MBEDTLS_CIPHER_DES_EDE_ECB, + MBEDTLS_CIPHER_DES_EDE_CBC, + MBEDTLS_CIPHER_DES_EDE3_ECB, + MBEDTLS_CIPHER_DES_EDE3_CBC, + MBEDTLS_CIPHER_BLOWFISH_ECB, + MBEDTLS_CIPHER_BLOWFISH_CBC, + MBEDTLS_CIPHER_BLOWFISH_CFB64, + MBEDTLS_CIPHER_BLOWFISH_CTR, + MBEDTLS_CIPHER_ARC4_128, + MBEDTLS_CIPHER_AES_128_CCM, + MBEDTLS_CIPHER_AES_192_CCM, + MBEDTLS_CIPHER_AES_256_CCM, + MBEDTLS_CIPHER_CAMELLIA_128_CCM, + MBEDTLS_CIPHER_CAMELLIA_192_CCM, + MBEDTLS_CIPHER_CAMELLIA_256_CCM, } mbedtls_cipher_type_t; /** Supported cipher modes. */ typedef enum { - MBEDTLS_MODE_NONE = 0, /**< None. */ - MBEDTLS_MODE_ECB, /**< The ECB cipher mode. */ - MBEDTLS_MODE_CBC, /**< The CBC cipher mode. */ - MBEDTLS_MODE_CFB, /**< The CFB cipher mode. */ - MBEDTLS_MODE_OFB, /**< The OFB cipher mode. */ - MBEDTLS_MODE_CTR, /**< The CTR cipher mode. */ - MBEDTLS_MODE_GCM, /**< The GCM cipher mode. */ - MBEDTLS_MODE_STREAM, /**< The stream cipher mode. */ - MBEDTLS_MODE_CCM, /**< The CCM cipher mode. */ - MBEDTLS_MODE_XTS, /**< The XTS cipher mode. */ - MBEDTLS_MODE_CHACHAPOLY, /**< The ChaCha-Poly cipher mode. */ + MBEDTLS_MODE_NONE = 0, + MBEDTLS_MODE_ECB, + MBEDTLS_MODE_CBC, + MBEDTLS_MODE_CFB, + MBEDTLS_MODE_OFB, /* Unused! */ + MBEDTLS_MODE_CTR, + MBEDTLS_MODE_GCM, + MBEDTLS_MODE_STREAM, + MBEDTLS_MODE_CCM, } mbedtls_cipher_mode_t; /** Supported cipher padding types. */ @@ -198,8 +163,8 @@ typedef enum { MBEDTLS_PADDING_PKCS7 = 0, /**< PKCS7 padding (default). */ MBEDTLS_PADDING_ONE_AND_ZEROS, /**< ISO/IEC 7816-4 padding. */ MBEDTLS_PADDING_ZEROS_AND_LEN, /**< ANSI X.923 padding. */ - MBEDTLS_PADDING_ZEROS, /**< Zero padding (not reversible). */ - MBEDTLS_PADDING_NONE, /**< Never pad (full blocks only). */ + MBEDTLS_PADDING_ZEROS, /**< zero padding (not reversible). */ + MBEDTLS_PADDING_NONE, /**< never pad (full blocks only). */ } mbedtls_cipher_padding_t; /** Type of operation. */ @@ -239,8 +204,7 @@ typedef struct mbedtls_cmac_context_t mbedtls_cmac_context_t; * Cipher information. Allows calling cipher functions * in a generic way. */ -typedef struct mbedtls_cipher_info_t -{ +typedef struct { /** Full cipher identifier. For example, * MBEDTLS_CIPHER_AES_256_CBC. */ @@ -264,10 +228,7 @@ typedef struct mbedtls_cipher_info_t */ unsigned int iv_size; - /** Bitflag comprised of MBEDTLS_CIPHER_VARIABLE_IV_LEN and - * MBEDTLS_CIPHER_VARIABLE_KEY_LEN indicating whether the - * cipher supports variable IV or variable key sizes, respectively. - */ + /** Flags to set. For example, if the cipher supports variable IV sizes or variable key sizes. */ int flags; /** The block size, in Bytes. */ @@ -281,19 +242,18 @@ typedef struct mbedtls_cipher_info_t /** * Generic cipher context. */ -typedef struct mbedtls_cipher_context_t -{ - /** Operation that the key of the context has been - * initialized for. - */ - mbedtls_operation_t operation; - +typedef struct { /** Information about the associated cipher. */ const mbedtls_cipher_info_t *cipher_info; /** Key length to use. */ int key_bitlen; + /** Operation that the key of the context has been + * initialized for. + */ + mbedtls_operation_t operation; + #if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) /** Padding functions to use, if relevant for * the specific cipher mode. @@ -302,9 +262,15 @@ typedef struct mbedtls_cipher_context_t int (*get_padding)( unsigned char *input, size_t ilen, size_t *data_len ); #endif + /** Buffer for input that has not been processed yet. */ + unsigned char unprocessed_data[MBEDTLS_MAX_BLOCK_LENGTH]; + /** Number of Bytes that have not been processed yet. */ size_t unprocessed_len; + /** Current IV or NONCE_COUNTER for CTR-mode. */ + unsigned char iv[MBEDTLS_MAX_IV_LENGTH]; + /** IV size in Bytes, for ciphers with variable-length IVs. */ size_t iv_size; @@ -315,13 +281,6 @@ typedef struct mbedtls_cipher_context_t /** CMAC-specific context. */ mbedtls_cmac_context_t *cmac_ctx; #endif - - /** Buffer for input that has not been processed yet. */ - unsigned char unprocessed_data[MBEDTLS_MAX_BLOCK_LENGTH]; - - /** Current IV or NONCE_COUNTER for CTR-mode, data unit (or sector) number - * for XTS-mode. */ - unsigned char iv[MBEDTLS_MAX_IV_LENGTH]; } mbedtls_cipher_context_t; /** @@ -337,12 +296,10 @@ const int *mbedtls_cipher_list( void ); * \brief This function retrieves the cipher-information * structure associated with the given cipher name. * - * \param cipher_name Name of the cipher to search for. This must not be - * \c NULL. + * \param cipher_name Name of the cipher to search for. * * \return The cipher information structure associated with the - * given \p cipher_name. - * \return \c NULL if the associated cipher information is 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 ); @@ -353,8 +310,7 @@ const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string( const char *cipher * \param cipher_type Type of the cipher to search for. * * \return The cipher information structure associated with the - * given \p cipher_type. - * \return \c NULL if the associated cipher information is 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 ); @@ -369,8 +325,7 @@ const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type( const mbedtls_cipher * \param mode The cipher mode. For example, #MBEDTLS_MODE_CBC. * * \return The cipher information structure associated with the - * given \p cipher_id. - * \return \c NULL if the associated cipher information is 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, int key_bitlen, @@ -378,8 +333,6 @@ const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values( const mbedtls_ciph /** * \brief This function initializes a \p cipher_context as NONE. - * - * \param ctx The context to be initialized. This must not be \c NULL. */ void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx ); @@ -387,10 +340,6 @@ void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx ); * \brief This function frees and clears the cipher-specific * context of \p ctx. Freeing \p ctx itself remains the * responsibility of the caller. - * - * \param ctx The context to be freed. If this is \c NULL, the - * function has no effect, otherwise this must point to an - * initialized context. */ void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx ); @@ -400,35 +349,31 @@ void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx ); * structure with the appropriate values. It also clears * the structure. * - * \param ctx The context to initialize. This must be initialized. + * \param ctx The context to initialize. May not be NULL. * \param cipher_info The cipher to use. * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on - * parameter-verification failure. - * \return #MBEDTLS_ERR_CIPHER_ALLOC_FAILED if allocation of the - * cipher-specific context fails. + * \return \c 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. * * \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 This function returns the block size of the given cipher. * - * \param ctx The context of the cipher. This must be initialized. + * \param ctx The context of the cipher. Must be initialized. * - * \return The block size of the underlying cipher. - * \return \c 0 if \p ctx has not been initialized. + * \return The size of the blocks of the cipher, or zero if \p ctx + * 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 ) { - MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, 0 ); - if( ctx->cipher_info == NULL ) + if( NULL == ctx || NULL == ctx->cipher_info ) return 0; return ctx->cipher_info->block_size; @@ -438,16 +383,14 @@ static inline unsigned int mbedtls_cipher_get_block_size( * \brief This function returns the mode of operation for * the cipher. For example, MBEDTLS_MODE_CBC. * - * \param ctx The context of the cipher. This must be initialized. + * \param ctx The context of the cipher. Must be initialized. * - * \return The mode of operation. - * \return #MBEDTLS_MODE_NONE if \p ctx has not been initialized. + * \return The mode of operation, or #MBEDTLS_MODE_NONE if + * \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 ) { - MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, MBEDTLS_MODE_NONE ); - if( ctx->cipher_info == NULL ) + if( NULL == ctx || NULL == ctx->cipher_info ) return MBEDTLS_MODE_NONE; return ctx->cipher_info->mode; @@ -457,17 +400,15 @@ static inline mbedtls_cipher_mode_t mbedtls_cipher_get_cipher_mode( * \brief This function returns the size of the IV or nonce * of the cipher, in Bytes. * - * \param ctx The context of the cipher. This must be initialized. + * \param ctx The context of the cipher. Must be initialized. * - * \return The recommended IV size if no IV has been set. - * \return \c 0 for ciphers not using an IV or a nonce. - * \return The actual size if an IV has been set. + * \return
    • If no IV has been set: the recommended IV size. + * 0 for ciphers not using IV or nonce.
    • + *
    • If IV has already been set: the actual size.
    */ -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 ) { - MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, 0 ); - if( ctx->cipher_info == NULL ) + if( NULL == ctx || NULL == ctx->cipher_info ) return 0; if( ctx->iv_size != 0 ) @@ -479,17 +420,14 @@ static inline int mbedtls_cipher_get_iv_size( /** * \brief This function returns the type of the given cipher. * - * \param ctx The context of the cipher. This must be initialized. + * \param ctx The context of the cipher. Must be initialized. * - * \return The type of the cipher. - * \return #MBEDTLS_CIPHER_NONE if \p ctx has not been initialized. + * \return The type of the cipher, or #MBEDTLS_CIPHER_NONE if + * \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 ) { - MBEDTLS_INTERNAL_VALIDATE_RET( - ctx != NULL, MBEDTLS_CIPHER_NONE ); - if( ctx->cipher_info == NULL ) + if( NULL == ctx || NULL == ctx->cipher_info ) return MBEDTLS_CIPHER_NONE; return ctx->cipher_info->type; @@ -499,16 +437,14 @@ static inline mbedtls_cipher_type_t mbedtls_cipher_get_type( * \brief This function returns the name of the given cipher * as a string. * - * \param ctx The context of the cipher. This must be initialized. + * \param ctx The context of the cipher. Must be initialized. * - * \return The name of the cipher. - * \return NULL if \p ctx has not been not initialized. + * \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 ) { - MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, 0 ); - if( ctx->cipher_info == NULL ) + if( NULL == ctx || NULL == ctx->cipher_info ) return 0; return ctx->cipher_info->name; @@ -517,18 +453,15 @@ static inline const char *mbedtls_cipher_get_name( /** * \brief This function returns the key length of the cipher. * - * \param ctx The context of the cipher. This must be initialized. + * \param ctx The context of the cipher. Must be initialized. * - * \return The key length of the cipher in bits. - * \return #MBEDTLS_KEY_LENGTH_NONE if ctx \p has not been + * \return The key length of the cipher in bits, or + * #MBEDTLS_KEY_LENGTH_NONE if ctx \p has not been * 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 ) { - MBEDTLS_INTERNAL_VALIDATE_RET( - ctx != NULL, MBEDTLS_KEY_LENGTH_NONE ); - if( ctx->cipher_info == NULL ) + if( NULL == ctx || NULL == ctx->cipher_info ) return MBEDTLS_KEY_LENGTH_NONE; return (int) ctx->cipher_info->key_bitlen; @@ -537,17 +470,15 @@ static inline int mbedtls_cipher_get_key_bitlen( /** * \brief This function returns the operation of the given cipher. * - * \param ctx The context of the cipher. This must be initialized. + * \param ctx The context of the cipher. Must be initialized. * - * \return The type of operation: #MBEDTLS_ENCRYPT or #MBEDTLS_DECRYPT. - * \return #MBEDTLS_OPERATION_NONE if \p ctx has not been initialized. + * \return The type of operation: #MBEDTLS_ENCRYPT or + * #MBEDTLS_DECRYPT, or #MBEDTLS_OPERATION_NONE if \p ctx + * 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 ) { - MBEDTLS_INTERNAL_VALIDATE_RET( - ctx != NULL, MBEDTLS_OPERATION_NONE ); - if( ctx->cipher_info == NULL ) + if( NULL == ctx || NULL == ctx->cipher_info ) return MBEDTLS_OPERATION_NONE; return ctx->operation; @@ -556,23 +487,20 @@ static inline mbedtls_operation_t mbedtls_cipher_get_operation( /** * \brief This function sets the key to use with the given context. * - * \param ctx The generic cipher context. This must be initialized and - * bound to a cipher information structure. - * \param key The key to use. This must be a readable buffer of at - * least \p key_bitlen Bits. - * \param key_bitlen The key length to use, in Bits. + * \param ctx The generic cipher context. May not be NULL. Must have + * been initialized using mbedtls_cipher_info_from_type() + * or mbedtls_cipher_info_from_string(). + * \param key The key to use. + * \param key_bitlen The key length to use, in bits. * \param operation The operation that the key will be used for: * #MBEDTLS_ENCRYPT or #MBEDTLS_DECRYPT. * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on - * parameter-verification failure. - * \return A cipher-specific error code on failure. + * \returns \c 0 on success, #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if + * parameter verification fails, or a cipher-specific + * error code. */ -int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx, - const unsigned char *key, - int key_bitlen, - const mbedtls_operation_t operation ); +int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx, const unsigned char *key, + int key_bitlen, const mbedtls_operation_t operation ); #if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) /** @@ -581,71 +509,59 @@ int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx, * * The default passing mode is PKCS7 padding. * - * \param ctx The generic cipher context. This must be initialized and - * bound to a cipher information structure. + * \param ctx The generic cipher context. * \param mode The padding mode. * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE - * if the selected padding mode is not supported. - * \return #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. */ -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 */ /** * \brief This function sets the initialization vector (IV) * or nonce. * - * \note Some ciphers do not use IVs nor nonce. For these - * ciphers, this function has no effect. - * - * \param ctx The generic cipher context. This must be initialized and - * bound to a cipher information structure. - * \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers. This - * must be a readable buffer of at least \p iv_len Bytes. + * \param ctx The generic cipher context. + * \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers. * \param iv_len The IV length for ciphers with variable-size IV. * This parameter is discarded by ciphers with fixed-size IV. * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on - * parameter-verification failure. + * \returns \c 0 on success, or #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA + * + * \note Some ciphers do not use IVs nor nonce. For these + * ciphers, this function has no effect. */ 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 This function resets the cipher state. * - * \param ctx The generic cipher context. This must be initialized. + * \param ctx The generic cipher context. * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on - * parameter-verification failure. + * \returns \c 0 on success, #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA + * if parameter verification fails. */ int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx ); -#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) +#if defined(MBEDTLS_GCM_C) /** * \brief This function adds additional data for AEAD ciphers. - * Currently supported with GCM and ChaCha20+Poly1305. - * This must be called exactly once, after - * mbedtls_cipher_reset(). + * Only supported with GCM. Must be called + * exactly once, after mbedtls_cipher_reset(). * - * \param ctx The generic cipher context. This must be initialized. - * \param ad The additional data to use. This must be a readable - * buffer of at least \p ad_len Bytes. - * \param ad_len the Length of \p ad Bytes. + * \param ctx The generic cipher context. + * \param ad The additional data to use. + * \param ad_len the Length of \p ad. * - * \return \c 0 on success. - * \return A specific error code on failure. + * \return \c 0 on success, or a specific error code on failure. */ int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx, const unsigned char *ad, size_t ad_len ); -#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */ +#endif /* MBEDTLS_GCM_C */ /** * \brief The generic cipher update function. It encrypts or @@ -657,29 +573,25 @@ int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx, * Exception: For MBEDTLS_MODE_ECB, expects a single block * in size. For example, 16 Bytes for AES. * - * \note If the underlying cipher is used in GCM mode, all calls - * to this function, except for the last one before - * mbedtls_cipher_finish(), must have \p ilen as a - * multiple of the block size of the cipher. - * - * \param ctx The generic cipher context. This must be initialized and - * bound to a key. - * \param input The buffer holding the input data. This must be a - * readable buffer of at least \p ilen Bytes. + * \param ctx The generic cipher context. + * \param input The buffer holding the input data. * \param ilen The length of the input data. - * \param output The buffer for the output data. This must be able to - * hold at least `ilen + block_size`. This must not be the - * same buffer as \p input. + * \param output The buffer for the output data. Must be able to hold at + * least \p ilen + block_size. Must not be the same buffer + * as input. * \param olen The length of the output data, to be updated with the - * actual number of Bytes written. This must not be - * \c NULL. + * actual number of Bytes written. * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on - * parameter-verification failure. - * \return #MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE on an - * unsupported mode for a cipher. - * \return A cipher-specific error code on failure. + * \returns \c 0 on success, #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if + * parameter verification fails, + * #MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE on an + * unsupported mode for a cipher, or a cipher-specific + * error code. + * + * \note If the underlying cipher is GCM, all calls to this + * function, except the last one before + * 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, size_t ilen, unsigned char *output, size_t *olen ); @@ -690,94 +602,78 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i * contained in it is padded to the size of * the last block, and written to the \p output buffer. * - * \param ctx The generic cipher context. This must be initialized and - * bound to a key. - * \param output The buffer to write data to. This needs to be a writable - * buffer of at least \p block_size Bytes. + * \param ctx The generic cipher context. + * \param output The buffer to write data to. Needs block_size available. * \param olen The length of the data written to the \p output buffer. - * This may not be \c NULL. * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on - * parameter-verification failure. - * \return #MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED on decryption - * expecting a full block but not receiving one. - * \return #MBEDTLS_ERR_CIPHER_INVALID_PADDING on invalid padding - * while decrypting. - * \return A cipher-specific error code on failure. + * \returns \c 0 on success, #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if + * parameter verification fails, + * #MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED if decryption + * expected a full block but was not provided one, + * #MBEDTLS_ERR_CIPHER_INVALID_PADDING on invalid padding + * while decrypting, or a cipher-specific error code + * on failure for any other reason. */ int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx, unsigned char *output, size_t *olen ); -#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) +#if defined(MBEDTLS_GCM_C) /** * \brief This function writes a tag for AEAD ciphers. - * Currently supported with GCM and ChaCha20+Poly1305. - * This must be called after mbedtls_cipher_finish(). + * Only supported with GCM. + * Must be called after mbedtls_cipher_finish(). * - * \param ctx The generic cipher context. This must be initialized, - * bound to a key, and have just completed a cipher - * operation through mbedtls_cipher_finish() the tag for - * which should be written. - * \param tag The buffer to write the tag to. This must be a writable - * buffer of at least \p tag_len Bytes. + * \param ctx The generic cipher context. + * \param tag The buffer to write the tag to. * \param tag_len The length of the tag to write. * - * \return \c 0 on success. - * \return A specific error code on failure. + * \return \c 0 on success, or a specific error code on failure. */ int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx, unsigned char *tag, size_t tag_len ); /** * \brief This function checks the tag for AEAD ciphers. - * Currently supported with GCM and ChaCha20+Poly1305. - * This must be called after mbedtls_cipher_finish(). + * Only supported with GCM. + * Must be called after mbedtls_cipher_finish(). * - * \param ctx The generic cipher context. This must be initialized. - * \param tag The buffer holding the tag. This must be a readable - * buffer of at least \p tag_len Bytes. + * \param ctx The generic cipher context. + * \param tag The buffer holding the tag. * \param tag_len The length of the tag to check. * - * \return \c 0 on success. - * \return A specific error code on failure. + * \return \c 0 on success, or a specific error code on failure. */ int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx, const unsigned char *tag, size_t tag_len ); -#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */ +#endif /* MBEDTLS_GCM_C */ /** * \brief The generic all-in-one encryption/decryption function, * for all ciphers except AEAD constructs. * - * \param ctx The generic cipher context. This must be initialized. + * \param ctx The generic cipher context. * \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers. - * This must be a readable buffer of at least \p iv_len - * Bytes. * \param iv_len The IV length for ciphers with variable-size IV. * This parameter is discarded by ciphers with fixed-size * IV. - * \param input The buffer holding the input data. This must be a - * readable buffer of at least \p ilen Bytes. - * \param ilen The length of the input data in Bytes. - * \param output The buffer for the output data. This must be able to - * hold at least `ilen + block_size`. This must not be the - * same buffer as \p input. + * \param input The buffer holding the input data. + * \param ilen The length of the input data. + * \param output The buffer for the output data. Must be able to hold at + * least \p ilen + block_size. Must not be the same buffer + * as input. * \param olen The length of the output data, to be updated with the - * actual number of Bytes written. This must not be - * \c NULL. + * actual number of Bytes written. * * \note Some ciphers do not use IVs nor nonce. For these * ciphers, use \p iv = NULL and \p iv_len = 0. * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on - * parameter-verification failure. - * \return #MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED on decryption - * expecting a full block but not receiving one. - * \return #MBEDTLS_ERR_CIPHER_INVALID_PADDING on invalid padding - * while decrypting. - * \return A cipher-specific error code on failure. + * \returns \c 0 on success, or + * #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA, or + * #MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED if decryption + * expected a full block but was not provided one, or + * #MBEDTLS_ERR_CIPHER_INVALID_PADDING on invalid padding + * while decrypting, or a cipher-specific error code on + * failure for any other reason. */ int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx, const unsigned char *iv, size_t iv_len, @@ -788,32 +684,24 @@ int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx, /** * \brief The generic autenticated encryption (AEAD) function. * - * \param ctx The generic cipher context. This must be initialized and - * bound to a key. + * \param ctx The generic cipher context. * \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers. - * This must be a readable buffer of at least \p iv_len - * Bytes. * \param iv_len The IV length for ciphers with variable-size IV. * This parameter is discarded by ciphers with fixed-size IV. - * \param ad The additional data to authenticate. This must be a - * readable buffer of at least \p ad_len Bytes. + * \param ad The additional data to authenticate. * \param ad_len The length of \p ad. - * \param input The buffer holding the input data. This must be a - * readable buffer of at least \p ilen Bytes. + * \param input The buffer holding the input data. * \param ilen The length of the input data. - * \param output The buffer for the output data. This must be able to - * hold at least \p ilen Bytes. + * \param output The buffer for the output data. + * Must be able to hold at least \p ilen. * \param olen The length of the output data, to be updated with the - * actual number of Bytes written. This must not be - * \c NULL. - * \param tag The buffer for the authentication tag. This must be a - * writable buffer of at least \p tag_len Bytes. + * actual number of Bytes written. + * \param tag The buffer for the authentication tag. * \param tag_len The desired length of the authentication tag. * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on - * parameter-verification failure. - * \return A cipher-specific error code on failure. + * \returns \c 0 on success, or + * #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA, or + * a cipher-specific error code. */ int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx, const unsigned char *iv, size_t iv_len, @@ -825,37 +713,29 @@ int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx, /** * \brief The generic autenticated decryption (AEAD) function. * + * \param ctx The generic cipher context. + * \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers. + * \param iv_len The IV length for ciphers with variable-size IV. + * This parameter is discarded by ciphers with fixed-size IV. + * \param ad The additional data to be authenticated. + * \param ad_len The length of \p ad. + * \param input The buffer holding the input data. + * \param ilen The length of the input data. + * \param output The buffer for the output data. + * Must be able to hold at least \p ilen. + * \param olen The length of the output data, to be updated with the + * actual number of Bytes written. + * \param tag The buffer holding the authentication tag. + * \param tag_len The length of the authentication tag. + * + * \returns \c 0 on success, or + * #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA, or + * #MBEDTLS_ERR_CIPHER_AUTH_FAILED if data is not authentic, + * or a cipher-specific error code on failure for any other reason. + * * \note If the data is not authentic, then the output buffer * is zeroed out to prevent the unauthentic plaintext being * used, making this interface safer. - * - * \param ctx The generic cipher context. This must be initialized and - * and bound to a key. - * \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers. - * This must be a readable buffer of at least \p iv_len - * Bytes. - * \param iv_len The IV length for ciphers with variable-size IV. - * This parameter is discarded by ciphers with fixed-size IV. - * \param ad The additional data to be authenticated. This must be a - * readable buffer of at least \p ad_len Bytes. - * \param ad_len The length of \p ad. - * \param input The buffer holding the input data. This must be a - * readable buffer of at least \p ilen Bytes. - * \param ilen The length of the input data. - * \param output The buffer for the output data. - * This must be able to hold at least \p ilen Bytes. - * \param olen The length of the output data, to be updated with the - * actual number of Bytes written. This must not be - * \c NULL. - * \param tag The buffer holding the authentication tag. This must be - * a readable buffer of at least \p tag_len Bytes. - * \param tag_len The length of the authentication tag. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on - * parameter-verification failure. - * \return #MBEDTLS_ERR_CIPHER_AUTH_FAILED if data is not authentic. - * \return A cipher-specific error code on failure. */ int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx, const unsigned char *iv, size_t iv_len, diff --git a/APP_Framework/Framework/security/mbedtls/cipher_internal.h b/APP_Framework/Framework/security/mbedtls/cipher_internal.h index c6def0bef..969ff9ccb 100644 --- a/APP_Framework/Framework/security/mbedtls/cipher_internal.h +++ b/APP_Framework/Framework/security/mbedtls/cipher_internal.h @@ -64,14 +64,6 @@ struct mbedtls_cipher_base_t unsigned char *output ); #endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - /** Encrypt using OFB (Full length) */ - int (*ofb_func)( void *ctx, size_t length, size_t *iv_off, - unsigned char *iv, - const unsigned char *input, - unsigned char *output ); -#endif - #if defined(MBEDTLS_CIPHER_MODE_CTR) /** Encrypt using CTR */ int (*ctr_func)( void *ctx, size_t length, size_t *nc_off, @@ -79,13 +71,6 @@ struct mbedtls_cipher_base_t const unsigned char *input, unsigned char *output ); #endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - /** Encrypt or decrypt using XTS. */ - int (*xts_func)( void *ctx, mbedtls_operation_t mode, size_t length, - const unsigned char data_unit[16], - const unsigned char *input, unsigned char *output ); -#endif - #if defined(MBEDTLS_CIPHER_MODE_STREAM) /** Encrypt using STREAM */ int (*stream_func)( void *ctx, size_t length, diff --git a/APP_Framework/Framework/security/mbedtls/cipher_wrap.c b/APP_Framework/Framework/security/mbedtls/cipher_wrap.c new file mode 100644 index 000000000..a2931ab24 --- /dev/null +++ b/APP_Framework/Framework/security/mbedtls/cipher_wrap.c @@ -0,0 +1,1451 @@ +/** + * \file cipher_wrap.c + * + * \brief Generic cipher wrapper for mbed TLS + * + * \author Adriaan de Jong + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_CIPHER_C) + +#include "cipher_internal.h" + +#if defined(MBEDTLS_AES_C) +#include "aes.h" +#endif + +#if defined(MBEDTLS_ARC4_C) +#include "arc4.h" +#endif + +#if defined(MBEDTLS_CAMELLIA_C) +#include "camellia.h" +#endif + +#if defined(MBEDTLS_DES_C) +#include "des.h" +#endif + +#if defined(MBEDTLS_BLOWFISH_C) +#include "blowfish.h" +#endif + +#if defined(MBEDTLS_GCM_C) +#include "gcm.h" +#endif + +#if defined(MBEDTLS_CCM_C) +#include "ccm.h" +#endif + +#if defined(MBEDTLS_CIPHER_NULL_CIPHER) +#include +#endif + +#if defined(MBEDTLS_PLATFORM_C) +#include "platform.h" +#else +#include +#define mbedtls_calloc calloc +#define mbedtls_free free +#endif + +#if defined(MBEDTLS_GCM_C) +/* shared by all GCM ciphers */ +static void *gcm_ctx_alloc( void ) +{ + void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_gcm_context ) ); + + if( ctx != NULL ) + mbedtls_gcm_init( (mbedtls_gcm_context *) ctx ); + + return( ctx ); +} + +static void gcm_ctx_free( void *ctx ) +{ + mbedtls_gcm_free( ctx ); + mbedtls_free( ctx ); +} +#endif /* MBEDTLS_GCM_C */ + +#if defined(MBEDTLS_CCM_C) +/* shared by all CCM ciphers */ +static void *ccm_ctx_alloc( void ) +{ + void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ccm_context ) ); + + if( ctx != NULL ) + mbedtls_ccm_init( (mbedtls_ccm_context *) ctx ); + + return( ctx ); +} + +static void ccm_ctx_free( void *ctx ) +{ + mbedtls_ccm_free( ctx ); + mbedtls_free( ctx ); +} +#endif /* MBEDTLS_CCM_C */ + +#if defined(MBEDTLS_AES_C) + +static int aes_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation, + const unsigned char *input, unsigned char *output ) +{ + return mbedtls_aes_crypt_ecb( (mbedtls_aes_context *) ctx, operation, input, output ); +} + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static int aes_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, size_t length, + unsigned char *iv, const unsigned char *input, unsigned char *output ) +{ + return mbedtls_aes_crypt_cbc( (mbedtls_aes_context *) ctx, operation, length, iv, input, + output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +static int aes_crypt_cfb128_wrap( void *ctx, mbedtls_operation_t operation, + size_t length, size_t *iv_off, unsigned char *iv, + const unsigned char *input, unsigned char *output ) +{ + return mbedtls_aes_crypt_cfb128( (mbedtls_aes_context *) ctx, operation, length, iv_off, iv, + input, output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +static int aes_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off, + unsigned char *nonce_counter, unsigned char *stream_block, + const unsigned char *input, unsigned char *output ) +{ + return mbedtls_aes_crypt_ctr( (mbedtls_aes_context *) ctx, length, nc_off, nonce_counter, + stream_block, input, output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +static int aes_setkey_dec_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + return mbedtls_aes_setkey_dec( (mbedtls_aes_context *) ctx, key, key_bitlen ); +} + +static int aes_setkey_enc_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + return mbedtls_aes_setkey_enc( (mbedtls_aes_context *) ctx, key, key_bitlen ); +} + +static void * aes_ctx_alloc( void ) +{ + mbedtls_aes_context *aes = mbedtls_calloc( 1, sizeof( mbedtls_aes_context ) ); + + if( aes == NULL ) + return( NULL ); + + mbedtls_aes_init( aes ); + + return( aes ); +} + +static void aes_ctx_free( void *ctx ) +{ + mbedtls_aes_free( (mbedtls_aes_context *) ctx ); + mbedtls_free( ctx ); +} + +static const mbedtls_cipher_base_t aes_info = { + MBEDTLS_CIPHER_ID_AES, + aes_crypt_ecb_wrap, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + aes_crypt_cbc_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + aes_crypt_cfb128_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + aes_crypt_ctr_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + aes_setkey_enc_wrap, + aes_setkey_dec_wrap, + aes_ctx_alloc, + aes_ctx_free +}; + +static const mbedtls_cipher_info_t aes_128_ecb_info = { + MBEDTLS_CIPHER_AES_128_ECB, + MBEDTLS_MODE_ECB, + 128, + "AES-128-ECB", + 0, + 0, + 16, + &aes_info +}; + +static const mbedtls_cipher_info_t aes_192_ecb_info = { + MBEDTLS_CIPHER_AES_192_ECB, + MBEDTLS_MODE_ECB, + 192, + "AES-192-ECB", + 0, + 0, + 16, + &aes_info +}; + +static const mbedtls_cipher_info_t aes_256_ecb_info = { + MBEDTLS_CIPHER_AES_256_ECB, + MBEDTLS_MODE_ECB, + 256, + "AES-256-ECB", + 0, + 0, + 16, + &aes_info +}; + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static const mbedtls_cipher_info_t aes_128_cbc_info = { + MBEDTLS_CIPHER_AES_128_CBC, + MBEDTLS_MODE_CBC, + 128, + "AES-128-CBC", + 16, + 0, + 16, + &aes_info +}; + +static const mbedtls_cipher_info_t aes_192_cbc_info = { + MBEDTLS_CIPHER_AES_192_CBC, + MBEDTLS_MODE_CBC, + 192, + "AES-192-CBC", + 16, + 0, + 16, + &aes_info +}; + +static const mbedtls_cipher_info_t aes_256_cbc_info = { + MBEDTLS_CIPHER_AES_256_CBC, + MBEDTLS_MODE_CBC, + 256, + "AES-256-CBC", + 16, + 0, + 16, + &aes_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +static const mbedtls_cipher_info_t aes_128_cfb128_info = { + MBEDTLS_CIPHER_AES_128_CFB128, + MBEDTLS_MODE_CFB, + 128, + "AES-128-CFB128", + 16, + 0, + 16, + &aes_info +}; + +static const mbedtls_cipher_info_t aes_192_cfb128_info = { + MBEDTLS_CIPHER_AES_192_CFB128, + MBEDTLS_MODE_CFB, + 192, + "AES-192-CFB128", + 16, + 0, + 16, + &aes_info +}; + +static const mbedtls_cipher_info_t aes_256_cfb128_info = { + MBEDTLS_CIPHER_AES_256_CFB128, + MBEDTLS_MODE_CFB, + 256, + "AES-256-CFB128", + 16, + 0, + 16, + &aes_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +static const mbedtls_cipher_info_t aes_128_ctr_info = { + MBEDTLS_CIPHER_AES_128_CTR, + MBEDTLS_MODE_CTR, + 128, + "AES-128-CTR", + 16, + 0, + 16, + &aes_info +}; + +static const mbedtls_cipher_info_t aes_192_ctr_info = { + MBEDTLS_CIPHER_AES_192_CTR, + MBEDTLS_MODE_CTR, + 192, + "AES-192-CTR", + 16, + 0, + 16, + &aes_info +}; + +static const mbedtls_cipher_info_t aes_256_ctr_info = { + MBEDTLS_CIPHER_AES_256_CTR, + MBEDTLS_MODE_CTR, + 256, + "AES-256-CTR", + 16, + 0, + 16, + &aes_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +#if defined(MBEDTLS_GCM_C) +static int gcm_aes_setkey_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + return mbedtls_gcm_setkey( (mbedtls_gcm_context *) ctx, MBEDTLS_CIPHER_ID_AES, + key, key_bitlen ); +} + +static const mbedtls_cipher_base_t gcm_aes_info = { + MBEDTLS_CIPHER_ID_AES, + NULL, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + gcm_aes_setkey_wrap, + gcm_aes_setkey_wrap, + gcm_ctx_alloc, + gcm_ctx_free, +}; + +static const mbedtls_cipher_info_t aes_128_gcm_info = { + MBEDTLS_CIPHER_AES_128_GCM, + MBEDTLS_MODE_GCM, + 128, + "AES-128-GCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &gcm_aes_info +}; + +static const mbedtls_cipher_info_t aes_192_gcm_info = { + MBEDTLS_CIPHER_AES_192_GCM, + MBEDTLS_MODE_GCM, + 192, + "AES-192-GCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &gcm_aes_info +}; + +static const mbedtls_cipher_info_t aes_256_gcm_info = { + MBEDTLS_CIPHER_AES_256_GCM, + MBEDTLS_MODE_GCM, + 256, + "AES-256-GCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &gcm_aes_info +}; +#endif /* MBEDTLS_GCM_C */ + +#if defined(MBEDTLS_CCM_C) +static int ccm_aes_setkey_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + return mbedtls_ccm_setkey( (mbedtls_ccm_context *) ctx, MBEDTLS_CIPHER_ID_AES, + key, key_bitlen ); +} + +static const mbedtls_cipher_base_t ccm_aes_info = { + MBEDTLS_CIPHER_ID_AES, + NULL, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + ccm_aes_setkey_wrap, + ccm_aes_setkey_wrap, + ccm_ctx_alloc, + ccm_ctx_free, +}; + +static const mbedtls_cipher_info_t aes_128_ccm_info = { + MBEDTLS_CIPHER_AES_128_CCM, + MBEDTLS_MODE_CCM, + 128, + "AES-128-CCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &ccm_aes_info +}; + +static const mbedtls_cipher_info_t aes_192_ccm_info = { + MBEDTLS_CIPHER_AES_192_CCM, + MBEDTLS_MODE_CCM, + 192, + "AES-192-CCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &ccm_aes_info +}; + +static const mbedtls_cipher_info_t aes_256_ccm_info = { + MBEDTLS_CIPHER_AES_256_CCM, + MBEDTLS_MODE_CCM, + 256, + "AES-256-CCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &ccm_aes_info +}; +#endif /* MBEDTLS_CCM_C */ + +#endif /* MBEDTLS_AES_C */ + +#if defined(MBEDTLS_CAMELLIA_C) + +static int camellia_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation, + const unsigned char *input, unsigned char *output ) +{ + return mbedtls_camellia_crypt_ecb( (mbedtls_camellia_context *) ctx, operation, input, + output ); +} + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static int camellia_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, + size_t length, unsigned char *iv, + const unsigned char *input, unsigned char *output ) +{ + return mbedtls_camellia_crypt_cbc( (mbedtls_camellia_context *) ctx, operation, length, iv, + input, output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +static int camellia_crypt_cfb128_wrap( void *ctx, mbedtls_operation_t operation, + size_t length, size_t *iv_off, unsigned char *iv, + const unsigned char *input, unsigned char *output ) +{ + return mbedtls_camellia_crypt_cfb128( (mbedtls_camellia_context *) ctx, operation, length, + iv_off, iv, input, output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +static int camellia_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off, + unsigned char *nonce_counter, unsigned char *stream_block, + const unsigned char *input, unsigned char *output ) +{ + return mbedtls_camellia_crypt_ctr( (mbedtls_camellia_context *) ctx, length, nc_off, + nonce_counter, stream_block, input, output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +static int camellia_setkey_dec_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + return mbedtls_camellia_setkey_dec( (mbedtls_camellia_context *) ctx, key, key_bitlen ); +} + +static int camellia_setkey_enc_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + return mbedtls_camellia_setkey_enc( (mbedtls_camellia_context *) ctx, key, key_bitlen ); +} + +static void * camellia_ctx_alloc( void ) +{ + mbedtls_camellia_context *ctx; + ctx = mbedtls_calloc( 1, sizeof( mbedtls_camellia_context ) ); + + if( ctx == NULL ) + return( NULL ); + + mbedtls_camellia_init( ctx ); + + return( ctx ); +} + +static void camellia_ctx_free( void *ctx ) +{ + mbedtls_camellia_free( (mbedtls_camellia_context *) ctx ); + mbedtls_free( ctx ); +} + +static const mbedtls_cipher_base_t camellia_info = { + MBEDTLS_CIPHER_ID_CAMELLIA, + camellia_crypt_ecb_wrap, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + camellia_crypt_cbc_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + camellia_crypt_cfb128_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + camellia_crypt_ctr_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + camellia_setkey_enc_wrap, + camellia_setkey_dec_wrap, + camellia_ctx_alloc, + camellia_ctx_free +}; + +static const mbedtls_cipher_info_t camellia_128_ecb_info = { + MBEDTLS_CIPHER_CAMELLIA_128_ECB, + MBEDTLS_MODE_ECB, + 128, + "CAMELLIA-128-ECB", + 16, + 0, + 16, + &camellia_info +}; + +static const mbedtls_cipher_info_t camellia_192_ecb_info = { + MBEDTLS_CIPHER_CAMELLIA_192_ECB, + MBEDTLS_MODE_ECB, + 192, + "CAMELLIA-192-ECB", + 16, + 0, + 16, + &camellia_info +}; + +static const mbedtls_cipher_info_t camellia_256_ecb_info = { + MBEDTLS_CIPHER_CAMELLIA_256_ECB, + MBEDTLS_MODE_ECB, + 256, + "CAMELLIA-256-ECB", + 16, + 0, + 16, + &camellia_info +}; + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static const mbedtls_cipher_info_t camellia_128_cbc_info = { + MBEDTLS_CIPHER_CAMELLIA_128_CBC, + MBEDTLS_MODE_CBC, + 128, + "CAMELLIA-128-CBC", + 16, + 0, + 16, + &camellia_info +}; + +static const mbedtls_cipher_info_t camellia_192_cbc_info = { + MBEDTLS_CIPHER_CAMELLIA_192_CBC, + MBEDTLS_MODE_CBC, + 192, + "CAMELLIA-192-CBC", + 16, + 0, + 16, + &camellia_info +}; + +static const mbedtls_cipher_info_t camellia_256_cbc_info = { + MBEDTLS_CIPHER_CAMELLIA_256_CBC, + MBEDTLS_MODE_CBC, + 256, + "CAMELLIA-256-CBC", + 16, + 0, + 16, + &camellia_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +static const mbedtls_cipher_info_t camellia_128_cfb128_info = { + MBEDTLS_CIPHER_CAMELLIA_128_CFB128, + MBEDTLS_MODE_CFB, + 128, + "CAMELLIA-128-CFB128", + 16, + 0, + 16, + &camellia_info +}; + +static const mbedtls_cipher_info_t camellia_192_cfb128_info = { + MBEDTLS_CIPHER_CAMELLIA_192_CFB128, + MBEDTLS_MODE_CFB, + 192, + "CAMELLIA-192-CFB128", + 16, + 0, + 16, + &camellia_info +}; + +static const mbedtls_cipher_info_t camellia_256_cfb128_info = { + MBEDTLS_CIPHER_CAMELLIA_256_CFB128, + MBEDTLS_MODE_CFB, + 256, + "CAMELLIA-256-CFB128", + 16, + 0, + 16, + &camellia_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +static const mbedtls_cipher_info_t camellia_128_ctr_info = { + MBEDTLS_CIPHER_CAMELLIA_128_CTR, + MBEDTLS_MODE_CTR, + 128, + "CAMELLIA-128-CTR", + 16, + 0, + 16, + &camellia_info +}; + +static const mbedtls_cipher_info_t camellia_192_ctr_info = { + MBEDTLS_CIPHER_CAMELLIA_192_CTR, + MBEDTLS_MODE_CTR, + 192, + "CAMELLIA-192-CTR", + 16, + 0, + 16, + &camellia_info +}; + +static const mbedtls_cipher_info_t camellia_256_ctr_info = { + MBEDTLS_CIPHER_CAMELLIA_256_CTR, + MBEDTLS_MODE_CTR, + 256, + "CAMELLIA-256-CTR", + 16, + 0, + 16, + &camellia_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +#if defined(MBEDTLS_GCM_C) +static int gcm_camellia_setkey_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + return mbedtls_gcm_setkey( (mbedtls_gcm_context *) ctx, MBEDTLS_CIPHER_ID_CAMELLIA, + key, key_bitlen ); +} + +static const mbedtls_cipher_base_t gcm_camellia_info = { + MBEDTLS_CIPHER_ID_CAMELLIA, + NULL, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + gcm_camellia_setkey_wrap, + gcm_camellia_setkey_wrap, + gcm_ctx_alloc, + gcm_ctx_free, +}; + +static const mbedtls_cipher_info_t camellia_128_gcm_info = { + MBEDTLS_CIPHER_CAMELLIA_128_GCM, + MBEDTLS_MODE_GCM, + 128, + "CAMELLIA-128-GCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &gcm_camellia_info +}; + +static const mbedtls_cipher_info_t camellia_192_gcm_info = { + MBEDTLS_CIPHER_CAMELLIA_192_GCM, + MBEDTLS_MODE_GCM, + 192, + "CAMELLIA-192-GCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &gcm_camellia_info +}; + +static const mbedtls_cipher_info_t camellia_256_gcm_info = { + MBEDTLS_CIPHER_CAMELLIA_256_GCM, + MBEDTLS_MODE_GCM, + 256, + "CAMELLIA-256-GCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &gcm_camellia_info +}; +#endif /* MBEDTLS_GCM_C */ + +#if defined(MBEDTLS_CCM_C) +static int ccm_camellia_setkey_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + return mbedtls_ccm_setkey( (mbedtls_ccm_context *) ctx, MBEDTLS_CIPHER_ID_CAMELLIA, + key, key_bitlen ); +} + +static const mbedtls_cipher_base_t ccm_camellia_info = { + MBEDTLS_CIPHER_ID_CAMELLIA, + NULL, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + ccm_camellia_setkey_wrap, + ccm_camellia_setkey_wrap, + ccm_ctx_alloc, + ccm_ctx_free, +}; + +static const mbedtls_cipher_info_t camellia_128_ccm_info = { + MBEDTLS_CIPHER_CAMELLIA_128_CCM, + MBEDTLS_MODE_CCM, + 128, + "CAMELLIA-128-CCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &ccm_camellia_info +}; + +static const mbedtls_cipher_info_t camellia_192_ccm_info = { + MBEDTLS_CIPHER_CAMELLIA_192_CCM, + MBEDTLS_MODE_CCM, + 192, + "CAMELLIA-192-CCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &ccm_camellia_info +}; + +static const mbedtls_cipher_info_t camellia_256_ccm_info = { + MBEDTLS_CIPHER_CAMELLIA_256_CCM, + MBEDTLS_MODE_CCM, + 256, + "CAMELLIA-256-CCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &ccm_camellia_info +}; +#endif /* MBEDTLS_CCM_C */ + +#endif /* MBEDTLS_CAMELLIA_C */ + +#if defined(MBEDTLS_DES_C) + +static int des_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation, + const unsigned char *input, unsigned char *output ) +{ + ((void) operation); + return mbedtls_des_crypt_ecb( (mbedtls_des_context *) ctx, input, output ); +} + +static int des3_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation, + const unsigned char *input, unsigned char *output ) +{ + ((void) operation); + return mbedtls_des3_crypt_ecb( (mbedtls_des3_context *) ctx, input, output ); +} + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static int des_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, size_t length, + unsigned char *iv, const unsigned char *input, unsigned char *output ) +{ + return mbedtls_des_crypt_cbc( (mbedtls_des_context *) ctx, operation, length, iv, input, + output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static int des3_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, size_t length, + unsigned char *iv, const unsigned char *input, unsigned char *output ) +{ + return mbedtls_des3_crypt_cbc( (mbedtls_des3_context *) ctx, operation, length, iv, input, + output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +static int des_setkey_dec_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + ((void) key_bitlen); + + return mbedtls_des_setkey_dec( (mbedtls_des_context *) ctx, key ); +} + +static int des_setkey_enc_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + ((void) key_bitlen); + + return mbedtls_des_setkey_enc( (mbedtls_des_context *) ctx, key ); +} + +static int des3_set2key_dec_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + ((void) key_bitlen); + + return mbedtls_des3_set2key_dec( (mbedtls_des3_context *) ctx, key ); +} + +static int des3_set2key_enc_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + ((void) key_bitlen); + + return mbedtls_des3_set2key_enc( (mbedtls_des3_context *) ctx, key ); +} + +static int des3_set3key_dec_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + ((void) key_bitlen); + + return mbedtls_des3_set3key_dec( (mbedtls_des3_context *) ctx, key ); +} + +static int des3_set3key_enc_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + ((void) key_bitlen); + + return mbedtls_des3_set3key_enc( (mbedtls_des3_context *) ctx, key ); +} + +static void * des_ctx_alloc( void ) +{ + mbedtls_des_context *des = mbedtls_calloc( 1, sizeof( mbedtls_des_context ) ); + + if( des == NULL ) + return( NULL ); + + mbedtls_des_init( des ); + + return( des ); +} + +static void des_ctx_free( void *ctx ) +{ + mbedtls_des_free( (mbedtls_des_context *) ctx ); + mbedtls_free( ctx ); +} + +static void * des3_ctx_alloc( void ) +{ + mbedtls_des3_context *des3; + des3 = mbedtls_calloc( 1, sizeof( mbedtls_des3_context ) ); + + if( des3 == NULL ) + return( NULL ); + + mbedtls_des3_init( des3 ); + + return( des3 ); +} + +static void des3_ctx_free( void *ctx ) +{ + mbedtls_des3_free( (mbedtls_des3_context *) ctx ); + mbedtls_free( ctx ); +} + +static const mbedtls_cipher_base_t des_info = { + MBEDTLS_CIPHER_ID_DES, + des_crypt_ecb_wrap, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + des_crypt_cbc_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + des_setkey_enc_wrap, + des_setkey_dec_wrap, + des_ctx_alloc, + des_ctx_free +}; + +static const mbedtls_cipher_info_t des_ecb_info = { + MBEDTLS_CIPHER_DES_ECB, + MBEDTLS_MODE_ECB, + MBEDTLS_KEY_LENGTH_DES, + "DES-ECB", + 8, + 0, + 8, + &des_info +}; + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static const mbedtls_cipher_info_t des_cbc_info = { + MBEDTLS_CIPHER_DES_CBC, + MBEDTLS_MODE_CBC, + MBEDTLS_KEY_LENGTH_DES, + "DES-CBC", + 8, + 0, + 8, + &des_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +static const mbedtls_cipher_base_t des_ede_info = { + MBEDTLS_CIPHER_ID_DES, + des3_crypt_ecb_wrap, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + des3_crypt_cbc_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + des3_set2key_enc_wrap, + des3_set2key_dec_wrap, + des3_ctx_alloc, + des3_ctx_free +}; + +static const mbedtls_cipher_info_t des_ede_ecb_info = { + MBEDTLS_CIPHER_DES_EDE_ECB, + MBEDTLS_MODE_ECB, + MBEDTLS_KEY_LENGTH_DES_EDE, + "DES-EDE-ECB", + 8, + 0, + 8, + &des_ede_info +}; + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static const mbedtls_cipher_info_t des_ede_cbc_info = { + MBEDTLS_CIPHER_DES_EDE_CBC, + MBEDTLS_MODE_CBC, + MBEDTLS_KEY_LENGTH_DES_EDE, + "DES-EDE-CBC", + 8, + 0, + 8, + &des_ede_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +static const mbedtls_cipher_base_t des_ede3_info = { + MBEDTLS_CIPHER_ID_3DES, + des3_crypt_ecb_wrap, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + des3_crypt_cbc_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + des3_set3key_enc_wrap, + des3_set3key_dec_wrap, + des3_ctx_alloc, + des3_ctx_free +}; + +static const mbedtls_cipher_info_t des_ede3_ecb_info = { + MBEDTLS_CIPHER_DES_EDE3_ECB, + MBEDTLS_MODE_ECB, + MBEDTLS_KEY_LENGTH_DES_EDE3, + "DES-EDE3-ECB", + 8, + 0, + 8, + &des_ede3_info +}; +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static const mbedtls_cipher_info_t des_ede3_cbc_info = { + MBEDTLS_CIPHER_DES_EDE3_CBC, + MBEDTLS_MODE_CBC, + MBEDTLS_KEY_LENGTH_DES_EDE3, + "DES-EDE3-CBC", + 8, + 0, + 8, + &des_ede3_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#endif /* MBEDTLS_DES_C */ + +#if defined(MBEDTLS_BLOWFISH_C) + +static int blowfish_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation, + const unsigned char *input, unsigned char *output ) +{ + return mbedtls_blowfish_crypt_ecb( (mbedtls_blowfish_context *) ctx, operation, input, + output ); +} + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static int blowfish_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, + size_t length, unsigned char *iv, const unsigned char *input, + unsigned char *output ) +{ + return mbedtls_blowfish_crypt_cbc( (mbedtls_blowfish_context *) ctx, operation, length, iv, + input, output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +static int blowfish_crypt_cfb64_wrap( void *ctx, mbedtls_operation_t operation, + size_t length, size_t *iv_off, unsigned char *iv, + const unsigned char *input, unsigned char *output ) +{ + return mbedtls_blowfish_crypt_cfb64( (mbedtls_blowfish_context *) ctx, operation, length, + iv_off, iv, input, output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +static int blowfish_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off, + unsigned char *nonce_counter, unsigned char *stream_block, + const unsigned char *input, unsigned char *output ) +{ + return mbedtls_blowfish_crypt_ctr( (mbedtls_blowfish_context *) ctx, length, nc_off, + nonce_counter, stream_block, input, output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +static int blowfish_setkey_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + return mbedtls_blowfish_setkey( (mbedtls_blowfish_context *) ctx, key, key_bitlen ); +} + +static void * blowfish_ctx_alloc( void ) +{ + mbedtls_blowfish_context *ctx; + ctx = mbedtls_calloc( 1, sizeof( mbedtls_blowfish_context ) ); + + if( ctx == NULL ) + return( NULL ); + + mbedtls_blowfish_init( ctx ); + + return( ctx ); +} + +static void blowfish_ctx_free( void *ctx ) +{ + mbedtls_blowfish_free( (mbedtls_blowfish_context *) ctx ); + mbedtls_free( ctx ); +} + +static const mbedtls_cipher_base_t blowfish_info = { + MBEDTLS_CIPHER_ID_BLOWFISH, + blowfish_crypt_ecb_wrap, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + blowfish_crypt_cbc_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + blowfish_crypt_cfb64_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + blowfish_crypt_ctr_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + blowfish_setkey_wrap, + blowfish_setkey_wrap, + blowfish_ctx_alloc, + blowfish_ctx_free +}; + +static const mbedtls_cipher_info_t blowfish_ecb_info = { + MBEDTLS_CIPHER_BLOWFISH_ECB, + MBEDTLS_MODE_ECB, + 128, + "BLOWFISH-ECB", + 8, + MBEDTLS_CIPHER_VARIABLE_KEY_LEN, + 8, + &blowfish_info +}; + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static const mbedtls_cipher_info_t blowfish_cbc_info = { + MBEDTLS_CIPHER_BLOWFISH_CBC, + MBEDTLS_MODE_CBC, + 128, + "BLOWFISH-CBC", + 8, + MBEDTLS_CIPHER_VARIABLE_KEY_LEN, + 8, + &blowfish_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +static const mbedtls_cipher_info_t blowfish_cfb64_info = { + MBEDTLS_CIPHER_BLOWFISH_CFB64, + MBEDTLS_MODE_CFB, + 128, + "BLOWFISH-CFB64", + 8, + MBEDTLS_CIPHER_VARIABLE_KEY_LEN, + 8, + &blowfish_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +static const mbedtls_cipher_info_t blowfish_ctr_info = { + MBEDTLS_CIPHER_BLOWFISH_CTR, + MBEDTLS_MODE_CTR, + 128, + "BLOWFISH-CTR", + 8, + MBEDTLS_CIPHER_VARIABLE_KEY_LEN, + 8, + &blowfish_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CTR */ +#endif /* MBEDTLS_BLOWFISH_C */ + +#if defined(MBEDTLS_ARC4_C) +static int arc4_crypt_stream_wrap( void *ctx, size_t length, + const unsigned char *input, + unsigned char *output ) +{ + return( mbedtls_arc4_crypt( (mbedtls_arc4_context *) ctx, length, input, output ) ); +} + +static int arc4_setkey_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + /* we get key_bitlen in bits, arc4 expects it in bytes */ + if( key_bitlen % 8 != 0 ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + mbedtls_arc4_setup( (mbedtls_arc4_context *) ctx, key, key_bitlen / 8 ); + return( 0 ); +} + +static void * arc4_ctx_alloc( void ) +{ + mbedtls_arc4_context *ctx; + ctx = mbedtls_calloc( 1, sizeof( mbedtls_arc4_context ) ); + + if( ctx == NULL ) + return( NULL ); + + mbedtls_arc4_init( ctx ); + + return( ctx ); +} + +static void arc4_ctx_free( void *ctx ) +{ + mbedtls_arc4_free( (mbedtls_arc4_context *) ctx ); + mbedtls_free( ctx ); +} + +static const mbedtls_cipher_base_t arc4_base_info = { + MBEDTLS_CIPHER_ID_ARC4, + NULL, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + arc4_crypt_stream_wrap, +#endif + arc4_setkey_wrap, + arc4_setkey_wrap, + arc4_ctx_alloc, + arc4_ctx_free +}; + +static const mbedtls_cipher_info_t arc4_128_info = { + MBEDTLS_CIPHER_ARC4_128, + MBEDTLS_MODE_STREAM, + 128, + "ARC4-128", + 0, + 0, + 1, + &arc4_base_info +}; +#endif /* MBEDTLS_ARC4_C */ + +#if defined(MBEDTLS_CIPHER_NULL_CIPHER) +static int null_crypt_stream( void *ctx, size_t length, + const unsigned char *input, + unsigned char *output ) +{ + ((void) ctx); + memmove( output, input, length ); + return( 0 ); +} + +static int null_setkey( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + ((void) ctx); + ((void) key); + ((void) key_bitlen); + + return( 0 ); +} + +static void * null_ctx_alloc( void ) +{ + return( (void *) 1 ); +} + +static void null_ctx_free( void *ctx ) +{ + ((void) ctx); +} + +static const mbedtls_cipher_base_t null_base_info = { + MBEDTLS_CIPHER_ID_NULL, + NULL, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + null_crypt_stream, +#endif + null_setkey, + null_setkey, + null_ctx_alloc, + null_ctx_free +}; + +static const mbedtls_cipher_info_t null_cipher_info = { + MBEDTLS_CIPHER_NULL, + MBEDTLS_MODE_STREAM, + 0, + "NULL", + 0, + 0, + 1, + &null_base_info +}; +#endif /* defined(MBEDTLS_CIPHER_NULL_CIPHER) */ + +const mbedtls_cipher_definition_t mbedtls_cipher_definitions[] = +{ +#if defined(MBEDTLS_AES_C) + { MBEDTLS_CIPHER_AES_128_ECB, &aes_128_ecb_info }, + { MBEDTLS_CIPHER_AES_192_ECB, &aes_192_ecb_info }, + { MBEDTLS_CIPHER_AES_256_ECB, &aes_256_ecb_info }, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + { MBEDTLS_CIPHER_AES_128_CBC, &aes_128_cbc_info }, + { MBEDTLS_CIPHER_AES_192_CBC, &aes_192_cbc_info }, + { MBEDTLS_CIPHER_AES_256_CBC, &aes_256_cbc_info }, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + { MBEDTLS_CIPHER_AES_128_CFB128, &aes_128_cfb128_info }, + { MBEDTLS_CIPHER_AES_192_CFB128, &aes_192_cfb128_info }, + { MBEDTLS_CIPHER_AES_256_CFB128, &aes_256_cfb128_info }, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + { MBEDTLS_CIPHER_AES_128_CTR, &aes_128_ctr_info }, + { MBEDTLS_CIPHER_AES_192_CTR, &aes_192_ctr_info }, + { MBEDTLS_CIPHER_AES_256_CTR, &aes_256_ctr_info }, +#endif +#if defined(MBEDTLS_GCM_C) + { MBEDTLS_CIPHER_AES_128_GCM, &aes_128_gcm_info }, + { MBEDTLS_CIPHER_AES_192_GCM, &aes_192_gcm_info }, + { MBEDTLS_CIPHER_AES_256_GCM, &aes_256_gcm_info }, +#endif +#if defined(MBEDTLS_CCM_C) + { MBEDTLS_CIPHER_AES_128_CCM, &aes_128_ccm_info }, + { MBEDTLS_CIPHER_AES_192_CCM, &aes_192_ccm_info }, + { MBEDTLS_CIPHER_AES_256_CCM, &aes_256_ccm_info }, +#endif +#endif /* MBEDTLS_AES_C */ + +#if defined(MBEDTLS_ARC4_C) + { MBEDTLS_CIPHER_ARC4_128, &arc4_128_info }, +#endif + +#if defined(MBEDTLS_BLOWFISH_C) + { MBEDTLS_CIPHER_BLOWFISH_ECB, &blowfish_ecb_info }, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + { MBEDTLS_CIPHER_BLOWFISH_CBC, &blowfish_cbc_info }, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + { MBEDTLS_CIPHER_BLOWFISH_CFB64, &blowfish_cfb64_info }, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + { MBEDTLS_CIPHER_BLOWFISH_CTR, &blowfish_ctr_info }, +#endif +#endif /* MBEDTLS_BLOWFISH_C */ + +#if defined(MBEDTLS_CAMELLIA_C) + { MBEDTLS_CIPHER_CAMELLIA_128_ECB, &camellia_128_ecb_info }, + { MBEDTLS_CIPHER_CAMELLIA_192_ECB, &camellia_192_ecb_info }, + { MBEDTLS_CIPHER_CAMELLIA_256_ECB, &camellia_256_ecb_info }, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + { MBEDTLS_CIPHER_CAMELLIA_128_CBC, &camellia_128_cbc_info }, + { MBEDTLS_CIPHER_CAMELLIA_192_CBC, &camellia_192_cbc_info }, + { MBEDTLS_CIPHER_CAMELLIA_256_CBC, &camellia_256_cbc_info }, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + { MBEDTLS_CIPHER_CAMELLIA_128_CFB128, &camellia_128_cfb128_info }, + { MBEDTLS_CIPHER_CAMELLIA_192_CFB128, &camellia_192_cfb128_info }, + { MBEDTLS_CIPHER_CAMELLIA_256_CFB128, &camellia_256_cfb128_info }, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + { MBEDTLS_CIPHER_CAMELLIA_128_CTR, &camellia_128_ctr_info }, + { MBEDTLS_CIPHER_CAMELLIA_192_CTR, &camellia_192_ctr_info }, + { MBEDTLS_CIPHER_CAMELLIA_256_CTR, &camellia_256_ctr_info }, +#endif +#if defined(MBEDTLS_GCM_C) + { MBEDTLS_CIPHER_CAMELLIA_128_GCM, &camellia_128_gcm_info }, + { MBEDTLS_CIPHER_CAMELLIA_192_GCM, &camellia_192_gcm_info }, + { MBEDTLS_CIPHER_CAMELLIA_256_GCM, &camellia_256_gcm_info }, +#endif +#if defined(MBEDTLS_CCM_C) + { MBEDTLS_CIPHER_CAMELLIA_128_CCM, &camellia_128_ccm_info }, + { MBEDTLS_CIPHER_CAMELLIA_192_CCM, &camellia_192_ccm_info }, + { MBEDTLS_CIPHER_CAMELLIA_256_CCM, &camellia_256_ccm_info }, +#endif +#endif /* MBEDTLS_CAMELLIA_C */ + +#if defined(MBEDTLS_DES_C) + { MBEDTLS_CIPHER_DES_ECB, &des_ecb_info }, + { MBEDTLS_CIPHER_DES_EDE_ECB, &des_ede_ecb_info }, + { MBEDTLS_CIPHER_DES_EDE3_ECB, &des_ede3_ecb_info }, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + { MBEDTLS_CIPHER_DES_CBC, &des_cbc_info }, + { MBEDTLS_CIPHER_DES_EDE_CBC, &des_ede_cbc_info }, + { MBEDTLS_CIPHER_DES_EDE3_CBC, &des_ede3_cbc_info }, +#endif +#endif /* MBEDTLS_DES_C */ + +#if defined(MBEDTLS_CIPHER_NULL_CIPHER) + { MBEDTLS_CIPHER_NULL, &null_cipher_info }, +#endif /* MBEDTLS_CIPHER_NULL_CIPHER */ + + { MBEDTLS_CIPHER_NONE, NULL } +}; + +#define NUM_CIPHERS sizeof mbedtls_cipher_definitions / sizeof mbedtls_cipher_definitions[0] +int mbedtls_cipher_supported[NUM_CIPHERS]; + +#endif /* MBEDTLS_CIPHER_C */ diff --git a/APP_Framework/Framework/security/mbedtls/cmac.c b/APP_Framework/Framework/security/mbedtls/cmac.c index 13a411892..3fc036903 100644 --- a/APP_Framework/Framework/security/mbedtls/cmac.c +++ b/APP_Framework/Framework/security/mbedtls/cmac.c @@ -49,7 +49,6 @@ #if defined(MBEDTLS_CMAC_C) #include "cmac.h" -#include "platform_util.h" #include @@ -68,6 +67,11 @@ #if !defined(MBEDTLS_CMAC_ALT) || defined(MBEDTLS_SELF_TEST) +/* 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; +} + /* * Multiplication by u in the Galois field of GF(2^n) * @@ -140,7 +144,7 @@ static int cmac_generate_subkeys( mbedtls_cipher_context_t *ctx, unsigned char L[MBEDTLS_CIPHER_BLKSIZE_MAX]; size_t olen, block_size; - mbedtls_platform_zeroize( L, sizeof( L ) ); + mbedtls_zeroize( L, sizeof( L ) ); block_size = ctx->cipher_info->block_size; @@ -158,7 +162,7 @@ static int cmac_generate_subkeys( mbedtls_cipher_context_t *ctx, goto exit; exit: - mbedtls_platform_zeroize( L, sizeof( L ) ); + mbedtls_zeroize( L, sizeof( L ) ); return( ret ); } @@ -234,7 +238,7 @@ int mbedtls_cipher_cmac_starts( mbedtls_cipher_context_t *ctx, ctx->cmac_ctx = cmac_ctx; - mbedtls_platform_zeroize( cmac_ctx->state, sizeof( cmac_ctx->state ) ); + mbedtls_zeroize( cmac_ctx->state, sizeof( cmac_ctx->state ) ); return 0; } @@ -260,7 +264,7 @@ int mbedtls_cipher_cmac_update( mbedtls_cipher_context_t *ctx, if( cmac_ctx->unprocessed_len > 0 && ilen > block_size - cmac_ctx->unprocessed_len ) { - mbedtls_platform_memcpy( &cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len], + memcpy( &cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len], input, block_size - cmac_ctx->unprocessed_len ); @@ -297,7 +301,7 @@ int mbedtls_cipher_cmac_update( mbedtls_cipher_context_t *ctx, /* If there is data left over that wasn't aligned to a block */ if( ilen > 0 ) { - mbedtls_platform_memcpy( &cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len], + memcpy( &cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len], input, ilen ); cmac_ctx->unprocessed_len += ilen; @@ -326,8 +330,8 @@ int mbedtls_cipher_cmac_finish( mbedtls_cipher_context_t *ctx, block_size = ctx->cipher_info->block_size; state = cmac_ctx->state; - mbedtls_platform_zeroize( K1, sizeof( K1 ) ); - mbedtls_platform_zeroize( K2, sizeof( K2 ) ); + mbedtls_zeroize( K1, sizeof( K1 ) ); + mbedtls_zeroize( K2, sizeof( K2 ) ); cmac_generate_subkeys( ctx, K1, K2 ); last_block = cmac_ctx->unprocessed_block; @@ -352,19 +356,19 @@ int mbedtls_cipher_cmac_finish( mbedtls_cipher_context_t *ctx, goto exit; } - mbedtls_platform_memcpy( output, state, block_size ); + memcpy( output, state, block_size ); exit: /* Wipe the generated keys on the stack, and any other transients to avoid * side channel leakage */ - mbedtls_platform_zeroize( K1, sizeof( K1 ) ); - mbedtls_platform_zeroize( K2, sizeof( K2 ) ); + mbedtls_zeroize( K1, sizeof( K1 ) ); + mbedtls_zeroize( K2, sizeof( K2 ) ); cmac_ctx->unprocessed_len = 0; - mbedtls_platform_zeroize( cmac_ctx->unprocessed_block, - sizeof( cmac_ctx->unprocessed_block ) ); + mbedtls_zeroize( cmac_ctx->unprocessed_block, + sizeof( cmac_ctx->unprocessed_block ) ); - mbedtls_platform_zeroize( state, MBEDTLS_CIPHER_BLKSIZE_MAX ); + mbedtls_zeroize( state, MBEDTLS_CIPHER_BLKSIZE_MAX ); return( ret ); } @@ -379,10 +383,10 @@ int mbedtls_cipher_cmac_reset( mbedtls_cipher_context_t *ctx ) /* Reset the internal state */ cmac_ctx->unprocessed_len = 0; - mbedtls_platform_zeroize( cmac_ctx->unprocessed_block, - sizeof( cmac_ctx->unprocessed_block ) ); - mbedtls_platform_zeroize( cmac_ctx->state, - sizeof( cmac_ctx->state ) ); + mbedtls_zeroize( cmac_ctx->unprocessed_block, + sizeof( cmac_ctx->unprocessed_block ) ); + mbedtls_zeroize( cmac_ctx->state, + sizeof( cmac_ctx->state ) ); return( 0 ); } @@ -446,11 +450,11 @@ int mbedtls_aes_cmac_prf_128( const unsigned char *key, size_t key_length, if( key_length == MBEDTLS_AES_BLOCK_SIZE ) { /* Use key as is */ - mbedtls_platform_memcpy( int_key, key, MBEDTLS_AES_BLOCK_SIZE ); + memcpy( int_key, key, MBEDTLS_AES_BLOCK_SIZE ); } else { - mbedtls_platform_memset( zero_key, 0, MBEDTLS_AES_BLOCK_SIZE ); + memset( zero_key, 0, MBEDTLS_AES_BLOCK_SIZE ); ret = mbedtls_cipher_cmac( cipher_info, zero_key, 128, key, key_length, int_key ); @@ -462,7 +466,7 @@ int mbedtls_aes_cmac_prf_128( const unsigned char *key, size_t key_length, output ); exit: - mbedtls_platform_zeroize( int_key, sizeof( int_key ) ); + mbedtls_zeroize( int_key, sizeof( int_key ) ); return( ret ); } @@ -902,7 +906,7 @@ static int test_aes128_cmac_prf( int verbose ) mbedtls_printf( " AES CMAC 128 PRF #%u: ", i ); ret = mbedtls_aes_cmac_prf_128( PRFK, PRFKlen[i], PRFM, 20, output ); if( ret != 0 || - memcmp( output, PRFT[i], MBEDTLS_AES_BLOCK_SIZE ) != 0 ) + memcmp( output, PRFT[i], MBEDTLS_AES_BLOCK_SIZE ) != 0 ) { if( verbose != 0 ) diff --git a/APP_Framework/Framework/security/mbedtls/cmac.h b/APP_Framework/Framework/security/mbedtls/cmac.h index 9d42b3f20..adfe1c3e0 100644 --- a/APP_Framework/Framework/security/mbedtls/cmac.h +++ b/APP_Framework/Framework/security/mbedtls/cmac.h @@ -1,10 +1,8 @@ /** * \file cmac.h * - * \brief This file contains CMAC definitions and functions. - * - * The Cipher-based Message Authentication Code (CMAC) Mode for - * Authentication is defined in RFC-4493: The AES-CMAC Algorithm. + * \brief The Cipher-based Message Authentication Code (CMAC) Mode for + * Authentication. */ /* * Copyright (C) 2015-2018, Arm Limited (or its affiliates), All Rights Reserved @@ -40,16 +38,15 @@ extern "C" { #endif -/* MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED is deprecated and should not be used. */ #define MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED -0x007A /**< CMAC hardware accelerator failed. */ #define MBEDTLS_AES_BLOCK_SIZE 16 #define MBEDTLS_DES3_BLOCK_SIZE 8 #if defined(MBEDTLS_AES_C) -#define MBEDTLS_CIPHER_BLKSIZE_MAX 16 /**< The longest block used by CMAC is that of AES. */ +#define MBEDTLS_CIPHER_BLKSIZE_MAX 16 /* The longest block used by CMAC is that of AES. */ #else -#define MBEDTLS_CIPHER_BLKSIZE_MAX 8 /**< The longest block used by CMAC is that of 3DES. */ +#define MBEDTLS_CIPHER_BLKSIZE_MAX 8 /* The longest block used by CMAC is that of 3DES. */ #endif #if !defined(MBEDTLS_CMAC_ALT) @@ -70,25 +67,22 @@ struct mbedtls_cmac_context_t size_t unprocessed_len; }; -#else /* !MBEDTLS_CMAC_ALT */ -#include "cmac_alt.h" -#endif /* !MBEDTLS_CMAC_ALT */ - /** * \brief This function sets the CMAC key, and prepares to authenticate * the input data. * Must be called with an initialized cipher context. * * \param ctx The cipher context used for the CMAC operation, initialized - * as one of the following types: MBEDTLS_CIPHER_AES_128_ECB, - * MBEDTLS_CIPHER_AES_192_ECB, MBEDTLS_CIPHER_AES_256_ECB, - * or MBEDTLS_CIPHER_DES_EDE3_ECB. + * as one of the following types:
      + *
    • MBEDTLS_CIPHER_AES_128_ECB
    • + *
    • MBEDTLS_CIPHER_AES_192_ECB
    • + *
    • MBEDTLS_CIPHER_AES_256_ECB
    • + *
    • MBEDTLS_CIPHER_DES_EDE3_ECB
    * \param key The CMAC key. * \param keybits The length of the CMAC key in bits. * Must be supported by the cipher. * - * \return \c 0 on success. - * \return A cipher-specific error code on failure. + * \return \c 0 on success, or a cipher-specific error code. */ int mbedtls_cipher_cmac_starts( mbedtls_cipher_context_t *ctx, const unsigned char *key, size_t keybits ); @@ -105,9 +99,8 @@ int mbedtls_cipher_cmac_starts( mbedtls_cipher_context_t *ctx, * \param input The buffer holding the input data. * \param ilen The length of the input data. * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA - * if parameter verification fails. + * \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, const unsigned char *input, size_t ilen ); @@ -123,8 +116,7 @@ int mbedtls_cipher_cmac_update( mbedtls_cipher_context_t *ctx, * \param ctx The cipher context used for the CMAC operation. * \param output The output buffer for the CMAC checksum result. * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA + * \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, @@ -140,8 +132,7 @@ int mbedtls_cipher_cmac_finish( mbedtls_cipher_context_t *ctx, * * \param ctx The cipher context used for the CMAC operation. * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA + * \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 ); @@ -164,8 +155,7 @@ int mbedtls_cipher_cmac_reset( mbedtls_cipher_context_t *ctx ); * \param ilen The length of the input data. * \param output The buffer for the generic CMAC result. * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA + * \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, @@ -196,12 +186,23 @@ int mbedtls_aes_cmac_prf_128( const unsigned char *key, size_t key_len, unsigned char output[16] ); #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) ) /** * \brief The CMAC checkup routine. * - * \return \c 0 on success. - * \return \c 1 on failure. + * \return \c 0 on success, or \c 1 on failure. */ int mbedtls_cmac_self_test( int verbose ); #endif /* MBEDTLS_SELF_TEST && ( MBEDTLS_AES_C || MBEDTLS_DES_C ) */ diff --git a/APP_Framework/Framework/security/mbedtls/compat-1.3.h b/APP_Framework/Framework/security/mbedtls/compat-1.3.h index bd6de87f7..94de845dd 100644 --- a/APP_Framework/Framework/security/mbedtls/compat-1.3.h +++ b/APP_Framework/Framework/security/mbedtls/compat-1.3.h @@ -1384,8 +1384,7 @@ #define SSL_ANTI_REPLAY_ENABLED MBEDTLS_SSL_ANTI_REPLAY_ENABLED #define SSL_ARC4_DISABLED MBEDTLS_SSL_ARC4_DISABLED #define SSL_ARC4_ENABLED MBEDTLS_SSL_ARC4_ENABLED -#define SSL_BUFFER_LEN ( ( ( MBEDTLS_SSL_IN_BUFFER_LEN ) < ( MBEDTLS_SSL_OUT_BUFFER_LEN ) ) \ - ? ( MBEDTLS_SSL_IN_BUFFER_LEN ) : ( MBEDTLS_SSL_OUT_BUFFER_LEN ) ) +#define SSL_BUFFER_LEN MBEDTLS_SSL_BUFFER_LEN #define SSL_CACHE_DEFAULT_MAX_ENTRIES MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES #define SSL_CACHE_DEFAULT_TIMEOUT MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT #define SSL_CBC_RECORD_SPLITTING_DISABLED MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED @@ -2231,7 +2230,7 @@ #define rsa_rsassa_pss_verify_ext mbedtls_rsa_rsassa_pss_verify_ext #define rsa_self_test mbedtls_rsa_self_test #define rsa_set_padding mbedtls_rsa_set_padding -#define safer_memcmp mbedtls_platform_memequal +#define safer_memcmp mbedtls_ssl_safer_memcmp #define set_alarm mbedtls_set_alarm #define sha1 mbedtls_sha1 #define sha1_context mbedtls_sha1_context diff --git a/APP_Framework/Framework/security/mbedtls/config.h b/APP_Framework/Framework/security/mbedtls/config.h index dc05de92f..0d64281e6 100644 --- a/APP_Framework/Framework/security/mbedtls/config.h +++ b/APP_Framework/Framework/security/mbedtls/config.h @@ -1,5 +1,5 @@ /** - * \file config.h + * \file tls_config.h * * \brief Configuration options (set of defines) * @@ -8,7 +8,7 @@ * memory footprint. */ /* - * Copyright (C) 2006-2018, ARM Limited, All Rights Reserved + * Copyright (C) 2006-2019, ARM Limited, All Rights Reserved * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -40,15 +40,6 @@ * \{ */ -/** - * \def MBEDTLS_SSL_DELAYED_SERVER_CERT_VERIFICATION - * - * Enable the delayed verification of server - * certificates on the client side. - * - */ -//#define MBEDTLS_SSL_DELAYED_SERVER_CERT_VERIFICATION - /** * \def MBEDTLS_HAVE_ASM * @@ -57,13 +48,9 @@ * Requires support for asm() in compiler. * * Used in: - * library/aria.c * library/timing.c - * include/bn_mul.h - * - * Required by: - * MBEDTLS_AESNI_C - * MBEDTLS_PADLOCK_C + * library/padlock.c + * include/mbedtls/bn_mul.h * * Comment to disable the use of assembly code. */ @@ -76,7 +63,7 @@ * division on a 32-bit platform, 128-bit division on a 64-bit platform). * * Used in: - * include/bignum.h + * include/mbedtls/bignum.h * library/bignum.c * * The bignum code uses double-width division to speed up some operations. @@ -97,28 +84,6 @@ */ //#define MBEDTLS_NO_UDBL_DIVISION -/** - * \def MBEDTLS_NO_64BIT_MULTIPLICATION - * - * The platform lacks support for 32x32 -> 64-bit multiplication. - * - * Used in: - * library/poly1305.c - * - * Some parts of the library may use multiplication of two unsigned 32-bit - * operands with a 64-bit result in order to speed up computations. On some - * platforms, this is not available in hardware and has to be implemented in - * software, usually in a library provided by the toolchain. - * - * Sometimes it is not desirable to have to link to that library. This option - * removes the dependency of that library on platforms that lack a hardware - * 64-bit multiplier by embedding a software implementation in Mbed TLS. - * - * Note that depending on the compiler, this may decrease performance compared - * to using the library function provided by the toolchain. - */ -//#define MBEDTLS_NO_64BIT_MULTIPLICATION - /** * \def MBEDTLS_HAVE_SSE2 * @@ -146,23 +111,14 @@ /** * \def MBEDTLS_HAVE_TIME_DATE * - * System has time.h, time(), and an implementation for - * mbedtls_platform_gmtime_r() (see below). - * The time needs to be correct (not necessarily very accurate, but at least + * System has time.h and time(), gmtime() and the clock is correct. + * The time needs to be correct (not necesarily very accurate, but at least * the date should be correct). This is used to verify the validity period of * X.509 certificates. * * Comment if your system does not have a correct clock. - * - * \note mbedtls_platform_gmtime_r() is an abstraction in platform_util.h that - * behaves similarly to the gmtime_r() function from the C standard. Refer to - * the documentation for mbedtls_platform_gmtime_r() for more information. - * - * \note It is possible to configure an implementation for - * mbedtls_platform_gmtime_r() at compile-time by using the macro - * MBEDTLS_PLATFORM_GMTIME_R_ALT. */ -#define MBEDTLS_HAVE_TIME_DATE +// #define MBEDTLS_HAVE_TIME_DATE /** * \def MBEDTLS_PLATFORM_MEMORY @@ -265,72 +221,6 @@ */ //#define MBEDTLS_DEPRECATED_REMOVED -/** - * \def MBEDTLS_CHECK_PARAMS - * - * This configuration option controls whether the library validates more of - * the parameters passed to it. - * - * When this flag is not defined, the library only attempts to validate an - * input parameter if: (1) they may come from the outside world (such as the - * network, the filesystem, etc.) or (2) not validating them could result in - * internal memory errors such as overflowing a buffer controlled by the - * library. On the other hand, it doesn't attempt to validate parameters whose - * values are fully controlled by the application (such as pointers). - * - * When this flag is defined, the library additionally attempts to validate - * parameters that are fully controlled by the application, and should always - * be valid if the application code is fully correct and trusted. - * - * For example, when a function accepts as input a pointer to a buffer that may - * contain untrusted data, and its documentation mentions that this pointer - * must not be NULL: - * - The pointer is checked to be non-NULL only if this option is enabled. - * - The content of the buffer is always validated. - * - * When this flag is defined, if a library function receives a parameter that - * is invalid: - * 1. The function will invoke the macro MBEDTLS_PARAM_FAILED(). - * 2. If MBEDTLS_PARAM_FAILED() did not terminate the program, the function - * will immediately return. If the function returns an Mbed TLS error code, - * the error code in this case is MBEDTLS_ERR_xxx_BAD_INPUT_DATA. - * - * When defining this flag, you also need to arrange a definition for - * MBEDTLS_PARAM_FAILED(). You can do this by any of the following methods: - * - By default, the library defines MBEDTLS_PARAM_FAILED() to call a - * function mbedtls_param_failed(), but the library does not define this - * function. If you do not make any other arrangements, you must provide - * the function mbedtls_param_failed() in your application. - * See `platform_util.h` for its prototype. - * - If you enable the macro #MBEDTLS_CHECK_PARAMS_ASSERT, then the - * library defines #MBEDTLS_PARAM_FAILED(\c cond) to be `assert(cond)`. - * You can still supply an alternative definition of - * MBEDTLS_PARAM_FAILED(), which may call `assert`. - * - If you define a macro MBEDTLS_PARAM_FAILED() before including `config.h` - * or you uncomment the definition of MBEDTLS_PARAM_FAILED() in `config.h`, - * the library will call the macro that you defined and will not supply - * its own version. Note that if MBEDTLS_PARAM_FAILED() calls `assert`, - * you need to enable #MBEDTLS_CHECK_PARAMS_ASSERT so that library source - * files include ``. - * - * Uncomment to enable validation of application-controlled parameters. - */ -//#define MBEDTLS_CHECK_PARAMS - -/** - * \def MBEDTLS_CHECK_PARAMS_ASSERT - * - * Allow MBEDTLS_PARAM_FAILED() to call `assert`, and make it default to - * `assert`. This macro is only used if #MBEDTLS_CHECK_PARAMS is defined. - * - * If this macro is not defined, then MBEDTLS_PARAM_FAILED() defaults to - * calling a function mbedtls_param_failed(). See the documentation of - * #MBEDTLS_CHECK_PARAMS for details. - * - * Uncomment to allow MBEDTLS_PARAM_FAILED() to call `assert`. - */ -//#define MBEDTLS_CHECK_PARAMS_ASSERT - /* \} name SECTION: System support */ /** @@ -379,29 +269,40 @@ * digests and ciphers instead. * */ -//#define MBEDTLS_AES_ALT -//#define MBEDTLS_ARC4_ALT -//#define MBEDTLS_ARIA_ALT +#if defined(RT_HWCRYPTO_USING_AES) +#define MBEDTLS_AES_ALT +#endif +#if defined(RT_HWCRYPTO_USING_RC4) +#define MBEDTLS_ARC4_ALT +#endif +#if defined(RT_HWCRYPTO_USING_DES) || defined(RT_HWCRYPTO_USING_3DES) +#define MBEDTLS_DES_ALT +#endif +#if defined(RT_HWCRYPTO_USING_GCM) +#define MBEDTLS_GCM_ALT +#endif +#ifdef RT_HWCRYPTO_USING_MD5 +#define MBEDTLS_MD5_ALT +#endif +#if defined(RT_HWCRYPTO_USING_BIGNUM) +#define MBEDTLS_RSA_ALT +#endif +#if defined(RT_HWCRYPTO_USING_SHA1) +#define MBEDTLS_SHA1_ALT +#endif +#if defined(RT_HWCRYPTO_USING_SHA2_256) || defined(RT_HWCRYPTO_USING_SHA2_224) +#define MBEDTLS_SHA256_ALT +#endif +#if defined(RT_HWCRYPTO_USING_SHA2_512) || defined(RT_HWCRYPTO_USING_SHA2_384) +#define MBEDTLS_SHA512_ALT +#endif +//#define MBEDTLS_DHM_ALT +//#define MBEDTLS_ECJPAKE_ALT //#define MBEDTLS_BLOWFISH_ALT //#define MBEDTLS_CAMELLIA_ALT //#define MBEDTLS_CCM_ALT -//#define MBEDTLS_CHACHA20_ALT -//#define MBEDTLS_CHACHAPOLY_ALT //#define MBEDTLS_CMAC_ALT -//#define MBEDTLS_DES_ALT -//#define MBEDTLS_DHM_ALT -//#define MBEDTLS_ECJPAKE_ALT -//#define MBEDTLS_GCM_ALT -//#define MBEDTLS_NIST_KW_ALT -//#define MBEDTLS_MD2_ALT -//#define MBEDTLS_MD4_ALT -//#define MBEDTLS_MD5_ALT -//#define MBEDTLS_POLY1305_ALT //#define MBEDTLS_RIPEMD160_ALT -//#define MBEDTLS_RSA_ALT -//#define MBEDTLS_SHA1_ALT -//#define MBEDTLS_SHA256_ALT -//#define MBEDTLS_SHA512_ALT //#define MBEDTLS_XTEA_ALT /* @@ -434,7 +335,7 @@ * \note Because of a signature change, the core AES encryption and decryption routines are * currently named mbedtls_aes_internal_encrypt and mbedtls_aes_internal_decrypt, * respectively. When setting up alternative implementations, these functions should - * be overridden, but the wrapper functions mbedtls_aes_decrypt and mbedtls_aes_encrypt + * be overriden, but the wrapper functions mbedtls_aes_decrypt and mbedtls_aes_encrypt * must stay untouched. * * \note If you use the AES_xxx_ALT macros, then is is recommended to also set @@ -449,16 +350,6 @@ * dependencies on them, and considering stronger message digests * and ciphers instead. * - * \warning If both MBEDTLS_ECDSA_SIGN_ALT and MBEDTLS_ECDSA_DETERMINISTIC are - * enabled, then the deterministic ECDH signature functions pass the - * the static HMAC-DRBG as RNG to mbedtls_ecdsa_sign(). Therefore - * alternative implementations should use the RNG only for generating - * the ephemeral key and nothing else. If this is not possible, then - * MBEDTLS_ECDSA_DETERMINISTIC should be disabled and an alternative - * implementation should be provided for mbedtls_ecdsa_sign_det_ext() - * (and for mbedtls_ecdsa_sign_det() too if backward compatibility is - * desirable). - * */ //#define MBEDTLS_MD2_PROCESS_ALT //#define MBEDTLS_MD4_PROCESS_ALT @@ -499,11 +390,11 @@ * unsigned char mbedtls_internal_ecp_grp_capable( * const mbedtls_ecp_group *grp ) * int mbedtls_internal_ecp_init( const mbedtls_ecp_group *grp ) - * void mbedtls_internal_ecp_free( const mbedtls_ecp_group *grp ) + * void mbedtls_internal_ecp_deinit( const mbedtls_ecp_group *grp ) * The mbedtls_internal_ecp_grp_capable function should return 1 if the * replacement functions implement arithmetic for the given group and 0 * otherwise. - * The functions mbedtls_internal_ecp_init and mbedtls_internal_ecp_free are + * The functions mbedtls_internal_ecp_init and mbedtls_internal_ecp_deinit are * called before and after each point operation and provide an opportunity to * implement optimized set up and tear down instructions. * @@ -561,150 +452,17 @@ * * Uncomment to use your own hardware entropy collector. */ -//#define MBEDTLS_ENTROPY_HARDWARE_ALT +#define MBEDTLS_ENTROPY_HARDWARE_ALT /** * \def MBEDTLS_AES_ROM_TABLES * - * Use precomputed AES tables stored in ROM. - * - * Uncomment this macro to use precomputed AES tables stored in ROM. - * Comment this macro to generate AES tables in RAM at runtime. - * - * Tradeoff: Using precomputed ROM tables reduces RAM usage by ~8kb - * (or ~2kb if \c MBEDTLS_AES_FEWER_TABLES is used) and reduces the - * initialization time before the first AES operation can be performed. - * It comes at the cost of additional ~8kb ROM use (resp. ~2kb if \c - * MBEDTLS_AES_FEWER_TABLES below is used), and potentially degraded - * performance if ROM access is slower than RAM access. - * - * This option is independent of \c MBEDTLS_AES_FEWER_TABLES. + * Store the AES tables in ROM. * + * Uncomment this macro to store the AES tables in ROM. */ //#define MBEDTLS_AES_ROM_TABLES -/** - * \def MBEDTLS_AES_FEWER_TABLES - * - * Use less ROM/RAM for AES tables. - * - * Uncommenting this macro omits 75% of the AES tables from - * ROM / RAM (depending on the value of \c MBEDTLS_AES_ROM_TABLES) - * by computing their values on the fly during operations - * (the tables are entry-wise rotations of one another). - * - * Tradeoff: Uncommenting this reduces the RAM / ROM footprint - * by ~6kb but at the cost of more arithmetic operations during - * runtime. Specifically, one has to compare 4 accesses within - * different tables to 4 accesses with additional arithmetic - * operations within the same table. The performance gain/loss - * depends on the system and memory details. - * - * This option is independent of \c MBEDTLS_AES_ROM_TABLES. - * - */ -//#define MBEDTLS_AES_FEWER_TABLES - -/** - * \def MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH - * - * Use only 128-bit keys in AES operations to save ROM. - * - * Uncommenting this macro removes support for AES operations that are using 192 - * or 256-bit keys. - * - * Tradeoff: Uncommenting this macro reduces ROM footprint by ~240 bytes. - * - * If uncommented, uncomment also MBEDTLS_CTR_DRBG_USE_128_BIT_KEY - * - * Module: library/aes.c - * - * Requires: MBEDTLS_AES_C - * - */ -//#define MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH - -/** - * \def MBEDTLS_AES_ONLY_ENCRYPT - * - * Use only AES encryption, decryption is not possible. - * - * Uncommenting this macro removes support for AES decryption. - * - * Tradeoff: Uncommenting this macro reduces the footprint. For - * example, when both MBEDTLS_AES_ROM_TABLES and - * MBEDTLS_AES_FEWER_TABLES are enabled, enabling this macro - * further reduces the ROM footprint by ~2.5kB. - * - * Module: library/aes.c - * - * Requires: MBEDTLS_AES_C - * - */ -//#define MBEDTLS_AES_ONLY_ENCRYPT - -/** - * \def MBEDTLS_AES_SCA_COUNTERMEASURES - * - * Add countermeasures against possible side-channel-attack to AES calculation. - * - * Uncommenting this macro adds additional calculation rounds to AES - * calculation. Additional rounds are using random data for calculation. The - * additional rounds are added to: - * -initial key addition phase - * -before the first AES calculation round - * -after the last AES calculation round - * - * Tradeoff: Uncommenting this macro does not increase codesize. - * The performance loss is ~50% with 128 bit AES. - * - * This option is dependent of \c MBEDTLS_ENTROPY_HARDWARE_ALT. - * - */ -//#define MBEDTLS_AES_SCA_COUNTERMEASURES - -/** - * \def MBEDTLS_AES_128_BIT_MASKED - * - * Requires MBEDTLS_AES_SCA_COUNTERMEASURES - * MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH - * MBEDTLS_AES_ONLY_ENCRYPT - * - * Add boolean masking against possible combined side-channel-attack - * fault injection attacks. - * - * Uncommenting this macro adds data, key and Sbox masking additionally - * to dummy rounds. - * - * Tradeoff: - * Uncommenting this macro does not increase codesize in MBEDTLS_AES_ROM_TABLES - * configuration. - * Uncommenting this macro increases codesize in AES RAM tables configuration - * by ~600 bytes. - * The performance loss is ~50% with 128 bit AES encrypt. - * - */ -//#define MBEDTLS_AES_128_BIT_MASKED - -/** - * \def MBEDTLS_FI_COUNTERMEASURES - * - * Add countermeasures against a possible FI attack. - * - * Uncommenting this macro increases code size and slows performance, - * it performs double calls and double result checks of some crypto functions - */ -//#define MBEDTLS_FI_COUNTERMEASURES - -/** - * \def MBEDTLS_CCM_SHUFFLING_MASKING - * - * Add shuffling and masking to the CCM module as an additional security - * measure. - * - */ -//#define MBEDTLS_CCM_SHUFFLING_MASKING - /** * \def MBEDTLS_CAMELLIA_SMALL_MEMORY * @@ -735,20 +493,6 @@ */ #define MBEDTLS_CIPHER_MODE_CTR -/** - * \def MBEDTLS_CIPHER_MODE_OFB - * - * Enable Output Feedback mode (OFB) for symmetric ciphers. - */ -#define MBEDTLS_CIPHER_MODE_OFB - -/** - * \def MBEDTLS_CIPHER_MODE_XTS - * - * Enable Xor-encrypt-xor with ciphertext stealing mode (XTS) for AES. - */ -#define MBEDTLS_CIPHER_MODE_XTS - /** * \def MBEDTLS_CIPHER_NULL_CIPHER * @@ -798,13 +542,6 @@ #define MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN #define MBEDTLS_CIPHER_PADDING_ZEROS -/** \def MBEDTLS_CTR_DRBG_USE_128_BIT_KEY - * - * Uncomment this macro to use a 128-bit key in the CTR_DRBG module. - * By default, CTR_DRBG uses a 256-bit key. - */ -//#define MBEDTLS_CTR_DRBG_USE_128_BIT_KEY - /** * \def MBEDTLS_ENABLE_WEAK_CIPHERSUITES * @@ -876,7 +613,6 @@ #define MBEDTLS_ECP_DP_BP384R1_ENABLED #define MBEDTLS_ECP_DP_BP512R1_ENABLED #define MBEDTLS_ECP_DP_CURVE25519_ENABLED -#define MBEDTLS_ECP_DP_CURVE448_ENABLED /** * \def MBEDTLS_ECP_NIST_OPTIM @@ -889,30 +625,6 @@ */ #define MBEDTLS_ECP_NIST_OPTIM -/** - * \def MBEDTLS_ECP_RESTARTABLE - * - * Enable "non-blocking" ECC operations that can return early and be resumed. - * - * This allows various functions to pause by returning - * #MBEDTLS_ERR_ECP_IN_PROGRESS (or, for functions in the SSL module, - * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS) and then be called later again in - * order to further progress and eventually complete their operation. This is - * controlled through mbedtls_ecp_set_max_ops() which limits the maximum - * number of ECC operations a function may perform before pausing; see - * mbedtls_ecp_set_max_ops() for more information. - * - * This is useful in non-threaded environments if you want to avoid blocking - * for too long on ECC (and, hence, X.509 or SSL/TLS) operations. - * - * Uncomment this macro to enable restartable ECC computations. - * - * \note This option only works with the default software implementation of - * elliptic curve functionality. It is incompatible with - * MBEDTLS_ECP_ALT, MBEDTLS_ECDH_XXX_ALT and MBEDTLS_ECDSA_XXX_ALT. - */ -//#define MBEDTLS_ECP_RESTARTABLE - /** * \def MBEDTLS_ECDSA_DETERMINISTIC * @@ -1269,7 +981,7 @@ * * Uncomment this macro to disable the built-in platform entropy functions. */ -//#define MBEDTLS_NO_PLATFORM_ENTROPY +#define MBEDTLS_NO_PLATFORM_ENTROPY /** * \def MBEDTLS_ENTROPY_FORCE_SHA256 @@ -1397,26 +1109,14 @@ * * The default implementation is meant to be a reasonnable compromise between * performance and size. This version optimizes more aggressively for size at - * the expense of performance. - * - * For example, on a Cortex-M0 core it reduces the size of the module by about - * 2KiB for a performance cost of about 45%; on a Cortex-M4 core the size - * benefit is about 1.5 KiB for a performance cost of of about 30%. + * the expense of performance. Eg on Cortex-M4 it reduces the size of + * mbedtls_sha256_process() from ~2KB to ~0.5KB for a performance hit of about + * 30%. * * Uncomment to enable the smaller implementation of SHA256. */ //#define MBEDTLS_SHA256_SMALLER -/** - * \def MBEDTLS_SHA256_NO_SHA224 - * - * Disable the SHA-224 option of the SHA-256 module. Use this to save some - * code size on devices that don't use SHA-224. - * - * Uncomment to disable SHA-224 - */ -//#define MBEDTLS_SHA256_NO_SHA224 - /** * \def MBEDTLS_SSL_ALL_ALERT_MESSAGES * @@ -1431,85 +1131,6 @@ */ #define MBEDTLS_SSL_ALL_ALERT_MESSAGES -/** - * \def MBEDTLS_SSL_RECORD_CHECKING - * - * Enable the API mbedtls_ssl_check_record() which allows to check the - * validity, freshness and authenticity of an incoming record without - * modifying the externally visible state of the SSL context. - * - * See mbedtls_ssl_check_record() for more information. - * - * Uncomment to enable support for record checking. - */ -#define MBEDTLS_SSL_RECORD_CHECKING - -/** - * \def MBEDTLS_SSL_DTLS_CONNECTION_ID - * - * Enable support for the DTLS Connection ID extension - * (version draft-ietf-tls-dtls-connection-id-05, - * https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05) - * which allows to identify DTLS connections across changes - * in the underlying transport. - * - * Setting this option enables the SSL APIs mbedtls_ssl_set_cid(), - * mbedtls_ssl_get_peer_cid() and mbedtls_ssl_conf_cid(). - * See the corresponding documentation for more information. - * - * \warning The Connection ID extension is still in draft state. - * We make no stability promises for the availability - * or the shape of the API controlled by this option. - * - * The maximum lengths of outgoing and incoming CIDs can be configured - * through the options - * - MBEDTLS_SSL_CID_OUT_LEN_MAX - * - MBEDTLS_SSL_CID_IN_LEN_MAX. - * - * Requires: MBEDTLS_SSL_PROTO_DTLS - * - * Uncomment to enable the Connection ID extension. - */ -//#define MBEDTLS_SSL_DTLS_CONNECTION_ID - -/** - * \def MBEDTLS_SSL_ASYNC_PRIVATE - * - * Enable asynchronous external private key operations in SSL. This allows - * you to configure an SSL connection to call an external cryptographic - * module to perform private key operations instead of performing the - * operation inside the library. - * - */ -//#define MBEDTLS_SSL_ASYNC_PRIVATE - -/** - * \def MBEDTLS_SSL_CONTEXT_SERIALIZATION - * - * Enable serialization of the TLS context structures, through use of the - * functions mbedtls_ssl_context_save() and mbedtls_ssl_context_load(). - * - * This pair of functions allows one side of a connection to serialize the - * context associated with the connection, then free or re-use that context - * while the serialized state is persisted elsewhere, and finally deserialize - * that state to a live context for resuming read/write operations on the - * connection. From a protocol perspective, the state of the connection is - * unaffected, in particular this is entirely transparent to the peer. - * - * Note: this is distinct from TLS session resumption, which is part of the - * protocol and fully visible by the peer. TLS session resumption enables - * establishing new connections associated to a saved session with shorter, - * lighter handshakes, while context serialization is a local optimization in - * handling a single, potentially long-lived connection. - * - * Enabling these APIs makes some SSL structures larger, as 64 extra bytes are - * saved after the handshake to allow for more efficient serialization, so if - * you don't need this feature you'll save RAM by disabling it. - * - * Comment to disable the context serialization APIs. - */ -#define MBEDTLS_SSL_CONTEXT_SERIALIZATION - /** * \def MBEDTLS_SSL_DEBUG_ALL * @@ -1579,61 +1200,6 @@ */ #define MBEDTLS_SSL_FALLBACK_SCSV -/** - * \def MBEDTLS_SSL_KEEP_PEER_CERTIFICATE - * - * This option controls the availability of the API mbedtls_ssl_get_peer_cert() - * giving access to the peer's certificate after completion of the handshake. - * - * Unless you need mbedtls_ssl_peer_cert() in your application, it is - * recommended to disable this option for reduced RAM usage. - * - * \note If this option is disabled, mbedtls_ssl_get_peer_cert() is still - * defined, but always returns \c NULL. - * - * \note This option has no influence on the protection against the - * triple handshake attack. Even if it is disabled, Mbed TLS will - * still ensure that certificates do not change during renegotiation, - * for exaple by keeping a hash of the peer's certificate. - * - * Comment this macro to disable storing the peer's certificate - * after the handshake. - */ -#define MBEDTLS_SSL_KEEP_PEER_CERTIFICATE - -/** - * \def MBEDTLS_SSL_FREE_SERVER_CERTIFICATE - * - * This option controls determines whether the server certificate is discarded - * after a handshake when the MBEDTLS_SSL_KEEP_PEER_CERTIFICATE is enabled. - * - * Use of this option is useful in combined with the delayed certificate verification - * when the server certificate has to be kept for the duration of the handshake - * but not afterwards. - * - */ -//#define MBEDTLS_SSL_FREE_SERVER_CERTIFICATE - - -/** - * \def MBEDTLS_SSL_IMMEDIATE_TRANSMISSION - * - * Force stack to immediately transmit messages. - * - * Requires: MBEDTLS_SSL_PROTO_DTLS - */ -//#define MBEDTLS_SSL_IMMEDIATE_TRANSMISSION - -/** - * \def MBEDTLS_SSL_EARLY_KEY_COMPUTATION - * - * Create ephemeral Diffie-Hellman key pair after - * the ClientHello has been successfully transmitted. - * - * Requires: - */ -//#define MBEDTLS_SSL_EARLY_KEY_COMPUTATION - /** * \def MBEDTLS_SSL_HW_RECORD_ACCEL * @@ -1710,7 +1276,7 @@ /** * \def MBEDTLS_SSL_PROTO_SSL3 * - * Enable support for SSL 3.0 (if TLS is enabled). + * Enable support for SSL 3.0. * * Requires: MBEDTLS_MD5_C * MBEDTLS_SHA1_C @@ -1722,7 +1288,7 @@ /** * \def MBEDTLS_SSL_PROTO_TLS1 * - * Enable support for TLS 1.0 (if TLS is enabled). + * Enable support for TLS 1.0. * * Requires: MBEDTLS_MD5_C * MBEDTLS_SHA1_C @@ -1734,8 +1300,7 @@ /** * \def MBEDTLS_SSL_PROTO_TLS1_1 * - * Enable support for TLS 1.1 (if TLS is enabled) and DTLS 1.0 (if DTLS is - * enabled). + * Enable support for TLS 1.1 (and DTLS 1.0 if DTLS is enabled). * * Requires: MBEDTLS_MD5_C * MBEDTLS_SHA1_C @@ -1747,8 +1312,7 @@ /** * \def MBEDTLS_SSL_PROTO_TLS1_2 * - * Enable support for TLS 1.2 (if TLS is enabled) and DTLS 1.2 (if DTLS is - * enabled). + * Enable support for TLS 1.2 (and DTLS 1.2 if DTLS is enabled). * * Requires: MBEDTLS_SHA1_C or MBEDTLS_SHA256_C or MBEDTLS_SHA512_C * (Depends on ciphersuites) @@ -1762,10 +1326,8 @@ * * Enable support for DTLS (all available versions). * - * Enable this and MBEDTLS_SSL_PROTO_TLS1_2 to enable DTLS 1.2, - * and/or this and MBEDTLS_SSL_PROTO_TLS1_1 to enable DTLS 1.0. - * - * \see MBEDTLS_SSL_PROTO_NO_TLS + * Enable this and MBEDTLS_SSL_PROTO_TLS1_1 to enable DTLS 1.0, + * and/or this and MBEDTLS_SSL_PROTO_TLS1_2 to enable DTLS 1.2. * * Requires: MBEDTLS_SSL_PROTO_TLS1_1 * or MBEDTLS_SSL_PROTO_TLS1_2 @@ -1774,25 +1336,6 @@ */ #define MBEDTLS_SSL_PROTO_DTLS -/** - * \def MBEDTLS_SSL_PROTO_NO_TLS - * - * Disable support for SSL/TLS (all available versions) - this doesn't affect - * support for DTLS which is controlled by #MBEDTLS_SSL_PROTO_DTLS. This is - * useful to reduce code size in configurations where only DTLS is used. - * - * Disable this and enable MBEDTLS_SSL_PROTO_TLS1_2 to enable TLS 1.2; - * disable this and enable MBEDTLS_SSL_PROTO_TLS1_1 to enable TLS 1.1; - * disable this and enable MBEDTLS_SSL_PROTO_TLS1 to enable TLS 1.0; - * disable this and enable MBEDTLS_SSL_PROTO_SSL3 to enable SSL 3.0. - * - * Requirements: if this macro is disabled, at least one of the above - * TLS versions needs to be enabled. - * - * Uncomment this macro to disable support for TLS. - */ -//#define MBEDTLS_SSL_PROTO_NO_TLS - /** * \def MBEDTLS_SSL_ALPN * @@ -1866,69 +1409,16 @@ * \def MBEDTLS_SSL_SESSION_TICKETS * * Enable support for RFC 5077 session tickets in SSL. - * Client-side, provides full support for session tickets (maintenance of a + * Client-side, provides full support for session tickets (maintainance of a * session store remains the responsibility of the application, though). * Server-side, you also need to provide callbacks for writing and parsing * tickets, including authenticated encryption and key management. Example * callbacks are provided by MBEDTLS_SSL_TICKET_C. * - * Requires: !MBEDTLS_SSL_NO_SESSION_RESUMPTION - * - * Comment this macro to disable support for SSL session tickets. + * Comment this macro to disable support for SSL session tickets */ #define MBEDTLS_SSL_SESSION_TICKETS -/** - * \def MBEDTLS_SSL_NO_SESSION_CACHE - * - * Disable support for cache based session resumption. This is useful to - * reduce code size in configurations where cache-based session resumption is - * not used. - * - * This option is only about the server-side support of the session caches. - * Client will only need !MBEDTLS_SSL_NO_SESSION_RESUMPTION to support - * cache based session resumption. - * - * Server-side, you also need to provide callbacks for storing and reading - * sessions from cache. Example callbacks are provided by MBEDTLS_SSL_CACHE_C. - * - * If MBEDTLS_SSL_NO_SESSION_RESUMPTION is defined, this needs to be defined - * as well. - * - * Uncomment this macro to disable support for SSL session cache. - */ -//#define MBEDTLS_SSL_NO_SESSION_CACHE - -/** - * \def MBEDTLS_SSL_NO_SESSION_RESUMPTION - * - * Disable support for session resumption. This is useful to reduce code size - * in configurations where no form of session resumption is used. - * - * \note Session resumption is part of the TLS standard, disabling this - * option means that the full implementation of the standard is no longer - * used. This shouldn't cause any interoperability issues as the standard - * mandates that peers who want to resume a session need to be prepared to - * fall back to a full handshake. - * - * When this flag is enabled, following needs to be true: - * MBEDTLS_SSL_NO_SESSION_CACHE enabled - * MBEDTLS_SSL_SESSION_TICKETS disabled - * - * Client-side, this is enough to enable support for cache-based session - * resumption (as defined by the TLS standard); for ticket-based resumption - * you'll also need to enable MBEDTLS_SSL_SESSION_TICKETS. - * - * Server-side, this option is only useful in conjunction with at least - * one of !MBEDTLS_SSL_NO_SESSION_CACHE or MBEDTLS_SSL_SESSION_TICKETS. - * Each one of these additionally requires an implementation of the cache - * or tickets, examples of which are provided by MBEDTLS_SSL_CACHE_C - * and MBEDTLS_SSL_TICKET_C respectively. - * - * Uncomment this macro to disable support for SSL session resumption. - */ -//#define MBEDTLS_SSL_NO_SESSION_RESUMPTION - /** * \def MBEDTLS_SSL_EXPORT_KEYS * @@ -1983,17 +1473,6 @@ */ //#define MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT -/** - * \def MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH - * - * Enable modifying the maximum I/O buffer size in runtime. - * - * If the library runs out of memory during the resizing of an I/O buffer, - * there is no error returned. The operation continues as usual on an - * unchanged buffer without any negative impact on the flow. - */ -//#define MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH - /** * \def MBEDTLS_THREADING_ALT * @@ -2029,54 +1508,6 @@ */ #define MBEDTLS_VERSION_FEATURES -/** - * \def MBEDTLS_X509_ON_DEMAND_PARSING - * - * Save RAM by reducing mbedtls_x509_crt to a pointer - * to the raw CRT data and parsing CRTs on demand only. - * - * \warning This option changes the API by removing most of - * the structure fields of mbedtls_x509_crt. - * - * \warning This option and its corresponding X.509 API are currently - * under development and may change at any time. - * - * Regardless of whether this option is enabled or not, direct access of - * structure fields of `mbedtls_x509_crt` should be replaced by calls to - * one of the following functions: - * - mbedtls_x509_crt_get_frame(), to obtain a CRT frame giving - * access to several basic CRT fields (such as the CRT version), - * as well as pointers to the raw ASN.1 data of more complex fields - * (such as the issuer). - * - mbedtls_x509_crt_get_pk(), to obtain a public key context - * for the public key contained in the certificate. - * - mbedtls_x509_crt_get_issuer(), to obtain the issuer name. - * - mbedtls_x509_crt_get_subject(), to obtain the subject name. - * - mbedtls_x509_crt_get_subject_alt_names(), to obtain the - * alternative names from the subject alternative names extension. - * - mbedtls_x509_crt_get_ext_key_usage(), to obtain the state of - * the extended key usage extension. - * - * Uncomment this to enable on-demand CRT parsing to save RAM. - */ -//#define MBEDTLS_X509_ON_DEMAND_PARSING - -/** - * \def MBEDTLS_X509_ALWAYS_FLUSH - * - * Save RAM by having Mbed TLS always flush caches for parsed X.509 - * structures after use: This means, firstly, that caches of X.509 - * structures used by an API call are flushed when the call returns, - * but it also encompasses immediate flushing of caches when Mbed TLS uses - * multiple structures in succession, thereby reducing the peak RAM usage. - * Setting this option leads to minimal RAM usage of the X.509 module at - * the cost of performance penalties when using X.509 structures multiple - * times (such as trusted CRTs on systems serving many connections). - * - * Uncomment this to always flush caches for unused X.509 structures. - */ -#define MBEDTLS_X509_ALWAYS_FLUSH - /** * \def MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3 * @@ -2126,89 +1557,6 @@ */ #define MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE -/** - * \def MBEDTLS_X509_REMOVE_INFO - * - * Enable mbedtls_x509_*_info() and related APIs. - * - * Comment to omit mbedtls_x509_*_info(), as well as mbedtls_debug_print_crt() - * and other functions/constants only used by these functions, thus reducing - * the code footprint by several KB. - */ -//#define MBEDTLS_X509_REMOVE_INFO - -/** - * \def MBEDTLS_X509_CRT_REMOVE_TIME - * - * Don't store time validity fields in X.509 certificate structures. - * - * Uncomment this to save some code and RAM on constrained systems which - * don't have time and where there's no use of the time validity fields - * in a certificate. - * - * Requires: !MBEDTLS_HAVE_TIME_DATE - */ -//#define MBEDTLS_X509_CRT_REMOVE_TIME - -/** - * \def MBEDTLS_X509_CRT_REMOVE_SUBJECT_ISSUER_ID - * - * Don't store subject and issuer ID in X.509 certificate structures. - * - * Uncomment this to save some code and RAM on constrained systems which - * don't need to inspect issuer and subject ID fields in certificates. - */ -//#define MBEDTLS_X509_CRT_REMOVE_SUBJECT_ISSUER_ID - -/** - * \def MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION - * - * Remove hostname verification from APIs related to X.509 certificate validation. - * - * \warning Uncommenting this affects parsing and verification of - * X.509 certificate by leaving Common Name and Subject Alternative Name fields out - * of parsing and verification. - * - * Affected API's: - * - mbedtls_ssl_set_hostname() not available. - * - mbedtls_x509_crt_get_subject_alt_names() not available. - * - mbedtls_x509_crt_parse_der(): Subject Alternative Name field - * is not parsed. - * - mbedtls_x509_crt_parse_der_nocopy(): Subject Alternative Name field - * is not parsed. - * - mbedtls_x509_crt_parse(): Subject Alternative Name field - * is not parsed. - * - mbedtls_x509_crt_parse_file(): Subject Alternative Name field - * is not parsed. - * - mbedtls_x509_crt_parse_path(): Subject Alternative Name field - * is not parsed. - * - mbedtls_x509_crt_info(): Subject Alternative Name field - * is not parsed. - * - mbedtls_x509_crt_verify(): param \c cn is omitted from the API. - * - mbedtls_x509_crt_verify_with_profile(): param \c cn is omitted from the API. - * - mbedtls_x509_crt_verify_restartable(): param \c cn is omitted from the API. - * - - * - * Affected structs - * - ::mbedtls_x509_crt_frame: subject_alt_raw is defined out. - * - ::mbedtls_x509_crt: subject_alt_names is defined out. - * - * Uncomment this to save some code and RAM on constrained systems which - * don't need hostname verification. - */ -//#define MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION - -/** - * \def MBEDTLS_X509_REMOVE_VERIFY_CALLBACK - * - * Remove support for X.509 certificate verification callbacks. - * - * Uncomment to save some bytes of code by removing support for X.509 - * certificate verification callbacks in mbedtls_x509_crt_verify() and - * related verification API. - */ -//#define MBEDTLS_X509_REMOVE_VERIFY_CALLBACK - /** * \def MBEDTLS_X509_RSASSA_PSS_SUPPORT * @@ -2227,13 +1575,10 @@ * * \warning TLS-level compression MAY REDUCE SECURITY! See for example the * CRIME attack. Before enabling this option, you should examine with care if - * CRIME or similar exploits may be applicable to your use case. + * CRIME or similar exploits may be a applicable to your use case. * * \note Currently compression can't be used with DTLS. * - * \deprecated This feature is deprecated and will be removed - * in the next major revision of the library. - * * Used in: library/ssl_tls.c * library/ssl_cli.c * library/ssl_srv.c @@ -2272,7 +1617,7 @@ * Enable the AES block cipher. * * Module: library/aes.c - * Caller: library/cipher.c + * Caller: library/ssl_tls.c * library/pem.c * library/ctr_drbg.c * @@ -2347,7 +1692,7 @@ * Enable the ARCFOUR stream cipher. * * Module: library/arc4.c - * Caller: library/cipher.c + * Caller: library/ssl_tls.c * * This module enables the following ciphersuites (if other requisites are * enabled as well): @@ -2441,7 +1786,7 @@ * Enable the Camellia block cipher. * * Module: library/camellia.c - * Caller: library/cipher.c + * Caller: library/ssl_tls.c * * This module enables the following ciphersuites (if other requisites are * enabled as well): @@ -2490,58 +1835,6 @@ */ #define MBEDTLS_CAMELLIA_C -/** - * \def MBEDTLS_ARIA_C - * - * Enable the ARIA block cipher. - * - * Module: library/aria.c - * Caller: library/cipher.c - * - * This module enables the following ciphersuites (if other requisites are - * enabled as well): - * - * MBEDTLS_TLS_RSA_WITH_ARIA_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_ARIA_256_CBC_SHA384 - * MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384 - * MBEDTLS_TLS_RSA_WITH_ARIA_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_WITH_ARIA_256_GCM_SHA384 - * MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384 - * MBEDTLS_TLS_PSK_WITH_ARIA_128_CBC_SHA256 - * MBEDTLS_TLS_PSK_WITH_ARIA_256_CBC_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384 - * MBEDTLS_TLS_PSK_WITH_ARIA_128_GCM_SHA256 - * MBEDTLS_TLS_PSK_WITH_ARIA_256_GCM_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256 - * MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384 - */ -//#define MBEDTLS_ARIA_C - /** * \def MBEDTLS_CCM_C * @@ -2568,26 +1861,6 @@ */ #define MBEDTLS_CERTS_C -/** - * \def MBEDTLS_CHACHA20_C - * - * Enable the ChaCha20 stream cipher. - * - * Module: library/chacha20.c - */ -#define MBEDTLS_CHACHA20_C - -/** - * \def MBEDTLS_CHACHAPOLY_C - * - * Enable the ChaCha20-Poly1305 AEAD algorithm. - * - * Module: library/chachapoly.c - * - * This module requires: MBEDTLS_CHACHA20_C, MBEDTLS_POLY1305_C - */ -#define MBEDTLS_CHACHAPOLY_C - /** * \def MBEDTLS_CIPHER_C * @@ -2616,20 +1889,14 @@ /** * \def MBEDTLS_CTR_DRBG_C * - * Enable the CTR_DRBG AES-based random generator. - * The CTR_DRBG generator uses AES-256 by default. - * To use AES-128 instead, enable \c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY above. - * - * \note To achieve a 256-bit security strength with CTR_DRBG, - * you must use AES-256 *and* use sufficient entropy. - * See ctr_drbg.h for more details. + * Enable the CTR_DRBG AES-256-based random generator. * * Module: library/ctr_drbg.c * Caller: * * Requires: MBEDTLS_AES_C * - * This module provides the CTR_DRBG AES random number generator. + * This module provides the CTR_DRBG AES-256 random number generator. */ #define MBEDTLS_CTR_DRBG_C @@ -2645,7 +1912,10 @@ * * This module provides debugging functions. */ + +#ifdef PKG_USING_MBEDTLS_DEBUG #define MBEDTLS_DEBUG_C +#endif /** * \def MBEDTLS_DES_C @@ -2654,7 +1924,7 @@ * * Module: library/des.c * Caller: library/pem.c - * library/cipher.c + * library/ssl_tls.c * * This module enables the following ciphersuites (if other requisites are * enabled as well): @@ -2761,47 +2031,6 @@ */ #define MBEDTLS_ECP_C -/** - * \def MBEDTLS_USE_TINYCRYPT - * - * Enable the TinyCrypt ECC library. This module provides alternative ECC - * handling functions replacing the native Mbed TLS ECP module. - * - * TinyCrypt is a project independent from Mbed TLS, licensed under 3-clause - * BSD, and can be found at https://github.com/intel/tinycrypt - this option - * only enables the ECC modules from TinyCrypt. - * - * Requires: MBEDTLS_SSL_CONF_RNG - * MBEDTLS_SSL_CONF_SINGLE_EC - * MBEDTLS_SSL_CONF_SINGLE_EC_TLS_ID == 23 - * MBEDTLS_SSL_CONF_SINGLE_UECC_GRP_ID == MBEDTLS_UECC_DP_SECP256R1 - * MBEDTLS_SHA256_C - * - * \see MBEDTLS_SSL_CONF_RNG - * - * \see MBEDTLS_SSL_CONF_SINGLE_EC - * - * Module: tinycrypt/ecc.c - * tinycrypt/ecc_dh.c - * tinycrypt/ecc_dsa.c - */ -//#define MBEDTLS_USE_TINYCRYPT - -/** - * \def MBEDTLS_OPTIMIZE_TINYCRYPT_ASM - * - * Optimize TinyCrypt operations using assembly. - * Add T32/A32 assembly for core tinycrypt/microecc routines, for ARMC5 and GCC; - * Use fast integer types to avoid frequent narrowing instructions; - * Use __builtin_clz and avoid boolean ops. - * - * Requires: MBEDTLS_USE_TINYCRYPT - * MBEDTLS_HAVE_ASM - * - * Module: tinycrypt/ecc.c - */ -//#define MBEDTLS_OPTIMIZE_TINYCRYPT_ASM - /** * \def MBEDTLS_ENTROPY_C * @@ -2828,40 +2057,6 @@ */ #define MBEDTLS_ERROR_C -/** - * \def MBEDTLS_CRC_C - * - * Enable the CRC calculating module - * - * Module: library/crc.c - * - * This module enables mbedtls_crc_update(). - */ -//#define MBEDTLS_CRC_C - -/** - * \def MBEDTLS_VALIDATE_SSL_KEYS_INTEGRITY - * - * Enable validation of ssl keys by checking their hash - * during every encryption/decryption. - * - * Module: library/ssl_tls.c - * - * Requires: MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS - */ -//#define MBEDTLS_VALIDATE_SSL_KEYS_INTEGRITY - -/** - * \def MBEDTLS_VALIDATE_AES_KEYS_INTEGRITY - * - * Enable validation of AES keys by checking their hash - * during every encryption/decryption. - * - * Module: library/aes.c - * - */ -//#define MBEDTLS_VALIDATE_AES_KEYS_INTEGRITY - /** * \def MBEDTLS_GCM_C * @@ -2899,21 +2094,6 @@ */ //#define MBEDTLS_HAVEGE_C -/** - * \def MBEDTLS_HKDF_C - * - * Enable the HKDF algorithm (RFC 5869). - * - * Module: library/hkdf.c - * Caller: - * - * Requires: MBEDTLS_MD_C - * - * This module adds support for the Hashed Message Authentication Code - * (HMAC)-based key derivation function (HKDF). - */ -#define MBEDTLS_HKDF_C - /** * \def MBEDTLS_HMAC_DRBG_C * @@ -2928,19 +2108,6 @@ */ #define MBEDTLS_HMAC_DRBG_C -/** - * \def MBEDTLS_NIST_KW_C - * - * Enable the Key Wrapping mode for 128-bit block ciphers, - * as defined in NIST SP 800-38F. Only KW and KWP modes - * are supported. At the moment, only AES is approved by NIST. - * - * Module: library/nist_kw.c - * - * Requires: MBEDTLS_AES_C and MBEDTLS_CIPHER_C - */ -//#define MBEDTLS_NIST_KW_C - /** * \def MBEDTLS_MD_C * @@ -3025,20 +2192,6 @@ */ //#define MBEDTLS_MEMORY_BUFFER_ALLOC_C -/** - * \def MBEDTLS_PLATFORM_FAULT_CALLBACKS - * - * Uncomment to provide your own alternate implementation for - * mbedtls_platform_fault(), used in library/platform_util.c and - * tinycrypt/ecc.c to signal a fault injection in either - * mbedtls_platform_memcpy, mbedtls_platform_memset, mbedtls_platform_random_buf, - * or uECC_vli_mmod. - * - * You will need to provide a header "platform_fault.h" and an implementation at - * compile time. - */ -//#define MBEDTLS_PLATFORM_FAULT_CALLBACKS - /** * \def MBEDTLS_NET_C * @@ -3056,7 +2209,7 @@ * * This module provides networking routines. */ -#define MBEDTLS_NET_C +//#define MBEDTLS_NET_C /** * \def MBEDTLS_OID_C @@ -3238,16 +2391,6 @@ */ #define MBEDTLS_PLATFORM_C -/** - * \def MBEDTLS_POLY1305_C - * - * Enable the Poly1305 MAC algorithm. - * - * Module: library/poly1305.c - * Caller: library/chachapoly.c - */ -#define MBEDTLS_POLY1305_C - /** * \def MBEDTLS_RIPEMD160_C * @@ -3410,20 +2553,6 @@ */ #define MBEDTLS_SSL_TLS_C -/** - * \def MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS - * Use one cipher context for both decryption and encryption in ssl transforms. - * - * This change saves some RAM, but makes the operations last longer: - * before every encryption and decryption a key is set on the context. - * - * This change will not work with MBEDTLS_ARC4_C, since it requires an - * additional table and offsets to be saved between cipher calls, and this - * contradicts key resetting before each use. - * - */ -//#define MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS - /** * \def MBEDTLS_THREADING_C * @@ -3609,7 +2738,7 @@ /* MPI / BIGNUM options */ //#define MBEDTLS_MPI_WINDOW_SIZE 6 /**< Maximum windows size used. */ -//#define MBEDTLS_MPI_MAX_SIZE 1024 /**< Maximum number of bytes for usable MPIs. */ +//#define MBEDTLS_MPI_MAX_SIZE 256 /**< Maximum number of bytes for usable MPIs. */ /* CTR_DRBG options */ //#define MBEDTLS_CTR_DRBG_ENTROPY_LEN 48 /**< Amount of entropy used per seed by default (48 with SHA-512, 32 with SHA-256) */ @@ -3645,7 +2774,7 @@ //#define MBEDTLS_PLATFORM_STD_TIME time /**< Default time to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ //#define MBEDTLS_PLATFORM_STD_FPRINTF fprintf /**< Default fprintf to use, can be undefined */ //#define MBEDTLS_PLATFORM_STD_PRINTF printf /**< Default printf to use, can be undefined */ -/* Note: your snprintf must correctly zero-terminate the buffer! */ +/* Note: your snprintf must correclty zero-terminate the buffer! */ //#define MBEDTLS_PLATFORM_STD_SNPRINTF snprintf /**< Default snprintf to use, can be undefined */ //#define MBEDTLS_PLATFORM_STD_EXIT_SUCCESS 0 /**< Default exit value to use, can be undefined */ //#define MBEDTLS_PLATFORM_STD_EXIT_FAILURE 1 /**< Default exit value to use, can be undefined */ @@ -3662,176 +2791,17 @@ //#define MBEDTLS_PLATFORM_TIME_TYPE_MACRO time_t /**< Default time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ //#define MBEDTLS_PLATFORM_FPRINTF_MACRO fprintf /**< Default fprintf macro to use, can be undefined */ //#define MBEDTLS_PLATFORM_PRINTF_MACRO printf /**< Default printf macro to use, can be undefined */ -/* Note: your snprintf must correctly zero-terminate the buffer! */ +/* Note: your snprintf must correclty zero-terminate the buffer! */ //#define MBEDTLS_PLATFORM_SNPRINTF_MACRO snprintf /**< Default snprintf macro to use, can be undefined */ //#define MBEDTLS_PLATFORM_NV_SEED_READ_MACRO mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */ //#define MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */ -/** - * \brief This macro is invoked by the library when an invalid parameter - * is detected that is only checked with #MBEDTLS_CHECK_PARAMS - * (see the documentation of that option for context). - * - * When you leave this undefined here, the library provides - * a default definition. If the macro #MBEDTLS_CHECK_PARAMS_ASSERT - * is defined, the default definition is `assert(cond)`, - * otherwise the default definition calls a function - * mbedtls_param_failed(). This function is declared in - * `platform_util.h` for the benefit of the library, but - * you need to define in your application. - * - * When you define this here, this replaces the default - * definition in platform_util.h (which no longer declares the - * function mbedtls_param_failed()) and it is your responsibility - * to make sure this macro expands to something suitable (in - * particular, that all the necessary declarations are visible - * from within the library - you can ensure that by providing - * them in this file next to the macro definition). - * If you define this macro to call `assert`, also define - * #MBEDTLS_CHECK_PARAMS_ASSERT so that library source files - * include ``. - * - * Note that you may define this macro to expand to nothing, in - * which case you don't have to worry about declarations or - * definitions. However, you will then be notified about invalid - * parameters only in non-void functions, and void function will - * just silently return early on invalid parameters, which - * partially negates the benefits of enabling - * #MBEDTLS_CHECK_PARAMS in the first place, so is discouraged. - * - * \param cond The expression that should evaluate to true, but doesn't. - */ -//#define MBEDTLS_PARAM_FAILED( cond ) assert( cond ) - /* SSL Cache options */ //#define MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT 86400 /**< 1 day */ //#define MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES 50 /**< Maximum entries in cache */ /* SSL options */ - -/** \def MBEDTLS_SSL_MAX_CONTENT_LEN - * - * Maximum length (in bytes) of incoming and outgoing plaintext fragments. - * - * This determines the size of both the incoming and outgoing TLS I/O buffers - * in such a way that both are capable of holding the specified amount of - * plaintext data, regardless of the protection mechanism used. - * - * To configure incoming and outgoing I/O buffers separately, use - * #MBEDTLS_SSL_IN_CONTENT_LEN and #MBEDTLS_SSL_OUT_CONTENT_LEN, - * which overwrite the value set by this option. - * - * \note When using a value less than the default of 16KB on the client, it is - * recommended to use the Maximum Fragment Length (MFL) extension to - * inform the server about this limitation. On the server, there - * is no supported, standardized way of informing the client about - * restriction on the maximum size of incoming messages, and unless - * the limitation has been communicated by other means, it is recommended - * to only change the outgoing buffer size #MBEDTLS_SSL_OUT_CONTENT_LEN - * while keeping the default value of 16KB for the incoming buffer. - * - * Uncomment to set the maximum plaintext size of both - * incoming and outgoing I/O buffers. - */ -//#define MBEDTLS_SSL_MAX_CONTENT_LEN 16384 - -/** \def MBEDTLS_SSL_IN_CONTENT_LEN - * - * Maximum length (in bytes) of incoming plaintext fragments. - * - * This determines the size of the incoming TLS I/O buffer in such a way - * that it is capable of holding the specified amount of plaintext data, - * regardless of the protection mechanism used. - * - * If this option is undefined, it inherits its value from - * #MBEDTLS_SSL_MAX_CONTENT_LEN. - * - * \note When using a value less than the default of 16KB on the client, it is - * recommended to use the Maximum Fragment Length (MFL) extension to - * inform the server about this limitation. On the server, there - * is no supported, standardized way of informing the client about - * restriction on the maximum size of incoming messages, and unless - * the limitation has been communicated by other means, it is recommended - * to only change the outgoing buffer size #MBEDTLS_SSL_OUT_CONTENT_LEN - * while keeping the default value of 16KB for the incoming buffer. - * - * Uncomment to set the maximum plaintext size of the incoming I/O buffer - * independently of the outgoing I/O buffer. - */ -//#define MBEDTLS_SSL_IN_CONTENT_LEN 16384 - -/** \def MBEDTLS_SSL_CID_IN_LEN_MAX - * - * The maximum length of CIDs used for incoming DTLS messages. - * - */ -//#define MBEDTLS_SSL_CID_IN_LEN_MAX 32 - -/** \def MBEDTLS_SSL_CID_OUT_LEN_MAX - * - * The maximum length of CIDs used for outgoing DTLS messages. - * - */ -//#define MBEDTLS_SSL_CID_OUT_LEN_MAX 32 - -/** \def MBEDTLS_SSL_CID_PADDING_GRANULARITY - * - * This option controls the use of record plaintext padding - * when using the Connection ID extension in DTLS 1.2. - * - * The padding will always be chosen so that the length of the - * padded plaintext is a multiple of the value of this option. - * - * Note: A value of \c 1 means that no padding will be used - * for outgoing records. - * - * Note: On systems lacking division instructions, - * a power of two should be preferred. - * - */ -//#define MBEDTLS_SSL_CID_PADDING_GRANULARITY 16 - -/** \def MBEDTLS_SSL_OUT_CONTENT_LEN - * - * Maximum length (in bytes) of outgoing plaintext fragments. - * - * This determines the size of the outgoing TLS I/O buffer in such a way - * that it is capable of holding the specified amount of plaintext data, - * regardless of the protection mechanism used. - * - * If this option undefined, it inherits its value from - * #MBEDTLS_SSL_MAX_CONTENT_LEN. - * - * It is possible to save RAM by setting a smaller outward buffer, while keeping - * the default inward 16384 byte buffer to conform to the TLS specification. - * - * The minimum required outward buffer size is determined by the handshake - * protocol's usage. Handshaking will fail if the outward buffer is too small. - * The specific size requirement depends on the configured ciphers and any - * certificate data which is sent during the handshake. - * - * Uncomment to set the maximum plaintext size of the outgoing I/O buffer - * independently of the incoming I/O buffer. - */ -//#define MBEDTLS_SSL_OUT_CONTENT_LEN 16384 - -/** \def MBEDTLS_SSL_DTLS_MAX_BUFFERING - * - * Maximum number of heap-allocated bytes for the purpose of - * DTLS handshake message reassembly and future message buffering. - * - * This should be at least 9/8 * MBEDTLSSL_IN_CONTENT_LEN - * to account for a reassembled handshake message of maximum size, - * together with its reassembly bitmap. - * - * A value of 2 * MBEDTLS_SSL_IN_CONTENT_LEN (32768 by default) - * should be sufficient for all practical situations as it allows - * to reassembly a large handshake message (such as a certificate) - * while buffering multiple smaller handshake messages. - * - */ -//#define MBEDTLS_SSL_DTLS_MAX_BUFFERING 32768 - +//#define MBEDTLS_SSL_MAX_CONTENT_LEN 16384 /**< Maxium fragment length in bytes, determines the size of each of the two internal I/O buffers */ //#define MBEDTLS_SSL_DEFAULT_TICKET_LIFETIME 86400 /**< Lifetime of session tickets (if enabled) */ //#define MBEDTLS_PSK_MAX_LEN 32 /**< Max size of TLS pre-shared keys, in bytes (default 256 bits) */ //#define MBEDTLS_SSL_COOKIE_TIMEOUT 60 /**< Default expiration delay of DTLS cookies, in seconds if HAVE_TIME, or in number of cookies issued */ @@ -3848,7 +2818,7 @@ * * The value below is only an example, not the default. */ -//#define MBEDTLS_SSL_CIPHERSUITES MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 +#define MBEDTLS_SSL_CIPHERSUITES MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256 /* X509 options */ //#define MBEDTLS_X509_MAX_INTERMEDIATE_CA 8 /**< Maximum number of intermediate CAs in a verification chain. */ @@ -3885,237 +2855,52 @@ */ #define MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_KEY_EXCHANGE -/** - * Uncomment the macro to let mbed TLS use your alternate implementation of - * mbedtls_platform_zeroize(). This replaces the default implementation in - * platform_util.c. - * - * mbedtls_platform_zeroize() is a widely used function across the library to - * zero a block of memory. The implementation is expected to be secure in the - * sense that it has been written to prevent the compiler from removing calls - * to mbedtls_platform_zeroize() as part of redundant code elimination - * optimizations. However, it is difficult to guarantee that calls to - * mbedtls_platform_zeroize() will not be optimized by the compiler as older - * versions of the C language standards do not provide a secure implementation - * of memset(). Therefore, MBEDTLS_PLATFORM_ZEROIZE_ALT enables users to - * configure their own implementation of mbedtls_platform_zeroize(), for - * example by using directives specific to their compiler, features from newer - * C standards (e.g using memset_s() in C11) or calling a secure memset() from - * their system (e.g explicit_bzero() in BSD). - */ -//#define MBEDTLS_PLATFORM_ZEROIZE_ALT - -/** - * Uncomment the macro to let Mbed TLS use your alternate implementation of - * mbedtls_platform_gmtime_r(). This replaces the default implementation in - * platform_util.c. - * - * gmtime() is not a thread-safe function as defined in the C standard. The - * library will try to use safer implementations of this function, such as - * gmtime_r() when available. However, if Mbed TLS cannot identify the target - * system, the implementation of mbedtls_platform_gmtime_r() will default to - * using the standard gmtime(). In this case, calls from the library to - * gmtime() will be guarded by the global mutex mbedtls_threading_gmtime_mutex - * if MBEDTLS_THREADING_C is enabled. We recommend that calls from outside the - * library are also guarded with this mutex to avoid race conditions. However, - * if the macro MBEDTLS_PLATFORM_GMTIME_R_ALT is defined, Mbed TLS will - * unconditionally use the implementation for mbedtls_platform_gmtime_r() - * supplied at compile time. - */ -//#define MBEDTLS_PLATFORM_GMTIME_R_ALT - /* \} name SECTION: Customisation configuration options */ -/** - * \name SECTION: Compile-time SSL configuration - * - * This section allows to fix parts of the SSL configuration - * at compile-time. If a field is fixed at compile-time, the - * corresponding SSL configuration API `mbedtls_ssl_conf_xxx()` - * is removed. - * - * This can be used on constrained systems to reduce code-size. - * \{ - */ +/* Target and application specific configurations */ +//#define YOTTA_CFG_MBEDTLS_TARGET_CONFIG_FILE "mbedtls/target_config.h" -//#define MBEDTLS_SSL_CONF_ALLOW_LEGACY_RENEGOTIATION MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION +#if defined(TARGET_LIKE_MBED) && defined(YOTTA_CFG_MBEDTLS_TARGET_CONFIG_FILE) +#include YOTTA_CFG_MBEDTLS_TARGET_CONFIG_FILE +#endif -//#define MBEDTLS_SSL_CONF_AUTHMODE MBEDTLS_SSL_VERIFY_REQUIRED - -/* Timeout */ -//#define MBEDTLS_SSL_CONF_READ_TIMEOUT 0 - -/* Endpoint (Client/Server) */ -//#define MBEDTLS_SSL_CONF_ENDPOINT MBEDTLS_SSL_IS_CLIENT - -/* Transport (Stream/Datagram) */ -//#define MBEDTLS_SSL_CONF_TRANSPORT MBEDTLS_SSL_TRANSPORT_STREAM - -//#define MBEDTLS_SSL_CONF_CERT_REQ_CA_LIST MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED - -/* DTLS-specific settings */ -//#define MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MIN -//#define MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MAX -//#define MBEDTLS_SSL_CONF_ANTI_REPLAY MBEDTLS_SSL_ANTI_REPLAY_ENABLED -//#define MBEDTLS_SSL_CONF_BADMAC_LIMIT 0 -//#define MBEDTLS_SSL_CONF_CID_LEN 0 -//#define MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID MBEDTLS_SSL_UNEXPECTED_CID_IGNORE - -/* The timer callbacks to use by the SSL module. - * If defined, - * - MBEDTLS_SSL_CONF_SET_TIMER must evaluate to the name of an externally - * defined function with signature - * void f_set_timer( void* , uint32_t, uint32_t ), - * * MBEDTLS_SSL_CONF_SEND must evaluate to the name of an externally - * defined function with signature - * int f_get_timer( void* ). - */ -//#define MBEDTLS_SSL_CONF_GET_TIMER mbedtls_timing_get_delay -//#define MBEDTLS_SSL_CONF_SET_TIMER mbedtls_timing_set_delay - -/* The send and receive callbacks to use by the SSL module. - * If defined, - * - MBEDTLS_SSL_CONF_RECV must evaluate to the name of an externally - * defined function with signature - * int f_recv( void*, unsigned char *, size_t ), - * * MBEDTLS_SSL_CONF_SEND must evaluate to the name of an externally - * defined function with signature - * int f_send( void*, const unsigned char *, size_t ), - * * MBEDTLS_SSL_CONF_RECV_TIMEOUT must evaluate to the name of an - * externally defined function with signature - * int f_recv_timeout( void*, const unsigned char *, size_t, uint32_t ). - */ -//#define MBEDTLS_SSL_CONF_RECV mbedtls_net_recv -//#define MBEDTLS_SSL_CONF_SEND mbedtls_net_send -//#define MBEDTLS_SSL_CONF_RECV_TIMEOUT mbedtls_net_recv_timeout - -/* The PRNG to use by the SSL module. If defined, this must - * evaluate to the name of an externally defined function with signature - * int f_rng(void *, unsigned char *, size_t), - * which ignores its first parameter (the stack will always - * pass NULL to this function). - * NB: The reason not to drop the context parameter entirely - * is for compatibility with the Crypto and X.509 libraries - * which use RNG callbacks including context parameters. - */ -//#define MBEDTLS_SSL_CONF_RNG rng_wrap - -/* TLS version */ -//#define MBEDTLS_SSL_CONF_MIN_MINOR_VER MBEDTLS_SSL_MINOR_VERSION_3 -//#define MBEDTLS_SSL_CONF_MAX_MINOR_VER MBEDTLS_SSL_MINOR_VERSION_3 -//#define MBEDTLS_SSL_CONF_MIN_MAJOR_VER MBEDTLS_SSL_MAJOR_VERSION_3 -//#define MBEDTLS_SSL_CONF_MAX_MAJOR_VER MBEDTLS_SSL_MAJOR_VERSION_3 - -/* ExtendedMasterSecret extension - * The following two options must be set/unset simultaneously. */ -//#define MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET MBEDTLS_SSL_EXTENDED_MS_ENABLED -//#define MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET MBEDTLS_SSL_EXTENDED_MS_ENFORCE_DISABLED - -/* Set this to MBEDTLS_SUITE_{OFFICIAL_SUITE_NAME} to hardcode - * the choice of a fixed ciphersuite at compile-time. - * - * You need to make sure that the corresponding ciphersuite attributes - * are defined through macros in ssl_ciphersuites.h. See the definitions - * of MBEDTLS_SUITE_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8_XXX for an example. - * - * If this option is set, the API mbedtls_ssl_conf_ciphersuites() is removed. - */ -//#define MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE MBEDTLS_SUITE_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 - -/* Enable support of a single elliptic curve fixed - * at compile-time, at the benefit of code-size. - * - * On highly constrained systems with large control - * over the configuration of the connection endpoints, - * this option can be used to hardcode the choice of - * a single elliptic curve to be used for all elliptic - * curve operations during the handshake. - * - * If this is set, you must also define the following: - * - MBEDTLS_SSL_CONF_SINGLE_EC_GRP_ID (if MBEDTLS_ECP_C is set) - * This must resolve to the Mbed TLS group ID for the elliptic - * curve to use (e.g. MBEDTLS_ECP_DP_SECP256R1); see - * ::mbedtls_ecp_group_id in ecp.h for a complete list - * of curve identifiers. - * - MBEDTLS_SSL_CONF_SINGLE_UECC_GRP_ID (if MBEDTLS_USE_TINYCRYPT is set) - * This must resolve to MBEDTLS_UECC_DP_SECP256R1. - * - MBEDTLS_SSL_CONF_SINGLE_EC_TLS_ID - * This must resolve to the identifier for the elliptic curve - * to use according to the IANA NamedCurve registry: - * https://tools.ietf.org/html/rfc4492#section-5.1 - * - * If defined, this option overwrites the effect of the - * runtime configuration API mbedtls_ssl_conf_curves(). - */ -//#define MBEDTLS_SSL_CONF_SINGLE_EC -//#define MBEDTLS_SSL_CONF_SINGLE_EC_TLS_ID 23 -//#define MBEDTLS_SSL_CONF_SINGLE_EC_GRP_ID MBEDTLS_ECP_DP_SECP256R1 -//#define MBEDTLS_SSL_CONF_SINGLE_UECC_GRP_ID MBEDTLS_UECC_DP_SECP256R1 - -/* Enable support a single signature hash algorithm - * at compile-time, at the benefit of code-size. - * - * On highly constrained systems with large control - * over the configuration of the connection endpoints, - * this option can be used to hardcode the choice of - * hash algorithm to be used for signatures in the - * ServerKeyExchange and CertificateVerify messages. - * - * If this is set, you must also define the following: - * - MBEDTLS_SSL_CONF_SINGLE_SIG_HASH_MD_ID - * This must resolve to the Mbed TLS hash ID for the hash - * algorithm to use (e.g. MBEDTLS_MD_SHA256). See - * ::mbedtls_md_type_t in md.h for a complete - * list of supported hash algorithm identifiers. - * - MBEDTLS_SSL_CONF_SINGLE_SIG_HASH_TLS_ID - * This must resolve to the TLS identifier for the hash - * algorithm to use. See - * https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 - * for a list of the supported identifiers. - * - * If defined, this option overwrites the effect of the - * runtime configuration API mbedtls_ssl_conf_sig_hashes(). - */ -//#define MBEDTLS_SSL_CONF_SINGLE_SIG_HASH -//#define MBEDTLS_SSL_CONF_SINGLE_SIG_HASH_MD_ID -//#define MBEDTLS_SSL_CONF_SINGLE_SIG_HASH_TLS_ID - -/* Set this to MBEDTLS_MD_INFO_{DIGEST} support of a single message - * digest at compile-time, at the benefit of code-size. - * - * On highly constrained systems with large control over the configuration of - * the connection endpoints, this option can be used to hardcode support for - * a single hash algorithm. - * - * You need to make sure that the corresponding digest algorithm attributes - * are defined through macros in md.c. See the definitions - * MBEDTLS_MD_INFO_SHA256_XXX for example. - * - */ -//#define MBEDTLS_MD_SINGLE_HASH MBEDTLS_MD_INFO_SHA256 - -/* Enable support for a single PK type in the PK layer. - * - * This is mainly intented to reduce code size on highly constrained system - * with large control over the set of algorithms they need to support. It will - * also reduce dynamic memory allocation. - * - * Currently this is only supported with EC keys in conjunction with the - * MBEDTLS_USE_TINYCRYPT option. Set this to MBEDTLS_PK_INFO_ECKEY to enable. - */ -//#define MBEDTLS_PK_SINGLE_TYPE MBEDTLS_PK_INFO_ECKEY - -/* \} SECTION: Compile-time SSL configuration */ - -/* Target and application specific configurations - * +/* * Allow user to override any previous default. * + * Use two macro names for that, as: + * - with yotta the prefix YOTTA_CFG_ is forced + * - without yotta is looks weird to have a YOTTA prefix. */ -#if defined(MBEDTLS_USER_CONFIG_FILE) +#if defined(YOTTA_CFG_MBEDTLS_USER_CONFIG_FILE) +#include YOTTA_CFG_MBEDTLS_USER_CONFIG_FILE +#elif defined(MBEDTLS_USER_CONFIG_FILE) #include MBEDTLS_USER_CONFIG_FILE #endif +/* + * !!!!! The following two macros are added to the porting code !!!!! + * !!!!! The following two macros are added to the porting code !!!!! + * !!!!! The following two macros are added to the porting code !!!!! + * + * Upgraded version handles the following two macro definitions + * + * These two macros are defined in the ctr_drbg.c file + * + * #if !defined(MBEDTLS_CTR_DRBG_BLOCKSIZE) + * #define MBEDTLS_CTR_DRBG_BLOCKSIZE 16 + * #endif + * #if !defined(MBEDTLS_CTR_DRBG_KEYSIZE) + * #define MBEDTLS_CTR_DRBG_KEYSIZE 32 + * #endif + * +*/ + #include "check_config.h" +#define tls_malloc rt_malloc +#define tls_free rt_free +#define tls_realloc rt_realloc +#define tls_calloc rt_calloc +#define tls_strdup rt_strdup + #endif /* MBEDTLS_CONFIG_H */ diff --git a/APP_Framework/Framework/security/mbedtls/crc.h b/APP_Framework/Framework/security/mbedtls/crc.h deleted file mode 100644 index 013166674..000000000 --- a/APP_Framework/Framework/security/mbedtls/crc.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * CRC-16/ARC implementation, generated using pycrc v0.9.2, https://pycrc.org. - * - * Used options: --model=crc-16 --algorithm=tbl --generate=h --std=C89 --table-idx-width 4 - * - * Copyright (C) 2006-2020, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -#ifndef MBEDTLS_CRC_H -#define MBEDTLS_CRC_H - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Update the crc value with new data. - * - * \param[in] crc The current crc value. - * \param[in] data Pointer to a buffer of \a data_len bytes. - * \param[in] data_len Number of bytes in the \a data buffer. - * \return The updated crc value. - */ -uint16_t mbedtls_crc_update( uint16_t crc, const void *data, size_t data_len ); - -#ifdef __cplusplus -} -#endif -#endif /* MBEDTLS_CRC_H */ diff --git a/APP_Framework/Framework/security/mbedtls/ctr_drbg.c b/APP_Framework/Framework/security/mbedtls/ctr_drbg.c index f331cb3a8..48674bc48 100644 --- a/APP_Framework/Framework/security/mbedtls/ctr_drbg.c +++ b/APP_Framework/Framework/security/mbedtls/ctr_drbg.c @@ -33,7 +33,6 @@ #if defined(MBEDTLS_CTR_DRBG_C) #include "ctr_drbg.h" -#include "platform_util.h" #include @@ -50,18 +49,73 @@ #endif /* MBEDTLS_PLATFORM_C */ #endif /* MBEDTLS_SELF_TEST */ +/* 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; +} + /* * CTR_DRBG context initialization */ void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx ) { - mbedtls_platform_memset( ctx, 0, sizeof( mbedtls_ctr_drbg_context ) ); + memset( ctx, 0, sizeof( mbedtls_ctr_drbg_context ) ); #if defined(MBEDTLS_THREADING_C) mbedtls_mutex_init( &ctx->mutex ); #endif } +/* + * Non-public function wrapped by mbedtls_ctr_drbg_seed(). Necessary to allow + * NIST tests to succeed (which require known length fixed entropy) + */ +int mbedtls_ctr_drbg_seed_entropy_len( + mbedtls_ctr_drbg_context *ctx, + int (*f_entropy)(void *, unsigned char *, size_t), + void *p_entropy, + const unsigned char *custom, + size_t len, + size_t entropy_len ) +{ + int ret; + unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE]; + + memset( key, 0, MBEDTLS_CTR_DRBG_KEYSIZE ); + + mbedtls_aes_init( &ctx->aes_ctx ); + + ctx->f_entropy = f_entropy; + ctx->p_entropy = p_entropy; + + ctx->entropy_len = entropy_len; + ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL; + + /* + * Initialize with an empty key + */ + if( ( ret = mbedtls_aes_setkey_enc( &ctx->aes_ctx, key, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 ) + { + return( ret ); + } + + if( ( ret = mbedtls_ctr_drbg_reseed( ctx, custom, len ) ) != 0 ) + { + return( ret ); + } + return( 0 ); +} + +int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx, + int (*f_entropy)(void *, unsigned char *, size_t), + void *p_entropy, + const unsigned char *custom, + size_t len ) +{ + return( mbedtls_ctr_drbg_seed_entropy_len( ctx, f_entropy, p_entropy, custom, len, + MBEDTLS_CTR_DRBG_ENTROPY_LEN ) ); +} + void mbedtls_ctr_drbg_free( mbedtls_ctr_drbg_context *ctx ) { if( ctx == NULL ) @@ -71,7 +125,7 @@ void mbedtls_ctr_drbg_free( mbedtls_ctr_drbg_context *ctx ) mbedtls_mutex_free( &ctx->mutex ); #endif mbedtls_aes_free( &ctx->aes_ctx ); - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ctr_drbg_context ) ); + mbedtls_zeroize( ctx, sizeof( mbedtls_ctr_drbg_context ) ); } void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx, int resistance ) @@ -106,7 +160,7 @@ static int block_cipher_df( unsigned char *output, if( data_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT ) return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG ); - mbedtls_platform_memset( buf, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT + MBEDTLS_CTR_DRBG_BLOCKSIZE + 16 ); + memset( buf, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT + MBEDTLS_CTR_DRBG_BLOCKSIZE + 16 ); mbedtls_aes_init( &aes_ctx ); /* @@ -123,7 +177,7 @@ static int block_cipher_df( unsigned char *output, *p++ = ( data_len ) & 0xff; p += 3; *p++ = MBEDTLS_CTR_DRBG_SEEDLEN; - mbedtls_platform_memcpy( p, data, data_len ); + memcpy( p, data, data_len ); p[data_len] = 0x80; buf_len = MBEDTLS_CTR_DRBG_BLOCKSIZE + 8 + data_len + 1; @@ -142,7 +196,7 @@ static int block_cipher_df( unsigned char *output, for( j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE ) { p = buf; - mbedtls_platform_memset( chain, 0, MBEDTLS_CTR_DRBG_BLOCKSIZE ); + memset( chain, 0, MBEDTLS_CTR_DRBG_BLOCKSIZE ); use_len = buf_len; while( use_len > 0 ) @@ -159,7 +213,7 @@ static int block_cipher_df( unsigned char *output, } } - mbedtls_platform_memcpy( tmp + j, chain, MBEDTLS_CTR_DRBG_BLOCKSIZE ); + memcpy( tmp + j, chain, MBEDTLS_CTR_DRBG_BLOCKSIZE ); /* * Update IV @@ -183,7 +237,7 @@ static int block_cipher_df( unsigned char *output, { goto exit; } - mbedtls_platform_memcpy( p, iv, MBEDTLS_CTR_DRBG_BLOCKSIZE ); + memcpy( p, iv, MBEDTLS_CTR_DRBG_BLOCKSIZE ); p += MBEDTLS_CTR_DRBG_BLOCKSIZE; } exit: @@ -191,29 +245,21 @@ exit: /* * tidy up the stack */ - mbedtls_platform_zeroize( buf, sizeof( buf ) ); - mbedtls_platform_zeroize( tmp, sizeof( tmp ) ); - mbedtls_platform_zeroize( key, sizeof( key ) ); - mbedtls_platform_zeroize( chain, sizeof( chain ) ); + 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_platform_zeroize( output, MBEDTLS_CTR_DRBG_SEEDLEN ); + mbedtls_zeroize( output, MBEDTLS_CTR_DRBG_SEEDLEN ); } return( ret ); } -/* CTR_DRBG_Update (SP 800-90A §10.2.1.2) - * ctr_drbg_update_internal(ctx, provided_data) - * implements - * CTR_DRBG_Update(provided_data, Key, V) - * with inputs and outputs - * ctx->aes_ctx = Key - * ctx->counter = V - */ static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx, const unsigned char data[MBEDTLS_CTR_DRBG_SEEDLEN] ) { @@ -222,7 +268,7 @@ static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx, int i, j; int ret = 0; - mbedtls_platform_memset( tmp, 0, MBEDTLS_CTR_DRBG_SEEDLEN ); + memset( tmp, 0, MBEDTLS_CTR_DRBG_SEEDLEN ); for( j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE ) { @@ -250,25 +296,13 @@ static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx, */ if( ( ret = mbedtls_aes_setkey_enc( &ctx->aes_ctx, tmp, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 ) goto exit; - mbedtls_platform_memcpy( ctx->counter, tmp + MBEDTLS_CTR_DRBG_KEYSIZE, MBEDTLS_CTR_DRBG_BLOCKSIZE ); + memcpy( ctx->counter, tmp + MBEDTLS_CTR_DRBG_KEYSIZE, MBEDTLS_CTR_DRBG_BLOCKSIZE ); exit: - mbedtls_platform_zeroize( tmp, sizeof( tmp ) ); + mbedtls_zeroize( tmp, sizeof( tmp ) ); return( ret ); } -/* CTR_DRBG_Instantiate with derivation function (SP 800-90A §10.2.1.3.2) - * mbedtls_ctr_drbg_update(ctx, additional, add_len) - * implements - * CTR_DRBG_Instantiate(entropy_input, nonce, personalization_string, - * security_strength) -> initial_working_state - * with inputs - * ctx->counter = all-bits-0 - * ctx->aes_ctx = context from all-bits-0 key - * additional[:add_len] = entropy_input || nonce || personalization_string - * and with outputs - * ctx = initial_working_state - */ int mbedtls_ctr_drbg_update_ret( mbedtls_ctr_drbg_context *ctx, const unsigned char *additional, size_t add_len ) @@ -285,11 +319,11 @@ int mbedtls_ctr_drbg_update_ret( mbedtls_ctr_drbg_context *ctx, goto exit; exit: - mbedtls_platform_zeroize( add_input, sizeof( add_input ) ); + mbedtls_zeroize( add_input, sizeof( add_input ) ); return( ret ); } -#if !defined(MBEDTLS_DEPRECATED_REMOVED) +/* Deprecated function, kept for backward compatibility. */ void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx, const unsigned char *additional, size_t add_len ) @@ -300,20 +334,7 @@ void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx, add_len = MBEDTLS_CTR_DRBG_MAX_SEED_INPUT; (void) mbedtls_ctr_drbg_update_ret( ctx, additional, add_len ); } -#endif /* MBEDTLS_DEPRECATED_REMOVED */ -/* CTR_DRBG_Reseed with derivation function (SP 800-90A §10.2.1.4.2) - * mbedtls_ctr_drbg_reseed(ctx, additional, len) - * implements - * CTR_DRBG_Reseed(working_state, entropy_input, additional_input) - * -> new_working_state - * with inputs - * ctx contains working_state - * additional[:len] = additional_input - * and entropy_input comes from calling ctx->f_entropy - * and with output - * ctx contains new_working_state - */ int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx, const unsigned char *additional, size_t len ) { @@ -325,7 +346,7 @@ int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx, len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - ctx->entropy_len ) return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG ); - mbedtls_platform_memset( seed, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT ); + memset( seed, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT ); /* * Gather entropy_len bytes of entropy to seed state @@ -343,7 +364,7 @@ int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx, */ if( additional && len ) { - mbedtls_platform_memcpy( seed + seedlen, additional, len ); + memcpy( seed + seedlen, additional, len ); seedlen += len; } @@ -361,86 +382,10 @@ int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx, ctx->reseed_counter = 1; exit: - mbedtls_platform_zeroize( seed, sizeof( seed ) ); + mbedtls_zeroize( seed, sizeof( seed ) ); return( ret ); } -/* CTR_DRBG_Instantiate with derivation function (SP 800-90A §10.2.1.3.2) - * mbedtls_ctr_drbg_seed(ctx, f_entropy, p_entropy, custom, len) - * implements - * CTR_DRBG_Instantiate(entropy_input, nonce, personalization_string, - * security_strength) -> initial_working_state - * with inputs - * custom[:len] = nonce || personalization_string - * where entropy_input comes from f_entropy for ctx->entropy_len bytes - * and with outputs - * ctx = initial_working_state - */ -int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx, - int (*f_entropy)(void *, unsigned char *, size_t), - void *p_entropy, - const unsigned char *custom, - size_t len ) -{ - int ret; - unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE]; - - memset( key, 0, MBEDTLS_CTR_DRBG_KEYSIZE ); - - mbedtls_aes_init( &ctx->aes_ctx ); - - ctx->f_entropy = f_entropy; - ctx->p_entropy = p_entropy; - - if( ctx->entropy_len == 0 ) - ctx->entropy_len = MBEDTLS_CTR_DRBG_ENTROPY_LEN; - ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL; - - /* - * Initialize with an empty key - */ - if( ( ret = mbedtls_aes_setkey_enc( &ctx->aes_ctx, key, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 ) - { - return( ret ); - } - - if( ( ret = mbedtls_ctr_drbg_reseed( ctx, custom, len ) ) != 0 ) - { - return( ret ); - } - return( 0 ); -} - -/* Backward compatibility wrapper */ -int mbedtls_ctr_drbg_seed_entropy_len( - mbedtls_ctr_drbg_context *ctx, - int (*f_entropy)(void *, unsigned char *, size_t), void *p_entropy, - const unsigned char *custom, size_t len, - size_t entropy_len ) -{ - mbedtls_ctr_drbg_set_entropy_len( ctx, entropy_len ); - return( mbedtls_ctr_drbg_seed( ctx, f_entropy, p_entropy, custom, len ) ); -} - -/* CTR_DRBG_Generate with derivation function (SP 800-90A §10.2.1.5.2) - * mbedtls_ctr_drbg_random_with_add(ctx, output, output_len, additional, add_len) - * implements - * CTR_DRBG_Reseed(working_state, entropy_input, additional[:add_len]) - * -> working_state_after_reseed - * if required, then - * CTR_DRBG_Generate(working_state_after_reseed, - * requested_number_of_bits, additional_input) - * -> status, returned_bits, new_working_state - * with inputs - * ctx contains working_state - * requested_number_of_bits = 8 * output_len - * additional[:add_len] = additional_input - * and entropy_input comes from calling ctx->f_entropy - * and with outputs - * status = SUCCESS (this function does the reseed internally) - * returned_bits = output[:output_len] - * ctx contains new_working_state - */ int mbedtls_ctr_drbg_random_with_add( void *p_rng, unsigned char *output, size_t output_len, const unsigned char *additional, size_t add_len ) @@ -459,7 +404,7 @@ int mbedtls_ctr_drbg_random_with_add( void *p_rng, if( add_len > MBEDTLS_CTR_DRBG_MAX_INPUT ) return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG ); - mbedtls_platform_memset( add_input, 0, MBEDTLS_CTR_DRBG_SEEDLEN ); + memset( add_input, 0, MBEDTLS_CTR_DRBG_SEEDLEN ); if( ctx->reseed_counter > ctx->reseed_interval || ctx->prediction_resistance ) @@ -499,7 +444,7 @@ int mbedtls_ctr_drbg_random_with_add( void *p_rng, /* * Copy random block to destination */ - mbedtls_platform_memcpy( p, tmp, use_len ); + memcpy( p, tmp, use_len ); p += use_len; output_len -= use_len; } @@ -510,9 +455,9 @@ int mbedtls_ctr_drbg_random_with_add( void *p_rng, ctx->reseed_counter++; exit: - mbedtls_platform_zeroize( add_input, sizeof( add_input ) ); - mbedtls_platform_zeroize( tmp, sizeof( tmp ) ); - return( ret ); + mbedtls_zeroize( add_input, sizeof( add_input ) ); + mbedtls_zeroize( tmp, sizeof( tmp ) ); + return( 0 ); } int mbedtls_ctr_drbg_random( void *p_rng, unsigned char *output, size_t output_len ) @@ -554,7 +499,7 @@ int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx, const char ret = 0; exit: - mbedtls_platform_zeroize( buf, sizeof( buf ) ); + mbedtls_zeroize( buf, sizeof( buf ) ); fclose( f ); return( ret ); @@ -563,36 +508,35 @@ exit: int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path ) { int ret = 0; - FILE *f = NULL; + FILE *f; size_t n; unsigned char buf[ MBEDTLS_CTR_DRBG_MAX_INPUT ]; - unsigned char c; if( ( f = fopen( path, "rb" ) ) == NULL ) return( MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR ); - n = fread( buf, 1, sizeof( buf ), f ); - if( fread( &c, 1, 1, f ) != 0 ) - { - ret = MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG; - goto exit; - } - if( n == 0 || ferror( f ) ) - { - ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR; - goto exit; - } - fclose( f ); - f = NULL; + fseek( f, 0, SEEK_END ); + n = (size_t) ftell( f ); + fseek( f, 0, SEEK_SET ); - ret = mbedtls_ctr_drbg_update_ret( ctx, buf, n ); - -exit: - mbedtls_platform_zeroize( buf, sizeof( buf ) ); - if( f != NULL ) + if( n > MBEDTLS_CTR_DRBG_MAX_INPUT ) + { fclose( f ); + return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG ); + } + + if( fread( buf, 1, n, f ) != n ) + ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR; + else + ret = mbedtls_ctr_drbg_update_ret( ctx, buf, n ); + + fclose( f ); + + mbedtls_zeroize( buf, sizeof( buf ) ); + if( ret != 0 ) return( ret ); + return( mbedtls_ctr_drbg_write_seed_file( ctx, path ) ); } #endif /* MBEDTLS_FS_IO */ @@ -673,11 +617,8 @@ int mbedtls_ctr_drbg_self_test( int verbose ) mbedtls_printf( " CTR_DRBG (PR = TRUE) : " ); test_offset = 0; - mbedtls_ctr_drbg_set_entropy_len( &ctx, 32 ); - CHK( mbedtls_ctr_drbg_seed( &ctx, - ctr_drbg_self_test_entropy, - (void *) entropy_source_pr, - nonce_pers_pr, 16 ) ); + CHK( mbedtls_ctr_drbg_seed_entropy_len( &ctx, ctr_drbg_self_test_entropy, + (void *) entropy_source_pr, nonce_pers_pr, 16, 32 ) ); mbedtls_ctr_drbg_set_prediction_resistance( &ctx, MBEDTLS_CTR_DRBG_PR_ON ); CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) ); CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) ); @@ -697,11 +638,8 @@ int mbedtls_ctr_drbg_self_test( int verbose ) mbedtls_ctr_drbg_init( &ctx ); test_offset = 0; - mbedtls_ctr_drbg_set_entropy_len( &ctx, 32 ); - CHK( mbedtls_ctr_drbg_seed( &ctx, - ctr_drbg_self_test_entropy, - (void *) entropy_source_nopr, - nonce_pers_nopr, 16 ) ); + CHK( mbedtls_ctr_drbg_seed_entropy_len( &ctx, ctr_drbg_self_test_entropy, + (void *) entropy_source_nopr, nonce_pers_nopr, 16, 32 ) ); CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) ); CHK( mbedtls_ctr_drbg_reseed( &ctx, NULL, 0 ) ); CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) ); diff --git a/APP_Framework/Framework/security/mbedtls/ctr_drbg.h b/APP_Framework/Framework/security/mbedtls/ctr_drbg.h index e0b5ed9c9..4e58a7978 100644 --- a/APP_Framework/Framework/security/mbedtls/ctr_drbg.h +++ b/APP_Framework/Framework/security/mbedtls/ctr_drbg.h @@ -1,44 +1,13 @@ /** * \file ctr_drbg.h * - * \brief This file contains definitions and functions for the - * CTR_DRBG pseudorandom generator. + * \brief CTR_DRBG is based on AES-256, as defined in NIST SP 800-90A: + * Recommendation for Random Number Generation Using Deterministic + * Random Bit Generators. * - * CTR_DRBG is a standardized way of building a PRNG from a block-cipher - * in counter mode operation, as defined in NIST SP 800-90A: - * Recommendation for Random Number Generation Using Deterministic Random - * Bit Generators. - * - * The Mbed TLS implementation of CTR_DRBG uses AES-256 (default) or AES-128 - * (if \c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is enabled at compile time) - * as the underlying block cipher, with a derivation function. - * The initial seeding grabs #MBEDTLS_CTR_DRBG_ENTROPY_LEN bytes of entropy. - * See the documentation of mbedtls_ctr_drbg_seed() for more details. - * - * Based on NIST SP 800-90A §10.2.1 table 3 and NIST SP 800-57 part 1 table 2, - * here are the security strengths achieved in typical configuration: - * - 256 bits under the default configuration of the library, with AES-256 - * and with #MBEDTLS_CTR_DRBG_ENTROPY_LEN set to 48 or more. - * - 256 bits if AES-256 is used, #MBEDTLS_CTR_DRBG_ENTROPY_LEN is set - * to 32 or more, and the DRBG is initialized with an explicit - * nonce in the \c custom parameter to mbedtls_ctr_drbg_seed(). - * - 128 bits if AES-256 is used but #MBEDTLS_CTR_DRBG_ENTROPY_LEN is - * between 24 and 47 and the DRBG is not initialized with an explicit - * nonce (see mbedtls_ctr_drbg_seed()). - * - 128 bits if AES-128 is used (\c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY enabled) - * and #MBEDTLS_CTR_DRBG_ENTROPY_LEN is set to 24 or more (which is - * always the case unless it is explicitly set to a different value - * in config.h). - * - * Note that the value of #MBEDTLS_CTR_DRBG_ENTROPY_LEN defaults to: - * - \c 48 if the module \c MBEDTLS_SHA512_C is enabled and the symbol - * \c MBEDTLS_ENTROPY_FORCE_SHA256 is disabled at compile time. - * This is the default configuration of the library. - * - \c 32 if the module \c MBEDTLS_SHA512_C is disabled at compile time. - * - \c 32 if \c MBEDTLS_ENTROPY_FORCE_SHA256 is enabled at compile time. */ /* - * Copyright (C) 2006-2019, Arm Limited (or its affiliates), All Rights Reserved + * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -76,24 +45,12 @@ #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 or write error in file. */ +#if !defined(MBEDTLS_CTR_DRBG_BLOCKSIZE) #define MBEDTLS_CTR_DRBG_BLOCKSIZE 16 /**< The block size used by the cipher. */ - -#if defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY) -#define MBEDTLS_CTR_DRBG_KEYSIZE 16 -/**< The key size in bytes used by the cipher. - * - * Compile-time choice: 16 bytes (128 bits) - * because #MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is enabled. - */ -#else -#define MBEDTLS_CTR_DRBG_KEYSIZE 32 -/**< The key size in bytes used by the cipher. - * - * Compile-time choice: 32 bytes (256 bits) - * because \c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is disabled. - */ #endif - +#if !defined(MBEDTLS_CTR_DRBG_KEYSIZE) +#define MBEDTLS_CTR_DRBG_KEYSIZE 32 /**< The key size used by the cipher. */ +#endif #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 ) /**< The seed length, calculated as (counter + AES key). */ @@ -106,31 +63,21 @@ * \{ */ -/** \def MBEDTLS_CTR_DRBG_ENTROPY_LEN - * - * \brief The amount of entropy used per seed by default, in bytes. - */ #if !defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) #if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256) -/** This is 48 bytes because the entropy module uses SHA-512 - * (\c MBEDTLS_ENTROPY_FORCE_SHA256 is disabled). - */ #define MBEDTLS_CTR_DRBG_ENTROPY_LEN 48 - -#else /* defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256) */ - -/** This is 32 bytes because the entropy module uses SHA-256 - * (the SHA512 module is disabled or - * \c MBEDTLS_ENTROPY_FORCE_SHA256 is enabled). +/**< The amount of entropy used per seed by default: + *
    • 48 with SHA-512.
    • + *
    • 32 with SHA-256.
    */ -#if !defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY) -/** \warning To achieve a 256-bit security strength, you must pass a nonce - * to mbedtls_ctr_drbg_seed(). - */ -#endif /* !defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY) */ +#else #define MBEDTLS_CTR_DRBG_ENTROPY_LEN 32 -#endif /* defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256) */ -#endif /* !defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) */ +/**< Amount of entropy used per seed by default: + *
    • 48 with SHA-512.
    • + *
    • 32 with SHA-256.
    + */ +#endif +#endif #if !defined(MBEDTLS_CTR_DRBG_RESEED_INTERVAL) #define MBEDTLS_CTR_DRBG_RESEED_INTERVAL 10000 @@ -149,7 +96,7 @@ #if !defined(MBEDTLS_CTR_DRBG_MAX_SEED_INPUT) #define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT 384 -/**< The maximum size of seed or reseed buffer in bytes. */ +/**< The maximum size of seed or reseed buffer. */ #endif /* \} name SECTION: Module settings */ @@ -166,7 +113,7 @@ extern "C" { /** * \brief The CTR_DRBG context structure. */ -typedef struct mbedtls_ctr_drbg_context +typedef struct { unsigned char counter[16]; /*!< The counter (V). */ int reseed_counter; /*!< The reseed counter. */ @@ -207,71 +154,20 @@ void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx ); * \brief This function seeds and sets up the CTR_DRBG * entropy source for future reseeds. * - * A typical choice for the \p f_entropy and \p p_entropy parameters is - * to use the entropy module: - * - \p f_entropy is mbedtls_entropy_func(); - * - \p p_entropy is an instance of ::mbedtls_entropy_context initialized - * with mbedtls_entropy_init() (which registers the platform's default - * entropy sources). + * \note Personalization data can be provided in addition to the more generic + * entropy source, to make this instantiation as unique as possible. * - * The entropy length is #MBEDTLS_CTR_DRBG_ENTROPY_LEN by default. - * You can override it by calling mbedtls_ctr_drbg_set_entropy_len(). - * - * You can provide a personalization string in addition to the - * entropy source, to make this instantiation as unique as possible. - * - * \note The _seed_material_ value passed to the derivation - * function in the CTR_DRBG Instantiate Process - * described in NIST SP 800-90A §10.2.1.3.2 - * is the concatenation of the string obtained from - * calling \p f_entropy and the \p custom string. - * The origin of the nonce depends on the value of - * the entropy length relative to the security strength. - * - If the entropy length is at least 1.5 times the - * security strength then the nonce is taken from the - * string obtained with \p f_entropy. - * - If the entropy length is less than the security - * strength, then the nonce is taken from \p custom. - * In this case, for compliance with SP 800-90A, - * you must pass a unique value of \p custom at - * each invocation. See SP 800-90A §8.6.7 for more - * details. - */ -#if MBEDTLS_CTR_DRBG_ENTROPY_LEN < MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2 -/** \warning When #MBEDTLS_CTR_DRBG_ENTROPY_LEN is less than - * #MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2, to achieve the - * maximum security strength permitted by CTR_DRBG, - * you must pass a value of \p custom that is a nonce: - * this value must never be repeated in subsequent - * runs of the same application or on a different - * device. - */ -#endif -/** * \param ctx The CTR_DRBG context to seed. - * It must have been initialized with - * mbedtls_ctr_drbg_init(). - * After a successful call to mbedtls_ctr_drbg_seed(), - * you may not call mbedtls_ctr_drbg_seed() again on - * the same context unless you call - * mbedtls_ctr_drbg_free() and mbedtls_ctr_drbg_init() - * again first. * \param f_entropy The entropy callback, taking as arguments the * \p p_entropy context, the buffer to fill, and the - * length of the buffer. - * \p f_entropy is always called with a buffer size - * equal to the entropy length. - * \param p_entropy The entropy context to pass to \p f_entropy. - * \param custom The personalization string. - * This can be \c NULL, in which case the personalization - * string is empty regardless of the value of \p len. - * \param len The length of the personalization string. - * This must be at most - * #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - * - #MBEDTLS_CTR_DRBG_ENTROPY_LEN. + length of the buffer. + * \param p_entropy The entropy context. + * \param custom Personalization data, that is device-specific + identifiers. Can be NULL. + * \param len The length of the personalization data. * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on failure. + * \return \c 0 on success, or + * #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on failure. */ int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx, int (*f_entropy)(void *, unsigned char *, size_t), @@ -291,8 +187,7 @@ void mbedtls_ctr_drbg_free( mbedtls_ctr_drbg_context *ctx ); * The default value is off. * * \note If enabled, entropy is gathered at the beginning of - * every call to mbedtls_ctr_drbg_random_with_add() - * or mbedtls_ctr_drbg_random(). + * every call to mbedtls_ctr_drbg_random_with_add(). * Only use this if your entropy source has sufficient * throughput. * @@ -304,37 +199,18 @@ void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx, /** * \brief This function sets the amount of entropy grabbed on each - * seed or reseed. - * - * The default value is #MBEDTLS_CTR_DRBG_ENTROPY_LEN. - * - * \note The security strength of CTR_DRBG is bounded by the - * entropy length. Thus: - * - When using AES-256 - * (\c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is disabled, - * which is the default), - * \p len must be at least 32 (in bytes) - * to achieve a 256-bit strength. - * - When using AES-128 - * (\c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is enabled) - * \p len must be at least 16 (in bytes) - * to achieve a 128-bit strength. + * seed or reseed. The default value is + * #MBEDTLS_CTR_DRBG_ENTROPY_LEN. * * \param ctx The CTR_DRBG context. - * \param len The amount of entropy to grab, in bytes. - * This must be at most #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT. + * \param len The amount of entropy to grab. */ void mbedtls_ctr_drbg_set_entropy_len( mbedtls_ctr_drbg_context *ctx, size_t len ); /** * \brief This function sets the reseed interval. - * - * The reseed interval is the number of calls to mbedtls_ctr_drbg_random() - * or mbedtls_ctr_drbg_random_with_add() after which the entropy function - * is called again. - * - * The default value is #MBEDTLS_CTR_DRBG_RESEED_INTERVAL. + * The default value is #MBEDTLS_CTR_DRBG_RESEED_INTERVAL. * * \param ctx The CTR_DRBG context. * \param interval The reseed interval. @@ -347,62 +223,67 @@ void mbedtls_ctr_drbg_set_reseed_interval( mbedtls_ctr_drbg_context *ctx, * extracts data from the entropy source. * * \param ctx The CTR_DRBG context. - * \param additional Additional data to add to the state. Can be \c NULL. + * \param additional Additional data to add to the state. Can be NULL. * \param len The length of the additional data. - * This must be less than - * #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - \c entropy_len - * where \c entropy_len is the entropy length - * configured for the context. * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on failure. + * \return \c 0 on success, or + * #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on failure. */ int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx, const unsigned char *additional, size_t len ); /** - * \brief This function updates the state of the CTR_DRBG context. + * \brief This function updates the state of the CTR_DRBG context. * - * \param ctx The CTR_DRBG context. - * \param additional The data to update the state with. This must not be - * \c NULL unless \p add_len is \c 0. - * \param add_len Length of \p additional in bytes. This must be at - * most #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT. + * \param ctx The CTR_DRBG context. + * \param additional The data to update the state with. + * \param add_len Length of \p additional in bytes. This must be at + * most #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT. * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG if - * \p add_len is more than - * #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT. - * \return An error from the underlying AES cipher on failure. + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG if + * \p add_len is more than + * #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT. + * \return An error from the underlying AES cipher on failure. */ int mbedtls_ctr_drbg_update_ret( mbedtls_ctr_drbg_context *ctx, const unsigned char *additional, size_t add_len ); +/** + * \brief This function updates the state of the CTR_DRBG context. + * + * \warning This function cannot report errors. You should use + * mbedtls_ctr_drbg_update_ret() instead. + * + * \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. + * The remaining Bytes are silently discarded. + * + * \param ctx The CTR_DRBG context. + * \param additional The data to update the state with. + * \param add_len Length of \p additional data. + */ +void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx, + const unsigned char *additional, + size_t add_len ); + /** * \brief This function updates a CTR_DRBG instance with additional * data and uses it to generate random data. * - * This function automatically reseeds if the reseed counter is exceeded - * or prediction resistance is enabled. + * \note The function automatically reseeds if the reseed counter is exceeded. * * \param p_rng The CTR_DRBG context. This must be a pointer to a * #mbedtls_ctr_drbg_context structure. * \param output The buffer to fill. - * \param output_len The length of the buffer in bytes. - * \param additional Additional data to update. Can be \c NULL, in which - * case the additional data is empty regardless of - * the value of \p add_len. - * \param add_len The length of the additional data - * if \p additional is not \c NULL. - * This must be less than #MBEDTLS_CTR_DRBG_MAX_INPUT - * and less than - * #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - \c entropy_len - * where \c entropy_len is the entropy length - * configured for the context. + * \param output_len The length of the buffer. + * \param additional Additional data to update. Can be NULL. + * \param add_len The length of the additional data. * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or + * \return \c 0 on success, or + * #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or * #MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG on failure. */ int mbedtls_ctr_drbg_random_with_add( void *p_rng, @@ -412,51 +293,20 @@ int mbedtls_ctr_drbg_random_with_add( void *p_rng, /** * \brief This function uses CTR_DRBG to generate random data. * - * This function automatically reseeds if the reseed counter is exceeded - * or prediction resistance is enabled. - * + * \note The function automatically reseeds if the reseed counter is exceeded. * * \param p_rng The CTR_DRBG context. This must be a pointer to a * #mbedtls_ctr_drbg_context structure. * \param output The buffer to fill. - * \param output_len The length of the buffer in bytes. + * \param output_len The length of the buffer. * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or + * \return \c 0 on success, or + * #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or * #MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG on failure. */ int mbedtls_ctr_drbg_random( void *p_rng, unsigned char *output, size_t output_len ); - -#if ! defined(MBEDTLS_DEPRECATED_REMOVED) -#if defined(MBEDTLS_DEPRECATED_WARNING) -#define MBEDTLS_DEPRECATED __attribute__((deprecated)) -#else -#define MBEDTLS_DEPRECATED -#endif -/** - * \brief This function updates the state of the CTR_DRBG context. - * - * \deprecated Superseded by mbedtls_ctr_drbg_update_ret() - * in 2.16.0. - * - * \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. - * The remaining Bytes are silently discarded. - * - * \param ctx The CTR_DRBG context. - * \param additional The data to update the state with. - * \param add_len Length of \p additional data. - */ -MBEDTLS_DEPRECATED void mbedtls_ctr_drbg_update( - mbedtls_ctr_drbg_context *ctx, - const unsigned char *additional, - size_t add_len ); -#undef MBEDTLS_DEPRECATED -#endif /* !MBEDTLS_DEPRECATED_REMOVED */ - #if defined(MBEDTLS_FS_IO) /** * \brief This function writes a seed file. @@ -464,9 +314,9 @@ MBEDTLS_DEPRECATED void mbedtls_ctr_drbg_update( * \param ctx The CTR_DRBG context. * \param path The name of the file. * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR on file error. - * \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on reseed + * \return \c 0 on success, + * #MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR on file error, or + * #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on * failure. */ int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path ); @@ -478,28 +328,21 @@ int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx, const char * \param ctx The CTR_DRBG context. * \param path The name of the file. * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR on file error. - * \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on - * reseed failure. - * \return #MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG if the existing - * seed file is too large. + * \return \c 0 on success, + * #MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR on file error, + * #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or + * #MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG on failure. */ int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path ); #endif /* MBEDTLS_FS_IO */ -#if defined(MBEDTLS_SELF_TEST) - /** * \brief The CTR_DRBG checkup routine. * - * \return \c 0 on success. - * \return \c 1 on failure. + * \return \c 0 on success, or \c 1 on failure. */ int mbedtls_ctr_drbg_self_test( int verbose ); -#endif /* MBEDTLS_SELF_TEST */ - /* Internal functions (do not call directly) */ int mbedtls_ctr_drbg_seed_entropy_len( mbedtls_ctr_drbg_context *, int (*)(void *, unsigned char *, size_t), void *, diff --git a/APP_Framework/Framework/security/mbedtls/debug.c b/APP_Framework/Framework/security/mbedtls/debug.c new file mode 100644 index 000000000..453f08cb8 --- /dev/null +++ b/APP_Framework/Framework/security/mbedtls/debug.c @@ -0,0 +1,368 @@ +/* + * Debugging routines + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_DEBUG_C) + +#if defined(MBEDTLS_PLATFORM_C) +#include "platform.h" +#else +#include +#define mbedtls_calloc calloc +#define mbedtls_free free +#define mbedtls_time_t time_t +#define mbedtls_snprintf snprintf +#endif + +#include "debug.h" + +#include +#include +#include + +#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ + !defined(inline) && !defined(__cplusplus) +#define inline __inline +#endif + +#define DEBUG_BUF_SIZE 512 + +static int debug_threshold = 0; + +void mbedtls_debug_set_threshold( int threshold ) +{ + debug_threshold = threshold; +} + +/* + * All calls to f_dbg must be made via this function + */ +static inline void debug_send_line( const mbedtls_ssl_context *ssl, int level, + const char *file, int line, + const char *str ) +{ + /* + * If in a threaded environment, we need a thread identifier. + * Since there is no portable way to get one, use the address of the ssl + * context instead, as it shouldn't be shared between threads. + */ +#if defined(MBEDTLS_THREADING_C) + char idstr[20 + DEBUG_BUF_SIZE]; /* 0x + 16 nibbles + ': ' */ + mbedtls_snprintf( idstr, sizeof( idstr ), "%p: %s", (void*)ssl, str ); + ssl->conf->f_dbg( ssl->conf->p_dbg, level, file, line, idstr ); +#else + ssl->conf->f_dbg( ssl->conf->p_dbg, level, file, line, str ); +#endif +} + +void mbedtls_debug_print_msg( const mbedtls_ssl_context *ssl, int level, + const char *file, int line, + const char *format, ... ) +{ + va_list argp; + char str[DEBUG_BUF_SIZE]; + int ret; + + if( NULL == ssl || NULL == ssl->conf || NULL == ssl->conf->f_dbg || level > debug_threshold ) + return; + + va_start( argp, format ); +#if defined(_WIN32) +#if defined(_TRUNCATE) && !defined(__MINGW32__) + ret = _vsnprintf_s( str, DEBUG_BUF_SIZE, _TRUNCATE, format, argp ); +#else + ret = _vsnprintf( str, DEBUG_BUF_SIZE, format, argp ); + if( ret < 0 || (size_t) ret == DEBUG_BUF_SIZE ) + { + str[DEBUG_BUF_SIZE-1] = '\0'; + ret = -1; + } +#endif +#else + ret = vsnprintf( str, DEBUG_BUF_SIZE, format, argp ); +#endif + va_end( argp ); + + if( ret >= 0 && ret < DEBUG_BUF_SIZE - 1 ) + { + str[ret] = '\n'; + str[ret + 1] = '\0'; + } + + debug_send_line( ssl, level, file, line, str ); +} + +void mbedtls_debug_print_ret( const mbedtls_ssl_context *ssl, int level, + const char *file, int line, + const char *text, int ret ) +{ + char str[DEBUG_BUF_SIZE]; + + if( ssl->conf == NULL || ssl->conf->f_dbg == NULL || level > debug_threshold ) + return; + + /* + * With non-blocking I/O and examples that just retry immediately, + * the logs would be quickly flooded with WANT_READ, so ignore that. + * Don't ignore WANT_WRITE however, since is is usually rare. + */ + if( ret == MBEDTLS_ERR_SSL_WANT_READ ) + return; + + mbedtls_snprintf( str, sizeof( str ), "%s() returned %d (-0x%04x)\n", + text, ret, -ret ); + + debug_send_line( ssl, level, file, line, str ); +} + +void mbedtls_debug_print_buf( const mbedtls_ssl_context *ssl, int level, + const char *file, int line, const char *text, + const unsigned char *buf, size_t len ) +{ + char str[DEBUG_BUF_SIZE]; + char txt[17]; + size_t i, idx = 0; + + if( ssl->conf == NULL || ssl->conf->f_dbg == NULL || level > debug_threshold ) + return; + + mbedtls_snprintf( str + idx, sizeof( str ) - idx, "dumping '%s' (%u bytes)\n", + text, (unsigned int) len ); + + debug_send_line( ssl, level, file, line, str ); + + idx = 0; + memset( txt, 0, sizeof( txt ) ); + for( i = 0; i < len; i++ ) + { + if( i >= 4096 ) + break; + + if( i % 16 == 0 ) + { + if( i > 0 ) + { + mbedtls_snprintf( str + idx, sizeof( str ) - idx, " %s\n", txt ); + debug_send_line( ssl, level, file, line, str ); + + idx = 0; + memset( txt, 0, sizeof( txt ) ); + } + + idx += mbedtls_snprintf( str + idx, sizeof( str ) - idx, "%04x: ", + (unsigned int) i ); + + } + + idx += mbedtls_snprintf( str + idx, sizeof( str ) - idx, " %02x", + (unsigned int) buf[i] ); + txt[i % 16] = ( buf[i] > 31 && buf[i] < 127 ) ? buf[i] : '.' ; + } + + if( len > 0 ) + { + for( /* i = i */; i % 16 != 0; i++ ) + idx += mbedtls_snprintf( str + idx, sizeof( str ) - idx, " " ); + + mbedtls_snprintf( str + idx, sizeof( str ) - idx, " %s\n", txt ); + debug_send_line( ssl, level, file, line, str ); + } +} + +#if defined(MBEDTLS_ECP_C) +void mbedtls_debug_print_ecp( const mbedtls_ssl_context *ssl, int level, + const char *file, int line, + const char *text, const mbedtls_ecp_point *X ) +{ + char str[DEBUG_BUF_SIZE]; + + if( ssl->conf == NULL || ssl->conf->f_dbg == NULL || level > debug_threshold ) + return; + + mbedtls_snprintf( str, sizeof( str ), "%s(X)", text ); + mbedtls_debug_print_mpi( ssl, level, file, line, str, &X->X ); + + mbedtls_snprintf( str, sizeof( str ), "%s(Y)", text ); + mbedtls_debug_print_mpi( ssl, level, file, line, str, &X->Y ); +} +#endif /* MBEDTLS_ECP_C */ + +#if defined(MBEDTLS_BIGNUM_C) +void mbedtls_debug_print_mpi( const mbedtls_ssl_context *ssl, int level, + const char *file, int line, + const char *text, const mbedtls_mpi *X ) +{ + char str[DEBUG_BUF_SIZE]; + int j, k, zeros = 1; + size_t i, n, idx = 0; + + if( ssl->conf == NULL || ssl->conf->f_dbg == NULL || X == NULL || level > debug_threshold ) + return; + + for( n = X->n - 1; n > 0; n-- ) + if( X->p[n] != 0 ) + break; + + for( j = ( sizeof(mbedtls_mpi_uint) << 3 ) - 1; j >= 0; j-- ) + if( ( ( X->p[n] >> j ) & 1 ) != 0 ) + break; + + mbedtls_snprintf( str + idx, sizeof( str ) - idx, "value of '%s' (%d bits) is:\n", + text, (int) ( ( n * ( sizeof(mbedtls_mpi_uint) << 3 ) ) + j + 1 ) ); + + debug_send_line( ssl, level, file, line, str ); + + idx = 0; + for( i = n + 1, j = 0; i > 0; i-- ) + { + if( zeros && X->p[i - 1] == 0 ) + continue; + + for( k = sizeof( mbedtls_mpi_uint ) - 1; k >= 0; k-- ) + { + if( zeros && ( ( X->p[i - 1] >> ( k << 3 ) ) & 0xFF ) == 0 ) + continue; + else + zeros = 0; + + if( j % 16 == 0 ) + { + if( j > 0 ) + { + mbedtls_snprintf( str + idx, sizeof( str ) - idx, "\n" ); + debug_send_line( ssl, level, file, line, str ); + idx = 0; + } + } + + idx += mbedtls_snprintf( str + idx, sizeof( str ) - idx, " %02x", (unsigned int) + ( X->p[i - 1] >> ( k << 3 ) ) & 0xFF ); + + j++; + } + + } + + if( zeros == 1 ) + idx += mbedtls_snprintf( str + idx, sizeof( str ) - idx, " 00" ); + + mbedtls_snprintf( str + idx, sizeof( str ) - idx, "\n" ); + debug_send_line( ssl, level, file, line, str ); +} +#endif /* MBEDTLS_BIGNUM_C */ + +#if defined(MBEDTLS_X509_CRT_PARSE_C) +static void debug_print_pk( const mbedtls_ssl_context *ssl, int level, + const char *file, int line, + const char *text, const mbedtls_pk_context *pk ) +{ + size_t i; + mbedtls_pk_debug_item items[MBEDTLS_PK_DEBUG_MAX_ITEMS]; + char name[16]; + + memset( items, 0, sizeof( items ) ); + + if( mbedtls_pk_debug( pk, items ) != 0 ) + { + debug_send_line( ssl, level, file, line, + "invalid PK context\n" ); + return; + } + + for( i = 0; i < MBEDTLS_PK_DEBUG_MAX_ITEMS; i++ ) + { + if( items[i].type == MBEDTLS_PK_DEBUG_NONE ) + return; + + mbedtls_snprintf( name, sizeof( name ), "%s%s", text, items[i].name ); + name[sizeof( name ) - 1] = '\0'; + + if( items[i].type == MBEDTLS_PK_DEBUG_MPI ) + mbedtls_debug_print_mpi( ssl, level, file, line, name, items[i].value ); + else +#if defined(MBEDTLS_ECP_C) + if( items[i].type == MBEDTLS_PK_DEBUG_ECP ) + mbedtls_debug_print_ecp( ssl, level, file, line, name, items[i].value ); + else +#endif + debug_send_line( ssl, level, file, line, + "should not happen\n" ); + } +} + +static void debug_print_line_by_line( const mbedtls_ssl_context *ssl, int level, + const char *file, int line, const char *text ) +{ + char str[DEBUG_BUF_SIZE]; + const char *start, *cur; + + start = text; + for( cur = text; *cur != '\0'; cur++ ) + { + if( *cur == '\n' ) + { + size_t len = cur - start + 1; + if( len > DEBUG_BUF_SIZE - 1 ) + len = DEBUG_BUF_SIZE - 1; + + memcpy( str, start, len ); + str[len] = '\0'; + + debug_send_line( ssl, level, file, line, str ); + + start = cur + 1; + } + } +} + +void mbedtls_debug_print_crt( const mbedtls_ssl_context *ssl, int level, + const char *file, int line, + const char *text, const mbedtls_x509_crt *crt ) +{ + char str[DEBUG_BUF_SIZE]; + int i = 0; + + if( ssl->conf == NULL || ssl->conf->f_dbg == NULL || crt == NULL || level > debug_threshold ) + return; + + while( crt != NULL ) + { + char buf[1024]; + + mbedtls_snprintf( str, sizeof( str ), "%s #%d:\n", text, ++i ); + debug_send_line( ssl, level, file, line, str ); + + mbedtls_x509_crt_info( buf, sizeof( buf ) - 1, "", crt ); + debug_print_line_by_line( ssl, level, file, line, buf ); + + debug_print_pk( ssl, level, file, line, "crt->", &crt->pk ); + + crt = crt->next; + } +} +#endif /* MBEDTLS_X509_CRT_PARSE_C */ + +#endif /* MBEDTLS_DEBUG_C */ diff --git a/APP_Framework/Framework/security/mbedtls/debug.h b/APP_Framework/Framework/security/mbedtls/debug.h index 41cdd34a1..ef8db67ff 100644 --- a/APP_Framework/Framework/security/mbedtls/debug.h +++ b/APP_Framework/Framework/security/mbedtls/debug.h @@ -36,10 +36,6 @@ #include "ecp.h" #endif -#if defined(MBEDTLS_ECDH_C) -#include "ecdh.h" -#endif - #if defined(MBEDTLS_DEBUG_C) #define MBEDTLS_DEBUG_STRIP_PARENS( ... ) __VA_ARGS__ @@ -65,17 +61,8 @@ #endif #if defined(MBEDTLS_X509_CRT_PARSE_C) -#if !defined(MBEDTLS_X509_REMOVE_INFO) #define MBEDTLS_SSL_DEBUG_CRT( level, text, crt ) \ mbedtls_debug_print_crt( ssl, level, __FILE__, __LINE__, text, crt ) -#else -#define MBEDTLS_SSL_DEBUG_CRT( level, text, crt ) do { } while( 0 ) -#endif /* !MBEDTLS_X509_REMOVE_INFO */ -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -#if defined(MBEDTLS_ECDH_C) -#define MBEDTLS_SSL_DEBUG_ECDH( level, ecdh, attr ) \ - mbedtls_debug_printf_ecdh( ssl, level, __FILE__, __LINE__, ecdh, attr ) #endif #else /* MBEDTLS_DEBUG_C */ @@ -86,7 +73,6 @@ #define MBEDTLS_SSL_DEBUG_MPI( level, text, X ) do { } while( 0 ) #define MBEDTLS_SSL_DEBUG_ECP( level, text, X ) do { } while( 0 ) #define MBEDTLS_SSL_DEBUG_CRT( level, text, crt ) do { } while( 0 ) -#define MBEDTLS_SSL_DEBUG_ECDH( level, ecdh, attr ) do { } while( 0 ) #endif /* MBEDTLS_DEBUG_C */ @@ -214,7 +200,7 @@ void mbedtls_debug_print_ecp( const mbedtls_ssl_context *ssl, int level, const char *text, const mbedtls_ecp_point *X ); #endif -#if defined(MBEDTLS_X509_CRT_PARSE_C) && !defined(MBEDTLS_X509_REMOVE_INFO) +#if defined(MBEDTLS_X509_CRT_PARSE_C) /** * \brief Print a X.509 certificate structure to the debug output. This * function is always used through the MBEDTLS_SSL_DEBUG_CRT() macro, @@ -235,38 +221,9 @@ void mbedtls_debug_print_crt( const mbedtls_ssl_context *ssl, int level, const char *text, const mbedtls_x509_crt *crt ); #endif -#if defined(MBEDTLS_ECDH_C) -typedef enum -{ - MBEDTLS_DEBUG_ECDH_Q, - MBEDTLS_DEBUG_ECDH_QP, - MBEDTLS_DEBUG_ECDH_Z, -} mbedtls_debug_ecdh_attr; - -/** - * \brief Print a field of the ECDH structure in the SSL context to the debug - * output. This function is always used through the - * MBEDTLS_SSL_DEBUG_ECDH() macro, which supplies the ssl context, file - * and line number parameters. - * - * \param ssl SSL context - * \param level error level of the debug message - * \param file file the error has occurred in - * \param line line number the error has occurred in - * \param ecdh the ECDH context - * \param attr the identifier of the attribute being output - * - * \attention This function is intended for INTERNAL usage within the - * library only. - */ -void mbedtls_debug_printf_ecdh( const mbedtls_ssl_context *ssl, int level, - const char *file, int line, - const mbedtls_ecdh_context *ecdh, - mbedtls_debug_ecdh_attr attr ); -#endif - #ifdef __cplusplus } #endif #endif /* debug.h */ + diff --git a/APP_Framework/Framework/security/mbedtls/des.c b/APP_Framework/Framework/security/mbedtls/des.c new file mode 100644 index 000000000..30ae9d9e5 --- /dev/null +++ b/APP_Framework/Framework/security/mbedtls/des.c @@ -0,0 +1,1061 @@ +/* + * FIPS-46-3 compliant Triple-DES implementation + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +/* + * DES, on which TDES is based, was originally designed by Horst Feistel + * at IBM in 1974, and was adopted as a standard by NIST (formerly NBS). + * + * http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_DES_C) + +#include "des.h" + +#include + +#if defined(MBEDTLS_SELF_TEST) +#if defined(MBEDTLS_PLATFORM_C) +#include "platform.h" +#else +#include +#define mbedtls_printf printf +#endif /* MBEDTLS_PLATFORM_C */ +#endif /* MBEDTLS_SELF_TEST */ + +#if !defined(MBEDTLS_DES_ALT) + +/* 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; +} + +/* + * 32-bit integer manipulation macros (big endian) + */ +#ifndef GET_UINT32_BE +#define GET_UINT32_BE(n,b,i) \ +{ \ + (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ + | ( (uint32_t) (b)[(i) + 1] << 16 ) \ + | ( (uint32_t) (b)[(i) + 2] << 8 ) \ + | ( (uint32_t) (b)[(i) + 3] ); \ +} +#endif + +#ifndef PUT_UINT32_BE +#define PUT_UINT32_BE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) ); \ +} +#endif + +/* + * Expanded DES S-boxes + */ +static const uint32_t SB1[64] = +{ + 0x01010400, 0x00000000, 0x00010000, 0x01010404, + 0x01010004, 0x00010404, 0x00000004, 0x00010000, + 0x00000400, 0x01010400, 0x01010404, 0x00000400, + 0x01000404, 0x01010004, 0x01000000, 0x00000004, + 0x00000404, 0x01000400, 0x01000400, 0x00010400, + 0x00010400, 0x01010000, 0x01010000, 0x01000404, + 0x00010004, 0x01000004, 0x01000004, 0x00010004, + 0x00000000, 0x00000404, 0x00010404, 0x01000000, + 0x00010000, 0x01010404, 0x00000004, 0x01010000, + 0x01010400, 0x01000000, 0x01000000, 0x00000400, + 0x01010004, 0x00010000, 0x00010400, 0x01000004, + 0x00000400, 0x00000004, 0x01000404, 0x00010404, + 0x01010404, 0x00010004, 0x01010000, 0x01000404, + 0x01000004, 0x00000404, 0x00010404, 0x01010400, + 0x00000404, 0x01000400, 0x01000400, 0x00000000, + 0x00010004, 0x00010400, 0x00000000, 0x01010004 +}; + +static const uint32_t SB2[64] = +{ + 0x80108020, 0x80008000, 0x00008000, 0x00108020, + 0x00100000, 0x00000020, 0x80100020, 0x80008020, + 0x80000020, 0x80108020, 0x80108000, 0x80000000, + 0x80008000, 0x00100000, 0x00000020, 0x80100020, + 0x00108000, 0x00100020, 0x80008020, 0x00000000, + 0x80000000, 0x00008000, 0x00108020, 0x80100000, + 0x00100020, 0x80000020, 0x00000000, 0x00108000, + 0x00008020, 0x80108000, 0x80100000, 0x00008020, + 0x00000000, 0x00108020, 0x80100020, 0x00100000, + 0x80008020, 0x80100000, 0x80108000, 0x00008000, + 0x80100000, 0x80008000, 0x00000020, 0x80108020, + 0x00108020, 0x00000020, 0x00008000, 0x80000000, + 0x00008020, 0x80108000, 0x00100000, 0x80000020, + 0x00100020, 0x80008020, 0x80000020, 0x00100020, + 0x00108000, 0x00000000, 0x80008000, 0x00008020, + 0x80000000, 0x80100020, 0x80108020, 0x00108000 +}; + +static const uint32_t SB3[64] = +{ + 0x00000208, 0x08020200, 0x00000000, 0x08020008, + 0x08000200, 0x00000000, 0x00020208, 0x08000200, + 0x00020008, 0x08000008, 0x08000008, 0x00020000, + 0x08020208, 0x00020008, 0x08020000, 0x00000208, + 0x08000000, 0x00000008, 0x08020200, 0x00000200, + 0x00020200, 0x08020000, 0x08020008, 0x00020208, + 0x08000208, 0x00020200, 0x00020000, 0x08000208, + 0x00000008, 0x08020208, 0x00000200, 0x08000000, + 0x08020200, 0x08000000, 0x00020008, 0x00000208, + 0x00020000, 0x08020200, 0x08000200, 0x00000000, + 0x00000200, 0x00020008, 0x08020208, 0x08000200, + 0x08000008, 0x00000200, 0x00000000, 0x08020008, + 0x08000208, 0x00020000, 0x08000000, 0x08020208, + 0x00000008, 0x00020208, 0x00020200, 0x08000008, + 0x08020000, 0x08000208, 0x00000208, 0x08020000, + 0x00020208, 0x00000008, 0x08020008, 0x00020200 +}; + +static const uint32_t SB4[64] = +{ + 0x00802001, 0x00002081, 0x00002081, 0x00000080, + 0x00802080, 0x00800081, 0x00800001, 0x00002001, + 0x00000000, 0x00802000, 0x00802000, 0x00802081, + 0x00000081, 0x00000000, 0x00800080, 0x00800001, + 0x00000001, 0x00002000, 0x00800000, 0x00802001, + 0x00000080, 0x00800000, 0x00002001, 0x00002080, + 0x00800081, 0x00000001, 0x00002080, 0x00800080, + 0x00002000, 0x00802080, 0x00802081, 0x00000081, + 0x00800080, 0x00800001, 0x00802000, 0x00802081, + 0x00000081, 0x00000000, 0x00000000, 0x00802000, + 0x00002080, 0x00800080, 0x00800081, 0x00000001, + 0x00802001, 0x00002081, 0x00002081, 0x00000080, + 0x00802081, 0x00000081, 0x00000001, 0x00002000, + 0x00800001, 0x00002001, 0x00802080, 0x00800081, + 0x00002001, 0x00002080, 0x00800000, 0x00802001, + 0x00000080, 0x00800000, 0x00002000, 0x00802080 +}; + +static const uint32_t SB5[64] = +{ + 0x00000100, 0x02080100, 0x02080000, 0x42000100, + 0x00080000, 0x00000100, 0x40000000, 0x02080000, + 0x40080100, 0x00080000, 0x02000100, 0x40080100, + 0x42000100, 0x42080000, 0x00080100, 0x40000000, + 0x02000000, 0x40080000, 0x40080000, 0x00000000, + 0x40000100, 0x42080100, 0x42080100, 0x02000100, + 0x42080000, 0x40000100, 0x00000000, 0x42000000, + 0x02080100, 0x02000000, 0x42000000, 0x00080100, + 0x00080000, 0x42000100, 0x00000100, 0x02000000, + 0x40000000, 0x02080000, 0x42000100, 0x40080100, + 0x02000100, 0x40000000, 0x42080000, 0x02080100, + 0x40080100, 0x00000100, 0x02000000, 0x42080000, + 0x42080100, 0x00080100, 0x42000000, 0x42080100, + 0x02080000, 0x00000000, 0x40080000, 0x42000000, + 0x00080100, 0x02000100, 0x40000100, 0x00080000, + 0x00000000, 0x40080000, 0x02080100, 0x40000100 +}; + +static const uint32_t SB6[64] = +{ + 0x20000010, 0x20400000, 0x00004000, 0x20404010, + 0x20400000, 0x00000010, 0x20404010, 0x00400000, + 0x20004000, 0x00404010, 0x00400000, 0x20000010, + 0x00400010, 0x20004000, 0x20000000, 0x00004010, + 0x00000000, 0x00400010, 0x20004010, 0x00004000, + 0x00404000, 0x20004010, 0x00000010, 0x20400010, + 0x20400010, 0x00000000, 0x00404010, 0x20404000, + 0x00004010, 0x00404000, 0x20404000, 0x20000000, + 0x20004000, 0x00000010, 0x20400010, 0x00404000, + 0x20404010, 0x00400000, 0x00004010, 0x20000010, + 0x00400000, 0x20004000, 0x20000000, 0x00004010, + 0x20000010, 0x20404010, 0x00404000, 0x20400000, + 0x00404010, 0x20404000, 0x00000000, 0x20400010, + 0x00000010, 0x00004000, 0x20400000, 0x00404010, + 0x00004000, 0x00400010, 0x20004010, 0x00000000, + 0x20404000, 0x20000000, 0x00400010, 0x20004010 +}; + +static const uint32_t SB7[64] = +{ + 0x00200000, 0x04200002, 0x04000802, 0x00000000, + 0x00000800, 0x04000802, 0x00200802, 0x04200800, + 0x04200802, 0x00200000, 0x00000000, 0x04000002, + 0x00000002, 0x04000000, 0x04200002, 0x00000802, + 0x04000800, 0x00200802, 0x00200002, 0x04000800, + 0x04000002, 0x04200000, 0x04200800, 0x00200002, + 0x04200000, 0x00000800, 0x00000802, 0x04200802, + 0x00200800, 0x00000002, 0x04000000, 0x00200800, + 0x04000000, 0x00200800, 0x00200000, 0x04000802, + 0x04000802, 0x04200002, 0x04200002, 0x00000002, + 0x00200002, 0x04000000, 0x04000800, 0x00200000, + 0x04200800, 0x00000802, 0x00200802, 0x04200800, + 0x00000802, 0x04000002, 0x04200802, 0x04200000, + 0x00200800, 0x00000000, 0x00000002, 0x04200802, + 0x00000000, 0x00200802, 0x04200000, 0x00000800, + 0x04000002, 0x04000800, 0x00000800, 0x00200002 +}; + +static const uint32_t SB8[64] = +{ + 0x10001040, 0x00001000, 0x00040000, 0x10041040, + 0x10000000, 0x10001040, 0x00000040, 0x10000000, + 0x00040040, 0x10040000, 0x10041040, 0x00041000, + 0x10041000, 0x00041040, 0x00001000, 0x00000040, + 0x10040000, 0x10000040, 0x10001000, 0x00001040, + 0x00041000, 0x00040040, 0x10040040, 0x10041000, + 0x00001040, 0x00000000, 0x00000000, 0x10040040, + 0x10000040, 0x10001000, 0x00041040, 0x00040000, + 0x00041040, 0x00040000, 0x10041000, 0x00001000, + 0x00000040, 0x10040040, 0x00001000, 0x00041040, + 0x10001000, 0x00000040, 0x10000040, 0x10040000, + 0x10040040, 0x10000000, 0x00040000, 0x10001040, + 0x00000000, 0x10041040, 0x00040040, 0x10000040, + 0x10040000, 0x10001000, 0x10001040, 0x00000000, + 0x10041040, 0x00041000, 0x00041000, 0x00001040, + 0x00001040, 0x00040040, 0x10000000, 0x10041000 +}; + +/* + * PC1: left and right halves bit-swap + */ +static const uint32_t LHs[16] = +{ + 0x00000000, 0x00000001, 0x00000100, 0x00000101, + 0x00010000, 0x00010001, 0x00010100, 0x00010101, + 0x01000000, 0x01000001, 0x01000100, 0x01000101, + 0x01010000, 0x01010001, 0x01010100, 0x01010101 +}; + +static const uint32_t RHs[16] = +{ + 0x00000000, 0x01000000, 0x00010000, 0x01010000, + 0x00000100, 0x01000100, 0x00010100, 0x01010100, + 0x00000001, 0x01000001, 0x00010001, 0x01010001, + 0x00000101, 0x01000101, 0x00010101, 0x01010101, +}; + +/* + * Initial Permutation macro + */ +#define DES_IP(X,Y) \ +{ \ + T = ((X >> 4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T << 4); \ + T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16); \ + T = ((Y >> 2) ^ X) & 0x33333333; X ^= T; Y ^= (T << 2); \ + T = ((Y >> 8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T << 8); \ + Y = ((Y << 1) | (Y >> 31)) & 0xFFFFFFFF; \ + T = (X ^ Y) & 0xAAAAAAAA; Y ^= T; X ^= T; \ + X = ((X << 1) | (X >> 31)) & 0xFFFFFFFF; \ +} + +/* + * Final Permutation macro + */ +#define DES_FP(X,Y) \ +{ \ + X = ((X << 31) | (X >> 1)) & 0xFFFFFFFF; \ + T = (X ^ Y) & 0xAAAAAAAA; X ^= T; Y ^= T; \ + Y = ((Y << 31) | (Y >> 1)) & 0xFFFFFFFF; \ + T = ((Y >> 8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T << 8); \ + T = ((Y >> 2) ^ X) & 0x33333333; X ^= T; Y ^= (T << 2); \ + T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16); \ + T = ((X >> 4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T << 4); \ +} + +/* + * DES round macro + */ +#define DES_ROUND(X,Y) \ +{ \ + T = *SK++ ^ X; \ + Y ^= SB8[ (T ) & 0x3F ] ^ \ + SB6[ (T >> 8) & 0x3F ] ^ \ + SB4[ (T >> 16) & 0x3F ] ^ \ + SB2[ (T >> 24) & 0x3F ]; \ + \ + T = *SK++ ^ ((X << 28) | (X >> 4)); \ + Y ^= SB7[ (T ) & 0x3F ] ^ \ + SB5[ (T >> 8) & 0x3F ] ^ \ + SB3[ (T >> 16) & 0x3F ] ^ \ + SB1[ (T >> 24) & 0x3F ]; \ +} + +#define SWAP(a,b) { uint32_t t = a; a = b; b = t; t = 0; } + +void mbedtls_des_init( mbedtls_des_context *ctx ) +{ + memset( ctx, 0, sizeof( mbedtls_des_context ) ); +} + +void mbedtls_des_free( mbedtls_des_context *ctx ) +{ + if( ctx == NULL ) + return; + + mbedtls_zeroize( ctx, sizeof( mbedtls_des_context ) ); +} + +void mbedtls_des3_init( mbedtls_des3_context *ctx ) +{ + memset( ctx, 0, sizeof( mbedtls_des3_context ) ); +} + +void mbedtls_des3_free( mbedtls_des3_context *ctx ) +{ + if( ctx == NULL ) + return; + + mbedtls_zeroize( ctx, sizeof( mbedtls_des3_context ) ); +} + +static const unsigned char odd_parity_table[128] = { 1, 2, 4, 7, 8, + 11, 13, 14, 16, 19, 21, 22, 25, 26, 28, 31, 32, 35, 37, 38, 41, 42, 44, + 47, 49, 50, 52, 55, 56, 59, 61, 62, 64, 67, 69, 70, 73, 74, 76, 79, 81, + 82, 84, 87, 88, 91, 93, 94, 97, 98, 100, 103, 104, 107, 109, 110, 112, + 115, 117, 118, 121, 122, 124, 127, 128, 131, 133, 134, 137, 138, 140, + 143, 145, 146, 148, 151, 152, 155, 157, 158, 161, 162, 164, 167, 168, + 171, 173, 174, 176, 179, 181, 182, 185, 186, 188, 191, 193, 194, 196, + 199, 200, 203, 205, 206, 208, 211, 213, 214, 217, 218, 220, 223, 224, + 227, 229, 230, 233, 234, 236, 239, 241, 242, 244, 247, 248, 251, 253, + 254 }; + +void mbedtls_des_key_set_parity( unsigned char key[MBEDTLS_DES_KEY_SIZE] ) +{ + int i; + + for( i = 0; i < MBEDTLS_DES_KEY_SIZE; i++ ) + key[i] = odd_parity_table[key[i] / 2]; +} + +/* + * Check the given key's parity, returns 1 on failure, 0 on SUCCESS + */ +int mbedtls_des_key_check_key_parity( const unsigned char key[MBEDTLS_DES_KEY_SIZE] ) +{ + int i; + + for( i = 0; i < MBEDTLS_DES_KEY_SIZE; i++ ) + if( key[i] != odd_parity_table[key[i] / 2] ) + return( 1 ); + + return( 0 ); +} + +/* + * Table of weak and semi-weak keys + * + * Source: http://en.wikipedia.org/wiki/Weak_key + * + * Weak: + * Alternating ones + zeros (0x0101010101010101) + * Alternating 'F' + 'E' (0xFEFEFEFEFEFEFEFE) + * '0xE0E0E0E0F1F1F1F1' + * '0x1F1F1F1F0E0E0E0E' + * + * Semi-weak: + * 0x011F011F010E010E and 0x1F011F010E010E01 + * 0x01E001E001F101F1 and 0xE001E001F101F101 + * 0x01FE01FE01FE01FE and 0xFE01FE01FE01FE01 + * 0x1FE01FE00EF10EF1 and 0xE01FE01FF10EF10E + * 0x1FFE1FFE0EFE0EFE and 0xFE1FFE1FFE0EFE0E + * 0xE0FEE0FEF1FEF1FE and 0xFEE0FEE0FEF1FEF1 + * + */ + +#define WEAK_KEY_COUNT 16 + +static const unsigned char weak_key_table[WEAK_KEY_COUNT][MBEDTLS_DES_KEY_SIZE] = +{ + { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE }, + { 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E }, + { 0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1 }, + + { 0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E }, + { 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01 }, + { 0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1 }, + { 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01 }, + { 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE }, + { 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01 }, + { 0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1 }, + { 0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E }, + { 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE }, + { 0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E }, + { 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE }, + { 0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1 } +}; + +int mbedtls_des_key_check_weak( const unsigned char key[MBEDTLS_DES_KEY_SIZE] ) +{ + int i; + + for( i = 0; i < WEAK_KEY_COUNT; i++ ) + if( memcmp( weak_key_table[i], key, MBEDTLS_DES_KEY_SIZE) == 0 ) + return( 1 ); + + return( 0 ); +} + +#if !defined(MBEDTLS_DES_SETKEY_ALT) +void mbedtls_des_setkey( uint32_t SK[32], const unsigned char key[MBEDTLS_DES_KEY_SIZE] ) +{ + int i; + uint32_t X, Y, T; + + GET_UINT32_BE( X, key, 0 ); + GET_UINT32_BE( Y, key, 4 ); + + /* + * Permuted Choice 1 + */ + T = ((Y >> 4) ^ X) & 0x0F0F0F0F; X ^= T; Y ^= (T << 4); + T = ((Y ) ^ X) & 0x10101010; X ^= T; Y ^= (T ); + + X = (LHs[ (X ) & 0xF] << 3) | (LHs[ (X >> 8) & 0xF ] << 2) + | (LHs[ (X >> 16) & 0xF] << 1) | (LHs[ (X >> 24) & 0xF ] ) + | (LHs[ (X >> 5) & 0xF] << 7) | (LHs[ (X >> 13) & 0xF ] << 6) + | (LHs[ (X >> 21) & 0xF] << 5) | (LHs[ (X >> 29) & 0xF ] << 4); + + Y = (RHs[ (Y >> 1) & 0xF] << 3) | (RHs[ (Y >> 9) & 0xF ] << 2) + | (RHs[ (Y >> 17) & 0xF] << 1) | (RHs[ (Y >> 25) & 0xF ] ) + | (RHs[ (Y >> 4) & 0xF] << 7) | (RHs[ (Y >> 12) & 0xF ] << 6) + | (RHs[ (Y >> 20) & 0xF] << 5) | (RHs[ (Y >> 28) & 0xF ] << 4); + + X &= 0x0FFFFFFF; + Y &= 0x0FFFFFFF; + + /* + * calculate subkeys + */ + for( i = 0; i < 16; i++ ) + { + if( i < 2 || i == 8 || i == 15 ) + { + X = ((X << 1) | (X >> 27)) & 0x0FFFFFFF; + Y = ((Y << 1) | (Y >> 27)) & 0x0FFFFFFF; + } + else + { + X = ((X << 2) | (X >> 26)) & 0x0FFFFFFF; + Y = ((Y << 2) | (Y >> 26)) & 0x0FFFFFFF; + } + + *SK++ = ((X << 4) & 0x24000000) | ((X << 28) & 0x10000000) + | ((X << 14) & 0x08000000) | ((X << 18) & 0x02080000) + | ((X << 6) & 0x01000000) | ((X << 9) & 0x00200000) + | ((X >> 1) & 0x00100000) | ((X << 10) & 0x00040000) + | ((X << 2) & 0x00020000) | ((X >> 10) & 0x00010000) + | ((Y >> 13) & 0x00002000) | ((Y >> 4) & 0x00001000) + | ((Y << 6) & 0x00000800) | ((Y >> 1) & 0x00000400) + | ((Y >> 14) & 0x00000200) | ((Y ) & 0x00000100) + | ((Y >> 5) & 0x00000020) | ((Y >> 10) & 0x00000010) + | ((Y >> 3) & 0x00000008) | ((Y >> 18) & 0x00000004) + | ((Y >> 26) & 0x00000002) | ((Y >> 24) & 0x00000001); + + *SK++ = ((X << 15) & 0x20000000) | ((X << 17) & 0x10000000) + | ((X << 10) & 0x08000000) | ((X << 22) & 0x04000000) + | ((X >> 2) & 0x02000000) | ((X << 1) & 0x01000000) + | ((X << 16) & 0x00200000) | ((X << 11) & 0x00100000) + | ((X << 3) & 0x00080000) | ((X >> 6) & 0x00040000) + | ((X << 15) & 0x00020000) | ((X >> 4) & 0x00010000) + | ((Y >> 2) & 0x00002000) | ((Y << 8) & 0x00001000) + | ((Y >> 14) & 0x00000808) | ((Y >> 9) & 0x00000400) + | ((Y ) & 0x00000200) | ((Y << 7) & 0x00000100) + | ((Y >> 7) & 0x00000020) | ((Y >> 3) & 0x00000011) + | ((Y << 2) & 0x00000004) | ((Y >> 21) & 0x00000002); + } +} +#endif /* !MBEDTLS_DES_SETKEY_ALT */ + +/* + * DES key schedule (56-bit, encryption) + */ +int mbedtls_des_setkey_enc( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] ) +{ + mbedtls_des_setkey( ctx->sk, key ); + + return( 0 ); +} + +/* + * DES key schedule (56-bit, decryption) + */ +int mbedtls_des_setkey_dec( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] ) +{ + int i; + + mbedtls_des_setkey( ctx->sk, key ); + + for( i = 0; i < 16; i += 2 ) + { + SWAP( ctx->sk[i ], ctx->sk[30 - i] ); + SWAP( ctx->sk[i + 1], ctx->sk[31 - i] ); + } + + return( 0 ); +} + +static void des3_set2key( uint32_t esk[96], + uint32_t dsk[96], + const unsigned char key[MBEDTLS_DES_KEY_SIZE*2] ) +{ + int i; + + mbedtls_des_setkey( esk, key ); + mbedtls_des_setkey( dsk + 32, key + 8 ); + + for( i = 0; i < 32; i += 2 ) + { + dsk[i ] = esk[30 - i]; + dsk[i + 1] = esk[31 - i]; + + esk[i + 32] = dsk[62 - i]; + esk[i + 33] = dsk[63 - i]; + + esk[i + 64] = esk[i ]; + esk[i + 65] = esk[i + 1]; + + dsk[i + 64] = dsk[i ]; + dsk[i + 65] = dsk[i + 1]; + } +} + +/* + * Triple-DES key schedule (112-bit, encryption) + */ +int mbedtls_des3_set2key_enc( mbedtls_des3_context *ctx, + const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] ) +{ + uint32_t sk[96]; + + des3_set2key( ctx->sk, sk, key ); + mbedtls_zeroize( sk, sizeof( sk ) ); + + return( 0 ); +} + +/* + * Triple-DES key schedule (112-bit, decryption) + */ +int mbedtls_des3_set2key_dec( mbedtls_des3_context *ctx, + const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] ) +{ + uint32_t sk[96]; + + des3_set2key( sk, ctx->sk, key ); + mbedtls_zeroize( sk, sizeof( sk ) ); + + return( 0 ); +} + +static void des3_set3key( uint32_t esk[96], + uint32_t dsk[96], + const unsigned char key[24] ) +{ + int i; + + mbedtls_des_setkey( esk, key ); + mbedtls_des_setkey( dsk + 32, key + 8 ); + mbedtls_des_setkey( esk + 64, key + 16 ); + + for( i = 0; i < 32; i += 2 ) + { + dsk[i ] = esk[94 - i]; + dsk[i + 1] = esk[95 - i]; + + esk[i + 32] = dsk[62 - i]; + esk[i + 33] = dsk[63 - i]; + + dsk[i + 64] = esk[30 - i]; + dsk[i + 65] = esk[31 - i]; + } +} + +/* + * Triple-DES key schedule (168-bit, encryption) + */ +int mbedtls_des3_set3key_enc( mbedtls_des3_context *ctx, + const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] ) +{ + uint32_t sk[96]; + + des3_set3key( ctx->sk, sk, key ); + mbedtls_zeroize( sk, sizeof( sk ) ); + + return( 0 ); +} + +/* + * Triple-DES key schedule (168-bit, decryption) + */ +int mbedtls_des3_set3key_dec( mbedtls_des3_context *ctx, + const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] ) +{ + uint32_t sk[96]; + + des3_set3key( sk, ctx->sk, key ); + mbedtls_zeroize( sk, sizeof( sk ) ); + + return( 0 ); +} + +/* + * DES-ECB block encryption/decryption + */ +#if !defined(MBEDTLS_DES_CRYPT_ECB_ALT) +int mbedtls_des_crypt_ecb( mbedtls_des_context *ctx, + const unsigned char input[8], + unsigned char output[8] ) +{ + int i; + uint32_t X, Y, T, *SK; + + SK = ctx->sk; + + GET_UINT32_BE( X, input, 0 ); + GET_UINT32_BE( Y, input, 4 ); + + DES_IP( X, Y ); + + for( i = 0; i < 8; i++ ) + { + DES_ROUND( Y, X ); + DES_ROUND( X, Y ); + } + + DES_FP( Y, X ); + + PUT_UINT32_BE( Y, output, 0 ); + PUT_UINT32_BE( X, output, 4 ); + + return( 0 ); +} +#endif /* !MBEDTLS_DES_CRYPT_ECB_ALT */ + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +/* + * DES-CBC buffer encryption/decryption + */ +int mbedtls_des_crypt_cbc( mbedtls_des_context *ctx, + int mode, + size_t length, + unsigned char iv[8], + const unsigned char *input, + unsigned char *output ) +{ + int i; + unsigned char temp[8]; + + if( length % 8 ) + return( MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH ); + + if( mode == MBEDTLS_DES_ENCRYPT ) + { + while( length > 0 ) + { + for( i = 0; i < 8; i++ ) + output[i] = (unsigned char)( input[i] ^ iv[i] ); + + mbedtls_des_crypt_ecb( ctx, output, output ); + memcpy( iv, output, 8 ); + + input += 8; + output += 8; + length -= 8; + } + } + else /* MBEDTLS_DES_DECRYPT */ + { + while( length > 0 ) + { + memcpy( temp, input, 8 ); + mbedtls_des_crypt_ecb( ctx, input, output ); + + for( i = 0; i < 8; i++ ) + output[i] = (unsigned char)( output[i] ^ iv[i] ); + + memcpy( iv, temp, 8 ); + + input += 8; + output += 8; + length -= 8; + } + } + + return( 0 ); +} +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +/* + * 3DES-ECB block encryption/decryption + */ +#if !defined(MBEDTLS_DES3_CRYPT_ECB_ALT) +int mbedtls_des3_crypt_ecb( mbedtls_des3_context *ctx, + const unsigned char input[8], + unsigned char output[8] ) +{ + int i; + uint32_t X, Y, T, *SK; + + SK = ctx->sk; + + GET_UINT32_BE( X, input, 0 ); + GET_UINT32_BE( Y, input, 4 ); + + DES_IP( X, Y ); + + for( i = 0; i < 8; i++ ) + { + DES_ROUND( Y, X ); + DES_ROUND( X, Y ); + } + + for( i = 0; i < 8; i++ ) + { + DES_ROUND( X, Y ); + DES_ROUND( Y, X ); + } + + for( i = 0; i < 8; i++ ) + { + DES_ROUND( Y, X ); + DES_ROUND( X, Y ); + } + + DES_FP( Y, X ); + + PUT_UINT32_BE( Y, output, 0 ); + PUT_UINT32_BE( X, output, 4 ); + + return( 0 ); +} +#endif /* !MBEDTLS_DES3_CRYPT_ECB_ALT */ + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +/* + * 3DES-CBC buffer encryption/decryption + */ +int mbedtls_des3_crypt_cbc( mbedtls_des3_context *ctx, + int mode, + size_t length, + unsigned char iv[8], + const unsigned char *input, + unsigned char *output ) +{ + int i; + unsigned char temp[8]; + + if( length % 8 ) + return( MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH ); + + if( mode == MBEDTLS_DES_ENCRYPT ) + { + while( length > 0 ) + { + for( i = 0; i < 8; i++ ) + output[i] = (unsigned char)( input[i] ^ iv[i] ); + + mbedtls_des3_crypt_ecb( ctx, output, output ); + memcpy( iv, output, 8 ); + + input += 8; + output += 8; + length -= 8; + } + } + else /* MBEDTLS_DES_DECRYPT */ + { + while( length > 0 ) + { + memcpy( temp, input, 8 ); + mbedtls_des3_crypt_ecb( ctx, input, output ); + + for( i = 0; i < 8; i++ ) + output[i] = (unsigned char)( output[i] ^ iv[i] ); + + memcpy( iv, temp, 8 ); + + input += 8; + output += 8; + length -= 8; + } + } + + return( 0 ); +} +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#endif /* !MBEDTLS_DES_ALT */ + +#if defined(MBEDTLS_SELF_TEST) +/* + * DES and 3DES test vectors from: + * + * http://csrc.nist.gov/groups/STM/cavp/documents/des/tripledes-vectors.zip + */ +static const unsigned char des3_test_keys[24] = +{ + 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, + 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, + 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23 +}; + +static const unsigned char des3_test_buf[8] = +{ + 0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74 +}; + +static const unsigned char des3_test_ecb_dec[3][8] = +{ + { 0xCD, 0xD6, 0x4F, 0x2F, 0x94, 0x27, 0xC1, 0x5D }, + { 0x69, 0x96, 0xC8, 0xFA, 0x47, 0xA2, 0xAB, 0xEB }, + { 0x83, 0x25, 0x39, 0x76, 0x44, 0x09, 0x1A, 0x0A } +}; + +static const unsigned char des3_test_ecb_enc[3][8] = +{ + { 0x6A, 0x2A, 0x19, 0xF4, 0x1E, 0xCA, 0x85, 0x4B }, + { 0x03, 0xE6, 0x9F, 0x5B, 0xFA, 0x58, 0xEB, 0x42 }, + { 0xDD, 0x17, 0xE8, 0xB8, 0xB4, 0x37, 0xD2, 0x32 } +}; + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static const unsigned char des3_test_iv[8] = +{ + 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, +}; + +static const unsigned char des3_test_cbc_dec[3][8] = +{ + { 0x12, 0x9F, 0x40, 0xB9, 0xD2, 0x00, 0x56, 0xB3 }, + { 0x47, 0x0E, 0xFC, 0x9A, 0x6B, 0x8E, 0xE3, 0x93 }, + { 0xC5, 0xCE, 0xCF, 0x63, 0xEC, 0xEC, 0x51, 0x4C } +}; + +static const unsigned char des3_test_cbc_enc[3][8] = +{ + { 0x54, 0xF1, 0x5A, 0xF6, 0xEB, 0xE3, 0xA4, 0xB4 }, + { 0x35, 0x76, 0x11, 0x56, 0x5F, 0xA1, 0x8E, 0x4D }, + { 0xCB, 0x19, 0x1F, 0x85, 0xD1, 0xED, 0x84, 0x39 } +}; +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +/* + * Checkup routine + */ +int mbedtls_des_self_test( int verbose ) +{ + int i, j, u, v, ret = 0; + mbedtls_des_context ctx; + mbedtls_des3_context ctx3; + unsigned char buf[8]; +#if defined(MBEDTLS_CIPHER_MODE_CBC) + unsigned char prv[8]; + unsigned char iv[8]; +#endif + + mbedtls_des_init( &ctx ); + mbedtls_des3_init( &ctx3 ); + /* + * ECB mode + */ + for( i = 0; i < 6; i++ ) + { + u = i >> 1; + v = i & 1; + + if( verbose != 0 ) + mbedtls_printf( " DES%c-ECB-%3d (%s): ", + ( u == 0 ) ? ' ' : '3', 56 + u * 56, + ( v == MBEDTLS_DES_DECRYPT ) ? "dec" : "enc" ); + + memcpy( buf, des3_test_buf, 8 ); + + switch( i ) + { + case 0: + mbedtls_des_setkey_dec( &ctx, des3_test_keys ); + break; + + case 1: + mbedtls_des_setkey_enc( &ctx, des3_test_keys ); + break; + + case 2: + mbedtls_des3_set2key_dec( &ctx3, des3_test_keys ); + break; + + case 3: + mbedtls_des3_set2key_enc( &ctx3, des3_test_keys ); + break; + + case 4: + mbedtls_des3_set3key_dec( &ctx3, des3_test_keys ); + break; + + case 5: + mbedtls_des3_set3key_enc( &ctx3, des3_test_keys ); + break; + + default: + return( 1 ); + } + + for( j = 0; j < 10000; j++ ) + { + if( u == 0 ) + mbedtls_des_crypt_ecb( &ctx, buf, buf ); + else + mbedtls_des3_crypt_ecb( &ctx3, buf, buf ); + } + + if( ( v == MBEDTLS_DES_DECRYPT && + memcmp( buf, des3_test_ecb_dec[u], 8 ) != 0 ) || + ( v != MBEDTLS_DES_DECRYPT && + memcmp( buf, des3_test_ecb_enc[u], 8 ) != 0 ) ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + ret = 1; + goto exit; + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + } + + if( verbose != 0 ) + mbedtls_printf( "\n" ); + +#if defined(MBEDTLS_CIPHER_MODE_CBC) + /* + * CBC mode + */ + for( i = 0; i < 6; i++ ) + { + u = i >> 1; + v = i & 1; + + if( verbose != 0 ) + mbedtls_printf( " DES%c-CBC-%3d (%s): ", + ( u == 0 ) ? ' ' : '3', 56 + u * 56, + ( v == MBEDTLS_DES_DECRYPT ) ? "dec" : "enc" ); + + memcpy( iv, des3_test_iv, 8 ); + memcpy( prv, des3_test_iv, 8 ); + memcpy( buf, des3_test_buf, 8 ); + + switch( i ) + { + case 0: + mbedtls_des_setkey_dec( &ctx, des3_test_keys ); + break; + + case 1: + mbedtls_des_setkey_enc( &ctx, des3_test_keys ); + break; + + case 2: + mbedtls_des3_set2key_dec( &ctx3, des3_test_keys ); + break; + + case 3: + mbedtls_des3_set2key_enc( &ctx3, des3_test_keys ); + break; + + case 4: + mbedtls_des3_set3key_dec( &ctx3, des3_test_keys ); + break; + + case 5: + mbedtls_des3_set3key_enc( &ctx3, des3_test_keys ); + break; + + default: + return( 1 ); + } + + if( v == MBEDTLS_DES_DECRYPT ) + { + for( j = 0; j < 10000; j++ ) + { + if( u == 0 ) + mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf ); + else + mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf ); + } + } + else + { + for( j = 0; j < 10000; j++ ) + { + unsigned char tmp[8]; + + if( u == 0 ) + mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf ); + else + mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf ); + + memcpy( tmp, prv, 8 ); + memcpy( prv, buf, 8 ); + memcpy( buf, tmp, 8 ); + } + + memcpy( buf, prv, 8 ); + } + + if( ( v == MBEDTLS_DES_DECRYPT && + memcmp( buf, des3_test_cbc_dec[u], 8 ) != 0 ) || + ( v != MBEDTLS_DES_DECRYPT && + memcmp( buf, des3_test_cbc_enc[u], 8 ) != 0 ) ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + ret = 1; + goto exit; + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + } +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + + if( verbose != 0 ) + mbedtls_printf( "\n" ); + +exit: + mbedtls_des_free( &ctx ); + mbedtls_des3_free( &ctx3 ); + + return( ret ); +} + +#endif /* MBEDTLS_SELF_TEST */ + +#endif /* MBEDTLS_DES_C */ diff --git a/APP_Framework/Framework/security/mbedtls/des.h b/APP_Framework/Framework/security/mbedtls/des.h index 54e6b7894..5a1a63652 100644 --- a/APP_Framework/Framework/security/mbedtls/des.h +++ b/APP_Framework/Framework/security/mbedtls/des.h @@ -42,20 +42,18 @@ #define MBEDTLS_DES_DECRYPT 0 #define MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH -0x0032 /**< The data input has an invalid length. */ - -/* MBEDTLS_ERR_DES_HW_ACCEL_FAILED is deprecated and should not be used. */ #define MBEDTLS_ERR_DES_HW_ACCEL_FAILED -0x0033 /**< DES hardware accelerator failed. */ #define MBEDTLS_DES_KEY_SIZE 8 -#ifdef __cplusplus -extern "C" { -#endif - #if !defined(MBEDTLS_DES_ALT) // Regular implementation // +#ifdef __cplusplus +extern "C" { +#endif + /** * \brief DES context structure * @@ -63,7 +61,7 @@ extern "C" { * security risk. We recommend considering stronger ciphers * instead. */ -typedef struct mbedtls_des_context +typedef struct { uint32_t sk[32]; /*!< DES subkeys */ } @@ -72,16 +70,12 @@ mbedtls_des_context; /** * \brief Triple-DES context structure */ -typedef struct mbedtls_des3_context +typedef struct { uint32_t sk[96]; /*!< 3DES subkeys */ } mbedtls_des3_context; -#else /* MBEDTLS_DES_ALT */ -#include "des_alt.h" -#endif /* MBEDTLS_DES_ALT */ - /** * \brief Initialize DES context * @@ -337,8 +331,17 @@ int mbedtls_des3_crypt_cbc( mbedtls_des3_context *ctx, */ void mbedtls_des_setkey( uint32_t SK[32], const unsigned char key[MBEDTLS_DES_KEY_SIZE] ); +#ifdef __cplusplus +} +#endif -#if defined(MBEDTLS_SELF_TEST) +#else /* MBEDTLS_DES_ALT */ +#include "des_alt.h" +#endif /* MBEDTLS_DES_ALT */ + +#ifdef __cplusplus +extern "C" { +#endif /** * \brief Checkup routine @@ -347,8 +350,6 @@ void mbedtls_des_setkey( uint32_t SK[32], */ int mbedtls_des_self_test( int verbose ); -#endif /* MBEDTLS_SELF_TEST */ - #ifdef __cplusplus } #endif diff --git a/APP_Framework/Framework/security/mbedtls/dhm.c b/APP_Framework/Framework/security/mbedtls/dhm.c index 4d2afb8c7..2c5bb9ba7 100644 --- a/APP_Framework/Framework/security/mbedtls/dhm.c +++ b/APP_Framework/Framework/security/mbedtls/dhm.c @@ -36,7 +36,6 @@ #if defined(MBEDTLS_DHM_C) #include "dhm.h" -#include "platform_util.h" #include @@ -59,11 +58,10 @@ #endif #if !defined(MBEDTLS_DHM_ALT) - -#define DHM_VALIDATE_RET( cond ) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_DHM_BAD_INPUT_DATA ) -#define DHM_VALIDATE( cond ) \ - MBEDTLS_INTERNAL_VALIDATE( cond ) +/* 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; +} /* * helper to validate the mbedtls_mpi size and import it @@ -126,8 +124,7 @@ cleanup: void mbedtls_dhm_init( mbedtls_dhm_context *ctx ) { - DHM_VALIDATE( ctx != NULL ); - mbedtls_platform_memset( ctx, 0, sizeof( mbedtls_dhm_context ) ); + memset( ctx, 0, sizeof( mbedtls_dhm_context ) ); } /* @@ -138,9 +135,6 @@ int mbedtls_dhm_read_params( mbedtls_dhm_context *ctx, const unsigned char *end ) { int ret; - DHM_VALIDATE_RET( ctx != NULL ); - DHM_VALIDATE_RET( p != NULL && *p != NULL ); - DHM_VALIDATE_RET( end != NULL ); if( ( ret = dhm_read_bignum( &ctx->P, p, end ) ) != 0 || ( ret = dhm_read_bignum( &ctx->G, p, end ) ) != 0 || @@ -166,10 +160,6 @@ int mbedtls_dhm_make_params( mbedtls_dhm_context *ctx, int x_size, int ret, count = 0; size_t n1, n2, n3; unsigned char *p; - DHM_VALIDATE_RET( ctx != NULL ); - DHM_VALIDATE_RET( output != NULL ); - DHM_VALIDATE_RET( olen != NULL ); - DHM_VALIDATE_RET( f_rng != NULL ); if( mbedtls_mpi_cmp_int( &ctx->P, 0 ) == 0 ) return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA ); @@ -240,9 +230,9 @@ int mbedtls_dhm_set_group( mbedtls_dhm_context *ctx, const mbedtls_mpi *G ) { int ret; - DHM_VALIDATE_RET( ctx != NULL ); - DHM_VALIDATE_RET( P != NULL ); - DHM_VALIDATE_RET( G != NULL ); + + 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 ) @@ -261,10 +251,8 @@ int mbedtls_dhm_read_public( mbedtls_dhm_context *ctx, const unsigned char *input, size_t ilen ) { int ret; - DHM_VALIDATE_RET( ctx != NULL ); - DHM_VALIDATE_RET( input != NULL ); - if( ilen < 1 || ilen > ctx->len ) + if( ctx == NULL || ilen < 1 || ilen > ctx->len ) return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA ); if( ( ret = mbedtls_mpi_read_binary( &ctx->GY, input, ilen ) ) != 0 ) @@ -282,11 +270,8 @@ int mbedtls_dhm_make_public( mbedtls_dhm_context *ctx, int x_size, void *p_rng ) { int ret, count = 0; - DHM_VALIDATE_RET( ctx != NULL ); - DHM_VALIDATE_RET( output != NULL ); - DHM_VALIDATE_RET( f_rng != NULL ); - if( olen < 1 || olen > ctx->len ) + if( ctx == NULL || olen < 1 || olen > ctx->len ) return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA ); if( mbedtls_mpi_cmp_int( &ctx->P, 0 ) == 0 ) @@ -398,11 +383,8 @@ int mbedtls_dhm_calc_secret( mbedtls_dhm_context *ctx, { int ret; mbedtls_mpi GYb; - DHM_VALIDATE_RET( ctx != NULL ); - DHM_VALIDATE_RET( output != NULL ); - DHM_VALIDATE_RET( olen != NULL ); - if( output_size < ctx->len ) + if( ctx == NULL || output_size < ctx->len ) return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA ); if( ( ret = dhm_check_range( &ctx->GY, &ctx->P ) ) != 0 ) @@ -449,21 +431,13 @@ cleanup: */ void mbedtls_dhm_free( mbedtls_dhm_context *ctx ) { - if( ctx == NULL ) - return; + mbedtls_mpi_free( &ctx->pX ); mbedtls_mpi_free( &ctx->Vf ); + mbedtls_mpi_free( &ctx->Vi ); mbedtls_mpi_free( &ctx->RP ); + mbedtls_mpi_free( &ctx->K ); mbedtls_mpi_free( &ctx->GY ); + mbedtls_mpi_free( &ctx->GX ); mbedtls_mpi_free( &ctx->X ); + mbedtls_mpi_free( &ctx->G ); mbedtls_mpi_free( &ctx->P ); - mbedtls_mpi_free( &ctx->pX ); - mbedtls_mpi_free( &ctx->Vf ); - mbedtls_mpi_free( &ctx->Vi ); - mbedtls_mpi_free( &ctx->RP ); - mbedtls_mpi_free( &ctx->K ); - mbedtls_mpi_free( &ctx->GY ); - mbedtls_mpi_free( &ctx->GX ); - mbedtls_mpi_free( &ctx->X ); - mbedtls_mpi_free( &ctx->G ); - mbedtls_mpi_free( &ctx->P ); - - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_dhm_context ) ); + mbedtls_zeroize( ctx, sizeof( mbedtls_dhm_context ) ); } #if defined(MBEDTLS_ASN1_PARSE_C) @@ -478,12 +452,7 @@ int mbedtls_dhm_parse_dhm( mbedtls_dhm_context *dhm, const unsigned char *dhmin, unsigned char *p, *end; #if defined(MBEDTLS_PEM_PARSE_C) mbedtls_pem_context pem; -#endif /* MBEDTLS_PEM_PARSE_C */ - DHM_VALIDATE_RET( dhm != NULL ); - DHM_VALIDATE_RET( dhmin != NULL ); - -#if defined(MBEDTLS_PEM_PARSE_C) mbedtls_pem_init( &pem ); /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ @@ -606,7 +575,7 @@ static int load_file( const char *path, unsigned char **buf, size_t *n ) { fclose( f ); - mbedtls_platform_zeroize( *buf, *n + 1 ); + mbedtls_zeroize( *buf, *n + 1 ); mbedtls_free( *buf ); return( MBEDTLS_ERR_DHM_FILE_IO_ERROR ); @@ -630,15 +599,13 @@ int mbedtls_dhm_parse_dhmfile( mbedtls_dhm_context *dhm, const char *path ) int ret; size_t n; unsigned char *buf; - DHM_VALIDATE_RET( dhm != NULL ); - DHM_VALIDATE_RET( path != NULL ); if( ( ret = load_file( path, &buf, &n ) ) != 0 ) return( ret ); ret = mbedtls_dhm_parse_dhm( dhm, buf, n ); - mbedtls_platform_zeroize( buf, n ); + mbedtls_zeroize( buf, n ); mbedtls_free( buf ); return( ret ); @@ -649,28 +616,12 @@ int mbedtls_dhm_parse_dhmfile( mbedtls_dhm_context *dhm, const char *path ) #if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PEM_PARSE_C) static const char mbedtls_test_dhm_params[] = "-----BEGIN DH PARAMETERS-----\r\n" "MIGHAoGBAJ419DBEOgmQTzo5qXl5fQcN9TN455wkOL7052HzxxRVMyhYmwQcgJvh\r\n" "1sa18fyfR9OiVEMYglOpkqVoGLN7qd5aQNNi5W7/C+VBdHTBJcGZJyyP5B3qcz32\r\n" "9mLJKudlVudV0Qxk5qUJaPZ/xupz0NyoVpviuiBOI1gNi8ovSXWzAgEC\r\n" "-----END DH PARAMETERS-----\r\n"; -#else /* MBEDTLS_PEM_PARSE_C */ -static const char mbedtls_test_dhm_params[] = { - 0x30, 0x81, 0x87, 0x02, 0x81, 0x81, 0x00, 0x9e, 0x35, 0xf4, 0x30, 0x44, - 0x3a, 0x09, 0x90, 0x4f, 0x3a, 0x39, 0xa9, 0x79, 0x79, 0x7d, 0x07, 0x0d, - 0xf5, 0x33, 0x78, 0xe7, 0x9c, 0x24, 0x38, 0xbe, 0xf4, 0xe7, 0x61, 0xf3, - 0xc7, 0x14, 0x55, 0x33, 0x28, 0x58, 0x9b, 0x04, 0x1c, 0x80, 0x9b, 0xe1, - 0xd6, 0xc6, 0xb5, 0xf1, 0xfc, 0x9f, 0x47, 0xd3, 0xa2, 0x54, 0x43, 0x18, - 0x82, 0x53, 0xa9, 0x92, 0xa5, 0x68, 0x18, 0xb3, 0x7b, 0xa9, 0xde, 0x5a, - 0x40, 0xd3, 0x62, 0xe5, 0x6e, 0xff, 0x0b, 0xe5, 0x41, 0x74, 0x74, 0xc1, - 0x25, 0xc1, 0x99, 0x27, 0x2c, 0x8f, 0xe4, 0x1d, 0xea, 0x73, 0x3d, 0xf6, - 0xf6, 0x62, 0xc9, 0x2a, 0xe7, 0x65, 0x56, 0xe7, 0x55, 0xd1, 0x0c, 0x64, - 0xe6, 0xa5, 0x09, 0x68, 0xf6, 0x7f, 0xc6, 0xea, 0x73, 0xd0, 0xdc, 0xa8, - 0x56, 0x9b, 0xe2, 0xba, 0x20, 0x4e, 0x23, 0x58, 0x0d, 0x8b, 0xca, 0x2f, - 0x49, 0x75, 0xb3, 0x02, 0x01, 0x02 }; -#endif /* MBEDTLS_PEM_PARSE_C */ static const size_t mbedtls_test_dhm_params_len = sizeof( mbedtls_test_dhm_params ); diff --git a/APP_Framework/Framework/security/mbedtls/dhm.h b/APP_Framework/Framework/security/mbedtls/dhm.h index 2909f5fbc..00fafd8d1 100644 --- a/APP_Framework/Framework/security/mbedtls/dhm.h +++ b/APP_Framework/Framework/security/mbedtls/dhm.h @@ -1,13 +1,7 @@ /** * \file dhm.h * - * \brief This file contains Diffie-Hellman-Merkle (DHM) key exchange - * definitions and functions. - * - * Diffie-Hellman-Merkle (DHM) key exchange is defined in - * RFC-2631: Diffie-Hellman Key Agreement Method and - * Public-Key Cryptography Standards (PKCS) #3: Diffie - * Hellman Key Agreement Standard. + * \brief Diffie-Hellman-Merkle key exchange. * * RFC-3526: More Modular Exponential (MODP) Diffie-Hellman groups for * Internet Key Exchange (IKE) defines a number of standardized @@ -71,6 +65,7 @@ #include MBEDTLS_CONFIG_FILE #endif #include "bignum.h" +#if !defined(MBEDTLS_DHM_ALT) /* * DHM Error codes @@ -84,22 +79,17 @@ #define MBEDTLS_ERR_DHM_INVALID_FORMAT -0x3380 /**< The ASN.1 data is not formatted correctly. */ #define MBEDTLS_ERR_DHM_ALLOC_FAILED -0x3400 /**< Allocation of memory failed. */ #define MBEDTLS_ERR_DHM_FILE_IO_ERROR -0x3480 /**< Read or write of file failed. */ - -/* MBEDTLS_ERR_DHM_HW_ACCEL_FAILED is deprecated and should not be used. */ #define MBEDTLS_ERR_DHM_HW_ACCEL_FAILED -0x3500 /**< DHM hardware accelerator failed. */ - #define MBEDTLS_ERR_DHM_SET_GROUP_FAILED -0x3580 /**< Setting the modulus and generator failed. */ #ifdef __cplusplus extern "C" { #endif -#if !defined(MBEDTLS_DHM_ALT) - /** * \brief The DHM context structure. */ -typedef struct mbedtls_dhm_context +typedef struct { size_t len; /*!< The size of \p P in Bytes. */ mbedtls_mpi P; /*!< The prime modulus. */ @@ -115,10 +105,6 @@ typedef struct mbedtls_dhm_context } mbedtls_dhm_context; -#else /* MBEDTLS_DHM_ALT */ -#include "dhm_alt.h" -#endif /* MBEDTLS_DHM_ALT */ - /** * \brief This function initializes the DHM context. * @@ -127,15 +113,9 @@ mbedtls_dhm_context; void mbedtls_dhm_init( mbedtls_dhm_context *ctx ); /** - * \brief This function parses the DHM parameters in a - * TLS ServerKeyExchange handshake message - * (DHM modulus, generator, and public key). + * \brief This function parses the ServerKeyExchange parameters. * - * \note In a TLS handshake, this is the how the client - * sets up its DHM context from the server's public - * DHM key material. - * - * \param ctx The DHM context to use. This must be initialized. + * \param ctx The DHM context. * \param p On input, *p must be the start of the input buffer. * On output, *p is updated to point to the end of the data * that has been read. On success, this is the first byte @@ -145,44 +125,38 @@ void mbedtls_dhm_init( mbedtls_dhm_context *ctx ); * failures. * \param end The end of the input buffer. * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_DHM_XXX error code on failure. + * \return \c 0 on success, or an \c MBEDTLS_ERR_DHM_XXX error code + * on failure. */ int mbedtls_dhm_read_params( mbedtls_dhm_context *ctx, - unsigned char **p, - const unsigned char *end ); + unsigned char **p, + const unsigned char *end ); /** - * \brief This function generates a DHM key pair and exports its - * public part together with the DHM parameters in the format - * used in a TLS ServerKeyExchange handshake message. + * \brief This function sets up and writes the ServerKeyExchange + * parameters. * - * \note This function assumes that the DHM parameters \c ctx->P - * and \c ctx->G have already been properly set. For that, use + * \param ctx The DHM context. + * \param x_size The private value size in Bytes. + * \param olen The number of characters written. + * \param output The destination buffer. + * \param f_rng The RNG function. + * \param p_rng The RNG parameter. + * + * \note The destination buffer must be large enough to hold + * the reduced binary presentation of the modulus, the generator + * and the public key, each wrapped with a 2-byte length field. + * It is the responsibility of the caller to ensure that enough + * space is available. Refer to \c mbedtls_mpi_size to computing + * the byte-size of an MPI. + * + * \note This function assumes that \c ctx->P and \c ctx->G + * have already been properly set. For that, use * mbedtls_dhm_set_group() below in conjunction with * mbedtls_mpi_read_binary() and mbedtls_mpi_read_string(). * - * \note In a TLS handshake, this is the how the server generates - * and exports its DHM key material. - * - * \param ctx The DHM context to use. This must be initialized - * and have the DHM parameters set. It may or may not - * already have imported the peer's public key. - * \param x_size The private key size in Bytes. - * \param olen The address at which to store the number of Bytes - * written on success. This must not be \c NULL. - * \param output The destination buffer. This must be a writable buffer of - * sufficient size to hold the reduced binary presentation of - * the modulus, the generator and the public key, each wrapped - * with a 2-byte length field. It is the responsibility of the - * caller to ensure that enough space is available. Refer to - * mbedtls_mpi_size() to computing the byte-size of an MPI. - * \param f_rng The RNG function. Must not be \c NULL. - * \param p_rng The RNG context to be passed to \p f_rng. This may be - * \c NULL if \p f_rng doesn't need a context parameter. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_DHM_XXX error code on failure. + * \return \c 0 on success, or an \c MBEDTLS_ERR_DHM_XXX error code + * on failure. */ int mbedtls_dhm_make_params( mbedtls_dhm_context *ctx, int x_size, unsigned char *output, size_t *olen, @@ -190,66 +164,54 @@ int mbedtls_dhm_make_params( mbedtls_dhm_context *ctx, int x_size, void *p_rng ); /** - * \brief This function sets the prime modulus and generator. + * \brief Set prime modulus and generator * - * \note This function can be used to set \c ctx->P, \c ctx->G - * in preparation for mbedtls_dhm_make_params(). + * \param ctx The DHM context. + * \param P The MPI holding DHM prime modulus. + * \param G The MPI holding DHM generator. * - * \param ctx The DHM context to configure. This must be initialized. - * \param P The MPI holding the DHM prime modulus. This must be - * an initialized MPI. - * \param G The MPI holding the DHM generator. This must be an - * initialized MPI. + * \note This function can be used to set P, G + * in preparation for \c mbedtls_dhm_make_params. * - * \return \c 0 if successful. - * \return An \c MBEDTLS_ERR_DHM_XXX error code on failure. + * \return \c 0 if successful, or an \c MBEDTLS_ERR_DHM_XXX error code + * on failure. */ int mbedtls_dhm_set_group( mbedtls_dhm_context *ctx, const mbedtls_mpi *P, const mbedtls_mpi *G ); /** - * \brief This function imports the raw public value of the peer. + * \brief This function imports the public value G^Y of the peer. * - * \note In a TLS handshake, this is the how the server imports - * the Client's public DHM key. + * \param ctx The DHM context. + * \param input The input buffer. + * \param ilen The size of the input buffer. * - * \param ctx The DHM context to use. This must be initialized and have - * its DHM parameters set, e.g. via mbedtls_dhm_set_group(). - * It may or may not already have generated its own private key. - * \param input The input buffer containing the \c G^Y value of the peer. - * This must be a readable buffer of size \p ilen Bytes. - * \param ilen The size of the input buffer \p input in Bytes. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_DHM_XXX error code on failure. + * \return \c 0 on success, or an \c MBEDTLS_ERR_DHM_XXX error code + * on failure. */ int mbedtls_dhm_read_public( mbedtls_dhm_context *ctx, const unsigned char *input, size_t ilen ); /** - * \brief This function creates a DHM key pair and exports - * the raw public key in big-endian format. + * \brief This function creates its own private value \c X and + * exports \c G^X. * - * \note The destination buffer is always fully written - * so as to contain a big-endian representation of G^X mod P. - * If it is larger than \c ctx->len, it is padded accordingly - * with zero-bytes at the beginning. + * \param ctx The DHM context. + * \param x_size The private value size in Bytes. + * \param output The destination buffer. + * \param olen The length of the destination buffer. Must be at least + equal to ctx->len (the size of \c P). + * \param f_rng The RNG function. + * \param p_rng The RNG parameter. * - * \param ctx The DHM context to use. This must be initialized and - * have the DHM parameters set. It may or may not already - * have imported the peer's public key. - * \param x_size The private key size in Bytes. - * \param output The destination buffer. This must be a writable buffer of - * size \p olen Bytes. - * \param olen The length of the destination buffer. This must be at least - * equal to `ctx->len` (the size of \c P). - * \param f_rng The RNG function. This must not be \c NULL. - * \param p_rng The RNG context to be passed to \p f_rng. This may be \c NULL - * if \p f_rng doesn't need a context argument. + * \note The destination buffer will always be fully written + * so as to contain a big-endian presentation of G^X mod P. + * If it is larger than ctx->len, it will accordingly be + * padded with zero-bytes in the beginning. * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_DHM_XXX error code on failure. + * \return \c 0 on success, or an \c MBEDTLS_ERR_DHM_XXX error code + * on failure. */ int mbedtls_dhm_make_public( mbedtls_dhm_context *ctx, int x_size, unsigned char *output, size_t olen, @@ -257,30 +219,25 @@ int mbedtls_dhm_make_public( mbedtls_dhm_context *ctx, int x_size, void *p_rng ); /** - * \brief This function derives and exports the shared secret - * \c (G^Y)^X mod \c P. + * \brief This function derives and exports the shared secret + * \c (G^Y)^X mod \c P. * - * \note If \p f_rng is not \c NULL, it is used to blind the input as - * a countermeasure against timing attacks. Blinding is used - * only if our private key \c X is re-used, and not used - * otherwise. We recommend always passing a non-NULL - * \p f_rng argument. - * - * \param ctx The DHM context to use. This must be initialized - * and have its own private key generated and the peer's - * public key imported. - * \param output The buffer to write the generated shared key to. This - * must be a writable buffer of size \p output_size Bytes. - * \param output_size The size of the destination buffer. This must be at - * least the size of \c ctx->len (the size of \c P). + * \param ctx The DHM context. + * \param output The destination buffer. + * \param output_size The size of the destination buffer. Must be at least + * the size of ctx->len. * \param olen On exit, holds the actual number of Bytes written. - * \param f_rng The RNG function, for blinding purposes. This may - * b \c NULL if blinding isn't needed. - * \param p_rng The RNG context. This may be \c NULL if \p f_rng - * doesn't need a context argument. + * \param f_rng The RNG function, for blinding purposes. + * \param p_rng The RNG parameter. * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_DHM_XXX error code on failure. + * \return \c 0 on success, or an \c MBEDTLS_ERR_DHM_XXX error code + * on failure. + * + * \note If non-NULL, \p f_rng is used to blind the input as + * a countermeasure against timing attacks. Blinding is used + * only if our secret value \p X is re-used and omitted + * otherwise. Therefore, we recommend always passing a + * non-NULL \p f_rng argument. */ int mbedtls_dhm_calc_secret( mbedtls_dhm_context *ctx, unsigned char *output, size_t output_size, size_t *olen, @@ -288,12 +245,9 @@ int mbedtls_dhm_calc_secret( mbedtls_dhm_context *ctx, void *p_rng ); /** - * \brief This function frees and clears the components - * of a DHM context. + * \brief This function frees and clears the components of a DHM key. * - * \param ctx The DHM context to free and clear. This may be \c NULL, - * in which case this function is a no-op. If it is not \c NULL, - * it must point to an initialized DHM context. + * \param ctx The DHM context to free and clear. */ void mbedtls_dhm_free( mbedtls_dhm_context *ctx ); @@ -302,19 +256,16 @@ void mbedtls_dhm_free( mbedtls_dhm_context *ctx ); /** * \brief This function parses DHM parameters in PEM or DER format. * - * \param dhm The DHM context to import the DHM parameters into. - * This must be initialized. - * \param dhmin The input buffer. This must be a readable buffer of - * length \p dhminlen Bytes. - * \param dhminlen The size of the input buffer \p dhmin, including the - * terminating \c NULL Byte for PEM data. + * \param dhm The DHM context to initialize. + * \param dhmin The input buffer. + * \param dhminlen The size of the buffer, including the terminating null + * Byte for PEM data. * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_DHM_XXX or \c MBEDTLS_ERR_PEM_XXX error - * code on failure. + * \return \c 0 on success, or a specific DHM or PEM error code + * on failure. */ int mbedtls_dhm_parse_dhm( mbedtls_dhm_context *dhm, const unsigned char *dhmin, - size_t dhminlen ); + size_t dhminlen ); #if defined(MBEDTLS_FS_IO) /** \ingroup x509_module */ @@ -322,29 +273,34 @@ int mbedtls_dhm_parse_dhm( mbedtls_dhm_context *dhm, const unsigned char *dhmin, * \brief This function loads and parses DHM parameters from a file. * * \param dhm The DHM context to load the parameters to. - * This must be initialized. * \param path The filename to read the DHM parameters from. - * This must not be \c NULL. * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_DHM_XXX or \c MBEDTLS_ERR_PEM_XXX - * error code on failure. + * \return \c 0 on success, or a specific DHM or PEM error code + * on failure. */ int mbedtls_dhm_parse_dhmfile( mbedtls_dhm_context *dhm, const char *path ); #endif /* MBEDTLS_FS_IO */ #endif /* MBEDTLS_ASN1_PARSE_C */ -#if defined(MBEDTLS_SELF_TEST) +#ifdef __cplusplus +} +#endif + +#else /* MBEDTLS_DHM_ALT */ +#include "dhm_alt.h" +#endif /* MBEDTLS_DHM_ALT */ + +#ifdef __cplusplus +extern "C" { +#endif /** * \brief The DMH checkup routine. * - * \return \c 0 on success. - * \return \c 1 on failure. + * \return \c 0 on success, or \c 1 on failure. */ int mbedtls_dhm_self_test( int verbose ); -#endif /* MBEDTLS_SELF_TEST */ #ifdef __cplusplus } #endif @@ -392,6 +348,15 @@ int mbedtls_dhm_self_test( int verbose ); #if !defined(MBEDTLS_DEPRECATED_REMOVED) +#if defined(MBEDTLS_DEPRECATED_WARNING) +#define MBEDTLS_DEPRECATED __attribute__((deprecated)) +MBEDTLS_DEPRECATED typedef char const * mbedtls_deprecated_constant_t; +#define MBEDTLS_DEPRECATED_STRING_CONSTANT( VAL ) \ + ( (mbedtls_deprecated_constant_t) ( VAL ) ) +#else +#define MBEDTLS_DEPRECATED_STRING_CONSTANT( VAL ) VAL +#endif /* ! MBEDTLS_DEPRECATED_WARNING */ + /** * \warning The origin of the primes in RFC 5114 is not documented and * their use therefore constitutes a security risk! diff --git a/APP_Framework/Framework/security/mbedtls/ecdh.c b/APP_Framework/Framework/security/mbedtls/ecdh.c new file mode 100644 index 000000000..8886a025b --- /dev/null +++ b/APP_Framework/Framework/security/mbedtls/ecdh.c @@ -0,0 +1,268 @@ +/* + * Elliptic curve Diffie-Hellman + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +/* + * References: + * + * SEC1 http://www.secg.org/index.php?action=secg,docs_secg + * RFC 4492 + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_ECDH_C) + +#include "ecdh.h" + +#include + +#if !defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT) +/* + * Generate public key: simple wrapper around mbedtls_ecp_gen_keypair + */ +int mbedtls_ecdh_gen_public( mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp_point *Q, + int (*f_rng)(void *, unsigned char *, size_t), + void *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) + */ +int mbedtls_ecdh_compute_shared( mbedtls_ecp_group *grp, mbedtls_mpi *z, + const mbedtls_ecp_point *Q, const mbedtls_mpi *d, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + mbedtls_ecp_point P; + + mbedtls_ecp_point_init( &P ); + + /* + * Make sure Q is a valid pubkey before using it + */ + MBEDTLS_MPI_CHK( mbedtls_ecp_check_pubkey( grp, Q ) ); + + MBEDTLS_MPI_CHK( mbedtls_ecp_mul( grp, &P, d, Q, f_rng, p_rng ) ); + + if( mbedtls_ecp_is_zero( &P ) ) + { + ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + goto cleanup; + } + + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( z, &P.X ) ); + +cleanup: + mbedtls_ecp_point_free( &P ); + + return( ret ); +} +#endif /* MBEDTLS_ECDH_COMPUTE_SHARED_ALT */ + +/* + * Initialize context + */ +void mbedtls_ecdh_init( mbedtls_ecdh_context *ctx ) +{ + memset( ctx, 0, sizeof( mbedtls_ecdh_context ) ); +} + +/* + * Free context + */ +void mbedtls_ecdh_free( mbedtls_ecdh_context *ctx ) +{ + if( ctx == NULL ) + return; + + mbedtls_ecp_group_free( &ctx->grp ); + mbedtls_ecp_point_free( &ctx->Q ); + mbedtls_ecp_point_free( &ctx->Qp ); + mbedtls_ecp_point_free( &ctx->Vi ); + mbedtls_ecp_point_free( &ctx->Vf ); + mbedtls_mpi_free( &ctx->d ); + mbedtls_mpi_free( &ctx->z ); + mbedtls_mpi_free( &ctx->_d ); +} + +/* + * Setup and write the ServerKeyExhange parameters (RFC 4492) + * struct { + * ECParameters curve_params; + * ECPoint public; + * } ServerECDHParams; + */ +int mbedtls_ecdh_make_params( mbedtls_ecdh_context *ctx, size_t *olen, + unsigned char *buf, size_t blen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + size_t grp_len, pt_len; + + if( ctx == NULL || ctx->grp.pbits == 0 ) + return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); + + if( ( ret = mbedtls_ecdh_gen_public( &ctx->grp, &ctx->d, &ctx->Q, f_rng, p_rng ) ) + != 0 ) + return( ret ); + + if( ( ret = mbedtls_ecp_tls_write_group( &ctx->grp, &grp_len, buf, blen ) ) + != 0 ) + return( ret ); + + buf += grp_len; + blen -= grp_len; + + if( ( ret = mbedtls_ecp_tls_write_point( &ctx->grp, &ctx->Q, ctx->point_format, + &pt_len, buf, blen ) ) != 0 ) + return( ret ); + + *olen = grp_len + pt_len; + return( 0 ); +} + +/* + * Read the ServerKeyExhange parameters (RFC 4492) + * struct { + * ECParameters curve_params; + * ECPoint public; + * } ServerECDHParams; + */ +int mbedtls_ecdh_read_params( mbedtls_ecdh_context *ctx, + const unsigned char **buf, const unsigned char *end ) +{ + int ret; + + if( ( ret = mbedtls_ecp_tls_read_group( &ctx->grp, buf, end - *buf ) ) != 0 ) + return( ret ); + + if( ( ret = mbedtls_ecp_tls_read_point( &ctx->grp, &ctx->Qp, buf, end - *buf ) ) + != 0 ) + return( ret ); + + return( 0 ); +} + +/* + * Get parameters from a keypair + */ +int mbedtls_ecdh_get_params( mbedtls_ecdh_context *ctx, const mbedtls_ecp_keypair *key, + mbedtls_ecdh_side side ) +{ + int ret; + + if( ( ret = mbedtls_ecp_group_copy( &ctx->grp, &key->grp ) ) != 0 ) + return( ret ); + + /* If it's not our key, just import the public part as Qp */ + if( side == MBEDTLS_ECDH_THEIRS ) + return( mbedtls_ecp_copy( &ctx->Qp, &key->Q ) ); + + /* Our key: import public (as Q) and private parts */ + if( side != MBEDTLS_ECDH_OURS ) + return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); + + if( ( ret = mbedtls_ecp_copy( &ctx->Q, &key->Q ) ) != 0 || + ( ret = mbedtls_mpi_copy( &ctx->d, &key->d ) ) != 0 ) + return( ret ); + + return( 0 ); +} + +/* + * Setup and export the client public value + */ +int mbedtls_ecdh_make_public( mbedtls_ecdh_context *ctx, size_t *olen, + unsigned char *buf, size_t blen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + + if( ctx == NULL || ctx->grp.pbits == 0 ) + return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); + + if( ( ret = mbedtls_ecdh_gen_public( &ctx->grp, &ctx->d, &ctx->Q, f_rng, p_rng ) ) + != 0 ) + return( ret ); + + return mbedtls_ecp_tls_write_point( &ctx->grp, &ctx->Q, ctx->point_format, + olen, buf, blen ); +} + +/* + * Parse and import the client's public value + */ +int mbedtls_ecdh_read_public( mbedtls_ecdh_context *ctx, + const unsigned char *buf, size_t blen ) +{ + int ret; + const unsigned char *p = buf; + + if( ctx == NULL ) + return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); + + if( ( ret = mbedtls_ecp_tls_read_point( &ctx->grp, &ctx->Qp, &p, blen ) ) != 0 ) + return( ret ); + + if( (size_t)( p - buf ) != blen ) + return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); + + return( 0 ); +} + +/* + * Derive and export the shared secret + */ +int mbedtls_ecdh_calc_secret( mbedtls_ecdh_context *ctx, size_t *olen, + unsigned char *buf, size_t blen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + + if( ctx == NULL ) + return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); + + if( ( ret = mbedtls_ecdh_compute_shared( &ctx->grp, &ctx->z, &ctx->Qp, &ctx->d, + f_rng, p_rng ) ) != 0 ) + { + return( ret ); + } + + if( mbedtls_mpi_size( &ctx->z ) > blen ) + return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); + + *olen = ctx->grp.pbits / 8 + ( ( ctx->grp.pbits % 8 ) != 0 ); + return mbedtls_mpi_write_binary( &ctx->z, buf, *olen ); +} + +#endif /* MBEDTLS_ECDH_C */ diff --git a/APP_Framework/Framework/security/mbedtls/ecdh.h b/APP_Framework/Framework/security/mbedtls/ecdh.h index 4479a1d46..fb12fb397 100644 --- a/APP_Framework/Framework/security/mbedtls/ecdh.h +++ b/APP_Framework/Framework/security/mbedtls/ecdh.h @@ -1,12 +1,11 @@ /** * \file ecdh.h * - * \brief This file contains ECDH definitions and functions. + * \brief The Elliptic Curve Diffie-Hellman (ECDH) protocol APIs. * - * The Elliptic Curve Diffie-Hellman (ECDH) protocol 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 public–private key pair. + * 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 public–private key pair. * * For more information, see NIST SP 800-56A Rev. 2: Recommendation for * Pair-Wise Key Establishment Schemes Using Discrete Logarithm @@ -42,74 +41,26 @@ #include "ecp.h" -/* - * Use a backward compatible ECDH context. - * - * This flag is always enabled for now and future versions might add a - * configuration option that conditionally undefines this flag. - * The configuration option in question may have a different name. - * - * Features undefining this flag, must have a warning in their description in - * config.h stating that the feature breaks backward compatibility. - */ -#define MBEDTLS_ECDH_LEGACY_CONTEXT - #ifdef __cplusplus extern "C" { #endif /** - * Defines the source of the imported EC key. + * Defines the source of the imported EC key: + *
    • Our key.
    • + *
    • The key of the peer.
    */ typedef enum { - MBEDTLS_ECDH_OURS, /**< Our key. */ - MBEDTLS_ECDH_THEIRS, /**< The key of the peer. */ + MBEDTLS_ECDH_OURS, + MBEDTLS_ECDH_THEIRS, } mbedtls_ecdh_side; -#if !defined(MBEDTLS_ECDH_LEGACY_CONTEXT) /** - * Defines the ECDH implementation used. - * - * Later versions of the library may add new variants, therefore users should - * not make any assumptions about them. - */ -typedef enum -{ - MBEDTLS_ECDH_VARIANT_NONE = 0, /*!< Implementation not defined. */ - MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0,/*!< The default Mbed TLS implementation */ -} mbedtls_ecdh_variant; - -/** - * The context used by the default ECDH implementation. - * - * Later versions might change the structure of this context, therefore users - * should not make any assumptions about the structure of - * mbedtls_ecdh_context_mbed. - */ -typedef struct mbedtls_ecdh_context_mbed -{ - mbedtls_ecp_group grp; /*!< The elliptic curve used. */ - mbedtls_mpi d; /*!< The private key. */ - mbedtls_ecp_point Q; /*!< The public key. */ - mbedtls_ecp_point Qp; /*!< The value of the public key of the peer. */ - mbedtls_mpi z; /*!< The shared secret. */ -#if defined(MBEDTLS_ECP_RESTARTABLE) - mbedtls_ecp_restart_ctx rs; /*!< The restart context for EC computations. */ -#endif -} mbedtls_ecdh_context_mbed; -#endif - -/** - * - * \warning Performing multiple operations concurrently on the same - * ECDSA context is not supported; objects of this type - * should not be shared between multiple threads. * \brief The ECDH context structure. */ -typedef struct mbedtls_ecdh_context +typedef struct { -#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) mbedtls_ecp_group grp; /*!< The elliptic curve used. */ mbedtls_mpi d; /*!< The private key. */ mbedtls_ecp_point Q; /*!< The public key. */ @@ -119,29 +70,6 @@ typedef struct mbedtls_ecdh_context mbedtls_ecp_point Vi; /*!< The blinding value. */ mbedtls_ecp_point Vf; /*!< The unblinding value. */ mbedtls_mpi _d; /*!< The previous \p d. */ -#if defined(MBEDTLS_ECP_RESTARTABLE) - int restart_enabled; /*!< The flag for restartable mode. */ - mbedtls_ecp_restart_ctx rs; /*!< The restart context for EC computations. */ -#endif /* MBEDTLS_ECP_RESTARTABLE */ -#else - uint8_t point_format; /*!< The format of point export in TLS messages - as defined in RFC 4492. */ - mbedtls_ecp_group_id grp_id;/*!< The elliptic curve used. */ - mbedtls_ecdh_variant var; /*!< The ECDH implementation/structure used. */ - union - { - mbedtls_ecdh_context_mbed mbed_ecdh; - } ctx; /*!< Implementation-specific context. The - context in use is specified by the \c var - field. */ -#if defined(MBEDTLS_ECP_RESTARTABLE) - uint8_t restart_enabled; /*!< The flag for restartable mode. Functions of - an alternative implementation not supporting - restartable mode must return - MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED error - if this flag is set. */ -#endif /* MBEDTLS_ECP_RESTARTABLE */ -#endif /* MBEDTLS_ECDH_LEGACY_CONTEXT */ } mbedtls_ecdh_context; @@ -153,22 +81,16 @@ mbedtls_ecdh_context; * implemented during the ECDH key exchange. The second core * computation is performed by mbedtls_ecdh_compute_shared(). * - * \see ecp.h - * - * \param grp The ECP group to use. This must be initialized and have - * domain parameters loaded, for example through - * mbedtls_ecp_load() or mbedtls_ecp_tls_read_group(). + * \param grp The ECP group. * \param d The destination MPI (private key). - * This must be initialized. * \param Q The destination point (public key). - * This must be initialized. - * \param f_rng The RNG function to use. This must not be \c NULL. - * \param p_rng The RNG context to be passed to \p f_rng. This may be - * \c NULL in case \p f_rng doesn't need a context argument. + * \param f_rng The RNG function. + * \param p_rng The RNG parameter. * - * \return \c 0 on success. - * \return Another \c MBEDTLS_ERR_ECP_XXX or + * \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 (*f_rng)(void *, unsigned char *, size_t), @@ -181,32 +103,21 @@ int mbedtls_ecdh_gen_public( mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp * implemented during the ECDH key exchange. The first core * computation is performed by mbedtls_ecdh_gen_public(). * + * \param grp The ECP group. + * \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. + * + * \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 side-channel attacks. - * For more information, see mbedtls_ecp_mul(). - * - * \param grp The ECP group to use. This must be initialized and have - * domain parameters loaded, for example through - * mbedtls_ecp_load() or mbedtls_ecp_tls_read_group(). - * \param z The destination MPI (shared secret). - * This must be initialized. - * \param Q The public key from another party. - * This must be initialized. - * \param d Our secret exponent (private key). - * This must be initialized. - * \param f_rng The RNG function. This may be \c NULL if randomization - * of intermediate results during the ECP computations is - * not needed (discouraged). See the documentation of - * mbedtls_ecp_mul() for more. - * \param p_rng The RNG context to be passed to \p f_rng. This may be - * \c NULL if \p f_rng is \c NULL or doesn't need a - * context argument. - * - * \return \c 0 on success. - * \return Another \c MBEDTLS_ERR_ECP_XXX or - * \c MBEDTLS_MPI_XXX error code on failure. + * countermeasures against potential elaborate timing + * attacks. For more information, see mbedtls_ecp_mul(). */ int mbedtls_ecdh_compute_shared( mbedtls_ecp_group *grp, mbedtls_mpi *z, const mbedtls_ecp_point *Q, const mbedtls_mpi *d, @@ -216,62 +127,39 @@ int mbedtls_ecdh_compute_shared( mbedtls_ecp_group *grp, mbedtls_mpi *z, /** * \brief This function initializes an ECDH context. * - * \param ctx The ECDH context to initialize. This must not be \c NULL. + * \param ctx The ECDH context to initialize. */ void mbedtls_ecdh_init( mbedtls_ecdh_context *ctx ); -/** - * \brief This function sets up the ECDH context with the information - * given. - * - * This function should be called after mbedtls_ecdh_init() but - * before mbedtls_ecdh_make_params(). There is no need to call - * this function before mbedtls_ecdh_read_params(). - * - * This is the first function used by a TLS server for ECDHE - * ciphersuites. - * - * \param ctx The ECDH context to set up. This must be initialized. - * \param grp_id The group id of the group to set up the context for. - * - * \return \c 0 on success. - */ -int mbedtls_ecdh_setup( mbedtls_ecdh_context *ctx, - mbedtls_ecp_group_id grp_id ); - /** * \brief This function frees a context. * - * \param ctx The context to free. This may be \c NULL, in which - * case this function does nothing. If it is not \c NULL, - * it must point to an initialized ECDH context. + * \param ctx The context to free. */ void mbedtls_ecdh_free( mbedtls_ecdh_context *ctx ); /** - * \brief This function generates an EC key pair and exports its - * in the format used in a TLS ServerKeyExchange handshake - * message. + * \brief This function generates a public key and a TLS + * ServerKeyExchange payload. * - * This is the second function used by a TLS server for ECDHE - * ciphersuites. (It is called after mbedtls_ecdh_setup().) + * This is the first function used by a TLS server for ECDHE + * ciphersuites. + * + * \param ctx The ECDH context. + * \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. + * + * \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 - * - * \param ctx The ECDH context to use. This must be initialized - * and bound to a group, for example via mbedtls_ecdh_setup(). - * \param olen The address at which to store the number of Bytes written. - * \param buf The destination buffer. This must be a writable buffer of - * length \p blen Bytes. - * \param blen The length of the destination buffer \p buf in Bytes. - * \param f_rng The RNG function to use. This must not be \c NULL. - * \param p_rng The RNG context to be passed to \p f_rng. This may be - * \c NULL in case \p f_rng doesn't need a context argument. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of - * operations was reached: see \c mbedtls_ecp_set_max_ops(). - * \return Another \c MBEDTLS_ERR_ECP_XXX error code on failure. */ int mbedtls_ecdh_make_params( mbedtls_ecdh_context *ctx, size_t *olen, unsigned char *buf, size_t blen, @@ -279,32 +167,23 @@ int mbedtls_ecdh_make_params( mbedtls_ecdh_context *ctx, size_t *olen, void *p_rng ); /** - * \brief This function parses the ECDHE parameters in a - * TLS ServerKeyExchange handshake message. + * \brief This function parses and processes a TLS ServerKeyExhange + * payload. * - * \note In a TLS handshake, this is the how the client - * sets up its ECDHE context from the server's public - * ECDHE key material. + * This is the first function used by a TLS client for ECDHE + * ciphersuites. + * + * \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 - * - * \param ctx The ECDHE context to use. This must be initialized. - * \param buf On input, \c *buf must be the start of the input buffer. - * On output, \c *buf is updated to point to the end of the - * data that has been read. On success, this is the first byte - * past the end of the ServerKeyExchange parameters. - * On error, this is the point at which an error has been - * detected, which is usually not useful except to debug - * failures. - * \param end The end of the input buffer. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_ECP_XXX error code on failure. - * */ 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 This function sets up an ECDH context from an EC key. @@ -313,47 +192,38 @@ int mbedtls_ecdh_read_params( mbedtls_ecdh_context *ctx, * ServerKeyEchange for static ECDH, and imports ECDH * parameters from the EC key information of a certificate. * + * \param ctx The ECDH context to set up. + * \param key The EC key to use. + * \param side Defines the source of the key: + *
    • 1: Our key.
    • +
    • 0: The key of the peer.
    + * + * \return \c 0 on success, or an \c MBEDTLS_ERR_ECP_XXX error code + * on failure. + * * \see ecp.h - * - * \param ctx The ECDH context to set up. This must be initialized. - * \param key The EC key to use. This must be initialized. - * \param side Defines the source of the key. Possible values are: - * - #MBEDTLS_ECDH_OURS: The key is ours. - * - #MBEDTLS_ECDH_THEIRS: The key is that of the peer. - * - * \return \c 0 on success. - * \return Another \c MBEDTLS_ERR_ECP_XXX error code on failure. - * */ -int mbedtls_ecdh_get_params( mbedtls_ecdh_context *ctx, - const mbedtls_ecp_keypair *key, - mbedtls_ecdh_side side ); +int mbedtls_ecdh_get_params( mbedtls_ecdh_context *ctx, const mbedtls_ecp_keypair *key, + mbedtls_ecdh_side side ); /** - * \brief This function generates a public key and exports it - * as a TLS ClientKeyExchange payload. + * \brief This function generates a public key and a TLS + * ClientKeyExchange payload. * * This is the second function used by a TLS client for ECDH(E) * ciphersuites. * + * \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 - * - * \param ctx The ECDH context to use. This must be initialized - * and bound to a group, the latter usually by - * mbedtls_ecdh_read_params(). - * \param olen The address at which to store the number of Bytes written. - * This must not be \c NULL. - * \param buf The destination buffer. This must be a writable buffer - * of length \p blen Bytes. - * \param blen The size of the destination buffer \p buf in Bytes. - * \param f_rng The RNG function to use. This must not be \c NULL. - * \param p_rng The RNG context to be passed to \p f_rng. This may be - * \c NULL in case \p f_rng doesn't need a context argument. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of - * operations was reached: see \c mbedtls_ecp_set_max_ops(). - * \return Another \c MBEDTLS_ERR_ECP_XXX error code on failure. */ int mbedtls_ecdh_make_public( mbedtls_ecdh_context *ctx, size_t *olen, unsigned char *buf, size_t blen, @@ -361,26 +231,23 @@ int mbedtls_ecdh_make_public( mbedtls_ecdh_context *ctx, size_t *olen, void *p_rng ); /** - * \brief This function parses and processes the ECDHE payload of a - * TLS ClientKeyExchange message. + * \brief This function parses and processes a TLS ClientKeyExchange + * payload. * - * This is the third function used by a TLS server for ECDH(E) - * ciphersuites. (It is called after mbedtls_ecdh_setup() and - * mbedtls_ecdh_make_params().) + * This is the second function used by a TLS server for ECDH(E) + * ciphersuites. + * + * \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 - * - * \param ctx The ECDH context to use. This must be initialized - * and bound to a group, for example via mbedtls_ecdh_setup(). - * \param buf The pointer to the ClientKeyExchange payload. This must - * be a readable buffer of length \p blen Bytes. - * \param blen The length of the input buffer \p buf in Bytes. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_ECP_XXX error code on failure. */ int mbedtls_ecdh_read_public( mbedtls_ecdh_context *ctx, - const unsigned char *buf, size_t blen ); + const unsigned char *buf, size_t blen ); /** * \brief This function derives and exports the shared secret. @@ -388,51 +255,27 @@ int mbedtls_ecdh_read_public( mbedtls_ecdh_context *ctx, * This is the last function used by both TLS client * and servers. * - * \note If \p f_rng is not NULL, it is used to implement - * countermeasures against side-channel attacks. - * For more information, see mbedtls_ecp_mul(). + * \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 - - * \param ctx The ECDH context to use. This must be initialized - * and have its own private key generated and the peer's - * public key imported. - * \param olen The address at which to store the total number of - * Bytes written on success. This must not be \c NULL. - * \param buf The buffer to write the generated shared key to. This - * must be a writable buffer of size \p blen Bytes. - * \param blen The length of the destination buffer \p buf in Bytes. - * \param f_rng The RNG function, for blinding purposes. This may - * b \c NULL if blinding isn't needed. - * \param p_rng The RNG context. This may be \c NULL if \p f_rng - * doesn't need a context argument. * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of - * operations was reached: see \c mbedtls_ecp_set_max_ops(). - * \return Another \c MBEDTLS_ERR_ECP_XXX error code on failure. + * \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, unsigned char *buf, size_t blen, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); -#if defined(MBEDTLS_ECP_RESTARTABLE) -/** - * \brief This function enables restartable EC computations for this - * context. (Default: disabled.) - * - * \see \c mbedtls_ecp_set_max_ops() - * - * \note It is not possible to safely disable restartable - * computations once enabled, except by free-ing the context, - * which cancels possible in-progress operations. - * - * \param ctx The ECDH context to use. This must be initialized. - */ -void mbedtls_ecdh_enable_restart( mbedtls_ecdh_context *ctx ); -#endif /* MBEDTLS_ECP_RESTARTABLE */ - #ifdef __cplusplus } #endif diff --git a/APP_Framework/Framework/security/mbedtls/ecdsa.c b/APP_Framework/Framework/security/mbedtls/ecdsa.c new file mode 100644 index 000000000..c818b5321 --- /dev/null +++ b/APP_Framework/Framework/security/mbedtls/ecdsa.c @@ -0,0 +1,466 @@ +/* + * Elliptic curve DSA + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +/* + * References: + * + * SEC1 http://www.secg.org/index.php?action=secg,docs_secg + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_ECDSA_C) + +#include "ecdsa.h" +#include "asn1write.h" + +#include + +#if defined(MBEDTLS_ECDSA_DETERMINISTIC) +#include "hmac_drbg.h" +#endif + +/* + * Derive a suitable integer for group grp from a buffer of length len + * SEC1 4.1.3 step 5 aka SEC1 4.1.4 step 3 + */ +static int derive_mpi( const mbedtls_ecp_group *grp, mbedtls_mpi *x, + const unsigned char *buf, size_t blen ) +{ + int ret; + size_t n_size = ( grp->nbits + 7 ) / 8; + size_t use_size = blen > n_size ? n_size : blen; + + MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( x, buf, use_size ) ); + if( use_size * 8 > grp->nbits ) + MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( x, use_size * 8 - grp->nbits ) ); + + /* While at it, reduce modulo N */ + if( mbedtls_mpi_cmp_mpi( x, &grp->N ) >= 0 ) + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( x, x, &grp->N ) ); + +cleanup: + return( ret ); +} + +#if !defined(MBEDTLS_ECDSA_SIGN_ALT) +/* + * Compute ECDSA signature of a hashed message (SEC1 4.1.3) + * Obviously, compared to SEC1 4.1.3, we skip step 4 (hash message) + */ +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, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + int ret, key_tries, sign_tries, blind_tries; + mbedtls_ecp_point R; + mbedtls_mpi k, e, t; + + /* Fail cleanly on curves such as Curve25519 that can't be used for ECDSA */ + if( grp->N.p == NULL ) + 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_mpi_init( &k ); mbedtls_mpi_init( &e ); mbedtls_mpi_init( &t ); + + sign_tries = 0; + do + { + /* + * Steps 1-3: generate a suitable ephemeral keypair + * and set r = xR mod n + */ + key_tries = 0; + do + { + MBEDTLS_MPI_CHK( mbedtls_ecp_gen_keypair( grp, &k, &R, f_rng, p_rng ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( r, &R.X, &grp->N ) ); + + if( key_tries++ > 10 ) + { + ret = MBEDTLS_ERR_ECP_RANDOM_FAILED; + goto cleanup; + } + } + while( mbedtls_mpi_cmp_int( r, 0 ) == 0 ); + + /* + * Step 5: derive MPI from hashed message + */ + MBEDTLS_MPI_CHK( derive_mpi( grp, &e, buf, blen ) ); + + /* + * Generate a random value to blind inv_mod in next step, + * avoiding a potential timing leak. + */ + blind_tries = 0; + do + { + size_t n_size = ( grp->nbits + 7 ) / 8; + MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &t, n_size, f_rng, p_rng ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &t, 8 * n_size - grp->nbits ) ); + + /* See mbedtls_ecp_gen_keypair() */ + if( ++blind_tries > 30 ) + return( MBEDTLS_ERR_ECP_RANDOM_FAILED ); + } + while( mbedtls_mpi_cmp_int( &t, 1 ) < 0 || + mbedtls_mpi_cmp_mpi( &t, &grp->N ) >= 0 ); + + /* + * Step 6: compute s = (e + r * d) / k = t (e + rd) / (kt) mod n + */ + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( s, r, d ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &e, &e, s ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &e, &e, &t ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &k, &k, &t ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( s, &k, &grp->N ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( s, s, &e ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( s, s, &grp->N ) ); + + if( sign_tries++ > 10 ) + { + ret = MBEDTLS_ERR_ECP_RANDOM_FAILED; + goto cleanup; + } + } + while( mbedtls_mpi_cmp_int( s, 0 ) == 0 ); + +cleanup: + mbedtls_ecp_point_free( &R ); + mbedtls_mpi_free( &k ); mbedtls_mpi_free( &e ); mbedtls_mpi_free( &t ); + + return( ret ); +} +#endif /* MBEDTLS_ECDSA_SIGN_ALT */ + +#if defined(MBEDTLS_ECDSA_DETERMINISTIC) +/* + * Deterministic signature wrapper + */ +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, + mbedtls_md_type_t md_alg ) +{ + int ret; + mbedtls_hmac_drbg_context rng_ctx; + unsigned char data[2 * MBEDTLS_ECP_MAX_BYTES]; + size_t grp_len = ( grp->nbits + 7 ) / 8; + const mbedtls_md_info_t *md_info; + mbedtls_mpi h; + + if( ( md_info = mbedtls_md_info_from_type( md_alg ) ) == NULL ) + return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); + + mbedtls_mpi_init( &h ); + mbedtls_hmac_drbg_init( &rng_ctx ); + + /* Use private key and message hash (reduced) to initialize HMAC_DRBG */ + MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( d, data, grp_len ) ); + MBEDTLS_MPI_CHK( derive_mpi( grp, &h, buf, blen ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &h, data + grp_len, grp_len ) ); + mbedtls_hmac_drbg_seed_buf( &rng_ctx, md_info, data, 2 * grp_len ); + + ret = mbedtls_ecdsa_sign( grp, r, s, d, buf, blen, + mbedtls_hmac_drbg_random, &rng_ctx ); + +cleanup: + mbedtls_hmac_drbg_free( &rng_ctx ); + mbedtls_mpi_free( &h ); + + return( ret ); +} +#endif /* MBEDTLS_ECDSA_DETERMINISTIC */ + +#if !defined(MBEDTLS_ECDSA_VERIFY_ALT) +/* + * Verify ECDSA signature of hashed message (SEC1 4.1.4) + * Obviously, compared to SEC1 4.1.3, we skip step 2 (hash message) + */ +int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp, + const unsigned char *buf, size_t blen, + const mbedtls_ecp_point *Q, const mbedtls_mpi *r, const mbedtls_mpi *s) +{ + int ret; + mbedtls_mpi e, s_inv, u1, u2; + mbedtls_ecp_point R; + + mbedtls_ecp_point_init( &R ); + mbedtls_mpi_init( &e ); mbedtls_mpi_init( &s_inv ); mbedtls_mpi_init( &u1 ); mbedtls_mpi_init( &u2 ); + + /* Fail cleanly on curves such as Curve25519 that can't be used for ECDSA */ + if( grp->N.p == NULL ) + return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); + + /* + * Step 1: make sure r and s are in range 1..n-1 + */ + if( mbedtls_mpi_cmp_int( r, 1 ) < 0 || mbedtls_mpi_cmp_mpi( r, &grp->N ) >= 0 || + mbedtls_mpi_cmp_int( s, 1 ) < 0 || mbedtls_mpi_cmp_mpi( s, &grp->N ) >= 0 ) + { + ret = MBEDTLS_ERR_ECP_VERIFY_FAILED; + goto cleanup; + } + + /* + * Additional precaution: make sure Q is valid + */ + MBEDTLS_MPI_CHK( mbedtls_ecp_check_pubkey( grp, Q ) ); + + /* + * Step 3: derive MPI from hashed message + */ + MBEDTLS_MPI_CHK( derive_mpi( grp, &e, buf, blen ) ); + + /* + * Step 4: u1 = e / s mod n, u2 = r / s mod n + */ + MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &s_inv, s, &grp->N ) ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &u1, &e, &s_inv ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &u1, &u1, &grp->N ) ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &u2, r, &s_inv ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &u2, &u2, &grp->N ) ); + + /* + * Step 5: R = u1 G + u2 Q + * + * Since we're not using any secret data, no need to pass a RNG to + * mbedtls_ecp_mul() for countermesures. + */ + MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( grp, &R, &u1, &grp->G, &u2, Q ) ); + + if( mbedtls_ecp_is_zero( &R ) ) + { + ret = MBEDTLS_ERR_ECP_VERIFY_FAILED; + goto cleanup; + } + + /* + * Step 6: convert xR to an integer (no-op) + * Step 7: reduce xR mod n (gives v) + */ + MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &R.X, &R.X, &grp->N ) ); + + /* + * Step 8: check if v (that is, R.X) is equal to r + */ + if( mbedtls_mpi_cmp_mpi( &R.X, r ) != 0 ) + { + ret = MBEDTLS_ERR_ECP_VERIFY_FAILED; + goto cleanup; + } + +cleanup: + mbedtls_ecp_point_free( &R ); + mbedtls_mpi_free( &e ); mbedtls_mpi_free( &s_inv ); mbedtls_mpi_free( &u1 ); mbedtls_mpi_free( &u2 ); + + return( ret ); +} +#endif /* MBEDTLS_ECDSA_VERIFY_ALT */ + +/* + * Convert a signature (given by context) to ASN.1 + */ +static int ecdsa_signature_to_asn1( const mbedtls_mpi *r, const mbedtls_mpi *s, + unsigned char *sig, size_t *slen ) +{ + int ret; + unsigned char buf[MBEDTLS_ECDSA_MAX_LEN]; + unsigned char *p = buf + sizeof( buf ); + size_t len = 0; + + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &p, buf, s ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &p, buf, r ) ); + + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &p, buf, len ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &p, buf, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ); + + memcpy( sig, p, len ); + *slen = len; + + return( 0 ); +} + +/* + * Compute and write signature + */ +int mbedtls_ecdsa_write_signature( mbedtls_ecdsa_context *ctx, mbedtls_md_type_t md_alg, + const unsigned char *hash, size_t hlen, + unsigned char *sig, size_t *slen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + mbedtls_mpi r, s; + + mbedtls_mpi_init( &r ); + mbedtls_mpi_init( &s ); + +#if defined(MBEDTLS_ECDSA_DETERMINISTIC) + (void) f_rng; + (void) p_rng; + + MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign_det( &ctx->grp, &r, &s, &ctx->d, + hash, hlen, md_alg ) ); +#else + (void) md_alg; + + MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign( &ctx->grp, &r, &s, &ctx->d, + hash, hlen, f_rng, p_rng ) ); +#endif + + MBEDTLS_MPI_CHK( ecdsa_signature_to_asn1( &r, &s, sig, slen ) ); + +cleanup: + mbedtls_mpi_free( &r ); + mbedtls_mpi_free( &s ); + + return( ret ); +} + +#if ! defined(MBEDTLS_DEPRECATED_REMOVED) && \ + defined(MBEDTLS_ECDSA_DETERMINISTIC) +int mbedtls_ecdsa_write_signature_det( mbedtls_ecdsa_context *ctx, + const unsigned char *hash, size_t hlen, + unsigned char *sig, size_t *slen, + mbedtls_md_type_t md_alg ) +{ + return( mbedtls_ecdsa_write_signature( ctx, md_alg, hash, hlen, sig, slen, + NULL, NULL ) ); +} +#endif + +/* + * Read and check signature + */ +int mbedtls_ecdsa_read_signature( mbedtls_ecdsa_context *ctx, + const unsigned char *hash, size_t hlen, + const unsigned char *sig, size_t slen ) +{ + int ret; + unsigned char *p = (unsigned char *) sig; + const unsigned char *end = sig + slen; + size_t len; + mbedtls_mpi r, s; + + mbedtls_mpi_init( &r ); + mbedtls_mpi_init( &s ); + + if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) + { + ret += MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + goto cleanup; + } + + if( p + len != end ) + { + ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA + + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH; + goto cleanup; + } + + if( ( ret = mbedtls_asn1_get_mpi( &p, end, &r ) ) != 0 || + ( ret = mbedtls_asn1_get_mpi( &p, end, &s ) ) != 0 ) + { + ret += MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + goto cleanup; + } + + if( ( ret = mbedtls_ecdsa_verify( &ctx->grp, hash, hlen, + &ctx->Q, &r, &s ) ) != 0 ) + 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 ) + ret = MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH; + +cleanup: + mbedtls_mpi_free( &r ); + mbedtls_mpi_free( &s ); + + return( ret ); +} + +#if !defined(MBEDTLS_ECDSA_GENKEY_ALT) +/* + * Generate key pair + */ +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 ret = 0; + ret = mbedtls_ecp_group_load( &ctx->grp, gid ); + if( ret != 0 ) + return( ret ); + + return( 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 + */ +int mbedtls_ecdsa_from_keypair( mbedtls_ecdsa_context *ctx, const mbedtls_ecp_keypair *key ) +{ + int ret; + + if( ( ret = mbedtls_ecp_group_copy( &ctx->grp, &key->grp ) ) != 0 || + ( ret = mbedtls_mpi_copy( &ctx->d, &key->d ) ) != 0 || + ( ret = mbedtls_ecp_copy( &ctx->Q, &key->Q ) ) != 0 ) + { + mbedtls_ecdsa_free( ctx ); + } + + return( ret ); +} + +/* + * Initialize context + */ +void mbedtls_ecdsa_init( mbedtls_ecdsa_context *ctx ) +{ + mbedtls_ecp_keypair_init( ctx ); +} + +/* + * Free context + */ +void mbedtls_ecdsa_free( mbedtls_ecdsa_context *ctx ) +{ + mbedtls_ecp_keypair_free( ctx ); +} + +#endif /* MBEDTLS_ECDSA_C */ diff --git a/APP_Framework/Framework/security/mbedtls/ecdsa.h b/APP_Framework/Framework/security/mbedtls/ecdsa.h index 932acc6d1..cfd137012 100644 --- a/APP_Framework/Framework/security/mbedtls/ecdsa.h +++ b/APP_Framework/Framework/security/mbedtls/ecdsa.h @@ -1,10 +1,9 @@ /** * \file ecdsa.h * - * \brief This file contains ECDSA definitions and functions. + * \brief The Elliptic Curve Digital Signature Algorithm (ECDSA). * - * The Elliptic Curve Digital Signature Algorithm (ECDSA) is defined in - * Standards for Efficient Cryptography Group (SECG): + * ECDSA is defined in Standards for Efficient Cryptography Group (SECG): * SEC1 Elliptic Curve Cryptography. * The use of ECDSA for TLS is defined in RFC-4492: Elliptic Curve * Cryptography (ECC) Cipher Suites for Transport Layer Security (TLS). @@ -61,71 +60,29 @@ /** The maximal size of an ECDSA signature in Bytes. */ #define MBEDTLS_ECDSA_MAX_LEN ( 3 + 2 * ( 3 + MBEDTLS_ECP_MAX_BYTES ) ) +/** + * \brief The ECDSA context structure. + */ +typedef mbedtls_ecp_keypair mbedtls_ecdsa_context; + #ifdef __cplusplus extern "C" { #endif -/** - * \brief The ECDSA context structure. - * - * \warning Performing multiple operations concurrently on the same - * ECDSA context is not supported; objects of this type - * should not be shared between multiple threads. - */ -typedef mbedtls_ecp_keypair mbedtls_ecdsa_context; - -#if defined(MBEDTLS_ECP_RESTARTABLE) - -/** - * \brief Internal restart context for ecdsa_verify() - * - * \note Opaque struct, defined in ecdsa.c - */ -typedef struct mbedtls_ecdsa_restart_ver mbedtls_ecdsa_restart_ver_ctx; - -/** - * \brief Internal restart context for ecdsa_sign() - * - * \note Opaque struct, defined in ecdsa.c - */ -typedef struct mbedtls_ecdsa_restart_sig mbedtls_ecdsa_restart_sig_ctx; - -#if defined(MBEDTLS_ECDSA_DETERMINISTIC) -/** - * \brief Internal restart context for ecdsa_sign_det() - * - * \note Opaque struct, defined in ecdsa.c - */ -typedef struct mbedtls_ecdsa_restart_det mbedtls_ecdsa_restart_det_ctx; -#endif - -/** - * \brief General context for resuming ECDSA operations - */ -typedef struct -{ - mbedtls_ecp_restart_ctx ecp; /*!< base context for ECP restart and - shared administrative info */ - mbedtls_ecdsa_restart_ver_ctx *ver; /*!< ecdsa_verify() sub-context */ - mbedtls_ecdsa_restart_sig_ctx *sig; /*!< ecdsa_sign() sub-context */ -#if defined(MBEDTLS_ECDSA_DETERMINISTIC) - mbedtls_ecdsa_restart_det_ctx *det; /*!< ecdsa_sign_det() sub-context */ -#endif -} mbedtls_ecdsa_restart_ctx; - -#else /* MBEDTLS_ECP_RESTARTABLE */ - -/* Now we can declare functions that take a pointer to that */ -typedef void mbedtls_ecdsa_restart_ctx; - -#endif /* MBEDTLS_ECP_RESTARTABLE */ - /** * \brief This function computes the ECDSA signature of a * previously-hashed message. * - * \note The deterministic version implemented in - * mbedtls_ecdsa_sign_det() is usually preferred. + * \note The deterministic version is usually preferred. + * + * \param grp The ECP group. + * \param r The first output integer. + * \param s The second output integer. + * \param d The private signing key. + * \param buf The message hash. + * \param blen The length of \p buf. + * \param f_rng The RNG function. + * \param p_rng The RNG parameter. * * \note If the bitlength of the message hash is larger than the * bitlength of the group order, then the hash is truncated @@ -133,28 +90,10 @@ typedef void mbedtls_ecdsa_restart_ctx; * (SECG): SEC1 Elliptic Curve Cryptography, section * 4.1.3, step 5. * - * \see ecp.h - * - * \param grp The context for the elliptic curve to use. - * This must be initialized and have group parameters - * set, for example through mbedtls_ecp_group_load(). - * \param r The MPI context in which to store the first part - * the signature. This must be initialized. - * \param s The MPI context in which to store the second part - * the signature. This must be initialized. - * \param d The private signing key. This must be initialized. - * \param buf The content to be signed. This is usually the hash of - * the original data to be signed. This must be a readable - * buffer of length \p blen Bytes. It may be \c NULL if - * \p blen is zero. - * \param blen The length of \p buf in Bytes. - * \param f_rng The RNG function. This must not be \c NULL. - * \param p_rng The RNG context to be passed to \p f_rng. This may be - * \c NULL if \p f_rng doesn't need a context parameter. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_ECP_XXX + * \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_ecdsa_sign( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s, const mbedtls_mpi *d, const unsigned char *buf, size_t blen, @@ -164,139 +103,62 @@ int mbedtls_ecdsa_sign( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s, /** * \brief This function computes the ECDSA signature of a * previously-hashed message, deterministic version. - * * For more information, see RFC-6979: Deterministic * Usage of the Digital Signature Algorithm (DSA) and Elliptic * Curve Digital Signature Algorithm (ECDSA). * + * \param grp The ECP group. + * \param r The first output integer. + * \param s The second output integer. + * \param d The private signing key. + * \param buf The message hash. + * \param blen The length of \p buf. + * \param md_alg The MD algorithm used to hash the message. + * * \note If the bitlength of the message hash is larger than the * bitlength of the group order, then the hash is truncated as * defined in Standards for Efficient Cryptography Group * (SECG): SEC1 Elliptic Curve Cryptography, section * 4.1.3, step 5. * - * \warning Since the output of the internal RNG is always the same for - * the same key and message, this limits the efficiency of - * blinding and leaks information through side channels. For - * secure behavior use mbedtls_ecdsa_sign_det_ext() instead. - * - * (Optimally the blinding is a random value that is different - * on every execution. In this case the blinding is still - * random from the attackers perspective, but is the same on - * each execution. This means that this blinding does not - * prevent attackers from recovering secrets by combining - * several measurement traces, but may prevent some attacks - * that exploit relationships between secret data.) + * \return \c 0 on success, + * or an \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX + * error code on failure. * * \see ecp.h - * - * \param grp The context for the elliptic curve to use. - * This must be initialized and have group parameters - * set, for example through mbedtls_ecp_group_load(). - * \param r The MPI context in which to store the first part - * the signature. This must be initialized. - * \param s The MPI context in which to store the second part - * the signature. This must be initialized. - * \param d The private signing key. This must be initialized - * and setup, for example through mbedtls_ecp_gen_privkey(). - * \param buf The hashed content to be signed. This must be a readable - * buffer of length \p blen Bytes. It may be \c NULL if - * \p blen is zero. - * \param blen The length of \p buf in Bytes. - * \param md_alg The hash algorithm used to hash the original data. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX - * error code on failure. */ -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, - mbedtls_md_type_t md_alg ); -/** - * \brief This function computes the ECDSA signature of a - * previously-hashed message, deterministic version. - * - * For more information, see RFC-6979: Deterministic - * Usage of the Digital Signature Algorithm (DSA) and Elliptic - * Curve Digital Signature Algorithm (ECDSA). - * - * \note If the bitlength of the message hash is larger than the - * bitlength of the group order, then the hash is truncated as - * defined in Standards for Efficient Cryptography Group - * (SECG): SEC1 Elliptic Curve Cryptography, section - * 4.1.3, step 5. - * - * \see ecp.h - * - * \param grp The context for the elliptic curve to use. - * This must be initialized and have group parameters - * set, for example through mbedtls_ecp_group_load(). - * \param r The MPI context in which to store the first part - * the signature. This must be initialized. - * \param s The MPI context in which to store the second part - * the signature. This must be initialized. - * \param d The private signing key. This must be initialized - * and setup, for example through mbedtls_ecp_gen_privkey(). - * \param buf The hashed content to be signed. This must be a readable - * buffer of length \p blen Bytes. It may be \c NULL if - * \p blen is zero. - * \param blen The length of \p buf in Bytes. - * \param md_alg The hash algorithm used to hash the original data. - * \param f_rng_blind The RNG function used for blinding. This must not be - * \c NULL. - * \param p_rng_blind The RNG context to be passed to \p f_rng. This may be - * \c NULL if \p f_rng doesn't need a context parameter. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX - * error code on failure. - */ -int mbedtls_ecdsa_sign_det_ext( mbedtls_ecp_group *grp, mbedtls_mpi *r, - mbedtls_mpi *s, const mbedtls_mpi *d, - const unsigned char *buf, size_t blen, - mbedtls_md_type_t md_alg, - int (*f_rng_blind)(void *, unsigned char *, - size_t), - void *p_rng_blind ); +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, + mbedtls_md_type_t md_alg ); #endif /* MBEDTLS_ECDSA_DETERMINISTIC */ /** * \brief This function verifies the ECDSA signature of a * previously-hashed message. * + * \param grp The ECP group. + * \param buf The message hash. + * \param blen The length of \p buf. + * \param Q The public key to use for verification. + * \param r The first integer of the signature. + * \param s The second integer of the signature. + * * \note If the bitlength of the message hash is larger than the * bitlength of the group order, then the hash is truncated as * defined in Standards for Efficient Cryptography Group * (SECG): SEC1 Elliptic Curve Cryptography, section * 4.1.4, step 3. * - * \see ecp.h - * - * \param grp The ECP group to use. - * This must be initialized and have group parameters - * set, for example through mbedtls_ecp_group_load(). - * \param buf The hashed content that was signed. This must be a readable - * buffer of length \p blen Bytes. It may be \c NULL if - * \p blen is zero. - * \param blen The length of \p buf in Bytes. - * \param Q The public key to use for verification. This must be - * initialized and setup. - * \param r The first integer of the signature. - * This must be initialized. - * \param s The second integer of the signature. - * This must be initialized. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the signature - * is invalid. - * \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX + * \return \c 0 on success, + * #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if signature is invalid, + * 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, - const unsigned char *buf, size_t blen, - const mbedtls_ecp_point *Q, const mbedtls_mpi *r, - const mbedtls_mpi *s); + const unsigned char *buf, size_t blen, + const mbedtls_ecp_point *Q, const mbedtls_mpi *r, const mbedtls_mpi *s); /** * \brief This function computes the ECDSA signature and writes it @@ -313,92 +175,38 @@ int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp, * of the Digital Signature Algorithm (DSA) and Elliptic * Curve Digital Signature Algorithm (ECDSA)
    . * + * \param ctx The ECDSA context. + * \param md_alg The message digest that was used to hash the message. + * \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 * bitlength of the group order, then the hash is truncated as * defined in Standards for Efficient Cryptography Group * (SECG): SEC1 Elliptic Curve Cryptography, section * 4.1.3, step 5. * - * \see ecp.h - * - * \param ctx The ECDSA context to use. This must be initialized - * and have a group and private key bound to it, for example - * via mbedtls_ecdsa_genkey() or mbedtls_ecdsa_from_keypair(). - * \param md_alg The message digest that was used to hash the message. - * \param hash The message hash to be signed. This must be a readable - * buffer of length \p blen Bytes. - * \param hlen The length of the hash \p hash in Bytes. - * \param sig The buffer to which to write the signature. This must be a - * writable buffer of length 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. - * \param slen The address at which to store the actual length of - * the signature written. Must not be \c NULL. - * \param f_rng The RNG function. This must not be \c NULL if - * #MBEDTLS_ECDSA_DETERMINISTIC is unset. Otherwise, - * it is unused and may be set to \c NULL. - * \param p_rng The RNG context to be passed to \p f_rng. This may be - * \c NULL if \p f_rng is \c NULL or doesn't use a context. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_ECP_XXX, \c MBEDTLS_ERR_MPI_XXX or + * \return \c 0 on success, + * or an \c MBEDTLS_ERR_ECP_XXX, \c MBEDTLS_ERR_MPI_XXX or * \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, unsigned char *sig, size_t *slen, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); -/** - * \brief This function computes the ECDSA signature and writes it - * to a buffer, in a restartable way. - * - * \see \c mbedtls_ecdsa_write_signature() - * - * \note This function is like \c mbedtls_ecdsa_write_signature() - * but it can return early and restart according to the limit - * set with \c mbedtls_ecp_set_max_ops() to reduce blocking. - * - * \param ctx The ECDSA context to use. This must be initialized - * and have a group and private key bound to it, for example - * via mbedtls_ecdsa_genkey() or mbedtls_ecdsa_from_keypair(). - * \param md_alg The message digest that was used to hash the message. - * \param hash The message hash to be signed. This must be a readable - * buffer of length \p blen Bytes. - * \param hlen The length of the hash \p hash in Bytes. - * \param sig The buffer to which to write the signature. This must be a - * writable buffer of length 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. - * \param slen The address at which to store the actual length of - * the signature written. Must not be \c NULL. - * \param f_rng The RNG function. This must not be \c NULL if - * #MBEDTLS_ECDSA_DETERMINISTIC is unset. Otherwise, - * it is unused and may be set to \c NULL. - * \param p_rng The RNG context to be passed to \p f_rng. This may be - * \c NULL if \p f_rng is \c NULL or doesn't use a context. - * \param rs_ctx The restart context to use. This may be \c NULL to disable - * restarting. If it is not \c NULL, it must point to an - * initialized restart context. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of - * operations was reached: see \c mbedtls_ecp_set_max_ops(). - * \return Another \c MBEDTLS_ERR_ECP_XXX, \c MBEDTLS_ERR_MPI_XXX or - * \c MBEDTLS_ERR_ASN1_XXX error code on failure. - */ -int mbedtls_ecdsa_write_signature_restartable( mbedtls_ecdsa_context *ctx, - mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hlen, - unsigned char *sig, size_t *slen, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - mbedtls_ecdsa_restart_ctx *rs_ctx ); - #if defined(MBEDTLS_ECDSA_DETERMINISTIC) #if ! defined(MBEDTLS_DEPRECATED_REMOVED) #if defined(MBEDTLS_DEPRECATED_WARNING) @@ -407,17 +215,31 @@ int mbedtls_ecdsa_write_signature_restartable( mbedtls_ecdsa_context *ctx, #define MBEDTLS_DEPRECATED #endif /** - * \brief This function computes an ECDSA signature and writes - * it to a buffer, serialized as defined in RFC-4492: - * Elliptic Curve Cryptography (ECC) Cipher Suites for - * Transport Layer Security (TLS). + * \brief This function computes an ECDSA signature and writes it to a buffer, + * serialized as defined in RFC-4492: Elliptic Curve Cryptography + * (ECC) Cipher Suites for Transport Layer Security (TLS). * - * The deterministic version is defined in RFC-6979: - * Deterministic Usage of the Digital Signature Algorithm (DSA) - * and Elliptic Curve Digital Signature Algorithm (ECDSA). + * The deterministic version is defined in RFC-6979: + * Deterministic Usage of the Digital Signature Algorithm (DSA) and + * Elliptic Curve Digital Signature Algorithm (ECDSA). * * \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 + * + * \param ctx The ECDSA context. + * \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 md_alg The MD algorithm used to hash the message. + * + * \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 * bitlength of the group order, then the hash is truncated as @@ -425,29 +247,11 @@ int mbedtls_ecdsa_write_signature_restartable( mbedtls_ecdsa_context *ctx, * (SECG): SEC1 Elliptic Curve Cryptography, section * 4.1.3, step 5. * - * \see ecp.h - * - * \deprecated Superseded by mbedtls_ecdsa_write_signature() in - * Mbed TLS version 2.0 and later. - * - * \param ctx The ECDSA context to use. This must be initialized - * and have a group and private key bound to it, for example - * via mbedtls_ecdsa_genkey() or mbedtls_ecdsa_from_keypair(). - * \param hash The message hash to be signed. This must be a readable - * buffer of length \p blen Bytes. - * \param hlen The length of the hash \p hash in Bytes. - * \param sig The buffer to which to write the signature. This must be a - * writable buffer of length 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. - * \param slen The address at which to store the actual length of - * the signature written. Must not be \c NULL. - * \param md_alg The message digest that was used to hash the message. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_ECP_XXX, \c MBEDTLS_ERR_MPI_XXX or + * \return \c 0 on success, + * or an \c MBEDTLS_ERR_ECP_XXX, \c MBEDTLS_ERR_MPI_XXX or * \c MBEDTLS_ERR_ASN1_XXX error code on failure. + * + * \see ecp.h */ int mbedtls_ecdsa_write_signature_det( mbedtls_ecdsa_context *ctx, const unsigned char *hash, size_t hlen, @@ -460,143 +264,75 @@ int mbedtls_ecdsa_write_signature_det( mbedtls_ecdsa_context *ctx, /** * \brief This function reads and verifies an ECDSA signature. * + * \param ctx The ECDSA context. + * \param hash The message hash. + * \param hlen The size of the hash. + * \param sig The signature to read and verify. + * \param slen The size of \p sig. + * * \note If the bitlength of the message hash is larger than the * bitlength of the group order, then the hash is truncated as * defined in Standards for Efficient Cryptography Group * (SECG): SEC1 Elliptic Curve Cryptography, section * 4.1.4, step 3. * - * \see ecp.h - * - * \param ctx The ECDSA context to use. This must be initialized - * and have a group and public key bound to it. - * \param hash The message hash that was signed. This must be a readable - * buffer of length \p size Bytes. - * \param hlen The size of the hash \p hash. - * \param sig The signature to read and verify. This must be a readable - * buffer of length \p slen Bytes. - * \param slen The size of \p sig in Bytes. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if signature is invalid. - * \return #MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH if there is a valid - * signature in \p sig, but its length is less than \p siglen. - * \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_ERR_MPI_XXX + * \return \c 0 on success, + * #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if signature is invalid, + * #MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH if there is a valid + * signature in sig but its length is less than \p siglen, + * 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, const unsigned char *hash, size_t hlen, const unsigned char *sig, size_t slen ); -/** - * \brief This function reads and verifies an ECDSA signature, - * in a restartable way. - * - * \see \c mbedtls_ecdsa_read_signature() - * - * \note This function is like \c mbedtls_ecdsa_read_signature() - * but it can return early and restart according to the limit - * set with \c mbedtls_ecp_set_max_ops() to reduce blocking. - * - * \param ctx The ECDSA context to use. This must be initialized - * and have a group and public key bound to it. - * \param hash The message hash that was signed. This must be a readable - * buffer of length \p size Bytes. - * \param hlen The size of the hash \p hash. - * \param sig The signature to read and verify. This must be a readable - * buffer of length \p slen Bytes. - * \param slen The size of \p sig in Bytes. - * \param rs_ctx The restart context to use. This may be \c NULL to disable - * restarting. If it is not \c NULL, it must point to an - * initialized restart context. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if signature is invalid. - * \return #MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH if there is a valid - * signature in \p sig, but its length is less than \p siglen. - * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of - * operations was reached: see \c mbedtls_ecp_set_max_ops(). - * \return Another \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_ERR_MPI_XXX - * error code on failure for any other reason. - */ -int mbedtls_ecdsa_read_signature_restartable( mbedtls_ecdsa_context *ctx, - const unsigned char *hash, size_t hlen, - const unsigned char *sig, size_t slen, - mbedtls_ecdsa_restart_ctx *rs_ctx ); - /** * \brief This function generates an ECDSA keypair on the given curve. * - * \see ecp.h - * * \param ctx The ECDSA context to store the keypair in. - * This must be initialized. * \param gid The elliptic curve to use. One of the various * \c MBEDTLS_ECP_DP_XXX macros depending on configuration. - * \param f_rng The RNG function to use. This must not be \c NULL. - * \param p_rng The RNG context to be passed to \p f_rng. This may be - * \c NULL if \p f_rng doesn't need a context argument. + * \param f_rng The RNG function. + * \param p_rng The RNG parameter. * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_ECP_XXX code on failure. + * \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 (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); /** - * \brief This function sets up an ECDSA context from an EC key pair. + * \brief This function sets an ECDSA context from an EC key pair. + * + * \param ctx The ECDSA context to set. + * \param key The EC key to use. + * + * \return \c 0 on success, or an \c MBEDTLS_ERR_ECP_XXX code on + * failure. * * \see ecp.h - * - * \param ctx The ECDSA context to setup. This must be initialized. - * \param key The EC key to use. This must be initialized and hold - * a private-public key pair or a public key. In the former - * case, the ECDSA context may be used for signature creation - * and verification after this call. In the latter case, it - * may be used for signature verification. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_ECP_XXX code on failure. */ -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 This function initializes an ECDSA context. * * \param ctx The ECDSA context to initialize. - * This must not be \c NULL. */ void mbedtls_ecdsa_init( mbedtls_ecdsa_context *ctx ); /** * \brief This function frees an ECDSA context. * - * \param ctx The ECDSA context to free. This may be \c NULL, - * in which case this function does nothing. If it - * is not \c NULL, it must be initialized. + * \param ctx The ECDSA context to free. */ void mbedtls_ecdsa_free( mbedtls_ecdsa_context *ctx ); -#if defined(MBEDTLS_ECP_RESTARTABLE) -/** - * \brief Initialize a restart context. - * - * \param ctx The restart context to initialize. - * This must not be \c NULL. - */ -void mbedtls_ecdsa_restart_init( mbedtls_ecdsa_restart_ctx *ctx ); - -/** - * \brief Free the components of a restart context. - * - * \param ctx The restart context to free. This may be \c NULL, - * in which case this function does nothing. If it - * is not \c NULL, it must be initialized. - */ -void mbedtls_ecdsa_restart_free( mbedtls_ecdsa_restart_ctx *ctx ); -#endif /* MBEDTLS_ECP_RESTARTABLE */ - #ifdef __cplusplus } #endif diff --git a/APP_Framework/Framework/security/mbedtls/ecjpake.c b/APP_Framework/Framework/security/mbedtls/ecjpake.c new file mode 100644 index 000000000..3bf42730a --- /dev/null +++ b/APP_Framework/Framework/security/mbedtls/ecjpake.c @@ -0,0 +1,1106 @@ +/* + * Elliptic curve J-PAKE + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +/* + * References in the code are to the Thread v1.0 Specification, + * available to members of the Thread Group http://threadgroup.org/ + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_ECJPAKE_C) + +#include "ecjpake.h" + +#include + +#if !defined(MBEDTLS_ECJPAKE_ALT) + +/* + * Convert a mbedtls_ecjpake_role to identifier string + */ +static const char * const ecjpake_id[] = { + "client", + "server" +}; + +#define ID_MINE ( ecjpake_id[ ctx->role ] ) +#define ID_PEER ( ecjpake_id[ 1 - ctx->role ] ) + +/* + * Initialize context + */ +void mbedtls_ecjpake_init( mbedtls_ecjpake_context *ctx ) +{ + if( ctx == NULL ) + return; + + ctx->md_info = NULL; + mbedtls_ecp_group_init( &ctx->grp ); + ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED; + + mbedtls_ecp_point_init( &ctx->Xm1 ); + mbedtls_ecp_point_init( &ctx->Xm2 ); + mbedtls_ecp_point_init( &ctx->Xp1 ); + mbedtls_ecp_point_init( &ctx->Xp2 ); + mbedtls_ecp_point_init( &ctx->Xp ); + + mbedtls_mpi_init( &ctx->xm1 ); + mbedtls_mpi_init( &ctx->xm2 ); + mbedtls_mpi_init( &ctx->s ); +} + +/* + * Free context + */ +void mbedtls_ecjpake_free( mbedtls_ecjpake_context *ctx ) +{ + if( ctx == NULL ) + return; + + ctx->md_info = NULL; + mbedtls_ecp_group_free( &ctx->grp ); + + mbedtls_ecp_point_free( &ctx->Xm1 ); + mbedtls_ecp_point_free( &ctx->Xm2 ); + mbedtls_ecp_point_free( &ctx->Xp1 ); + mbedtls_ecp_point_free( &ctx->Xp2 ); + mbedtls_ecp_point_free( &ctx->Xp ); + + mbedtls_mpi_free( &ctx->xm1 ); + mbedtls_mpi_free( &ctx->xm2 ); + mbedtls_mpi_free( &ctx->s ); +} + +/* + * Setup context + */ +int mbedtls_ecjpake_setup( mbedtls_ecjpake_context *ctx, + mbedtls_ecjpake_role role, + mbedtls_md_type_t hash, + mbedtls_ecp_group_id curve, + const unsigned char *secret, + size_t len ) +{ + int ret; + + ctx->role = role; + + if( ( ctx->md_info = mbedtls_md_info_from_type( hash ) ) == NULL ) + return( MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE ); + + MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &ctx->grp, curve ) ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->s, secret, len ) ); + +cleanup: + if( ret != 0 ) + mbedtls_ecjpake_free( ctx ); + + return( ret ); +} + +/* + * Check if context is ready for use + */ +int mbedtls_ecjpake_check( const mbedtls_ecjpake_context *ctx ) +{ + if( ctx->md_info == NULL || + ctx->grp.id == MBEDTLS_ECP_DP_NONE || + ctx->s.p == NULL ) + { + return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); + } + + return( 0 ); +} + +/* + * Write a point plus its length to a buffer + */ +static int ecjpake_write_len_point( unsigned char **p, + const unsigned char *end, + const mbedtls_ecp_group *grp, + const int pf, + const mbedtls_ecp_point *P ) +{ + int ret; + size_t len; + + /* Need at least 4 for length plus 1 for point */ + if( end < *p || end - *p < 5 ) + return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); + + ret = mbedtls_ecp_point_write_binary( grp, P, pf, + &len, *p + 4, end - ( *p + 4 ) ); + if( ret != 0 ) + return( ret ); + + (*p)[0] = (unsigned char)( ( len >> 24 ) & 0xFF ); + (*p)[1] = (unsigned char)( ( len >> 16 ) & 0xFF ); + (*p)[2] = (unsigned char)( ( len >> 8 ) & 0xFF ); + (*p)[3] = (unsigned char)( ( len ) & 0xFF ); + + *p += 4 + len; + + return( 0 ); +} + +/* + * Size of the temporary buffer for ecjpake_hash: + * 3 EC points plus their length, plus ID and its length (4 + 6 bytes) + */ +#define ECJPAKE_HASH_BUF_LEN ( 3 * ( 4 + MBEDTLS_ECP_MAX_PT_LEN ) + 4 + 6 ) + +/* + * Compute hash for ZKP (7.4.2.2.2.1) + */ +static int ecjpake_hash( const mbedtls_md_info_t *md_info, + const mbedtls_ecp_group *grp, + const int pf, + const mbedtls_ecp_point *G, + const mbedtls_ecp_point *V, + const mbedtls_ecp_point *X, + const char *id, + mbedtls_mpi *h ) +{ + int ret; + unsigned char buf[ECJPAKE_HASH_BUF_LEN]; + unsigned char *p = buf; + const unsigned char *end = buf + sizeof( buf ); + const size_t id_len = strlen( id ); + unsigned char hash[MBEDTLS_MD_MAX_SIZE]; + + /* Write things to temporary buffer */ + MBEDTLS_MPI_CHK( ecjpake_write_len_point( &p, end, grp, pf, G ) ); + MBEDTLS_MPI_CHK( ecjpake_write_len_point( &p, end, grp, pf, V ) ); + MBEDTLS_MPI_CHK( ecjpake_write_len_point( &p, end, grp, pf, X ) ); + + if( end - p < 4 ) + return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); + + *p++ = (unsigned char)( ( id_len >> 24 ) & 0xFF ); + *p++ = (unsigned char)( ( id_len >> 16 ) & 0xFF ); + *p++ = (unsigned char)( ( id_len >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( id_len ) & 0xFF ); + + if( end < p || (size_t)( end - p ) < id_len ) + return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); + + memcpy( p, id, id_len ); + p += id_len; + + /* Compute hash */ + mbedtls_md( md_info, buf, p - buf, hash ); + + /* Turn it into an integer mod n */ + MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( h, hash, + mbedtls_md_get_size( md_info ) ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( h, h, &grp->N ) ); + +cleanup: + return( ret ); +} + +/* + * Parse a ECShnorrZKP (7.4.2.2.2) and verify it (7.4.2.3.3) + */ +static int ecjpake_zkp_read( const mbedtls_md_info_t *md_info, + const mbedtls_ecp_group *grp, + const int pf, + const mbedtls_ecp_point *G, + const mbedtls_ecp_point *X, + const char *id, + const unsigned char **p, + const unsigned char *end ) +{ + int ret; + mbedtls_ecp_point V, VV; + mbedtls_mpi r, h; + size_t r_len; + + mbedtls_ecp_point_init( &V ); + mbedtls_ecp_point_init( &VV ); + mbedtls_mpi_init( &r ); + mbedtls_mpi_init( &h ); + + /* + * struct { + * ECPoint V; + * opaque r<1..2^8-1>; + * } ECSchnorrZKP; + */ + if( end < *p ) + return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); + + MBEDTLS_MPI_CHK( mbedtls_ecp_tls_read_point( grp, &V, p, end - *p ) ); + + if( end < *p || (size_t)( end - *p ) < 1 ) + { + ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + goto cleanup; + } + + r_len = *(*p)++; + + if( end < *p || (size_t)( end - *p ) < r_len ) + { + ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + goto cleanup; + } + + MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &r, *p, r_len ) ); + *p += r_len; + + /* + * Verification + */ + MBEDTLS_MPI_CHK( ecjpake_hash( md_info, grp, pf, G, &V, X, id, &h ) ); + MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( (mbedtls_ecp_group *) grp, + &VV, &h, X, &r, G ) ); + + if( mbedtls_ecp_point_cmp( &VV, &V ) != 0 ) + { + ret = MBEDTLS_ERR_ECP_VERIFY_FAILED; + goto cleanup; + } + +cleanup: + mbedtls_ecp_point_free( &V ); + mbedtls_ecp_point_free( &VV ); + mbedtls_mpi_free( &r ); + mbedtls_mpi_free( &h ); + + return( ret ); +} + +/* + * Generate ZKP (7.4.2.3.2) and write it as ECSchnorrZKP (7.4.2.2.2) + */ +static int ecjpake_zkp_write( const mbedtls_md_info_t *md_info, + const mbedtls_ecp_group *grp, + const int pf, + const mbedtls_ecp_point *G, + const mbedtls_mpi *x, + const mbedtls_ecp_point *X, + const char *id, + unsigned char **p, + const unsigned char *end, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + mbedtls_ecp_point V; + mbedtls_mpi v; + mbedtls_mpi h; /* later recycled to hold r */ + size_t len; + + if( end < *p ) + return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); + + mbedtls_ecp_point_init( &V ); + mbedtls_mpi_init( &v ); + mbedtls_mpi_init( &h ); + + /* Compute signature */ + MBEDTLS_MPI_CHK( mbedtls_ecp_gen_keypair_base( (mbedtls_ecp_group *) grp, + G, &v, &V, f_rng, p_rng ) ); + MBEDTLS_MPI_CHK( ecjpake_hash( md_info, grp, pf, G, &V, X, id, &h ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &h, &h, x ) ); /* x*h */ + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &h, &v, &h ) ); /* v - x*h */ + MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &h, &h, &grp->N ) ); /* r */ + + /* Write it out */ + MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_point( grp, &V, + pf, &len, *p, end - *p ) ); + *p += len; + + len = mbedtls_mpi_size( &h ); /* actually r */ + if( end < *p || (size_t)( end - *p ) < 1 + len || len > 255 ) + { + ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; + goto cleanup; + } + + *(*p)++ = (unsigned char)( len & 0xFF ); + MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &h, *p, len ) ); /* r */ + *p += len; + +cleanup: + mbedtls_ecp_point_free( &V ); + mbedtls_mpi_free( &v ); + mbedtls_mpi_free( &h ); + + return( ret ); +} + +/* + * Parse a ECJPAKEKeyKP (7.4.2.2.1) and check proof + * Output: verified public key X + */ +static int ecjpake_kkp_read( const mbedtls_md_info_t *md_info, + const mbedtls_ecp_group *grp, + const int pf, + const mbedtls_ecp_point *G, + mbedtls_ecp_point *X, + const char *id, + const unsigned char **p, + const unsigned char *end ) +{ + int ret; + + if( end < *p ) + return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); + + /* + * struct { + * ECPoint X; + * ECSchnorrZKP zkp; + * } ECJPAKEKeyKP; + */ + MBEDTLS_MPI_CHK( mbedtls_ecp_tls_read_point( grp, X, p, end - *p ) ); + if( mbedtls_ecp_is_zero( X ) ) + { + ret = MBEDTLS_ERR_ECP_INVALID_KEY; + goto cleanup; + } + + MBEDTLS_MPI_CHK( ecjpake_zkp_read( md_info, grp, pf, G, X, id, p, end ) ); + +cleanup: + return( ret ); +} + +/* + * Generate an ECJPAKEKeyKP + * Output: the serialized structure, plus private/public key pair + */ +static int ecjpake_kkp_write( const mbedtls_md_info_t *md_info, + const mbedtls_ecp_group *grp, + const int pf, + const mbedtls_ecp_point *G, + mbedtls_mpi *x, + mbedtls_ecp_point *X, + const char *id, + unsigned char **p, + const unsigned char *end, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + size_t len; + + if( end < *p ) + return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); + + /* Generate key (7.4.2.3.1) and write it out */ + MBEDTLS_MPI_CHK( mbedtls_ecp_gen_keypair_base( (mbedtls_ecp_group *) grp, G, x, X, + f_rng, p_rng ) ); + MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_point( grp, X, + pf, &len, *p, end - *p ) ); + *p += len; + + /* Generate and write proof */ + MBEDTLS_MPI_CHK( ecjpake_zkp_write( md_info, grp, pf, G, x, X, id, + p, end, f_rng, p_rng ) ); + +cleanup: + return( ret ); +} + +/* + * Read a ECJPAKEKeyKPPairList (7.4.2.3) and check proofs + * Ouputs: verified peer public keys Xa, Xb + */ +static int ecjpake_kkpp_read( const mbedtls_md_info_t *md_info, + const mbedtls_ecp_group *grp, + const int pf, + const mbedtls_ecp_point *G, + mbedtls_ecp_point *Xa, + mbedtls_ecp_point *Xb, + const char *id, + const unsigned char *buf, + size_t len ) +{ + int ret; + const unsigned char *p = buf; + const unsigned char *end = buf + len; + + /* + * struct { + * ECJPAKEKeyKP ecjpake_key_kp_pair_list[2]; + * } ECJPAKEKeyKPPairList; + */ + MBEDTLS_MPI_CHK( ecjpake_kkp_read( md_info, grp, pf, G, Xa, id, &p, end ) ); + MBEDTLS_MPI_CHK( ecjpake_kkp_read( md_info, grp, pf, G, Xb, id, &p, end ) ); + + if( p != end ) + ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + +cleanup: + return( ret ); +} + +/* + * Generate a ECJPAKEKeyKPPairList + * Outputs: the serialized structure, plus two private/public key pairs + */ +static int ecjpake_kkpp_write( const mbedtls_md_info_t *md_info, + const mbedtls_ecp_group *grp, + const int pf, + const mbedtls_ecp_point *G, + mbedtls_mpi *xm1, + mbedtls_ecp_point *Xa, + mbedtls_mpi *xm2, + mbedtls_ecp_point *Xb, + const char *id, + unsigned char *buf, + size_t len, + size_t *olen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + unsigned char *p = buf; + const unsigned char *end = buf + len; + + MBEDTLS_MPI_CHK( ecjpake_kkp_write( md_info, grp, pf, G, xm1, Xa, id, + &p, end, f_rng, p_rng ) ); + MBEDTLS_MPI_CHK( ecjpake_kkp_write( md_info, grp, pf, G, xm2, Xb, id, + &p, end, f_rng, p_rng ) ); + + *olen = p - buf; + +cleanup: + return( ret ); +} + +/* + * Read and process the first round message + */ +int mbedtls_ecjpake_read_round_one( mbedtls_ecjpake_context *ctx, + const unsigned char *buf, + size_t len ) +{ + return( ecjpake_kkpp_read( ctx->md_info, &ctx->grp, ctx->point_format, + &ctx->grp.G, + &ctx->Xp1, &ctx->Xp2, ID_PEER, + buf, len ) ); +} + +/* + * Generate and write the first round message + */ +int mbedtls_ecjpake_write_round_one( mbedtls_ecjpake_context *ctx, + unsigned char *buf, size_t len, size_t *olen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + return( ecjpake_kkpp_write( ctx->md_info, &ctx->grp, ctx->point_format, + &ctx->grp.G, + &ctx->xm1, &ctx->Xm1, &ctx->xm2, &ctx->Xm2, + ID_MINE, buf, len, olen, f_rng, p_rng ) ); +} + +/* + * Compute the sum of three points R = A + B + C + */ +static int ecjpake_ecp_add3( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, + const mbedtls_ecp_point *A, + const mbedtls_ecp_point *B, + const mbedtls_ecp_point *C ) +{ + int ret; + mbedtls_mpi one; + + mbedtls_mpi_init( &one ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &one, 1 ) ); + MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( grp, R, &one, A, &one, B ) ); + MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( grp, R, &one, R, &one, C ) ); + +cleanup: + mbedtls_mpi_free( &one ); + + return( ret ); +} + +/* + * Read and process second round message (C: 7.4.2.5, S: 7.4.2.6) + */ +int mbedtls_ecjpake_read_round_two( mbedtls_ecjpake_context *ctx, + const unsigned char *buf, + size_t len ) +{ + int ret; + const unsigned char *p = buf; + const unsigned char *end = buf + len; + mbedtls_ecp_group grp; + mbedtls_ecp_point G; /* C: GB, S: GA */ + + mbedtls_ecp_group_init( &grp ); + mbedtls_ecp_point_init( &G ); + + /* + * Server: GA = X3 + X4 + X1 (7.4.2.6.1) + * Client: GB = X1 + X2 + X3 (7.4.2.5.1) + * Unified: G = Xm1 + Xm2 + Xp1 + * We need that before parsing in order to check Xp as we read it + */ + MBEDTLS_MPI_CHK( ecjpake_ecp_add3( &ctx->grp, &G, + &ctx->Xm1, &ctx->Xm2, &ctx->Xp1 ) ); + + /* + * struct { + * ECParameters curve_params; // only client reading server msg + * ECJPAKEKeyKP ecjpake_key_kp; + * } Client/ServerECJPAKEParams; + */ + if( ctx->role == MBEDTLS_ECJPAKE_CLIENT ) + { + MBEDTLS_MPI_CHK( mbedtls_ecp_tls_read_group( &grp, &p, len ) ); + if( grp.id != ctx->grp.id ) + { + ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; + goto cleanup; + } + } + + MBEDTLS_MPI_CHK( ecjpake_kkp_read( ctx->md_info, &ctx->grp, + ctx->point_format, + &G, &ctx->Xp, ID_PEER, &p, end ) ); + + if( p != end ) + { + ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + goto cleanup; + } + +cleanup: + mbedtls_ecp_group_free( &grp ); + mbedtls_ecp_point_free( &G ); + + return( ret ); +} + +/* + * Compute R = +/- X * S mod N, taking care not to leak S + */ +static int ecjpake_mul_secret( mbedtls_mpi *R, int sign, + const mbedtls_mpi *X, + const mbedtls_mpi *S, + const mbedtls_mpi *N, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + mbedtls_mpi b; /* Blinding value, then s + N * blinding */ + + mbedtls_mpi_init( &b ); + + /* b = s + rnd-128-bit * N */ + MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &b, 16, f_rng, p_rng ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &b, &b, N ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &b, &b, S ) ); + + /* R = sign * X * b mod N */ + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( R, X, &b ) ); + R->s *= sign; + MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( R, R, N ) ); + +cleanup: + mbedtls_mpi_free( &b ); + + return( ret ); +} + +/* + * Generate and write the second round message (S: 7.4.2.5, C: 7.4.2.6) + */ +int mbedtls_ecjpake_write_round_two( mbedtls_ecjpake_context *ctx, + unsigned char *buf, size_t len, size_t *olen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + mbedtls_ecp_point G; /* C: GA, S: GB */ + mbedtls_ecp_point Xm; /* C: Xc, S: Xs */ + mbedtls_mpi xm; /* C: xc, S: xs */ + unsigned char *p = buf; + const unsigned char *end = buf + len; + size_t ec_len; + + mbedtls_ecp_point_init( &G ); + mbedtls_ecp_point_init( &Xm ); + mbedtls_mpi_init( &xm ); + + /* + * First generate private/public key pair (S: 7.4.2.5.1, C: 7.4.2.6.1) + * + * Client: GA = X1 + X3 + X4 | xs = x2 * s | Xc = xc * GA + * Server: GB = X3 + X1 + X2 | xs = x4 * s | Xs = xs * GB + * Unified: G = Xm1 + Xp1 + Xp2 | xm = xm2 * s | Xm = xm * G + */ + MBEDTLS_MPI_CHK( ecjpake_ecp_add3( &ctx->grp, &G, + &ctx->Xp1, &ctx->Xp2, &ctx->Xm1 ) ); + MBEDTLS_MPI_CHK( ecjpake_mul_secret( &xm, 1, &ctx->xm2, &ctx->s, + &ctx->grp.N, f_rng, p_rng ) ); + MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &Xm, &xm, &G, f_rng, p_rng ) ); + + /* + * Now write things out + * + * struct { + * ECParameters curve_params; // only server writing its message + * ECJPAKEKeyKP ecjpake_key_kp; + * } Client/ServerECJPAKEParams; + */ + if( ctx->role == MBEDTLS_ECJPAKE_SERVER ) + { + if( end < p ) + { + ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; + goto cleanup; + } + MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_group( &ctx->grp, &ec_len, + p, end - p ) ); + p += ec_len; + } + + if( end < p ) + { + ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; + goto cleanup; + } + MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_point( &ctx->grp, &Xm, + ctx->point_format, &ec_len, p, end - p ) ); + p += ec_len; + + MBEDTLS_MPI_CHK( ecjpake_zkp_write( ctx->md_info, &ctx->grp, + ctx->point_format, + &G, &xm, &Xm, ID_MINE, + &p, end, f_rng, p_rng ) ); + + *olen = p - buf; + +cleanup: + mbedtls_ecp_point_free( &G ); + mbedtls_ecp_point_free( &Xm ); + mbedtls_mpi_free( &xm ); + + return( ret ); +} + +/* + * Derive PMS (7.4.2.7 / 7.4.2.8) + */ +int mbedtls_ecjpake_derive_secret( mbedtls_ecjpake_context *ctx, + unsigned char *buf, size_t len, size_t *olen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + mbedtls_ecp_point K; + mbedtls_mpi m_xm2_s, one; + unsigned char kx[MBEDTLS_ECP_MAX_BYTES]; + size_t x_bytes; + + *olen = mbedtls_md_get_size( ctx->md_info ); + if( len < *olen ) + return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); + + mbedtls_ecp_point_init( &K ); + mbedtls_mpi_init( &m_xm2_s ); + mbedtls_mpi_init( &one ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &one, 1 ) ); + + /* + * Client: K = ( Xs - X4 * x2 * s ) * x2 + * Server: K = ( Xc - X2 * x4 * s ) * x4 + * Unified: K = ( Xp - Xp2 * xm2 * s ) * xm2 + */ + MBEDTLS_MPI_CHK( ecjpake_mul_secret( &m_xm2_s, -1, &ctx->xm2, &ctx->s, + &ctx->grp.N, f_rng, p_rng ) ); + MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( &ctx->grp, &K, + &one, &ctx->Xp, + &m_xm2_s, &ctx->Xp2 ) ); + MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &K, &ctx->xm2, &K, + f_rng, p_rng ) ); + + /* PMS = SHA-256( K.X ) */ + x_bytes = ( ctx->grp.pbits + 7 ) / 8; + MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &K.X, kx, x_bytes ) ); + MBEDTLS_MPI_CHK( mbedtls_md( ctx->md_info, kx, x_bytes, buf ) ); + +cleanup: + mbedtls_ecp_point_free( &K ); + mbedtls_mpi_free( &m_xm2_s ); + mbedtls_mpi_free( &one ); + + return( ret ); +} + +#undef ID_MINE +#undef ID_PEER + +#endif /* ! MBEDTLS_ECJPAKE_ALT */ + +#if defined(MBEDTLS_SELF_TEST) + +#if defined(MBEDTLS_PLATFORM_C) +#include "platform.h" +#else +#include +#define mbedtls_printf printf +#endif + +#if !defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \ + !defined(MBEDTLS_SHA256_C) +int mbedtls_ecjpake_self_test( int verbose ) +{ + (void) verbose; + return( 0 ); +} +#else + +static const unsigned char ecjpake_test_password[] = { + 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x6a, 0x70, 0x61, 0x6b, 0x65, 0x74, + 0x65, 0x73, 0x74 +}; + +static const unsigned char ecjpake_test_x1[] = { + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, + 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x21 +}; + +static const unsigned char ecjpake_test_x2[] = { + 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, + 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, + 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x81 +}; + +static const unsigned char ecjpake_test_x3[] = { + 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, + 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, + 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x81 +}; + +static const unsigned char ecjpake_test_x4[] = { + 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, + 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, + 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe1 +}; + +static const unsigned char ecjpake_test_cli_one[] = { + 0x41, 0x04, 0xac, 0xcf, 0x01, 0x06, 0xef, 0x85, 0x8f, 0xa2, 0xd9, 0x19, + 0x33, 0x13, 0x46, 0x80, 0x5a, 0x78, 0xb5, 0x8b, 0xba, 0xd0, 0xb8, 0x44, + 0xe5, 0xc7, 0x89, 0x28, 0x79, 0x14, 0x61, 0x87, 0xdd, 0x26, 0x66, 0xad, + 0xa7, 0x81, 0xbb, 0x7f, 0x11, 0x13, 0x72, 0x25, 0x1a, 0x89, 0x10, 0x62, + 0x1f, 0x63, 0x4d, 0xf1, 0x28, 0xac, 0x48, 0xe3, 0x81, 0xfd, 0x6e, 0xf9, + 0x06, 0x07, 0x31, 0xf6, 0x94, 0xa4, 0x41, 0x04, 0x1d, 0xd0, 0xbd, 0x5d, + 0x45, 0x66, 0xc9, 0xbe, 0xd9, 0xce, 0x7d, 0xe7, 0x01, 0xb5, 0xe8, 0x2e, + 0x08, 0xe8, 0x4b, 0x73, 0x04, 0x66, 0x01, 0x8a, 0xb9, 0x03, 0xc7, 0x9e, + 0xb9, 0x82, 0x17, 0x22, 0x36, 0xc0, 0xc1, 0x72, 0x8a, 0xe4, 0xbf, 0x73, + 0x61, 0x0d, 0x34, 0xde, 0x44, 0x24, 0x6e, 0xf3, 0xd9, 0xc0, 0x5a, 0x22, + 0x36, 0xfb, 0x66, 0xa6, 0x58, 0x3d, 0x74, 0x49, 0x30, 0x8b, 0xab, 0xce, + 0x20, 0x72, 0xfe, 0x16, 0x66, 0x29, 0x92, 0xe9, 0x23, 0x5c, 0x25, 0x00, + 0x2f, 0x11, 0xb1, 0x50, 0x87, 0xb8, 0x27, 0x38, 0xe0, 0x3c, 0x94, 0x5b, + 0xf7, 0xa2, 0x99, 0x5d, 0xda, 0x1e, 0x98, 0x34, 0x58, 0x41, 0x04, 0x7e, + 0xa6, 0xe3, 0xa4, 0x48, 0x70, 0x37, 0xa9, 0xe0, 0xdb, 0xd7, 0x92, 0x62, + 0xb2, 0xcc, 0x27, 0x3e, 0x77, 0x99, 0x30, 0xfc, 0x18, 0x40, 0x9a, 0xc5, + 0x36, 0x1c, 0x5f, 0xe6, 0x69, 0xd7, 0x02, 0xe1, 0x47, 0x79, 0x0a, 0xeb, + 0x4c, 0xe7, 0xfd, 0x65, 0x75, 0xab, 0x0f, 0x6c, 0x7f, 0xd1, 0xc3, 0x35, + 0x93, 0x9a, 0xa8, 0x63, 0xba, 0x37, 0xec, 0x91, 0xb7, 0xe3, 0x2b, 0xb0, + 0x13, 0xbb, 0x2b, 0x41, 0x04, 0xa4, 0x95, 0x58, 0xd3, 0x2e, 0xd1, 0xeb, + 0xfc, 0x18, 0x16, 0xaf, 0x4f, 0xf0, 0x9b, 0x55, 0xfc, 0xb4, 0xca, 0x47, + 0xb2, 0xa0, 0x2d, 0x1e, 0x7c, 0xaf, 0x11, 0x79, 0xea, 0x3f, 0xe1, 0x39, + 0x5b, 0x22, 0xb8, 0x61, 0x96, 0x40, 0x16, 0xfa, 0xba, 0xf7, 0x2c, 0x97, + 0x56, 0x95, 0xd9, 0x3d, 0x4d, 0xf0, 0xe5, 0x19, 0x7f, 0xe9, 0xf0, 0x40, + 0x63, 0x4e, 0xd5, 0x97, 0x64, 0x93, 0x77, 0x87, 0xbe, 0x20, 0xbc, 0x4d, + 0xee, 0xbb, 0xf9, 0xb8, 0xd6, 0x0a, 0x33, 0x5f, 0x04, 0x6c, 0xa3, 0xaa, + 0x94, 0x1e, 0x45, 0x86, 0x4c, 0x7c, 0xad, 0xef, 0x9c, 0xf7, 0x5b, 0x3d, + 0x8b, 0x01, 0x0e, 0x44, 0x3e, 0xf0 +}; + +static const unsigned char ecjpake_test_srv_one[] = { + 0x41, 0x04, 0x7e, 0xa6, 0xe3, 0xa4, 0x48, 0x70, 0x37, 0xa9, 0xe0, 0xdb, + 0xd7, 0x92, 0x62, 0xb2, 0xcc, 0x27, 0x3e, 0x77, 0x99, 0x30, 0xfc, 0x18, + 0x40, 0x9a, 0xc5, 0x36, 0x1c, 0x5f, 0xe6, 0x69, 0xd7, 0x02, 0xe1, 0x47, + 0x79, 0x0a, 0xeb, 0x4c, 0xe7, 0xfd, 0x65, 0x75, 0xab, 0x0f, 0x6c, 0x7f, + 0xd1, 0xc3, 0x35, 0x93, 0x9a, 0xa8, 0x63, 0xba, 0x37, 0xec, 0x91, 0xb7, + 0xe3, 0x2b, 0xb0, 0x13, 0xbb, 0x2b, 0x41, 0x04, 0x09, 0xf8, 0x5b, 0x3d, + 0x20, 0xeb, 0xd7, 0x88, 0x5c, 0xe4, 0x64, 0xc0, 0x8d, 0x05, 0x6d, 0x64, + 0x28, 0xfe, 0x4d, 0xd9, 0x28, 0x7a, 0xa3, 0x65, 0xf1, 0x31, 0xf4, 0x36, + 0x0f, 0xf3, 0x86, 0xd8, 0x46, 0x89, 0x8b, 0xc4, 0xb4, 0x15, 0x83, 0xc2, + 0xa5, 0x19, 0x7f, 0x65, 0xd7, 0x87, 0x42, 0x74, 0x6c, 0x12, 0xa5, 0xec, + 0x0a, 0x4f, 0xfe, 0x2f, 0x27, 0x0a, 0x75, 0x0a, 0x1d, 0x8f, 0xb5, 0x16, + 0x20, 0x93, 0x4d, 0x74, 0xeb, 0x43, 0xe5, 0x4d, 0xf4, 0x24, 0xfd, 0x96, + 0x30, 0x6c, 0x01, 0x17, 0xbf, 0x13, 0x1a, 0xfa, 0xbf, 0x90, 0xa9, 0xd3, + 0x3d, 0x11, 0x98, 0xd9, 0x05, 0x19, 0x37, 0x35, 0x14, 0x41, 0x04, 0x19, + 0x0a, 0x07, 0x70, 0x0f, 0xfa, 0x4b, 0xe6, 0xae, 0x1d, 0x79, 0xee, 0x0f, + 0x06, 0xae, 0xb5, 0x44, 0xcd, 0x5a, 0xdd, 0xaa, 0xbe, 0xdf, 0x70, 0xf8, + 0x62, 0x33, 0x21, 0x33, 0x2c, 0x54, 0xf3, 0x55, 0xf0, 0xfb, 0xfe, 0xc7, + 0x83, 0xed, 0x35, 0x9e, 0x5d, 0x0b, 0xf7, 0x37, 0x7a, 0x0f, 0xc4, 0xea, + 0x7a, 0xce, 0x47, 0x3c, 0x9c, 0x11, 0x2b, 0x41, 0xcc, 0xd4, 0x1a, 0xc5, + 0x6a, 0x56, 0x12, 0x41, 0x04, 0x36, 0x0a, 0x1c, 0xea, 0x33, 0xfc, 0xe6, + 0x41, 0x15, 0x64, 0x58, 0xe0, 0xa4, 0xea, 0xc2, 0x19, 0xe9, 0x68, 0x31, + 0xe6, 0xae, 0xbc, 0x88, 0xb3, 0xf3, 0x75, 0x2f, 0x93, 0xa0, 0x28, 0x1d, + 0x1b, 0xf1, 0xfb, 0x10, 0x60, 0x51, 0xdb, 0x96, 0x94, 0xa8, 0xd6, 0xe8, + 0x62, 0xa5, 0xef, 0x13, 0x24, 0xa3, 0xd9, 0xe2, 0x78, 0x94, 0xf1, 0xee, + 0x4f, 0x7c, 0x59, 0x19, 0x99, 0x65, 0xa8, 0xdd, 0x4a, 0x20, 0x91, 0x84, + 0x7d, 0x2d, 0x22, 0xdf, 0x3e, 0xe5, 0x5f, 0xaa, 0x2a, 0x3f, 0xb3, 0x3f, + 0xd2, 0xd1, 0xe0, 0x55, 0xa0, 0x7a, 0x7c, 0x61, 0xec, 0xfb, 0x8d, 0x80, + 0xec, 0x00, 0xc2, 0xc9, 0xeb, 0x12 +}; + +static const unsigned char ecjpake_test_srv_two[] = { + 0x03, 0x00, 0x17, 0x41, 0x04, 0x0f, 0xb2, 0x2b, 0x1d, 0x5d, 0x11, 0x23, + 0xe0, 0xef, 0x9f, 0xeb, 0x9d, 0x8a, 0x2e, 0x59, 0x0a, 0x1f, 0x4d, 0x7c, + 0xed, 0x2c, 0x2b, 0x06, 0x58, 0x6e, 0x8f, 0x2a, 0x16, 0xd4, 0xeb, 0x2f, + 0xda, 0x43, 0x28, 0xa2, 0x0b, 0x07, 0xd8, 0xfd, 0x66, 0x76, 0x54, 0xca, + 0x18, 0xc5, 0x4e, 0x32, 0xa3, 0x33, 0xa0, 0x84, 0x54, 0x51, 0xe9, 0x26, + 0xee, 0x88, 0x04, 0xfd, 0x7a, 0xf0, 0xaa, 0xa7, 0xa6, 0x41, 0x04, 0x55, + 0x16, 0xea, 0x3e, 0x54, 0xa0, 0xd5, 0xd8, 0xb2, 0xce, 0x78, 0x6b, 0x38, + 0xd3, 0x83, 0x37, 0x00, 0x29, 0xa5, 0xdb, 0xe4, 0x45, 0x9c, 0x9d, 0xd6, + 0x01, 0xb4, 0x08, 0xa2, 0x4a, 0xe6, 0x46, 0x5c, 0x8a, 0xc9, 0x05, 0xb9, + 0xeb, 0x03, 0xb5, 0xd3, 0x69, 0x1c, 0x13, 0x9e, 0xf8, 0x3f, 0x1c, 0xd4, + 0x20, 0x0f, 0x6c, 0x9c, 0xd4, 0xec, 0x39, 0x22, 0x18, 0xa5, 0x9e, 0xd2, + 0x43, 0xd3, 0xc8, 0x20, 0xff, 0x72, 0x4a, 0x9a, 0x70, 0xb8, 0x8c, 0xb8, + 0x6f, 0x20, 0xb4, 0x34, 0xc6, 0x86, 0x5a, 0xa1, 0xcd, 0x79, 0x06, 0xdd, + 0x7c, 0x9b, 0xce, 0x35, 0x25, 0xf5, 0x08, 0x27, 0x6f, 0x26, 0x83, 0x6c +}; + +static const unsigned char ecjpake_test_cli_two[] = { + 0x41, 0x04, 0x69, 0xd5, 0x4e, 0xe8, 0x5e, 0x90, 0xce, 0x3f, 0x12, 0x46, + 0x74, 0x2d, 0xe5, 0x07, 0xe9, 0x39, 0xe8, 0x1d, 0x1d, 0xc1, 0xc5, 0xcb, + 0x98, 0x8b, 0x58, 0xc3, 0x10, 0xc9, 0xfd, 0xd9, 0x52, 0x4d, 0x93, 0x72, + 0x0b, 0x45, 0x54, 0x1c, 0x83, 0xee, 0x88, 0x41, 0x19, 0x1d, 0xa7, 0xce, + 0xd8, 0x6e, 0x33, 0x12, 0xd4, 0x36, 0x23, 0xc1, 0xd6, 0x3e, 0x74, 0x98, + 0x9a, 0xba, 0x4a, 0xff, 0xd1, 0xee, 0x41, 0x04, 0x07, 0x7e, 0x8c, 0x31, + 0xe2, 0x0e, 0x6b, 0xed, 0xb7, 0x60, 0xc1, 0x35, 0x93, 0xe6, 0x9f, 0x15, + 0xbe, 0x85, 0xc2, 0x7d, 0x68, 0xcd, 0x09, 0xcc, 0xb8, 0xc4, 0x18, 0x36, + 0x08, 0x91, 0x7c, 0x5c, 0x3d, 0x40, 0x9f, 0xac, 0x39, 0xfe, 0xfe, 0xe8, + 0x2f, 0x72, 0x92, 0xd3, 0x6f, 0x0d, 0x23, 0xe0, 0x55, 0x91, 0x3f, 0x45, + 0xa5, 0x2b, 0x85, 0xdd, 0x8a, 0x20, 0x52, 0xe9, 0xe1, 0x29, 0xbb, 0x4d, + 0x20, 0x0f, 0x01, 0x1f, 0x19, 0x48, 0x35, 0x35, 0xa6, 0xe8, 0x9a, 0x58, + 0x0c, 0x9b, 0x00, 0x03, 0xba, 0xf2, 0x14, 0x62, 0xec, 0xe9, 0x1a, 0x82, + 0xcc, 0x38, 0xdb, 0xdc, 0xae, 0x60, 0xd9, 0xc5, 0x4c +}; + +static const unsigned char ecjpake_test_pms[] = { + 0xf3, 0xd4, 0x7f, 0x59, 0x98, 0x44, 0xdb, 0x92, 0xa5, 0x69, 0xbb, 0xe7, + 0x98, 0x1e, 0x39, 0xd9, 0x31, 0xfd, 0x74, 0x3b, 0xf2, 0x2e, 0x98, 0xf9, + 0xb4, 0x38, 0xf7, 0x19, 0xd3, 0xc4, 0xf3, 0x51 +}; + +/* Load my private keys and generate the correponding public keys */ +static int ecjpake_test_load( mbedtls_ecjpake_context *ctx, + const unsigned char *xm1, size_t len1, + const unsigned char *xm2, size_t len2 ) +{ + int ret; + + MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->xm1, xm1, len1 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->xm2, xm2, len2 ) ); + MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &ctx->Xm1, &ctx->xm1, + &ctx->grp.G, NULL, NULL ) ); + MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &ctx->Xm2, &ctx->xm2, + &ctx->grp.G, NULL, NULL ) ); + +cleanup: + return( ret ); +} + +/* For tests we don't need a secure RNG; + * use the LGC from Numerical Recipes for simplicity */ +static int ecjpake_lgc( void *p, unsigned char *out, size_t len ) +{ + static uint32_t x = 42; + (void) p; + + while( len > 0 ) + { + size_t use_len = len > 4 ? 4 : len; + x = 1664525 * x + 1013904223; + memcpy( out, &x, use_len ); + out += use_len; + len -= use_len; + } + + return( 0 ); +} + +#define TEST_ASSERT( x ) \ + do { \ + if( x ) \ + ret = 0; \ + else \ + { \ + ret = 1; \ + goto cleanup; \ + } \ + } while( 0 ) + +/* + * Checkup routine + */ +int mbedtls_ecjpake_self_test( int verbose ) +{ + int ret; + mbedtls_ecjpake_context cli; + mbedtls_ecjpake_context srv; + unsigned char buf[512], pms[32]; + size_t len, pmslen; + + mbedtls_ecjpake_init( &cli ); + mbedtls_ecjpake_init( &srv ); + + if( verbose != 0 ) + mbedtls_printf( " ECJPAKE test #0 (setup): " ); + + TEST_ASSERT( mbedtls_ecjpake_setup( &cli, MBEDTLS_ECJPAKE_CLIENT, + MBEDTLS_MD_SHA256, MBEDTLS_ECP_DP_SECP256R1, + ecjpake_test_password, + sizeof( ecjpake_test_password ) ) == 0 ); + + TEST_ASSERT( mbedtls_ecjpake_setup( &srv, MBEDTLS_ECJPAKE_SERVER, + MBEDTLS_MD_SHA256, MBEDTLS_ECP_DP_SECP256R1, + ecjpake_test_password, + sizeof( ecjpake_test_password ) ) == 0 ); + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + + if( verbose != 0 ) + mbedtls_printf( " ECJPAKE test #1 (random handshake): " ); + + TEST_ASSERT( mbedtls_ecjpake_write_round_one( &cli, + buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 ); + + TEST_ASSERT( mbedtls_ecjpake_read_round_one( &srv, buf, len ) == 0 ); + + TEST_ASSERT( mbedtls_ecjpake_write_round_one( &srv, + buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 ); + + TEST_ASSERT( mbedtls_ecjpake_read_round_one( &cli, buf, len ) == 0 ); + + TEST_ASSERT( mbedtls_ecjpake_write_round_two( &srv, + buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 ); + + TEST_ASSERT( mbedtls_ecjpake_read_round_two( &cli, buf, len ) == 0 ); + + TEST_ASSERT( mbedtls_ecjpake_derive_secret( &cli, + pms, sizeof( pms ), &pmslen, ecjpake_lgc, NULL ) == 0 ); + + TEST_ASSERT( mbedtls_ecjpake_write_round_two( &cli, + buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 ); + + TEST_ASSERT( mbedtls_ecjpake_read_round_two( &srv, buf, len ) == 0 ); + + TEST_ASSERT( mbedtls_ecjpake_derive_secret( &srv, + buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 ); + + TEST_ASSERT( len == pmslen ); + TEST_ASSERT( memcmp( buf, pms, len ) == 0 ); + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + + if( verbose != 0 ) + mbedtls_printf( " ECJPAKE test #2 (reference handshake): " ); + + /* Simulate generation of round one */ + MBEDTLS_MPI_CHK( ecjpake_test_load( &cli, + ecjpake_test_x1, sizeof( ecjpake_test_x1 ), + ecjpake_test_x2, sizeof( ecjpake_test_x2 ) ) ); + + MBEDTLS_MPI_CHK( ecjpake_test_load( &srv, + ecjpake_test_x3, sizeof( ecjpake_test_x3 ), + ecjpake_test_x4, sizeof( ecjpake_test_x4 ) ) ); + + /* Read round one */ + TEST_ASSERT( mbedtls_ecjpake_read_round_one( &srv, + ecjpake_test_cli_one, + sizeof( ecjpake_test_cli_one ) ) == 0 ); + + TEST_ASSERT( mbedtls_ecjpake_read_round_one( &cli, + ecjpake_test_srv_one, + sizeof( ecjpake_test_srv_one ) ) == 0 ); + + /* Skip generation of round two, read round two */ + TEST_ASSERT( mbedtls_ecjpake_read_round_two( &cli, + ecjpake_test_srv_two, + sizeof( ecjpake_test_srv_two ) ) == 0 ); + + TEST_ASSERT( mbedtls_ecjpake_read_round_two( &srv, + ecjpake_test_cli_two, + sizeof( ecjpake_test_cli_two ) ) == 0 ); + + /* Server derives PMS */ + TEST_ASSERT( mbedtls_ecjpake_derive_secret( &srv, + buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 ); + + TEST_ASSERT( len == sizeof( ecjpake_test_pms ) ); + TEST_ASSERT( memcmp( buf, ecjpake_test_pms, len ) == 0 ); + + memset( buf, 0, len ); /* Avoid interferences with next step */ + + /* Client derives PMS */ + TEST_ASSERT( mbedtls_ecjpake_derive_secret( &cli, + buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 ); + + TEST_ASSERT( len == sizeof( ecjpake_test_pms ) ); + TEST_ASSERT( memcmp( buf, ecjpake_test_pms, len ) == 0 ); + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + +cleanup: + mbedtls_ecjpake_free( &cli ); + mbedtls_ecjpake_free( &srv ); + + if( ret != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + ret = 1; + } + + if( verbose != 0 ) + mbedtls_printf( "\n" ); + + return( ret ); +} + +#undef TEST_ASSERT + +#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED && MBEDTLS_SHA256_C */ + +#endif /* MBEDTLS_SELF_TEST */ + +#endif /* MBEDTLS_ECJPAKE_C */ diff --git a/APP_Framework/Framework/security/mbedtls/ecjpake.h b/APP_Framework/Framework/security/mbedtls/ecjpake.h index 00e752b23..8d09bf229 100644 --- a/APP_Framework/Framework/security/mbedtls/ecjpake.h +++ b/APP_Framework/Framework/security/mbedtls/ecjpake.h @@ -49,6 +49,8 @@ #include "ecp.h" #include "md.h" +#if !defined(MBEDTLS_ECJPAKE_ALT) + #ifdef __cplusplus extern "C" { #endif @@ -61,7 +63,6 @@ typedef enum { MBEDTLS_ECJPAKE_SERVER, /**< Server */ } mbedtls_ecjpake_role; -#if !defined(MBEDTLS_ECJPAKE_ALT) /** * EC J-PAKE context structure. * @@ -73,9 +74,9 @@ typedef enum { * convetion from the Thread v1.0 spec. Correspondance is indicated in the * description as a pair C: client name, S: server name */ -typedef struct mbedtls_ecjpake_context +typedef struct { - mbedtls_md_handle_t md_info; /**< Hash to use */ + const mbedtls_md_info_t *md_info; /**< Hash to use */ mbedtls_ecp_group grp; /**< Elliptic curve */ mbedtls_ecjpake_role role; /**< Are we client or server? */ int point_format; /**< Format for point export */ @@ -92,38 +93,29 @@ typedef struct mbedtls_ecjpake_context mbedtls_mpi s; /**< Pre-shared secret (passphrase) */ } mbedtls_ecjpake_context; -#else /* MBEDTLS_ECJPAKE_ALT */ -#include "ecjpake_alt.h" -#endif /* MBEDTLS_ECJPAKE_ALT */ - /** - * \brief Initialize an ECJPAKE context. + * \brief Initialize a context + * (just makes it ready for setup() or free()). * - * \param ctx The ECJPAKE context to initialize. - * This must not be \c NULL. + * \param ctx context to initialize */ void mbedtls_ecjpake_init( mbedtls_ecjpake_context *ctx ); /** - * \brief Set up an ECJPAKE context for use. + * \brief Set up a context for use * * \note Currently the only values for hash/curve allowed by the - * standard are #MBEDTLS_MD_SHA256/#MBEDTLS_ECP_DP_SECP256R1. + * standard are MBEDTLS_MD_SHA256/MBEDTLS_ECP_DP_SECP256R1. * - * \param ctx The ECJPAKE context to set up. This must be initialized. - * \param role The role of the caller. This must be either - * #MBEDTLS_ECJPAKE_CLIENT or #MBEDTLS_ECJPAKE_SERVER. - * \param hash The identifier of the hash function to use, - * for example #MBEDTLS_MD_SHA256. - * \param curve The identifier of the elliptic curve to use, - * for example #MBEDTLS_ECP_DP_SECP256R1. - * \param secret The pre-shared secret (passphrase). This must be - * a readable buffer of length \p len Bytes. It need - * only be valid for the duration of this call. - * \param len The length of the pre-shared secret \p secret. + * \param ctx context to set up + * \param role Our role: client or server + * \param hash hash function to use (MBEDTLS_MD_XXX) + * \param curve elliptic curve identifier (MBEDTLS_ECP_DP_XXX) + * \param secret pre-shared secret (passphrase) + * \param len length of the shared secret * - * \return \c 0 if successful. - * \return A negative error code on failure. + * \return 0 if successfull, + * a negative error code otherwise */ int mbedtls_ecjpake_setup( mbedtls_ecjpake_context *ctx, mbedtls_ecjpake_role role, @@ -133,34 +125,29 @@ int mbedtls_ecjpake_setup( mbedtls_ecjpake_context *ctx, size_t len ); /** - * \brief Check if an ECJPAKE context is ready for use. + * \brief Check if a context is ready for use * - * \param ctx The ECJPAKE context to check. This must be - * initialized. + * \param ctx Context to check * - * \return \c 0 if the context is ready for use. - * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA otherwise. + * \return 0 if the context is ready for use, + * MBEDTLS_ERR_ECP_BAD_INPUT_DATA otherwise */ int mbedtls_ecjpake_check( const mbedtls_ecjpake_context *ctx ); /** * \brief Generate and write the first round message * (TLS: contents of the Client/ServerHello extension, - * excluding extension type and length bytes). + * excluding extension type and length bytes) * - * \param ctx The ECJPAKE context to use. This must be - * initialized and set up. - * \param buf The buffer to write the contents to. This must be a - * writable buffer of length \p len Bytes. - * \param len The length of \p buf in Bytes. - * \param olen The address at which to store the total number - * of Bytes written to \p buf. This must not be \c NULL. - * \param f_rng The RNG function to use. This must not be \c NULL. - * \param p_rng The RNG parameter to be passed to \p f_rng. This - * may be \c NULL if \p f_rng doesn't use a context. + * \param ctx Context to use + * \param buf Buffer to write the contents to + * \param len Buffer size + * \param olen Will be updated with the number of bytes written + * \param f_rng RNG function + * \param p_rng RNG parameter * - * \return \c 0 if successful. - * \return A negative error code on failure. + * \return 0 if successfull, + * a negative error code otherwise */ int mbedtls_ecjpake_write_round_one( mbedtls_ecjpake_context *ctx, unsigned char *buf, size_t len, size_t *olen, @@ -170,16 +157,14 @@ int mbedtls_ecjpake_write_round_one( mbedtls_ecjpake_context *ctx, /** * \brief Read and process the first round message * (TLS: contents of the Client/ServerHello extension, - * excluding extension type and length bytes). + * excluding extension type and length bytes) * - * \param ctx The ECJPAKE context to use. This must be initialized - * and set up. - * \param buf The buffer holding the first round message. This must - * be a readable buffer of length \p len Bytes. - * \param len The length in Bytes of \p buf. + * \param ctx Context to use + * \param buf Pointer to extension contents + * \param len Extension length * - * \return \c 0 if successful. - * \return A negative error code on failure. + * \return 0 if successfull, + * a negative error code otherwise */ int mbedtls_ecjpake_read_round_one( mbedtls_ecjpake_context *ctx, const unsigned char *buf, @@ -187,21 +172,17 @@ int mbedtls_ecjpake_read_round_one( mbedtls_ecjpake_context *ctx, /** * \brief Generate and write the second round message - * (TLS: contents of the Client/ServerKeyExchange). + * (TLS: contents of the Client/ServerKeyExchange) * - * \param ctx The ECJPAKE context to use. This must be initialized, - * set up, and already have performed round one. - * \param buf The buffer to write the round two contents to. - * This must be a writable buffer of length \p len Bytes. - * \param len The size of \p buf in Bytes. - * \param olen The address at which to store the total number of Bytes - * written to \p buf. This must not be \c NULL. - * \param f_rng The RNG function to use. This must not be \c NULL. - * \param p_rng The RNG parameter to be passed to \p f_rng. This - * may be \c NULL if \p f_rng doesn't use a context. + * \param ctx Context to use + * \param buf Buffer to write the contents to + * \param len Buffer size + * \param olen Will be updated with the number of bytes written + * \param f_rng RNG function + * \param p_rng RNG parameter * - * \return \c 0 if successful. - * \return A negative error code on failure. + * \return 0 if successfull, + * a negative error code otherwise */ int mbedtls_ecjpake_write_round_two( mbedtls_ecjpake_context *ctx, unsigned char *buf, size_t len, size_t *olen, @@ -210,16 +191,14 @@ int mbedtls_ecjpake_write_round_two( mbedtls_ecjpake_context *ctx, /** * \brief Read and process the second round message - * (TLS: contents of the Client/ServerKeyExchange). + * (TLS: contents of the Client/ServerKeyExchange) * - * \param ctx The ECJPAKE context to use. This must be initialized - * and set up and already have performed round one. - * \param buf The buffer holding the second round message. This must - * be a readable buffer of length \p len Bytes. - * \param len The length in Bytes of \p buf. + * \param ctx Context to use + * \param buf Pointer to the message + * \param len Message length * - * \return \c 0 if successful. - * \return A negative error code on failure. + * \return 0 if successfull, + * a negative error code otherwise */ int mbedtls_ecjpake_read_round_two( mbedtls_ecjpake_context *ctx, const unsigned char *buf, @@ -227,21 +206,17 @@ int mbedtls_ecjpake_read_round_two( mbedtls_ecjpake_context *ctx, /** * \brief Derive the shared secret - * (TLS: Pre-Master Secret). + * (TLS: Pre-Master Secret) * - * \param ctx The ECJPAKE context to use. This must be initialized, - * set up and have performed both round one and two. - * \param buf The buffer to write the derived secret to. This must - * be a writable buffer of length \p len Bytes. - * \param len The length of \p buf in Bytes. - * \param olen The address at which to store the total number of Bytes - * written to \p buf. This must not be \c NULL. - * \param f_rng The RNG function to use. This must not be \c NULL. - * \param p_rng The RNG parameter to be passed to \p f_rng. This - * may be \c NULL if \p f_rng doesn't use a context. + * \param ctx Context to use + * \param buf Buffer to write the contents to + * \param len Buffer size + * \param olen Will be updated with the number of bytes written + * \param f_rng RNG function + * \param p_rng RNG parameter * - * \return \c 0 if successful. - * \return A negative error code on failure. + * \return 0 if successfull, + * a negative error code otherwise */ int mbedtls_ecjpake_derive_secret( mbedtls_ecjpake_context *ctx, unsigned char *buf, size_t len, size_t *olen, @@ -249,17 +224,26 @@ int mbedtls_ecjpake_derive_secret( mbedtls_ecjpake_context *ctx, void *p_rng ); /** - * \brief This clears an ECJPAKE context and frees any - * embedded data structure. + * \brief Free a context's content * - * \param ctx The ECJPAKE context to free. This may be \c NULL, - * in which case this function does nothing. If it is not - * \c NULL, it must point to an initialized ECJPAKE context. + * \param ctx context to free */ 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) +#ifdef __cplusplus +extern "C" { +#endif + /** * \brief Checkup routine * @@ -267,11 +251,10 @@ void mbedtls_ecjpake_free( mbedtls_ecjpake_context *ctx ); */ int mbedtls_ecjpake_self_test( int verbose ); -#endif /* MBEDTLS_SELF_TEST */ - #ifdef __cplusplus } #endif +#endif /* MBEDTLS_SELF_TEST */ #endif /* ecjpake.h */ diff --git a/APP_Framework/Framework/security/mbedtls/ecp.c b/APP_Framework/Framework/security/mbedtls/ecp.c index 2ae932913..1c8949de9 100644 --- a/APP_Framework/Framework/security/mbedtls/ecp.c +++ b/APP_Framework/Framework/security/mbedtls/ecp.c @@ -26,7 +26,6 @@ * GECC = Guide to Elliptic Curve Cryptography - Hankerson, Menezes, Vanstone * FIPS 186-3 http://csrc.nist.gov/publications/fips/fips186-3/fips_186-3.pdf * RFC 4492 for the related TLS structures and constants - * RFC 7748 for the Curve448 and Curve25519 curve definitions * * [Curve25519] http://cr.yp.to/ecdh/curve25519-20060209.pdf * @@ -47,52 +46,15 @@ #include MBEDTLS_CONFIG_FILE #endif -/** - * \brief Function level alternative implementation. - * - * The MBEDTLS_ECP_INTERNAL_ALT macro enables alternative implementations to - * replace certain functions in this module. The alternative implementations are - * typically hardware accelerators and need to activate the hardware before the - * computation starts and deactivate it after it finishes. The - * mbedtls_internal_ecp_init() and mbedtls_internal_ecp_free() functions serve - * this purpose. - * - * To preserve the correct functionality the following conditions must hold: - * - * - The alternative implementation must be activated by - * mbedtls_internal_ecp_init() before any of the replaceable functions is - * called. - * - mbedtls_internal_ecp_free() must \b only be called when the alternative - * implementation is activated. - * - mbedtls_internal_ecp_init() must \b not be called when the alternative - * implementation is activated. - * - Public functions must not return while the alternative implementation is - * activated. - * - Replaceable functions are guarded by \c MBEDTLS_ECP_XXX_ALT macros and - * before calling them an \code if( mbedtls_internal_ecp_grp_capable( grp ) ) - * \endcode ensures that the alternative implementation supports the current - * group. - */ -#if defined(MBEDTLS_ECP_INTERNAL_ALT) -#endif - #if defined(MBEDTLS_ECP_C) #include "ecp.h" #include "threading.h" -#include "platform_util.h" -#include #include #if !defined(MBEDTLS_ECP_ALT) -/* Parameter validation macros based on platform_util.h */ -#define ECP_VALIDATE_RET( cond ) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA ) -#define ECP_VALIDATE( cond ) \ - MBEDTLS_INTERNAL_VALIDATE( cond ) - #if defined(MBEDTLS_PLATFORM_C) #include "platform.h" #else @@ -110,6 +72,11 @@ #define inline __inline #endif +/* 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; +} + #if defined(MBEDTLS_SELF_TEST) /* * Counts of point addition and doubling, and field multiplications. @@ -118,233 +85,6 @@ static unsigned long add_count, dbl_count, mul_count; #endif -#if defined(MBEDTLS_ECP_RESTARTABLE) -/* - * Maximum number of "basic operations" to be done in a row. - * - * Default value 0 means that ECC operations will not yield. - * Note that regardless of the value of ecp_max_ops, always at - * least one step is performed before yielding. - * - * Setting ecp_max_ops=1 can be suitable for testing purposes - * as it will interrupt computation at all possible points. - */ -static unsigned ecp_max_ops = 0; - -/* - * Set ecp_max_ops - */ -void mbedtls_ecp_set_max_ops( unsigned max_ops ) -{ - ecp_max_ops = max_ops; -} - -/* - * Check if restart is enabled - */ -int mbedtls_ecp_restart_is_enabled( void ) -{ - return( ecp_max_ops != 0 ); -} - -/* - * Restart sub-context for ecp_mul_comb() - */ -struct mbedtls_ecp_restart_mul -{ - mbedtls_ecp_point R; /* current intermediate result */ - size_t i; /* current index in various loops, 0 outside */ - mbedtls_ecp_point *T; /* table for precomputed points */ - unsigned char T_size; /* number of points in table T */ - enum { /* what were we doing last time we returned? */ - ecp_rsm_init = 0, /* nothing so far, dummy initial state */ - ecp_rsm_pre_dbl, /* precompute 2^n multiples */ - ecp_rsm_pre_norm_dbl, /* normalize precomputed 2^n multiples */ - ecp_rsm_pre_add, /* precompute remaining points by adding */ - ecp_rsm_pre_norm_add, /* normalize all precomputed points */ - ecp_rsm_comb_core, /* ecp_mul_comb_core() */ - ecp_rsm_final_norm, /* do the final normalization */ - } state; -}; - -/* - * Init restart_mul sub-context - */ -static void ecp_restart_rsm_init( mbedtls_ecp_restart_mul_ctx *ctx ) -{ - mbedtls_ecp_point_init( &ctx->R ); - ctx->i = 0; - ctx->T = NULL; - ctx->T_size = 0; - ctx->state = ecp_rsm_init; -} - -/* - * Free the components of a restart_mul sub-context - */ -static void ecp_restart_rsm_free( mbedtls_ecp_restart_mul_ctx *ctx ) -{ - uint_fast8_t i; - - if( ctx == NULL ) - return; - - mbedtls_ecp_point_free( &ctx->R ); - - if( ctx->T != NULL ) - { - for( i = 0; i < ctx->T_size; i++ ) - mbedtls_ecp_point_free( ctx->T + i ); - mbedtls_free( ctx->T ); - } - - ecp_restart_rsm_init( ctx ); -} - -/* - * Restart context for ecp_muladd() - */ -struct mbedtls_ecp_restart_muladd -{ - mbedtls_ecp_point mP; /* mP value */ - mbedtls_ecp_point R; /* R intermediate result */ - enum { /* what should we do next? */ - ecp_rsma_mul1 = 0, /* first multiplication */ - ecp_rsma_mul2, /* second multiplication */ - ecp_rsma_add, /* addition */ - ecp_rsma_norm, /* normalization */ - } state; -}; - -/* - * Init restart_muladd sub-context - */ -static void ecp_restart_ma_init( mbedtls_ecp_restart_muladd_ctx *ctx ) -{ - mbedtls_ecp_point_init( &ctx->mP ); - mbedtls_ecp_point_init( &ctx->R ); - ctx->state = ecp_rsma_mul1; -} - -/* - * Free the components of a restart_muladd sub-context - */ -static void ecp_restart_ma_free( mbedtls_ecp_restart_muladd_ctx *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_ecp_point_free( &ctx->mP ); - mbedtls_ecp_point_free( &ctx->R ); - - ecp_restart_ma_init( ctx ); -} - -/* - * Initialize a restart context - */ -void mbedtls_ecp_restart_init( mbedtls_ecp_restart_ctx *ctx ) -{ - ECP_VALIDATE( ctx != NULL ); - ctx->ops_done = 0; - ctx->depth = 0; - ctx->rsm = NULL; - ctx->ma = NULL; -} - -/* - * Free the components of a restart context - */ -void mbedtls_ecp_restart_free( mbedtls_ecp_restart_ctx *ctx ) -{ - if( ctx == NULL ) - return; - - ecp_restart_rsm_free( ctx->rsm ); - mbedtls_free( ctx->rsm ); - - ecp_restart_ma_free( ctx->ma ); - mbedtls_free( ctx->ma ); - - mbedtls_ecp_restart_init( ctx ); -} - -/* - * Check if we can do the next step - */ -int mbedtls_ecp_check_budget( const mbedtls_ecp_group *grp, - mbedtls_ecp_restart_ctx *rs_ctx, - unsigned ops ) -{ - ECP_VALIDATE_RET( grp != NULL ); - - if( rs_ctx != NULL && ecp_max_ops != 0 ) - { - /* scale depending on curve size: the chosen reference is 256-bit, - * and multiplication is quadratic. Round to the closest integer. */ - if( grp->pbits >= 512 ) - ops *= 4; - else if( grp->pbits >= 384 ) - ops *= 2; - - /* Avoid infinite loops: always allow first step. - * Because of that, however, it's not generally true - * that ops_done <= ecp_max_ops, so the check - * ops_done > ecp_max_ops below is mandatory. */ - if( ( rs_ctx->ops_done != 0 ) && - ( rs_ctx->ops_done > ecp_max_ops || - ops > ecp_max_ops - rs_ctx->ops_done ) ) - { - return( MBEDTLS_ERR_ECP_IN_PROGRESS ); - } - - /* update running count */ - rs_ctx->ops_done += ops; - } - - return( 0 ); -} - -/* Call this when entering a function that needs its own sub-context */ -#define ECP_RS_ENTER( SUB ) do { \ - /* reset ops count for this call if top-level */ \ - if( rs_ctx != NULL && rs_ctx->depth++ == 0 ) \ - rs_ctx->ops_done = 0; \ - \ - /* set up our own sub-context if needed */ \ - if( mbedtls_ecp_restart_is_enabled() && \ - rs_ctx != NULL && rs_ctx->SUB == NULL ) \ - { \ - rs_ctx->SUB = mbedtls_calloc( 1, sizeof( *rs_ctx->SUB ) ); \ - if( rs_ctx->SUB == NULL ) \ - return( MBEDTLS_ERR_ECP_ALLOC_FAILED ); \ - \ - ecp_restart_## SUB ##_init( rs_ctx->SUB ); \ - } \ -} while( 0 ) - -/* Call this when leaving a function that needs its own sub-context */ -#define ECP_RS_LEAVE( SUB ) do { \ - /* clear our sub-context when not in progress (done or error) */ \ - if( rs_ctx != NULL && rs_ctx->SUB != NULL && \ - ret != MBEDTLS_ERR_ECP_IN_PROGRESS ) \ - { \ - ecp_restart_## SUB ##_free( rs_ctx->SUB ); \ - mbedtls_free( rs_ctx->SUB ); \ - rs_ctx->SUB = NULL; \ - } \ - \ - if( rs_ctx != NULL ) \ - rs_ctx->depth--; \ -} while( 0 ) - -#else /* MBEDTLS_ECP_RESTARTABLE */ - -#define ECP_RS_ENTER( sub ) (void) rs_ctx; -#define ECP_RS_LEAVE( sub ) (void) rs_ctx; - -#endif /* MBEDTLS_ECP_RESTARTABLE */ - #if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) || \ defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \ defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \ @@ -359,8 +99,7 @@ int mbedtls_ecp_check_budget( const mbedtls_ecp_group *grp, #define ECP_SHORTWEIERSTRASS #endif -#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) || \ - defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) +#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) #define ECP_MONTGOMERY #endif @@ -506,9 +245,6 @@ const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_name( const char *name { const mbedtls_ecp_curve_info *curve_info; - if( name == NULL ) - return( NULL ); - for( curve_info = mbedtls_ecp_curve_list(); curve_info->grp_id != MBEDTLS_ECP_DP_NONE; curve_info++ ) @@ -539,7 +275,8 @@ static inline ecp_curve_type ecp_get_type( const mbedtls_ecp_group *grp ) */ void mbedtls_ecp_point_init( mbedtls_ecp_point *pt ) { - ECP_VALIDATE( pt != NULL ); + if( pt == NULL ) + return; mbedtls_mpi_init( &pt->X ); mbedtls_mpi_init( &pt->Y ); @@ -551,23 +288,10 @@ void mbedtls_ecp_point_init( mbedtls_ecp_point *pt ) */ void mbedtls_ecp_group_init( mbedtls_ecp_group *grp ) { - ECP_VALIDATE( grp != NULL ); + if( grp == NULL ) + return; - grp->id = MBEDTLS_ECP_DP_NONE; - mbedtls_mpi_init( &grp->P ); - mbedtls_mpi_init( &grp->A ); - mbedtls_mpi_init( &grp->B ); - mbedtls_ecp_point_init( &grp->G ); - mbedtls_mpi_init( &grp->N ); - grp->pbits = 0; - grp->nbits = 0; - grp->h = 0; - grp->modp = NULL; - grp->t_pre = NULL; - grp->t_post = NULL; - grp->t_data = NULL; - grp->T = NULL; - grp->T_size = 0; + memset( grp, 0, sizeof( mbedtls_ecp_group ) ); } /* @@ -575,7 +299,8 @@ void mbedtls_ecp_group_init( mbedtls_ecp_group *grp ) */ void mbedtls_ecp_keypair_init( mbedtls_ecp_keypair *key ) { - ECP_VALIDATE( key != NULL ); + if( key == NULL ) + return; mbedtls_ecp_group_init( &key->grp ); mbedtls_mpi_init( &key->d ); @@ -621,7 +346,7 @@ void mbedtls_ecp_group_free( mbedtls_ecp_group *grp ) mbedtls_free( grp->T ); } - mbedtls_platform_zeroize( grp, sizeof( mbedtls_ecp_group ) ); + mbedtls_zeroize( grp, sizeof( mbedtls_ecp_group ) ); } /* @@ -643,8 +368,6 @@ void mbedtls_ecp_keypair_free( mbedtls_ecp_keypair *key ) int mbedtls_ecp_copy( mbedtls_ecp_point *P, const mbedtls_ecp_point *Q ) { int ret; - ECP_VALIDATE_RET( P != NULL ); - ECP_VALIDATE_RET( Q != NULL ); MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &P->X, &Q->X ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &P->Y, &Q->Y ) ); @@ -659,10 +382,7 @@ cleanup: */ int mbedtls_ecp_group_copy( mbedtls_ecp_group *dst, const mbedtls_ecp_group *src ) { - ECP_VALIDATE_RET( dst != NULL ); - ECP_VALIDATE_RET( src != NULL ); - - return( mbedtls_ecp_group_load( dst, src->id ) ); + return mbedtls_ecp_group_load( dst, src->id ); } /* @@ -671,7 +391,6 @@ int mbedtls_ecp_group_copy( mbedtls_ecp_group *dst, const mbedtls_ecp_group *src int mbedtls_ecp_set_zero( mbedtls_ecp_point *pt ) { int ret; - ECP_VALIDATE_RET( pt != NULL ); MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->X , 1 ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->Y , 1 ) ); @@ -686,8 +405,6 @@ cleanup: */ int mbedtls_ecp_is_zero( mbedtls_ecp_point *pt ) { - ECP_VALIDATE_RET( pt != NULL ); - return( mbedtls_mpi_cmp_int( &pt->Z, 0 ) == 0 ); } @@ -697,9 +414,6 @@ int mbedtls_ecp_is_zero( mbedtls_ecp_point *pt ) int mbedtls_ecp_point_cmp( const mbedtls_ecp_point *P, const mbedtls_ecp_point *Q ) { - ECP_VALIDATE_RET( P != NULL ); - ECP_VALIDATE_RET( Q != NULL ); - if( mbedtls_mpi_cmp_mpi( &P->X, &Q->X ) == 0 && mbedtls_mpi_cmp_mpi( &P->Y, &Q->Y ) == 0 && mbedtls_mpi_cmp_mpi( &P->Z, &Q->Z ) == 0 ) @@ -717,9 +431,6 @@ int mbedtls_ecp_point_read_string( mbedtls_ecp_point *P, int radix, const char *x, const char *y ) { int ret; - ECP_VALIDATE_RET( P != NULL ); - ECP_VALIDATE_RET( x != NULL ); - ECP_VALIDATE_RET( y != NULL ); MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &P->X, radix, x ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &P->Y, radix, y ) ); @@ -732,19 +443,16 @@ cleanup: /* * Export a point into unsigned binary data (SEC1 2.3.3) */ -int mbedtls_ecp_point_write_binary( const mbedtls_ecp_group *grp, - const mbedtls_ecp_point *P, - int format, size_t *olen, - unsigned char *buf, size_t buflen ) +int mbedtls_ecp_point_write_binary( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *P, + int format, size_t *olen, + unsigned char *buf, size_t buflen ) { int ret = 0; size_t plen; - ECP_VALIDATE_RET( grp != NULL ); - ECP_VALIDATE_RET( P != NULL ); - ECP_VALIDATE_RET( olen != NULL ); - ECP_VALIDATE_RET( buf != NULL ); - ECP_VALIDATE_RET( format == MBEDTLS_ECP_PF_UNCOMPRESSED || - format == MBEDTLS_ECP_PF_COMPRESSED ); + + if( format != MBEDTLS_ECP_PF_UNCOMPRESSED && + format != MBEDTLS_ECP_PF_COMPRESSED ) + return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); /* * Common case: P == 0 @@ -791,15 +499,11 @@ cleanup: /* * Import a point from unsigned binary data (SEC1 2.3.4) */ -int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp, - mbedtls_ecp_point *pt, - const unsigned char *buf, size_t ilen ) +int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp, mbedtls_ecp_point *pt, + const unsigned char *buf, size_t ilen ) { int ret; size_t plen; - ECP_VALIDATE_RET( grp != NULL ); - ECP_VALIDATE_RET( pt != NULL ); - ECP_VALIDATE_RET( buf != NULL ); if( ilen < 1 ) return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); @@ -834,16 +538,11 @@ cleanup: * opaque point <1..2^8-1>; * } ECPoint; */ -int mbedtls_ecp_tls_read_point( const mbedtls_ecp_group *grp, - mbedtls_ecp_point *pt, - const unsigned char **buf, size_t buf_len ) +int mbedtls_ecp_tls_read_point( const mbedtls_ecp_group *grp, mbedtls_ecp_point *pt, + const unsigned char **buf, size_t buf_len ) { unsigned char data_len; const unsigned char *buf_start; - ECP_VALIDATE_RET( grp != NULL ); - ECP_VALIDATE_RET( pt != NULL ); - ECP_VALIDATE_RET( buf != NULL ); - ECP_VALIDATE_RET( *buf != NULL ); /* * We must have at least two bytes (1 for length, at least one for data) @@ -861,7 +560,7 @@ int mbedtls_ecp_tls_read_point( const mbedtls_ecp_group *grp, buf_start = *buf; *buf += data_len; - return( mbedtls_ecp_point_read_binary( grp, pt, buf_start, data_len ) ); + return mbedtls_ecp_point_read_binary( grp, pt, buf_start, data_len ); } /* @@ -875,12 +574,6 @@ int mbedtls_ecp_tls_write_point( const mbedtls_ecp_group *grp, const mbedtls_ecp unsigned char *buf, size_t blen ) { int ret; - ECP_VALIDATE_RET( grp != NULL ); - ECP_VALIDATE_RET( pt != NULL ); - ECP_VALIDATE_RET( olen != NULL ); - ECP_VALIDATE_RET( buf != NULL ); - ECP_VALIDATE_RET( format == MBEDTLS_ECP_PF_UNCOMPRESSED || - format == MBEDTLS_ECP_PF_COMPRESSED ); /* * buffer length must be at least one, for our length byte @@ -904,33 +597,10 @@ int mbedtls_ecp_tls_write_point( const mbedtls_ecp_group *grp, const mbedtls_ecp /* * Set a group from an ECParameters record (RFC 4492) */ -int mbedtls_ecp_tls_read_group( mbedtls_ecp_group *grp, - const unsigned char **buf, size_t len ) -{ - int ret; - mbedtls_ecp_group_id grp_id; - ECP_VALIDATE_RET( grp != NULL ); - ECP_VALIDATE_RET( buf != NULL ); - ECP_VALIDATE_RET( *buf != NULL ); - - if( ( ret = mbedtls_ecp_tls_read_group_id( &grp_id, buf, len ) ) != 0 ) - return( ret ); - - return( mbedtls_ecp_group_load( grp, grp_id ) ); -} - -/* - * Read a group id from an ECParameters record (RFC 4492) and convert it to - * mbedtls_ecp_group_id. - */ -int mbedtls_ecp_tls_read_group_id( mbedtls_ecp_group_id *grp, - const unsigned char **buf, size_t len ) +int mbedtls_ecp_tls_read_group( mbedtls_ecp_group *grp, const unsigned char **buf, size_t len ) { uint16_t tls_id; const mbedtls_ecp_curve_info *curve_info; - ECP_VALIDATE_RET( grp != NULL ); - ECP_VALIDATE_RET( buf != NULL ); - ECP_VALIDATE_RET( *buf != NULL ); /* * We expect at least three bytes (see below) @@ -954,9 +624,7 @@ int mbedtls_ecp_tls_read_group_id( mbedtls_ecp_group_id *grp, if( ( curve_info = mbedtls_ecp_curve_info_from_tls_id( tls_id ) ) == NULL ) return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE ); - *grp = curve_info->grp_id; - - return( 0 ); + return mbedtls_ecp_group_load( grp, curve_info->grp_id ); } /* @@ -966,9 +634,6 @@ int mbedtls_ecp_tls_write_group( const mbedtls_ecp_group *grp, size_t *olen, unsigned char *buf, size_t blen ) { const mbedtls_ecp_curve_info *curve_info; - ECP_VALIDATE_RET( grp != NULL ); - ECP_VALIDATE_RET( buf != NULL ); - ECP_VALIDATE_RET( olen != NULL ); if( ( curve_info = mbedtls_ecp_curve_info_from_grp_id( grp->id ) ) == NULL ) return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); @@ -1047,29 +712,25 @@ cleanup: #define INC_MUL_COUNT #endif -#define MOD_MUL( N ) \ - do \ - { \ - MBEDTLS_MPI_CHK( ecp_modp( &(N), grp ) ); \ - INC_MUL_COUNT \ - } while( 0 ) +#define MOD_MUL( N ) do { MBEDTLS_MPI_CHK( ecp_modp( &N, grp ) ); INC_MUL_COUNT } \ + while( 0 ) /* * Reduce a mbedtls_mpi mod p in-place, to use after mbedtls_mpi_sub_mpi * N->s < 0 is a very fast test, which fails only if N is 0 */ -#define MOD_SUB( N ) \ - while( (N).s < 0 && mbedtls_mpi_cmp_int( &(N), 0 ) != 0 ) \ - MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &(N), &(N), &grp->P ) ) +#define MOD_SUB( N ) \ + while( N.s < 0 && mbedtls_mpi_cmp_int( &N, 0 ) != 0 ) \ + MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &N, &N, &grp->P ) ) /* * Reduce a mbedtls_mpi mod p in-place, to use after mbedtls_mpi_add_mpi and mbedtls_mpi_mul_int. * We known P, N and the result are positive, so sub_abs is correct, and * a bit faster. */ -#define MOD_ADD( N ) \ - while( mbedtls_mpi_cmp_mpi( &(N), &grp->P ) >= 0 ) \ - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( &(N), &(N), &grp->P ) ) +#define MOD_ADD( N ) \ + while( mbedtls_mpi_cmp_mpi( &N, &grp->P ) >= 0 ) \ + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( &N, &N, &grp->P ) ) #if defined(ECP_SHORTWEIERSTRASS) /* @@ -1093,10 +754,11 @@ static int ecp_normalize_jac( const mbedtls_ecp_group *grp, mbedtls_ecp_point *p return( 0 ); #if defined(MBEDTLS_ECP_NORMALIZE_JAC_ALT) - if( mbedtls_internal_ecp_grp_capable( grp ) ) - return( mbedtls_internal_ecp_normalize_jac( grp, pt ) ); + if ( mbedtls_internal_ecp_grp_capable( grp ) ) + { + return mbedtls_internal_ecp_normalize_jac( grp, pt ); + } #endif /* MBEDTLS_ECP_NORMALIZE_JAC_ALT */ - mbedtls_mpi_init( &Zi ); mbedtls_mpi_init( &ZZi ); /* @@ -1136,33 +798,32 @@ cleanup: * Cost: 1N(t) := 1I + (6t - 3)M + 1S */ static int ecp_normalize_jac_many( const mbedtls_ecp_group *grp, - mbedtls_ecp_point *T[], size_t T_size ) + mbedtls_ecp_point *T[], size_t t_len ) { int ret; size_t i; mbedtls_mpi *c, u, Zi, ZZi; - if( T_size < 2 ) + if( t_len < 2 ) return( ecp_normalize_jac( grp, *T ) ); #if defined(MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT) - if( mbedtls_internal_ecp_grp_capable( grp ) ) - return( mbedtls_internal_ecp_normalize_jac_many( grp, T, T_size ) ); + if ( mbedtls_internal_ecp_grp_capable( grp ) ) + { + return mbedtls_internal_ecp_normalize_jac_many(grp, T, t_len); + } #endif - if( ( c = mbedtls_calloc( T_size, sizeof( mbedtls_mpi ) ) ) == NULL ) + if( ( c = mbedtls_calloc( t_len, sizeof( mbedtls_mpi ) ) ) == NULL ) return( MBEDTLS_ERR_ECP_ALLOC_FAILED ); - for( i = 0; i < T_size; i++ ) - mbedtls_mpi_init( &c[i] ); - mbedtls_mpi_init( &u ); mbedtls_mpi_init( &Zi ); mbedtls_mpi_init( &ZZi ); /* * c[i] = Z_0 * ... * Z_i */ MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &c[0], &T[0]->Z ) ); - for( i = 1; i < T_size; i++ ) + for( i = 1; i < t_len; i++ ) { MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &c[i], &c[i-1], &T[i]->Z ) ); MOD_MUL( c[i] ); @@ -1171,9 +832,9 @@ static int ecp_normalize_jac_many( const mbedtls_ecp_group *grp, /* * u = 1 / (Z_0 * ... * Z_n) mod P */ - MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &u, &c[T_size-1], &grp->P ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &u, &c[t_len-1], &grp->P ) ); - for( i = T_size - 1; ; i-- ) + for( i = t_len - 1; ; i-- ) { /* * Zi = 1 / Z_i mod p @@ -1213,7 +874,7 @@ static int ecp_normalize_jac_many( const mbedtls_ecp_group *grp, cleanup: mbedtls_mpi_free( &u ); mbedtls_mpi_free( &Zi ); mbedtls_mpi_free( &ZZi ); - for( i = 0; i < T_size; i++ ) + for( i = 0; i < t_len; i++ ) mbedtls_mpi_free( &c[i] ); mbedtls_free( c ); @@ -1270,8 +931,10 @@ static int ecp_double_jac( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R, #endif #if defined(MBEDTLS_ECP_DOUBLE_JAC_ALT) - if( mbedtls_internal_ecp_grp_capable( grp ) ) - return( mbedtls_internal_ecp_double_jac( grp, R, P ) ); + if ( mbedtls_internal_ecp_grp_capable( grp ) ) + { + return mbedtls_internal_ecp_double_jac( grp, R, P ); + } #endif /* MBEDTLS_ECP_DOUBLE_JAC_ALT */ mbedtls_mpi_init( &M ); mbedtls_mpi_init( &S ); mbedtls_mpi_init( &T ); mbedtls_mpi_init( &U ); @@ -1366,8 +1029,10 @@ static int ecp_add_mixed( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R, #endif #if defined(MBEDTLS_ECP_ADD_MIXED_ALT) - if( mbedtls_internal_ecp_grp_capable( grp ) ) - return( mbedtls_internal_ecp_add_mixed( grp, R, P, Q ) ); + if ( mbedtls_internal_ecp_grp_capable( grp ) ) + { + return mbedtls_internal_ecp_add_mixed( grp, R, P, Q ); + } #endif /* MBEDTLS_ECP_ADD_MIXED_ALT */ /* @@ -1451,8 +1116,10 @@ static int ecp_randomize_jac( const mbedtls_ecp_group *grp, mbedtls_ecp_point *p int count = 0; #if defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT) - if( mbedtls_internal_ecp_grp_capable( grp ) ) - return( mbedtls_internal_ecp_randomize_jac( grp, pt, f_rng, p_rng ) ); + if ( mbedtls_internal_ecp_grp_capable( grp ) ) + { + return mbedtls_internal_ecp_randomize_jac( grp, pt, f_rng, p_rng ); + } #endif /* MBEDTLS_ECP_RANDOMIZE_JAC_ALT */ p_size = ( grp->pbits + 7 ) / 8; @@ -1508,38 +1175,11 @@ cleanup: * modified version that provides resistance to SPA by avoiding zero * digits in the representation as in [3]. We modify the method further by * requiring that all K_i be odd, which has the small cost that our - * representation uses one more K_i, due to carries, but saves on the size of - * the precomputed table. + * representation uses one more K_i, due to carries. * - * Summary of the comb method and its modifications: - * - * - The goal is to compute m*P for some w*d-bit integer m. - * - * - The basic comb method splits m into the w-bit integers - * x[0] .. x[d-1] where x[i] consists of the bits in m whose - * index has residue i modulo d, and computes m * P as - * S[x[0]] + 2 * S[x[1]] + .. + 2^(d-1) S[x[d-1]], where - * S[i_{w-1} .. i_0] := i_{w-1} 2^{(w-1)d} P + ... + i_1 2^d P + i_0 P. - * - * - If it happens that, say, x[i+1]=0 (=> S[x[i+1]]=0), one can replace the sum by - * .. + 2^{i-1} S[x[i-1]] - 2^i S[x[i]] + 2^{i+1} S[x[i]] + 2^{i+2} S[x[i+2]] .., - * thereby successively converting it into a form where all summands - * are nonzero, at the cost of negative summands. This is the basic idea of [3]. - * - * - More generally, even if x[i+1] != 0, we can first transform the sum as - * .. - 2^i S[x[i]] + 2^{i+1} ( S[x[i]] + S[x[i+1]] ) + 2^{i+2} S[x[i+2]] .., - * and then replace S[x[i]] + S[x[i+1]] = S[x[i] ^ x[i+1]] + 2 S[x[i] & x[i+1]]. - * Performing and iterating this procedure for those x[i] that are even - * (keeping track of carry), we can transform the original sum into one of the form - * S[x'[0]] +- 2 S[x'[1]] +- .. +- 2^{d-1} S[x'[d-1]] + 2^d S[x'[d]] - * with all x'[i] odd. It is therefore only necessary to know S at odd indices, - * which is why we are only computing half of it in the first place in - * ecp_precompute_comb and accessing it with index abs(i) / 2 in ecp_select_comb. - * - * - For the sake of compactness, only the seven low-order bits of x[i] - * are used to represent its absolute value (K_i in the paper), and the msb - * of x[i] encodes the sign (s_i in the paper): it is set if and only if - * if s_i == -1; + * Also, for the sake of compactness, only the seven low-order bits of x[i] + * are used to represent K_i, and the msb of x[i] encodes the the sign (s_i in + * the paper): it is set if and only if if s_i == -1; * * Calling conventions: * - x is an array of size d + 1 @@ -1548,13 +1188,13 @@ cleanup: * - m is the MPI, expected to be odd and such that bitlength(m) <= w * d * (the result will be incorrect if these assumptions are not satisfied) */ -static void ecp_comb_recode_core( unsigned char x[], size_t d, - unsigned char w, const mbedtls_mpi *m ) +static void ecp_comb_fixed( unsigned char x[], size_t d, + unsigned char w, const mbedtls_mpi *m ) { size_t i, j; unsigned char c, cc, adjust; - mbedtls_platform_memset( x, 0, d+1 ); + memset( x, 0, d+1 ); /* First get the classical comb values (except for x_d = 0) */ for( i = 0; i < d; i++ ) @@ -1579,188 +1219,80 @@ static void ecp_comb_recode_core( unsigned char x[], size_t d, } /* - * Precompute points for the adapted comb method + * Precompute points for the comb method * - * Assumption: T must be able to hold 2^{w - 1} elements. + * If i = i_{w-1} ... i_1 is the binary representation of i, then + * T[i] = i_{w-1} 2^{(w-1)d} P + ... + i_1 2^d P + P * - * Operation: If i = i_{w-1} ... i_1 is the binary representation of i, - * sets T[i] = i_{w-1} 2^{(w-1)d} P + ... + i_1 2^d P + P. + * T must be able to hold 2^{w - 1} elements * * Cost: d(w-1) D + (2^{w-1} - 1) A + 1 N(w-1) + 1 N(2^{w-1} - 1) - * - * Note: Even comb values (those where P would be omitted from the - * sum defining T[i] above) are not needed in our adaption - * the comb method. See ecp_comb_recode_core(). - * - * This function currently works in four steps: - * (1) [dbl] Computation of intermediate T[i] for 2-power values of i - * (2) [norm_dbl] Normalization of coordinates of these T[i] - * (3) [add] Computation of all T[i] - * (4) [norm_add] Normalization of all T[i] - * - * Step 1 can be interrupted but not the others; together with the final - * coordinate normalization they are the largest steps done at once, depending - * on the window size. Here are operation counts for P-256: - * - * step (2) (3) (4) - * w = 5 142 165 208 - * w = 4 136 77 160 - * w = 3 130 33 136 - * w = 2 124 11 124 - * - * So if ECC operations are blocking for too long even with a low max_ops - * value, it's useful to set MBEDTLS_ECP_WINDOW_SIZE to a lower value in order - * to minimize maximum blocking time. */ static int ecp_precompute_comb( const mbedtls_ecp_group *grp, mbedtls_ecp_point T[], const mbedtls_ecp_point *P, - unsigned char w, size_t d, - mbedtls_ecp_restart_ctx *rs_ctx ) + unsigned char w, size_t d ) { int ret; - unsigned char i; - size_t j = 0; - const unsigned char T_size = 1U << ( w - 1 ); + unsigned char i, k; + size_t j; mbedtls_ecp_point *cur, *TT[COMB_MAX_PRE - 1]; -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->rsm != NULL ) - { - if( rs_ctx->rsm->state == ecp_rsm_pre_dbl ) - goto dbl; - if( rs_ctx->rsm->state == ecp_rsm_pre_norm_dbl ) - goto norm_dbl; - if( rs_ctx->rsm->state == ecp_rsm_pre_add ) - goto add; - if( rs_ctx->rsm->state == ecp_rsm_pre_norm_add ) - goto norm_add; - } -#else - (void) rs_ctx; -#endif - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->rsm != NULL ) - { - rs_ctx->rsm->state = ecp_rsm_pre_dbl; - - /* initial state for the loop */ - rs_ctx->rsm->i = 0; - } - -dbl: -#endif /* * Set T[0] = P and * T[2^{l-1}] = 2^{dl} P for l = 1 .. w-1 (this is not the final value) */ MBEDTLS_MPI_CHK( mbedtls_ecp_copy( &T[0], P ) ); -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->rsm != NULL && rs_ctx->rsm->i != 0 ) - j = rs_ctx->rsm->i; - else -#endif - j = 0; - - for( ; j < d * ( w - 1 ); j++ ) + k = 0; + for( i = 1; i < ( 1U << ( w - 1 ) ); i <<= 1 ) { - MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_DBL ); - - i = 1U << ( j / d ); cur = T + i; + MBEDTLS_MPI_CHK( mbedtls_ecp_copy( cur, T + ( i >> 1 ) ) ); + for( j = 0; j < d; j++ ) + MBEDTLS_MPI_CHK( ecp_double_jac( grp, cur, cur ) ); - if( j % d == 0 ) - MBEDTLS_MPI_CHK( mbedtls_ecp_copy( cur, T + ( i >> 1 ) ) ); - - MBEDTLS_MPI_CHK( ecp_double_jac( grp, cur, cur ) ); + TT[k++] = cur; } -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->rsm != NULL ) - rs_ctx->rsm->state = ecp_rsm_pre_norm_dbl; + MBEDTLS_MPI_CHK( ecp_normalize_jac_many( grp, TT, k ) ); -norm_dbl: -#endif - /* - * Normalize current elements in T. As T has holes, - * use an auxiliary array of pointers to elements in T. - */ - j = 0; - for( i = 1; i < T_size; i <<= 1 ) - TT[j++] = T + i; - - MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_INV + 6 * j - 2 ); - - MBEDTLS_MPI_CHK( ecp_normalize_jac_many( grp, TT, j ) ); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->rsm != NULL ) - rs_ctx->rsm->state = ecp_rsm_pre_add; - -add: -#endif /* * Compute the remaining ones using the minimal number of additions * Be careful to update T[2^l] only after using it! */ - MBEDTLS_ECP_BUDGET( ( T_size - 1 ) * MBEDTLS_ECP_OPS_ADD ); - - for( i = 1; i < T_size; i <<= 1 ) + k = 0; + for( i = 1; i < ( 1U << ( w - 1 ) ); i <<= 1 ) { j = i; while( j-- ) + { MBEDTLS_MPI_CHK( ecp_add_mixed( grp, &T[i + j], &T[j], &T[i] ) ); + TT[k++] = &T[i + j]; + } } -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->rsm != NULL ) - rs_ctx->rsm->state = ecp_rsm_pre_norm_add; - -norm_add: -#endif - /* - * Normalize final elements in T. Even though there are no holes now, we - * still need the auxiliary array for homogeneity with the previous - * call. Also, skip T[0] which is already normalised, being a copy of P. - */ - for( j = 0; j + 1 < T_size; j++ ) - TT[j] = T + j + 1; - - MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_INV + 6 * j - 2 ); - - MBEDTLS_MPI_CHK( ecp_normalize_jac_many( grp, TT, j ) ); + MBEDTLS_MPI_CHK( ecp_normalize_jac_many( grp, TT, k ) ); cleanup: -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->rsm != NULL && - ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) - { - if( rs_ctx->rsm->state == ecp_rsm_pre_dbl ) - rs_ctx->rsm->i = j; - } -#endif return( ret ); } /* * Select precomputed point: R = sign(i) * T[ abs(i) / 2 ] - * - * See ecp_comb_recode_core() for background */ static int ecp_select_comb( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R, - const mbedtls_ecp_point T[], unsigned char T_size, + const mbedtls_ecp_point T[], unsigned char t_len, unsigned char i ) { int ret; - uint_fast8_t ii, j; + unsigned char ii, j; /* Ignore the "sign" bit and scale down */ ii = ( i & 0x7Fu ) >> 1; /* Read the whole table to thwart cache-based timing attacks */ - for( j = 0; j < T_size; j++ ) + for( j = 0; j < t_len; j++ ) { MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_assign( &R->X, &T[j].X, j == ii ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_assign( &R->Y, &T[j].Y, j == ii ) ); @@ -1780,11 +1312,10 @@ cleanup: * Cost: d A + d D + 1 R */ static int ecp_mul_comb_core( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R, - const mbedtls_ecp_point T[], unsigned char T_size, + const mbedtls_ecp_point T[], unsigned char t_len, const unsigned char x[], size_t d, int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - mbedtls_ecp_restart_ctx *rs_ctx ) + void *p_rng ) { int ret; mbedtls_ecp_point Txi; @@ -1792,42 +1323,17 @@ static int ecp_mul_comb_core( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R mbedtls_ecp_point_init( &Txi ); -#if !defined(MBEDTLS_ECP_RESTARTABLE) - (void) rs_ctx; -#endif + /* Start with a non-zero point and randomize its coordinates */ + i = d; + MBEDTLS_MPI_CHK( ecp_select_comb( grp, R, T, t_len, x[i] ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &R->Z, 1 ) ); + if( f_rng != 0 ) + MBEDTLS_MPI_CHK( ecp_randomize_jac( grp, R, f_rng, p_rng ) ); -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->rsm != NULL && - rs_ctx->rsm->state != ecp_rsm_comb_core ) + while( i-- != 0 ) { - rs_ctx->rsm->i = 0; - rs_ctx->rsm->state = ecp_rsm_comb_core; - } - - /* new 'if' instead of nested for the sake of the 'else' branch */ - if( rs_ctx != NULL && rs_ctx->rsm != NULL && rs_ctx->rsm->i != 0 ) - { - /* restore current index (R already pointing to rs_ctx->rsm->R) */ - i = rs_ctx->rsm->i; - } - else -#endif - { - /* Start with a non-zero point and randomize its coordinates */ - i = d; - MBEDTLS_MPI_CHK( ecp_select_comb( grp, R, T, T_size, x[i] ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &R->Z, 1 ) ); - if( f_rng != 0 ) - MBEDTLS_MPI_CHK( ecp_randomize_jac( grp, R, f_rng, p_rng ) ); - } - - while( i != 0 ) - { - MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_DBL + MBEDTLS_ECP_OPS_ADD ); - --i; - MBEDTLS_MPI_CHK( ecp_double_jac( grp, R, R ) ); - MBEDTLS_MPI_CHK( ecp_select_comb( grp, &Txi, T, T_size, x[i] ) ); + MBEDTLS_MPI_CHK( ecp_select_comb( grp, &Txi, T, t_len, x[i] ) ); MBEDTLS_MPI_CHK( ecp_add_mixed( grp, R, R, &Txi ) ); } @@ -1835,144 +1341,32 @@ cleanup: mbedtls_ecp_point_free( &Txi ); -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->rsm != NULL && - ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) - { - rs_ctx->rsm->i = i; - /* no need to save R, already pointing to rs_ctx->rsm->R */ - } -#endif - return( ret ); } /* - * Recode the scalar to get constant-time comb multiplication - * - * As the actual scalar recoding needs an odd scalar as a starting point, - * this wrapper ensures that by replacing m by N - m if necessary, and - * informs the caller that the result of multiplication will be negated. - * - * This works because we only support large prime order for Short Weierstrass - * curves, so N is always odd hence either m or N - m is. - * - * See ecp_comb_recode_core() for background. + * Multiplication using the comb method, + * for curves in short Weierstrass form */ -static int ecp_comb_recode_scalar( const mbedtls_ecp_group *grp, - const mbedtls_mpi *m, - unsigned char k[COMB_MAX_D + 1], - size_t d, - unsigned char w, - unsigned char *parity_trick ) +static int ecp_mul_comb( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, + const mbedtls_mpi *m, const mbedtls_ecp_point *P, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) { int ret; + unsigned char w, m_is_odd, p_eq_g, pre_len, i; + size_t d; + unsigned char k[COMB_MAX_D + 1]; + mbedtls_ecp_point *T; mbedtls_mpi M, mm; mbedtls_mpi_init( &M ); mbedtls_mpi_init( &mm ); - /* N is always odd (see above), just make extra sure */ + /* we need N to be odd to trnaform m in an odd number, check now */ if( mbedtls_mpi_get_bit( &grp->N, 0 ) != 1 ) return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - /* do we need the parity trick? */ - *parity_trick = ( mbedtls_mpi_get_bit( m, 0 ) == 0 ); - - /* execute parity fix in constant time */ - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &M, m ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &mm, &grp->N, m ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_assign( &M, &mm, *parity_trick ) ); - - /* actual scalar recoding */ - ecp_comb_recode_core( k, d, w, &M ); - -cleanup: - mbedtls_mpi_free( &mm ); - mbedtls_mpi_free( &M ); - - return( ret ); -} - -/* - * Perform comb multiplication (for short Weierstrass curves) - * once the auxiliary table has been pre-computed. - * - * Scalar recoding may use a parity trick that makes us compute -m * P, - * if that is the case we'll need to recover m * P at the end. - */ -static int ecp_mul_comb_after_precomp( const mbedtls_ecp_group *grp, - mbedtls_ecp_point *R, - const mbedtls_mpi *m, - const mbedtls_ecp_point *T, - unsigned char T_size, - unsigned char w, - size_t d, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - mbedtls_ecp_restart_ctx *rs_ctx ) -{ - int ret; - unsigned char parity_trick; - unsigned char k[COMB_MAX_D + 1]; - mbedtls_ecp_point *RR = R; - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->rsm != NULL ) - { - RR = &rs_ctx->rsm->R; - - if( rs_ctx->rsm->state == ecp_rsm_final_norm ) - goto final_norm; - } -#endif - - MBEDTLS_MPI_CHK( ecp_comb_recode_scalar( grp, m, k, d, w, - &parity_trick ) ); - MBEDTLS_MPI_CHK( ecp_mul_comb_core( grp, RR, T, T_size, k, d, - f_rng, p_rng, rs_ctx ) ); - MBEDTLS_MPI_CHK( ecp_safe_invert_jac( grp, RR, parity_trick ) ); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->rsm != NULL ) - rs_ctx->rsm->state = ecp_rsm_final_norm; - -final_norm: -#endif - /* - * Knowledge of the jacobian coordinates may leak the last few bits of the - * scalar [1], and since our MPI implementation isn't constant-flow, - * inversion (used for coordinate normalization) may leak the full value - * of its input via side-channels [2]. - * - * [1] https://eprint.iacr.org/2003/191 - * [2] https://eprint.iacr.org/2020/055 - * - * Avoid the leak by randomizing coordinates before we normalize them. - */ - if( f_rng != 0 ) - MBEDTLS_MPI_CHK( ecp_randomize_jac( grp, RR, f_rng, p_rng ) ); - - MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_INV ); - MBEDTLS_MPI_CHK( ecp_normalize_jac( grp, RR ) ); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->rsm != NULL ) - MBEDTLS_MPI_CHK( mbedtls_ecp_copy( R, RR ) ); -#endif - -cleanup: - return( ret ); -} - -/* - * Pick window size based on curve size and whether we optimize for base point - */ -static unsigned char ecp_pick_window_size( const mbedtls_ecp_group *grp, - unsigned char p_eq_g ) -{ - unsigned char w; - /* * Minimize the number of multiplications, that is minimize * 10 * d * w + 18 * 2^(w-1) + 11 * d + 7 * w, with d = ceil( nbits / w ) @@ -1985,8 +1379,14 @@ static unsigned char ecp_pick_window_size( const mbedtls_ecp_group *grp, * Just adding one avoids upping the cost of the first mul too much, * and the memory cost too. */ +#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1 + p_eq_g = ( mbedtls_mpi_cmp_mpi( &P->Y, &grp->G.Y ) == 0 && + mbedtls_mpi_cmp_mpi( &P->X, &grp->G.X ) == 0 ); if( p_eq_g ) w++; +#else + p_eq_g = 0; +#endif /* * Make sure w is within bounds. @@ -1997,141 +1397,75 @@ static unsigned char ecp_pick_window_size( const mbedtls_ecp_group *grp, if( w >= grp->nbits ) w = 2; - return( w ); -} - -/* - * Multiplication using the comb method - for curves in short Weierstrass form - * - * This function is mainly responsible for administrative work: - * - managing the restart context if enabled - * - managing the table of precomputed points (passed between the below two - * functions): allocation, computation, ownership tranfer, freeing. - * - * It delegates the actual arithmetic work to: - * ecp_precompute_comb() and ecp_mul_comb_with_precomp() - * - * See comments on ecp_comb_recode_core() regarding the computation strategy. - */ -static int ecp_mul_comb( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, - const mbedtls_mpi *m, const mbedtls_ecp_point *P, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - mbedtls_ecp_restart_ctx *rs_ctx ) -{ - int ret; - unsigned char w, p_eq_g; - uint_fast8_t i; - size_t d; - unsigned char T_size, T_ok; - mbedtls_ecp_point *T; - - ECP_RS_ENTER( rsm ); - - /* Is P the base point ? */ -#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1 - p_eq_g = ( mbedtls_mpi_cmp_mpi( &P->Y, &grp->G.Y ) == 0 && - mbedtls_mpi_cmp_mpi( &P->X, &grp->G.X ) == 0 ); -#else - p_eq_g = 0; -#endif - - /* Pick window size and deduce related sizes */ - w = ecp_pick_window_size( grp, p_eq_g ); - T_size = 1U << ( w - 1 ); + /* Other sizes that depend on w */ + pre_len = 1U << ( w - 1 ); d = ( grp->nbits + w - 1 ) / w; - /* Pre-computed table: do we have it already for the base point? */ - if( p_eq_g && grp->T != NULL ) - { - /* second pointer to the same table, will be deleted on exit */ - T = grp->T; - T_ok = 1; - } - else -#if defined(MBEDTLS_ECP_RESTARTABLE) - /* Pre-computed table: do we have one in progress? complete? */ - if( rs_ctx != NULL && rs_ctx->rsm != NULL && rs_ctx->rsm->T != NULL ) - { - /* transfer ownership of T from rsm to local function */ - T = rs_ctx->rsm->T; - rs_ctx->rsm->T = NULL; - rs_ctx->rsm->T_size = 0; + /* + * Prepare precomputed points: if P == G we want to + * use grp->T if already initialized, or initialize it. + */ + T = p_eq_g ? grp->T : NULL; - /* This effectively jumps to the call to mul_comb_after_precomp() */ - T_ok = rs_ctx->rsm->state >= ecp_rsm_comb_core; - } - else -#endif - /* Allocate table if we didn't have any */ + if( T == NULL ) { - T = mbedtls_calloc( T_size, sizeof( mbedtls_ecp_point ) ); + T = mbedtls_calloc( pre_len, sizeof( mbedtls_ecp_point ) ); if( T == NULL ) { ret = MBEDTLS_ERR_ECP_ALLOC_FAILED; goto cleanup; } - for( i = 0; i < T_size; i++ ) - mbedtls_ecp_point_init( &T[i] ); - - T_ok = 0; - } - - /* Compute table (or finish computing it) if not done already */ - if( !T_ok ) - { - MBEDTLS_MPI_CHK( ecp_precompute_comb( grp, T, P, w, d, rs_ctx ) ); + MBEDTLS_MPI_CHK( ecp_precompute_comb( grp, T, P, w, d ) ); if( p_eq_g ) { - /* almost transfer ownership of T to the group, but keep a copy of - * the pointer to use for calling the next function more easily */ grp->T = T; - grp->T_size = T_size; + grp->T_size = pre_len; } } - /* Actual comb multiplication using precomputed points */ - MBEDTLS_MPI_CHK( ecp_mul_comb_after_precomp( grp, R, m, - T, T_size, w, d, - f_rng, p_rng, rs_ctx ) ); + /* + * Make sure M is odd (M = m or M = N - m, since N is odd) + * using the fact that m * P = - (N - m) * P + */ + m_is_odd = ( mbedtls_mpi_get_bit( m, 0 ) == 1 ); + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &M, m ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &mm, &grp->N, m ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_assign( &M, &mm, ! m_is_odd ) ); + + /* + * Go for comb multiplication, R = M * P + */ + ecp_comb_fixed( k, d, w, &M ); + MBEDTLS_MPI_CHK( ecp_mul_comb_core( grp, R, T, pre_len, k, d, f_rng, p_rng ) ); + + /* + * Now get m * P from M * P and normalize it + */ + MBEDTLS_MPI_CHK( ecp_safe_invert_jac( grp, R, ! m_is_odd ) ); + MBEDTLS_MPI_CHK( ecp_normalize_jac( grp, R ) ); cleanup: - /* does T belong to the group? */ - if( T == grp->T ) - T = NULL; - - /* does T belong to the restart context? */ -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->rsm != NULL && ret == MBEDTLS_ERR_ECP_IN_PROGRESS && T != NULL ) + /* 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 ) { - /* transfer ownership of T from local function to rsm */ - rs_ctx->rsm->T_size = T_size; - rs_ctx->rsm->T = T; - T = NULL; - } -#endif - - /* did T belong to us? then let's destroy it! */ - if( T != NULL ) - { - for( i = 0; i < T_size; i++ ) + for( i = 0; i < pre_len; i++ ) mbedtls_ecp_point_free( &T[i] ); mbedtls_free( T ); } - /* don't free R while in progress in case R == P */ -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS ) -#endif - /* prevent caller from using invalid value */ + mbedtls_mpi_free( &M ); + mbedtls_mpi_free( &mm ); + if( ret != 0 ) mbedtls_ecp_point_free( R ); - ECP_RS_LEAVE( rsm ); - return( ret ); } @@ -2155,8 +1489,10 @@ static int ecp_normalize_mxz( const mbedtls_ecp_group *grp, mbedtls_ecp_point *P int ret; #if defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT) - if( mbedtls_internal_ecp_grp_capable( grp ) ) - return( mbedtls_internal_ecp_normalize_mxz( grp, P ) ); + if ( mbedtls_internal_ecp_grp_capable( grp ) ) + { + return mbedtls_internal_ecp_normalize_mxz( grp, P ); + } #endif /* MBEDTLS_ECP_NORMALIZE_MXZ_ALT */ MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &P->Z, &P->Z, &grp->P ) ); @@ -2184,8 +1520,10 @@ static int ecp_randomize_mxz( const mbedtls_ecp_group *grp, mbedtls_ecp_point *P int count = 0; #if defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT) - if( mbedtls_internal_ecp_grp_capable( grp ) ) - return( mbedtls_internal_ecp_randomize_mxz( grp, P, f_rng, p_rng ); + if ( mbedtls_internal_ecp_grp_capable( grp ) ) + { + return mbedtls_internal_ecp_randomize_mxz( grp, P, f_rng, p_rng ); + } #endif /* MBEDTLS_ECP_RANDOMIZE_MXZ_ALT */ p_size = ( grp->pbits + 7 ) / 8; @@ -2237,8 +1575,10 @@ static int ecp_double_add_mxz( const mbedtls_ecp_group *grp, mbedtls_mpi A, AA, B, BB, E, C, D, DA, CB; #if defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT) - if( mbedtls_internal_ecp_grp_capable( grp ) ) - return( mbedtls_internal_ecp_double_add_mxz( grp, R, S, P, Q, d ) ); + if ( mbedtls_internal_ecp_grp_capable( grp ) ) + { + return mbedtls_internal_ecp_double_add_mxz( grp, R, S, P, Q, d ); + } #endif /* MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT */ mbedtls_mpi_init( &A ); mbedtls_mpi_init( &AA ); mbedtls_mpi_init( &B ); @@ -2324,20 +1664,6 @@ static int ecp_mul_mxz( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_swap( &R->Z, &RP.Z, b ) ); } - /* - * Knowledge of the projective coordinates may leak the last few bits of the - * scalar [1], and since our MPI implementation isn't constant-flow, - * inversion (used for coordinate normalization) may leak the full value - * of its input via side-channels [2]. - * - * [1] https://eprint.iacr.org/2003/191 - * [2] https://eprint.iacr.org/2020/055 - * - * Avoid the leak by randomizing coordinates before we normalize them. - */ - if( f_rng != NULL ) - MBEDTLS_MPI_CHK( ecp_randomize_mxz( grp, R, f_rng, p_rng ) ); - MBEDTLS_MPI_CHK( ecp_normalize_mxz( grp, R ) ); cleanup: @@ -2348,72 +1674,6 @@ cleanup: #endif /* ECP_MONTGOMERY */ -/* - * Restartable multiplication R = m * P - */ -int mbedtls_ecp_mul_restartable( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, - const mbedtls_mpi *m, const mbedtls_ecp_point *P, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, - mbedtls_ecp_restart_ctx *rs_ctx ) -{ - int ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; -#if defined(MBEDTLS_ECP_INTERNAL_ALT) - char is_grp_capable = 0; -#endif - ECP_VALIDATE_RET( grp != NULL ); - ECP_VALIDATE_RET( R != NULL ); - ECP_VALIDATE_RET( m != NULL ); - ECP_VALIDATE_RET( P != NULL ); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - /* reset ops count for this call if top-level */ - if( rs_ctx != NULL && rs_ctx->depth++ == 0 ) - rs_ctx->ops_done = 0; -#endif - -#if defined(MBEDTLS_ECP_INTERNAL_ALT) - if( ( is_grp_capable = mbedtls_internal_ecp_grp_capable( grp ) ) ) - MBEDTLS_MPI_CHK( mbedtls_internal_ecp_init( grp ) ); -#endif /* MBEDTLS_ECP_INTERNAL_ALT */ - -#if defined(MBEDTLS_ECP_RESTARTABLE) - /* skip argument check when restarting */ - if( rs_ctx == NULL || rs_ctx->rsm == NULL ) -#endif - { - /* check_privkey is free */ - MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_CHK ); - - /* Common sanity checks */ - MBEDTLS_MPI_CHK( mbedtls_ecp_check_privkey( grp, m ) ); - MBEDTLS_MPI_CHK( mbedtls_ecp_check_pubkey( grp, P ) ); - } - - ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; -#if defined(ECP_MONTGOMERY) - if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY ) - MBEDTLS_MPI_CHK( ecp_mul_mxz( grp, R, m, P, f_rng, p_rng ) ); -#endif -#if defined(ECP_SHORTWEIERSTRASS) - if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS ) - MBEDTLS_MPI_CHK( ecp_mul_comb( grp, R, m, P, f_rng, p_rng, rs_ctx ) ); -#endif - -cleanup: - -#if defined(MBEDTLS_ECP_INTERNAL_ALT) - if( is_grp_capable ) - mbedtls_internal_ecp_free( grp ); -#endif /* MBEDTLS_ECP_INTERNAL_ALT */ - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL ) - rs_ctx->depth--; -#endif - - return( ret ); -} - /* * Multiplication R = m * P */ @@ -2421,11 +1681,46 @@ int mbedtls_ecp_mul( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, const mbedtls_mpi *m, const mbedtls_ecp_point *P, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) { - ECP_VALIDATE_RET( grp != NULL ); - ECP_VALIDATE_RET( R != NULL ); - ECP_VALIDATE_RET( m != NULL ); - ECP_VALIDATE_RET( P != NULL ); - return( mbedtls_ecp_mul_restartable( grp, R, m, P, f_rng, p_rng, NULL ) ); + int ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; +#if defined(MBEDTLS_ECP_INTERNAL_ALT) + char is_grp_capable = 0; +#endif + + /* Common sanity checks */ + if( mbedtls_mpi_cmp_int( &P->Z, 1 ) != 0 ) + return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); + + if( ( ret = mbedtls_ecp_check_privkey( grp, m ) ) != 0 || + ( ret = mbedtls_ecp_check_pubkey( grp, P ) ) != 0 ) + return( ret ); + +#if defined(MBEDTLS_ECP_INTERNAL_ALT) + if ( is_grp_capable = mbedtls_internal_ecp_grp_capable( grp ) ) + { + MBEDTLS_MPI_CHK( mbedtls_internal_ecp_init( grp ) ); + } + +#endif /* MBEDTLS_ECP_INTERNAL_ALT */ +#if defined(ECP_MONTGOMERY) + if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY ) + ret = ecp_mul_mxz( grp, R, m, P, f_rng, p_rng ); + +#endif +#if defined(ECP_SHORTWEIERSTRASS) + if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS ) + ret = ecp_mul_comb( grp, R, m, P, f_rng, p_rng ); + +#endif +#if defined(MBEDTLS_ECP_INTERNAL_ALT) +cleanup: + + if ( is_grp_capable ) + { + mbedtls_internal_ecp_free( grp ); + } + +#endif /* MBEDTLS_ECP_INTERNAL_ALT */ + return( ret ); } #if defined(ECP_SHORTWEIERSTRASS) @@ -2485,8 +1780,7 @@ cleanup: static int mbedtls_ecp_mul_shortcuts( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, const mbedtls_mpi *m, - const mbedtls_ecp_point *P, - mbedtls_ecp_restart_ctx *rs_ctx ) + const mbedtls_ecp_point *P ) { int ret; @@ -2502,111 +1796,13 @@ static int mbedtls_ecp_mul_shortcuts( mbedtls_ecp_group *grp, } else { - MBEDTLS_MPI_CHK( mbedtls_ecp_mul_restartable( grp, R, m, P, - NULL, NULL, rs_ctx ) ); + MBEDTLS_MPI_CHK( mbedtls_ecp_mul( grp, R, m, P, NULL, NULL ) ); } cleanup: return( ret ); } -/* - * Restartable linear combination - * NOT constant-time - */ -int mbedtls_ecp_muladd_restartable( - mbedtls_ecp_group *grp, mbedtls_ecp_point *R, - const mbedtls_mpi *m, const mbedtls_ecp_point *P, - const mbedtls_mpi *n, const mbedtls_ecp_point *Q, - mbedtls_ecp_restart_ctx *rs_ctx ) -{ - int ret; - mbedtls_ecp_point mP; - mbedtls_ecp_point *pmP = &mP; - mbedtls_ecp_point *pR = R; -#if defined(MBEDTLS_ECP_INTERNAL_ALT) - char is_grp_capable = 0; -#endif - ECP_VALIDATE_RET( grp != NULL ); - ECP_VALIDATE_RET( R != NULL ); - ECP_VALIDATE_RET( m != NULL ); - ECP_VALIDATE_RET( P != NULL ); - ECP_VALIDATE_RET( n != NULL ); - ECP_VALIDATE_RET( Q != NULL ); - - if( ecp_get_type( grp ) != ECP_TYPE_SHORT_WEIERSTRASS ) - return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE ); - - mbedtls_ecp_point_init( &mP ); - - ECP_RS_ENTER( ma ); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->ma != NULL ) - { - /* redirect intermediate results to restart context */ - pmP = &rs_ctx->ma->mP; - pR = &rs_ctx->ma->R; - - /* jump to next operation */ - if( rs_ctx->ma->state == ecp_rsma_mul2 ) - goto mul2; - if( rs_ctx->ma->state == ecp_rsma_add ) - goto add; - if( rs_ctx->ma->state == ecp_rsma_norm ) - goto norm; - } -#endif /* MBEDTLS_ECP_RESTARTABLE */ - - MBEDTLS_MPI_CHK( mbedtls_ecp_mul_shortcuts( grp, pmP, m, P, rs_ctx ) ); -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->ma != NULL ) - rs_ctx->ma->state = ecp_rsma_mul2; - -mul2: -#endif - MBEDTLS_MPI_CHK( mbedtls_ecp_mul_shortcuts( grp, pR, n, Q, rs_ctx ) ); - -#if defined(MBEDTLS_ECP_INTERNAL_ALT) - if( ( is_grp_capable = mbedtls_internal_ecp_grp_capable( grp ) ) ) - MBEDTLS_MPI_CHK( mbedtls_internal_ecp_init( grp ) ); -#endif /* MBEDTLS_ECP_INTERNAL_ALT */ - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->ma != NULL ) - rs_ctx->ma->state = ecp_rsma_add; - -add: -#endif - MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_ADD ); - MBEDTLS_MPI_CHK( ecp_add_mixed( grp, pR, pmP, pR ) ); -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->ma != NULL ) - rs_ctx->ma->state = ecp_rsma_norm; - -norm: -#endif - MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_INV ); - MBEDTLS_MPI_CHK( ecp_normalize_jac( grp, pR ) ); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->ma != NULL ) - MBEDTLS_MPI_CHK( mbedtls_ecp_copy( R, pR ) ); -#endif - -cleanup: -#if defined(MBEDTLS_ECP_INTERNAL_ALT) - if( is_grp_capable ) - mbedtls_internal_ecp_free( grp ); -#endif /* MBEDTLS_ECP_INTERNAL_ALT */ - - mbedtls_ecp_point_free( &mP ); - - ECP_RS_LEAVE( ma ); - - return( ret ); -} - /* * Linear combination * NOT constant-time @@ -2615,15 +1811,45 @@ int mbedtls_ecp_muladd( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, const mbedtls_mpi *m, const mbedtls_ecp_point *P, const mbedtls_mpi *n, const mbedtls_ecp_point *Q ) { - ECP_VALIDATE_RET( grp != NULL ); - ECP_VALIDATE_RET( R != NULL ); - ECP_VALIDATE_RET( m != NULL ); - ECP_VALIDATE_RET( P != NULL ); - ECP_VALIDATE_RET( n != NULL ); - ECP_VALIDATE_RET( Q != NULL ); - return( mbedtls_ecp_muladd_restartable( grp, R, m, P, n, Q, NULL ) ); + int ret; + mbedtls_ecp_point mP; +#if defined(MBEDTLS_ECP_INTERNAL_ALT) + char is_grp_capable = 0; +#endif + + if( ecp_get_type( grp ) != ECP_TYPE_SHORT_WEIERSTRASS ) + return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE ); + + mbedtls_ecp_point_init( &mP ); + + MBEDTLS_MPI_CHK( mbedtls_ecp_mul_shortcuts( grp, &mP, m, P ) ); + MBEDTLS_MPI_CHK( mbedtls_ecp_mul_shortcuts( grp, R, n, Q ) ); + +#if defined(MBEDTLS_ECP_INTERNAL_ALT) + if ( is_grp_capable = mbedtls_internal_ecp_grp_capable( grp ) ) + { + MBEDTLS_MPI_CHK( mbedtls_internal_ecp_init( grp ) ); + } + +#endif /* MBEDTLS_ECP_INTERNAL_ALT */ + MBEDTLS_MPI_CHK( ecp_add_mixed( grp, R, &mP, R ) ); + MBEDTLS_MPI_CHK( ecp_normalize_jac( grp, R ) ); + +cleanup: + +#if defined(MBEDTLS_ECP_INTERNAL_ALT) + if ( is_grp_capable ) + { + mbedtls_internal_ecp_free( grp ); + } + +#endif /* MBEDTLS_ECP_INTERNAL_ALT */ + mbedtls_ecp_point_free( &mP ); + + return( ret ); } + #if defined(ECP_MONTGOMERY) /* * Check validity of a public key for Montgomery curves with x-only schemes @@ -2631,8 +1857,6 @@ int mbedtls_ecp_muladd( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, static int ecp_check_pubkey_mx( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt ) { /* [Curve25519 p. 5] Just check X is the correct number of bytes */ - /* Allow any public value, if it's too big then we'll just reduce it mod p - * (RFC 7748 sec. 5 para. 3). */ if( mbedtls_mpi_size( &pt->X ) > ( grp->nbits + 7 ) / 8 ) return( MBEDTLS_ERR_ECP_INVALID_KEY ); @@ -2643,12 +1867,8 @@ static int ecp_check_pubkey_mx( const mbedtls_ecp_group *grp, const mbedtls_ecp_ /* * Check that a point is valid as a public key */ -int mbedtls_ecp_check_pubkey( const mbedtls_ecp_group *grp, - const mbedtls_ecp_point *pt ) +int mbedtls_ecp_check_pubkey( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt ) { - ECP_VALIDATE_RET( grp != NULL ); - ECP_VALIDATE_RET( pt != NULL ); - /* Must use affine coordinates */ if( mbedtls_mpi_cmp_int( &pt->Z, 1 ) != 0 ) return( MBEDTLS_ERR_ECP_INVALID_KEY ); @@ -2667,26 +1887,19 @@ int mbedtls_ecp_check_pubkey( const mbedtls_ecp_group *grp, /* * Check that an mbedtls_mpi is valid as a private key */ -int mbedtls_ecp_check_privkey( const mbedtls_ecp_group *grp, - const mbedtls_mpi *d ) +int mbedtls_ecp_check_privkey( const mbedtls_ecp_group *grp, const mbedtls_mpi *d ) { - ECP_VALIDATE_RET( grp != NULL ); - ECP_VALIDATE_RET( d != NULL ); - #if defined(ECP_MONTGOMERY) if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY ) { - /* see RFC 7748 sec. 5 para. 5 */ + /* see [Curve25519] page 5 */ if( mbedtls_mpi_get_bit( d, 0 ) != 0 || mbedtls_mpi_get_bit( d, 1 ) != 0 || + mbedtls_mpi_get_bit( d, 2 ) != 0 || mbedtls_mpi_bitlen( d ) - 1 != grp->nbits ) /* mbedtls_mpi_bitlen is one-based! */ return( MBEDTLS_ERR_ECP_INVALID_KEY ); - - /* see [Curve25519] page 5 */ - if( grp->nbits == 254 && mbedtls_mpi_get_bit( d, 2 ) != 0 ) - return( MBEDTLS_ERR_ECP_INVALID_KEY ); - - return( 0 ); + else + return( 0 ); } #endif /* ECP_MONTGOMERY */ #if defined(ECP_SHORTWEIERSTRASS) @@ -2705,21 +1918,16 @@ int mbedtls_ecp_check_privkey( const mbedtls_ecp_group *grp, } /* - * Generate a private key + * Generate a keypair with configurable base point */ -int mbedtls_ecp_gen_privkey( const mbedtls_ecp_group *grp, - mbedtls_mpi *d, +int mbedtls_ecp_gen_keypair_base( mbedtls_ecp_group *grp, + const mbedtls_ecp_point *G, + mbedtls_mpi *d, mbedtls_ecp_point *Q, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) { - int ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - size_t n_size; - - ECP_VALIDATE_RET( grp != NULL ); - ECP_VALIDATE_RET( d != NULL ); - ECP_VALIDATE_RET( f_rng != NULL ); - - n_size = ( grp->nbits + 7 ) / 8; + int ret; + size_t n_size = ( grp->nbits + 7 ) / 8; #if defined(ECP_MONTGOMERY) if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY ) @@ -2738,23 +1946,18 @@ int mbedtls_ecp_gen_privkey( const mbedtls_ecp_group *grp, else MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, grp->nbits, 1 ) ); - /* Make sure the last two bits are unset for Curve448, three bits for - Curve25519 */ + /* Make sure the last three bits are unset */ MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 0, 0 ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 1, 0 ) ); - if( grp->nbits == 254 ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 2, 0 ) ); - } + MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 2, 0 ) ); } + else #endif /* ECP_MONTGOMERY */ - #if defined(ECP_SHORTWEIERSTRASS) if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS ) { /* SEC1 3.2.1: Generate d such that 1 <= n < N */ int count = 0; - unsigned cmp = 0; /* * Match the procedure given in RFC 6979 (deterministic ECDSA): @@ -2779,42 +1982,19 @@ int mbedtls_ecp_gen_privkey( const mbedtls_ecp_group *grp, */ if( ++count > 30 ) return( MBEDTLS_ERR_ECP_RANDOM_FAILED ); - - ret = mbedtls_mpi_lt_mpi_ct( d, &grp->N, &cmp ); - if( ret != 0 ) - { - goto cleanup; - } } - while( mbedtls_mpi_cmp_int( d, 1 ) < 0 || cmp != 1 ); + while( mbedtls_mpi_cmp_int( d, 1 ) < 0 || + mbedtls_mpi_cmp_mpi( d, &grp->N ) >= 0 ); } + else #endif /* ECP_SHORTWEIERSTRASS */ + return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); cleanup: - return( ret ); -} + if( ret != 0 ) + return( ret ); -/* - * Generate a keypair with configurable base point - */ -int mbedtls_ecp_gen_keypair_base( mbedtls_ecp_group *grp, - const mbedtls_ecp_point *G, - mbedtls_mpi *d, mbedtls_ecp_point *Q, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - int ret; - ECP_VALIDATE_RET( grp != NULL ); - ECP_VALIDATE_RET( d != NULL ); - ECP_VALIDATE_RET( G != NULL ); - ECP_VALIDATE_RET( Q != NULL ); - ECP_VALIDATE_RET( f_rng != NULL ); - - MBEDTLS_MPI_CHK( mbedtls_ecp_gen_privkey( grp, d, f_rng, p_rng ) ); - MBEDTLS_MPI_CHK( mbedtls_ecp_mul( grp, Q, d, G, f_rng, p_rng ) ); - -cleanup: - return( ret ); + return( mbedtls_ecp_mul( grp, Q, d, G, f_rng, p_rng ) ); } /* @@ -2825,11 +2005,6 @@ int mbedtls_ecp_gen_keypair( mbedtls_ecp_group *grp, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) { - ECP_VALIDATE_RET( grp != NULL ); - ECP_VALIDATE_RET( d != NULL ); - ECP_VALIDATE_RET( Q != NULL ); - ECP_VALIDATE_RET( f_rng != NULL ); - return( mbedtls_ecp_gen_keypair_base( grp, &grp->G, d, Q, f_rng, p_rng ) ); } @@ -2840,8 +2015,6 @@ int mbedtls_ecp_gen_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) { int ret; - ECP_VALIDATE_RET( key != NULL ); - ECP_VALIDATE_RET( f_rng != NULL ); if( ( ret = mbedtls_ecp_group_load( &key->grp, grp_id ) ) != 0 ) return( ret ); @@ -2857,8 +2030,6 @@ int mbedtls_ecp_check_pub_priv( const mbedtls_ecp_keypair *pub, const mbedtls_ec int ret; mbedtls_ecp_point Q; mbedtls_ecp_group grp; - ECP_VALIDATE_RET( pub != NULL ); - ECP_VALIDATE_RET( prv != NULL ); if( pub->grp.id == MBEDTLS_ECP_DP_NONE || pub->grp.id != prv->grp.id || diff --git a/APP_Framework/Framework/security/mbedtls/ecp.h b/APP_Framework/Framework/security/mbedtls/ecp.h index 065a4cc0b..6c43c0069 100644 --- a/APP_Framework/Framework/security/mbedtls/ecp.h +++ b/APP_Framework/Framework/security/mbedtls/ecp.h @@ -1,21 +1,10 @@ /** * \file ecp.h * - * \brief This file provides an API for Elliptic Curves over GF(P) (ECP). - * - * The use of ECP in cryptography and TLS is defined in - * Standards for Efficient Cryptography Group (SECG): SEC1 - * Elliptic Curve Cryptography and - * RFC-4492: Elliptic Curve Cryptography (ECC) Cipher Suites - * for Transport Layer Security (TLS). - * - * RFC-2409: The Internet Key Exchange (IKE) defines ECP - * group types. - * + * \brief Elliptic curves over GF(p) */ - /* - * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -30,9 +19,8 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * This file is part of Mbed TLS (https://tls.mbed.org) + * This file is part of mbed TLS (https://tls.mbed.org) */ - #ifndef MBEDTLS_ECP_H #define MBEDTLS_ECP_H @@ -49,85 +37,13 @@ */ #define MBEDTLS_ERR_ECP_BAD_INPUT_DATA -0x4F80 /**< Bad input parameters to function. */ #define MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL -0x4F00 /**< The buffer is too small to write to. */ -#define MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE -0x4E80 /**< The requested feature is not available, for example, the requested curve is not supported. */ +#define MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE -0x4E80 /**< Requested curve not available. */ #define MBEDTLS_ERR_ECP_VERIFY_FAILED -0x4E00 /**< The signature is not valid. */ #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_SIG_LEN_MISMATCH -0x4C00 /**< The buffer contains a valid signature followed by more data. */ - -/* MBEDTLS_ERR_ECP_HW_ACCEL_FAILED is deprecated and should not be used. */ -#define MBEDTLS_ERR_ECP_HW_ACCEL_FAILED -0x4B80 /**< The ECP hardware accelerator failed. */ - -#define MBEDTLS_ERR_ECP_IN_PROGRESS -0x4B00 /**< Operation in progress, call again with the same parameters to continue. */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Domain-parameter identifiers: curve, subgroup, and generator. - * - * \note Only curves over prime fields are supported. - * - * \warning This library does not support validation of arbitrary domain - * parameters. Therefore, only standardized domain parameters from trusted - * sources should be used. See mbedtls_ecp_group_load(). - */ -typedef enum -{ - MBEDTLS_ECP_DP_NONE = 0, /*!< Curve not defined. */ - MBEDTLS_ECP_DP_SECP192R1, /*!< Domain parameters for the 192-bit curve defined by FIPS 186-4 and SEC1. */ - MBEDTLS_ECP_DP_SECP224R1, /*!< Domain parameters for the 224-bit curve defined by FIPS 186-4 and SEC1. */ - MBEDTLS_ECP_DP_SECP256R1, /*!< Domain parameters for the 256-bit curve defined by FIPS 186-4 and SEC1. */ - MBEDTLS_ECP_DP_SECP384R1, /*!< Domain parameters for the 384-bit curve defined by FIPS 186-4 and SEC1. */ - MBEDTLS_ECP_DP_SECP521R1, /*!< Domain parameters for the 521-bit curve defined by FIPS 186-4 and SEC1. */ - MBEDTLS_ECP_DP_BP256R1, /*!< Domain parameters for 256-bit Brainpool curve. */ - MBEDTLS_ECP_DP_BP384R1, /*!< Domain parameters for 384-bit Brainpool curve. */ - MBEDTLS_ECP_DP_BP512R1, /*!< Domain parameters for 512-bit Brainpool curve. */ - MBEDTLS_ECP_DP_CURVE25519, /*!< Domain parameters for Curve25519. */ - MBEDTLS_ECP_DP_SECP192K1, /*!< Domain parameters for 192-bit "Koblitz" curve. */ - MBEDTLS_ECP_DP_SECP224K1, /*!< Domain parameters for 224-bit "Koblitz" curve. */ - MBEDTLS_ECP_DP_SECP256K1, /*!< Domain parameters for 256-bit "Koblitz" curve. */ - MBEDTLS_ECP_DP_CURVE448, /*!< Domain parameters for Curve448. */ -} mbedtls_ecp_group_id; - -/** - * The number of supported curves, plus one for #MBEDTLS_ECP_DP_NONE. - * - * \note Montgomery curves are currently excluded. - */ -#define MBEDTLS_ECP_DP_MAX 12 - -/** - * Curve information, for use by other modules. - */ -typedef struct mbedtls_ecp_curve_info -{ - mbedtls_ecp_group_id grp_id; /*!< An internal identifier. */ - uint16_t tls_id; /*!< The TLS NamedCurve identifier. */ - uint16_t bit_size; /*!< The curve size in bits. */ - const char *name; /*!< A human-friendly name. */ -} mbedtls_ecp_curve_info; - -/** - * \brief The ECP point structure, in Jacobian coordinates. - * - * \note All functions expect and return points satisfying - * the following condition: Z == 0 or - * Z == 1. Other values of \p Z are - * used only by internal functions. - * The point is zero, or "at infinity", if Z == 0. - * Otherwise, \p X and \p Y are its standard (affine) - * coordinates. - */ -typedef struct mbedtls_ecp_point -{ - mbedtls_mpi X; /*!< The X coordinate of the ECP point. */ - mbedtls_mpi Y; /*!< The Y coordinate of the ECP point. */ - mbedtls_mpi Z; /*!< The Z coordinate of the ECP point. */ -} -mbedtls_ecp_point; +#define MBEDTLS_ERR_ECP_HW_ACCEL_FAILED -0x4B80 /**< ECP hardware accelerator failed. */ #if !defined(MBEDTLS_ECP_ALT) /* @@ -138,76 +54,143 @@ mbedtls_ecp_point; * one.) */ +#ifdef __cplusplus +extern "C" { +#endif + /** - * \brief The ECP group structure. + * Domain parameters (curve, subgroup and generator) identifiers. * - * We consider two types of curve equations: - *
    • Short Weierstrass: y^2 = x^3 + A x + B mod P - * (SEC1 + RFC-4492)
    • - *
    • Montgomery: y^2 = x^3 + A x^2 + x mod P (Curve25519, - * Curve448)
    - * In both cases, the generator (\p G) for a prime-order subgroup is fixed. - * - * For Short Weierstrass, this subgroup is the whole curve, and its - * cardinality is denoted by \p N. Our code requires that \p N is an - * odd prime as mbedtls_ecp_mul() requires an odd number, and - * mbedtls_ecdsa_sign() requires that it is prime for blinding purposes. - * - * For Montgomery curves, we do not store \p A, but (A + 2) / 4, - * which is the quantity used in the formulas. Additionally, \p nbits is - * not the size of \p N but the required size for private keys. - * - * If \p modp is NULL, reduction modulo \p P is done using a generic algorithm. - * Otherwise, \p modp must point to a function that takes an \p mbedtls_mpi in the - * range of 0..2^(2*pbits)-1, and transforms it in-place to an integer - * which is congruent mod \p P to the given MPI, and is close enough to \p pbits - * in size, so that it may be efficiently brought in the 0..P-1 range by a few - * additions or subtractions. Therefore, it is only an approximative modular - * reduction. It must return 0 on success and non-zero on failure. - * - * \note Alternative implementations must keep the group IDs distinct. If - * two group structures have the same ID, then they must be - * identical. + * Only curves over prime fields are supported. * + * \warning This library does not support validation of arbitrary domain + * parameters. Therefore, only well-known domain parameters from trusted + * sources should be used. See mbedtls_ecp_group_load(). */ -typedef struct mbedtls_ecp_group +typedef enum { - mbedtls_ecp_group_id id; /*!< An internal group identifier. */ - mbedtls_mpi P; /*!< The prime modulus of the base field. */ - mbedtls_mpi A; /*!< For Short Weierstrass: \p A in the equation. For - Montgomery curves: (A + 2) / 4. */ - mbedtls_mpi B; /*!< For Short Weierstrass: \p B in the equation. - For Montgomery curves: unused. */ - mbedtls_ecp_point G; /*!< The generator of the subgroup used. */ - mbedtls_mpi N; /*!< The order of \p G. */ - size_t pbits; /*!< The number of bits in \p P.*/ - size_t nbits; /*!< For Short Weierstrass: The number of bits in \p P. - For Montgomery curves: the number of bits in the - private keys. */ - unsigned int h; /*!< \internal 1 if the constants are static. */ - int (*modp)(mbedtls_mpi *); /*!< The function for fast pseudo-reduction - mod \p P (see above).*/ - int (*t_pre)(mbedtls_ecp_point *, void *); /*!< Unused. */ - int (*t_post)(mbedtls_ecp_point *, void *); /*!< Unused. */ - void *t_data; /*!< Unused. */ - mbedtls_ecp_point *T; /*!< Pre-computed points for ecp_mul_comb(). */ - size_t T_size; /*!< The number of pre-computed points. */ + MBEDTLS_ECP_DP_NONE = 0, + MBEDTLS_ECP_DP_SECP192R1, /*!< 192-bits NIST curve */ + MBEDTLS_ECP_DP_SECP224R1, /*!< 224-bits NIST curve */ + MBEDTLS_ECP_DP_SECP256R1, /*!< 256-bits NIST curve */ + MBEDTLS_ECP_DP_SECP384R1, /*!< 384-bits NIST curve */ + MBEDTLS_ECP_DP_SECP521R1, /*!< 521-bits NIST curve */ + MBEDTLS_ECP_DP_BP256R1, /*!< 256-bits Brainpool curve */ + MBEDTLS_ECP_DP_BP384R1, /*!< 384-bits Brainpool curve */ + MBEDTLS_ECP_DP_BP512R1, /*!< 512-bits Brainpool curve */ + MBEDTLS_ECP_DP_CURVE25519, /*!< Curve25519 */ + MBEDTLS_ECP_DP_SECP192K1, /*!< 192-bits "Koblitz" curve */ + MBEDTLS_ECP_DP_SECP224K1, /*!< 224-bits "Koblitz" curve */ + MBEDTLS_ECP_DP_SECP256K1, /*!< 256-bits "Koblitz" curve */ +} mbedtls_ecp_group_id; + +/** + * Number of supported curves (plus one for NONE). + * + * (Montgomery curves excluded for now.) + */ +#define MBEDTLS_ECP_DP_MAX 12 + +/** + * Curve information for use by other modules + */ +typedef struct +{ + mbedtls_ecp_group_id grp_id; /*!< Internal identifier */ + uint16_t tls_id; /*!< TLS NamedCurve identifier */ + uint16_t bit_size; /*!< Curve size in bits */ + const char *name; /*!< Human-friendly name */ +} mbedtls_ecp_curve_info; + +/** + * \brief ECP point structure (jacobian coordinates) + * + * \note All functions expect and return points satisfying + * the following condition: Z == 0 or Z == 1. (Other + * values of Z are used by internal functions only.) + * The point is zero, or "at infinity", if Z == 0. + * Otherwise, X and Y are its standard (affine) coordinates. + */ +typedef struct +{ + mbedtls_mpi X; /*!< the point's X coordinate */ + mbedtls_mpi Y; /*!< the point's Y coordinate */ + mbedtls_mpi Z; /*!< the point's Z coordinate */ +} +mbedtls_ecp_point; + +/** + * \brief ECP group structure + * + * We consider two types of curves equations: + * 1. Short Weierstrass y^2 = x^3 + A x + B mod P (SEC1 + RFC 4492) + * 2. Montgomery, y^2 = x^3 + A x^2 + x mod P (Curve25519 + draft) + * In both cases, a generator G for a prime-order subgroup is fixed. In the + * short weierstrass, this subgroup is actually the whole curve, and its + * cardinal is denoted by N. + * + * In the case of Short Weierstrass curves, our code requires that N is an odd + * prime. (Use odd in mbedtls_ecp_mul() and prime in mbedtls_ecdsa_sign() for blinding.) + * + * In the case of Montgomery curves, we don't store A but (A + 2) / 4 which is + * the quantity actually used in the formulas. Also, nbits is not the size of N + * but the required size for private keys. + * + * If modp is NULL, reduction modulo P is done using a generic algorithm. + * Otherwise, it must point to a function that takes an mbedtls_mpi in the range + * 0..2^(2*pbits)-1 and transforms it in-place in an integer of little more + * than pbits, so that the integer may be efficiently brought in the 0..P-1 + * range by a few additions or substractions. It must return 0 on success and + * non-zero on failure. + */ +typedef struct +{ + mbedtls_ecp_group_id id; /*!< internal group identifier */ + mbedtls_mpi P; /*!< prime modulus of the base field */ + mbedtls_mpi A; /*!< 1. A in the equation, or 2. (A + 2) / 4 */ + mbedtls_mpi B; /*!< 1. B in the equation, or 2. unused */ + mbedtls_ecp_point G; /*!< generator of the (sub)group used */ + mbedtls_mpi N; /*!< 1. the order of G, or 2. unused */ + size_t pbits; /*!< number of bits in P */ + size_t nbits; /*!< number of bits in 1. P, or 2. private keys */ + unsigned int h; /*!< internal: 1 if the constants are static */ + int (*modp)(mbedtls_mpi *); /*!< function for fast reduction mod P */ + int (*t_pre)(mbedtls_ecp_point *, void *); /*!< unused */ + int (*t_post)(mbedtls_ecp_point *, void *); /*!< unused */ + void *t_data; /*!< unused */ + mbedtls_ecp_point *T; /*!< pre-computed points for ecp_mul_comb() */ + size_t T_size; /*!< number for pre-computed points */ } mbedtls_ecp_group; +/** + * \brief ECP key pair structure + * + * A generic key pair that could be used for ECDSA, fixed ECDH, etc. + * + * \note Members purposefully in the same order as struc mbedtls_ecdsa_context. + */ +typedef struct +{ + mbedtls_ecp_group grp; /*!< Elliptic curve and base point */ + mbedtls_mpi d; /*!< our secret value */ + mbedtls_ecp_point Q; /*!< our public value */ +} +mbedtls_ecp_keypair; + /** * \name SECTION: Module settings * * The configuration options you can set for this module are in this section. - * Either change them in config.h, or define them using the compiler command line. + * Either change them in config.h or define them on the compiler command line. * \{ */ #if !defined(MBEDTLS_ECP_MAX_BITS) /** - * The maximum size of the groups, that is, of \c N and \c P. + * Maximum size of the groups (that is, of N and P) */ -#define MBEDTLS_ECP_MAX_BITS 521 /**< The maximum size of groups, in bits. */ +#define MBEDTLS_ECP_MAX_BITS 521 /**< Maximum bit size of groups */ #endif #define MBEDTLS_ECP_MAX_BYTES ( ( MBEDTLS_ECP_MAX_BITS + 7 ) / 8 ) @@ -230,10 +213,11 @@ mbedtls_ecp_group; * 521 145 141 135 120 97 * 384 214 209 198 177 146 * 256 320 320 303 262 226 + * 224 475 475 453 398 342 * 192 640 640 633 587 476 */ -#define MBEDTLS_ECP_WINDOW_SIZE 6 /**< The maximum window size used. */ +#define MBEDTLS_ECP_WINDOW_SIZE 6 /**< Maximum window size used */ #endif /* MBEDTLS_ECP_WINDOW_SIZE */ #if !defined(MBEDTLS_ECP_FIXED_POINT_OPTIM) @@ -248,188 +232,33 @@ mbedtls_ecp_group; * * Change this value to 0 to reduce peak memory usage. */ -#define MBEDTLS_ECP_FIXED_POINT_OPTIM 1 /**< Enable fixed-point speed-up. */ +#define MBEDTLS_ECP_FIXED_POINT_OPTIM 1 /**< Enable fixed-point speed-up */ #endif /* MBEDTLS_ECP_FIXED_POINT_OPTIM */ /* \} name SECTION: Module settings */ -#else /* MBEDTLS_ECP_ALT */ -#include "ecp_alt.h" -#endif /* MBEDTLS_ECP_ALT */ - -#if defined(MBEDTLS_ECP_RESTARTABLE) - -/** - * \brief Internal restart context for multiplication - * - * \note Opaque struct - */ -typedef struct mbedtls_ecp_restart_mul mbedtls_ecp_restart_mul_ctx; - -/** - * \brief Internal restart context for ecp_muladd() - * - * \note Opaque struct - */ -typedef struct mbedtls_ecp_restart_muladd mbedtls_ecp_restart_muladd_ctx; - -/** - * \brief General context for resuming ECC operations - */ -typedef struct -{ - unsigned ops_done; /*!< current ops count */ - unsigned depth; /*!< call depth (0 = top-level) */ - mbedtls_ecp_restart_mul_ctx *rsm; /*!< ecp_mul_comb() sub-context */ - mbedtls_ecp_restart_muladd_ctx *ma; /*!< ecp_muladd() sub-context */ -} mbedtls_ecp_restart_ctx; - -/* - * Operation counts for restartable functions - */ -#define MBEDTLS_ECP_OPS_CHK 3 /*!< basic ops count for ecp_check_pubkey() */ -#define MBEDTLS_ECP_OPS_DBL 8 /*!< basic ops count for ecp_double_jac() */ -#define MBEDTLS_ECP_OPS_ADD 11 /*!< basic ops count for see ecp_add_mixed() */ -#define MBEDTLS_ECP_OPS_INV 120 /*!< empirical equivalent for mpi_mod_inv() */ - -/** - * \brief Internal; for restartable functions in other modules. - * Check and update basic ops budget. - * - * \param grp Group structure - * \param rs_ctx Restart context - * \param ops Number of basic ops to do - * - * \return \c 0 if doing \p ops basic ops is still allowed, - * \return #MBEDTLS_ERR_ECP_IN_PROGRESS otherwise. - */ -int mbedtls_ecp_check_budget( const mbedtls_ecp_group *grp, - mbedtls_ecp_restart_ctx *rs_ctx, - unsigned ops ); - -/* Utility macro for checking and updating ops budget */ -#define MBEDTLS_ECP_BUDGET( ops ) \ - MBEDTLS_MPI_CHK( mbedtls_ecp_check_budget( grp, rs_ctx, \ - (unsigned) (ops) ) ); - -#else /* MBEDTLS_ECP_RESTARTABLE */ - -#define MBEDTLS_ECP_BUDGET( ops ) /* no-op; for compatibility */ - -/* We want to declare restartable versions of existing functions anyway */ -typedef void mbedtls_ecp_restart_ctx; - -#endif /* MBEDTLS_ECP_RESTARTABLE */ - -/** - * \brief The ECP key-pair structure. - * - * A generic key-pair that may be used for ECDSA and fixed ECDH, for example. - * - * \note Members are deliberately in the same order as in the - * ::mbedtls_ecdsa_context structure. - */ -typedef struct mbedtls_ecp_keypair -{ - mbedtls_ecp_group grp; /*!< Elliptic curve and base point */ - mbedtls_mpi d; /*!< our secret value */ - mbedtls_ecp_point Q; /*!< our public value */ -} -mbedtls_ecp_keypair; - /* * Point formats, from RFC 4492's enum ECPointFormat */ -#define MBEDTLS_ECP_PF_UNCOMPRESSED 0 /**< Uncompressed point format. */ -#define MBEDTLS_ECP_PF_COMPRESSED 1 /**< Compressed point format. */ +#define MBEDTLS_ECP_PF_UNCOMPRESSED 0 /**< Uncompressed point format */ +#define MBEDTLS_ECP_PF_COMPRESSED 1 /**< Compressed point format */ /* * Some other constants from RFC 4492 */ -#define MBEDTLS_ECP_TLS_NAMED_CURVE 3 /**< The named_curve of ECCurveType. */ - -#if defined(MBEDTLS_ECP_RESTARTABLE) -/** - * \brief Set the maximum number of basic operations done in a row. - * - * If more operations are needed to complete a computation, - * #MBEDTLS_ERR_ECP_IN_PROGRESS will be returned by the - * function performing the computation. It is then the - * caller's responsibility to either call again with the same - * parameters until it returns 0 or an error code; or to free - * the restart context if the operation is to be aborted. - * - * It is strictly required that all input parameters and the - * restart context be the same on successive calls for the - * same operation, but output parameters need not be the - * same; they must not be used until the function finally - * returns 0. - * - * This only applies to functions whose documentation - * mentions they may return #MBEDTLS_ERR_ECP_IN_PROGRESS (or - * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS for functions in the - * SSL module). For functions that accept a "restart context" - * argument, passing NULL disables restart and makes the - * function equivalent to the function with the same name - * with \c _restartable removed. For functions in the ECDH - * module, restart is disabled unless the function accepts - * an "ECDH context" argument and - * mbedtls_ecdh_enable_restart() was previously called on - * that context. For function in the SSL module, restart is - * only enabled for specific sides and key exchanges - * (currently only for clients and ECDHE-ECDSA). - * - * \param max_ops Maximum number of basic operations done in a row. - * Default: 0 (unlimited). - * Lower (non-zero) values mean ECC functions will block for - * a lesser maximum amount of time. - * - * \note A "basic operation" is defined as a rough equivalent of a - * multiplication in GF(p) for the NIST P-256 curve. - * As an indication, with default settings, a scalar - * multiplication (full run of \c mbedtls_ecp_mul()) is: - * - about 3300 basic operations for P-256 - * - about 9400 basic operations for P-384 - * - * \note Very low values are not always respected: sometimes - * functions need to block for a minimum number of - * operations, and will do so even if max_ops is set to a - * lower value. That minimum depends on the curve size, and - * can be made lower by decreasing the value of - * \c MBEDTLS_ECP_WINDOW_SIZE. As an indication, here is the - * lowest effective value for various curves and values of - * that parameter (w for short): - * w=6 w=5 w=4 w=3 w=2 - * P-256 208 208 160 136 124 - * P-384 682 416 320 272 248 - * P-521 1364 832 640 544 496 - * - * \note This setting is currently ignored by Curve25519. - */ -void mbedtls_ecp_set_max_ops( unsigned max_ops ); +#define MBEDTLS_ECP_TLS_NAMED_CURVE 3 /**< ECCurveType's named_curve */ /** - * \brief Check if restart is enabled (max_ops != 0) + * \brief Get the list of supported curves in order of preferrence + * (full information) * - * \return \c 0 if \c max_ops == 0 (restart disabled) - * \return \c 1 otherwise (restart enabled) - */ -int mbedtls_ecp_restart_is_enabled( void ); -#endif /* MBEDTLS_ECP_RESTARTABLE */ - -/** - * \brief This function retrieves the information defined in - * mbedtls_ecp_curve_info() for all supported curves in order - * of preference. - * - * \return A statically allocated array. The last entry is 0. + * \return A statically allocated array, the last entry is 0. */ const mbedtls_ecp_curve_info *mbedtls_ecp_curve_list( void ); /** - * \brief This function retrieves the list of internal group - * identifiers of all supported curves in the order of - * preference. + * \brief Get the list of supported curves in order of preferrence + * (grp_id only) * * \return A statically allocated array, * terminated with MBEDTLS_ECP_DP_NONE. @@ -437,689 +266,416 @@ const mbedtls_ecp_curve_info *mbedtls_ecp_curve_list( void ); const mbedtls_ecp_group_id *mbedtls_ecp_grp_id_list( void ); /** - * \brief This function retrieves curve information from an internal - * group identifier. + * \brief Get curve information from an internal group identifier * - * \param grp_id An \c MBEDTLS_ECP_DP_XXX value. + * \param grp_id A MBEDTLS_ECP_DP_XXX value * - * \return The associated curve information on success. - * \return NULL on failure. + * \return The associated curve information or NULL */ const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_grp_id( mbedtls_ecp_group_id grp_id ); /** - * \brief This function retrieves curve information from a TLS - * NamedCurve value. + * \brief Get curve information from a TLS NamedCurve value * - * \param tls_id An \c MBEDTLS_ECP_DP_XXX value. + * \param tls_id A MBEDTLS_ECP_DP_XXX value * - * \return The associated curve information on success. - * \return NULL on failure. + * \return The associated curve information or NULL */ const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_tls_id( uint16_t tls_id ); /** - * \brief This function retrieves curve information from a - * human-readable name. + * \brief Get curve information from a human-readable name * - * \param name The human-readable name. + * \param name The name * - * \return The associated curve information on success. - * \return NULL on failure. + * \return The associated curve information or NULL */ const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_name( const char *name ); /** - * \brief This function initializes a point as zero. - * - * \param pt The point to initialize. + * \brief Initialize a point (as zero) */ void mbedtls_ecp_point_init( mbedtls_ecp_point *pt ); /** - * \brief This function initializes an ECP group context - * without loading any domain parameters. - * - * \note After this function is called, domain parameters - * for various ECP groups can be loaded through the - * mbedtls_ecp_group_load() or mbedtls_ecp_tls_read_group() - * functions. + * \brief Initialize a group (to something meaningless) */ void mbedtls_ecp_group_init( mbedtls_ecp_group *grp ); /** - * \brief This function initializes a key pair as an invalid one. - * - * \param key The key pair to initialize. + * \brief Initialize a key pair (as an invalid one) */ void mbedtls_ecp_keypair_init( mbedtls_ecp_keypair *key ); /** - * \brief This function frees the components of a point. - * - * \param pt The point to free. + * \brief Free the components of a point */ void mbedtls_ecp_point_free( mbedtls_ecp_point *pt ); /** - * \brief This function frees the components of an ECP group. - * - * \param grp The group to free. This may be \c NULL, in which - * case this function returns immediately. If it is not - * \c NULL, it must point to an initialized ECP group. + * \brief Free the components of an ECP group */ void mbedtls_ecp_group_free( mbedtls_ecp_group *grp ); /** - * \brief This function frees the components of a key pair. - * - * \param key The key pair to free. This may be \c NULL, in which - * case this function returns immediately. If it is not - * \c NULL, it must point to an initialized ECP key pair. + * \brief Free the components of a key pair */ void mbedtls_ecp_keypair_free( mbedtls_ecp_keypair *key ); -#if defined(MBEDTLS_ECP_RESTARTABLE) /** - * \brief Initialize a restart context. + * \brief Copy the contents of point Q into P * - * \param ctx The restart context to initialize. This must - * not be \c NULL. - */ -void mbedtls_ecp_restart_init( mbedtls_ecp_restart_ctx *ctx ); - -/** - * \brief Free the components of a restart context. + * \param P Destination point + * \param Q Source point * - * \param ctx The restart context to free. This may be \c NULL, in which - * case this function returns immediately. If it is not - * \c NULL, it must point to an initialized restart context. - */ -void mbedtls_ecp_restart_free( mbedtls_ecp_restart_ctx *ctx ); -#endif /* MBEDTLS_ECP_RESTARTABLE */ - -/** - * \brief This function copies the contents of point \p Q into - * point \p P. - * - * \param P The destination point. This must be initialized. - * \param Q The source point. This must be initialized. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. - * \return Another negative error code for other kinds of failure. + * \return 0 if successful, + * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed */ int mbedtls_ecp_copy( mbedtls_ecp_point *P, const mbedtls_ecp_point *Q ); /** - * \brief This function copies the contents of group \p src into - * group \p dst. + * \brief Copy the contents of a group object * - * \param dst The destination group. This must be initialized. - * \param src The source group. This must be initialized. + * \param dst Destination group + * \param src Source group * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. - * \return Another negative error code on other kinds of failure. + * \return 0 if successful, + * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed */ -int mbedtls_ecp_group_copy( mbedtls_ecp_group *dst, - const mbedtls_ecp_group *src ); +int mbedtls_ecp_group_copy( mbedtls_ecp_group *dst, const mbedtls_ecp_group *src ); /** - * \brief This function sets a point to the point at infinity. + * \brief Set a point to zero * - * \param pt The point to set. This must be initialized. + * \param pt Destination point * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. - * \return Another negative error code on other kinds of failure. + * \return 0 if successful, + * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed */ int mbedtls_ecp_set_zero( mbedtls_ecp_point *pt ); /** - * \brief This function checks if a point is the point at infinity. + * \brief Tell if a point is zero * - * \param pt The point to test. This must be initialized. + * \param pt Point to test * - * \return \c 1 if the point is zero. - * \return \c 0 if the point is non-zero. - * \return A negative error code on failure. + * \return 1 if point is zero, 0 otherwise */ int mbedtls_ecp_is_zero( mbedtls_ecp_point *pt ); /** - * \brief This function compares two points. + * \brief Compare two points * - * \note This assumes that the points are normalized. Otherwise, + * \note This assumes the points are normalized. Otherwise, * they may compare as "not equal" even if they are. * - * \param P The first point to compare. This must be initialized. - * \param Q The second point to compare. This must be initialized. + * \param P First point to compare + * \param Q Second point to compare * - * \return \c 0 if the points are equal. - * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the points are not equal. + * \return 0 if the points are equal, + * MBEDTLS_ERR_ECP_BAD_INPUT_DATA otherwise */ int mbedtls_ecp_point_cmp( const mbedtls_ecp_point *P, const mbedtls_ecp_point *Q ); /** - * \brief This function imports a non-zero point from two ASCII - * strings. + * \brief Import a non-zero point from two ASCII strings * - * \param P The destination point. This must be initialized. - * \param radix The numeric base of the input. - * \param x The first affine coordinate, as a null-terminated string. - * \param y The second affine coordinate, as a null-terminated string. + * \param P Destination point + * \param radix Input numeric base + * \param x First affine coordinate as a null-terminated string + * \param y Second affine coordinate as a null-terminated string * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_MPI_XXX error code on failure. + * \return 0 if successful, or a MBEDTLS_ERR_MPI_XXX error code */ int mbedtls_ecp_point_read_string( mbedtls_ecp_point *P, int radix, const char *x, const char *y ); /** - * \brief This function exports a point into unsigned binary data. + * \brief Export a point into unsigned binary data * - * \param grp The group to which the point should belong. - * This must be initialized and have group parameters - * set, for example through mbedtls_ecp_group_load(). - * \param P The point to export. This must be initialized. - * \param format The point format. This must be either - * #MBEDTLS_ECP_PF_COMPRESSED or #MBEDTLS_ECP_PF_UNCOMPRESSED. - * \param olen The address at which to store the length of - * the output in Bytes. This must not be \c NULL. - * \param buf The output buffer. This must be a writable buffer - * of length \p buflen Bytes. - * \param buflen The length of the output buffer \p buf in Bytes. + * \param grp Group to which the point should belong + * \param P Point to export + * \param format Point format, should be a MBEDTLS_ECP_PF_XXX macro + * \param olen Length of the actual output + * \param buf Output buffer + * \param buflen Length of the output buffer * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL if the output buffer - * is too small to hold the point. - * \return Another negative error code on other kinds of failure. + * \return 0 if successful, + * or MBEDTLS_ERR_ECP_BAD_INPUT_DATA + * or MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL */ int mbedtls_ecp_point_write_binary( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *P, int format, size_t *olen, unsigned char *buf, size_t buflen ); /** - * \brief This function imports a point from unsigned binary data. + * \brief Import a point from unsigned binary data * - * \note This function does not check that the point actually - * belongs to the given group, see mbedtls_ecp_check_pubkey() - * for that. + * \param grp Group to which the point should belong + * \param P Point to import + * \param buf Input buffer + * \param ilen Actual length of input * - * \param grp The group to which the point should belong. - * This must be initialized and have group parameters - * set, for example through mbedtls_ecp_group_load(). - * \param P The destination context to import the point to. - * This must be initialized. - * \param buf The input buffer. This must be a readable buffer - * of length \p ilen Bytes. - * \param ilen The length of the input buffer \p buf in Bytes. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the input is invalid. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. - * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the point format + * \return 0 if successful, + * MBEDTLS_ERR_ECP_BAD_INPUT_DATA if input is invalid, + * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed, + * MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the point format * is not implemented. + * + * \note This function does NOT check that the point actually + * belongs to the given group, see mbedtls_ecp_check_pubkey() for + * that. */ -int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp, - mbedtls_ecp_point *P, - const unsigned char *buf, size_t ilen ); +int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp, mbedtls_ecp_point *P, + const unsigned char *buf, size_t ilen ); /** - * \brief This function imports a point from a TLS ECPoint record. + * \brief Import a point from a TLS ECPoint record * - * \note On function return, \p *buf is updated to point immediately - * after the ECPoint record. + * \param grp ECP group used + * \param pt Destination point + * \param buf $(Start of input buffer) + * \param len Buffer length * - * \param grp The ECP group to use. - * This must be initialized and have group parameters - * set, for example through mbedtls_ecp_group_load(). - * \param pt The destination point. - * \param buf The address of the pointer to the start of the input buffer. - * \param len The length of the buffer. + * \note buf is updated to point right after the ECPoint on exit * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_MPI_XXX error code on initialization - * failure. - * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if input is invalid. + * \return 0 if successful, + * MBEDTLS_ERR_MPI_XXX if initialization failed + * MBEDTLS_ERR_ECP_BAD_INPUT_DATA if input is invalid */ -int mbedtls_ecp_tls_read_point( const mbedtls_ecp_group *grp, - mbedtls_ecp_point *pt, - const unsigned char **buf, size_t len ); +int mbedtls_ecp_tls_read_point( const mbedtls_ecp_group *grp, mbedtls_ecp_point *pt, + const unsigned char **buf, size_t len ); /** - * \brief This function exports a point as a TLS ECPoint record - * defined in RFC 4492, Section 5.4. + * \brief Export a point as a TLS ECPoint record * - * \param grp The ECP group to use. - * This must be initialized and have group parameters - * set, for example through mbedtls_ecp_group_load(). - * \param pt The point to be exported. This must be initialized. - * \param format The point format to use. This must be either - * #MBEDTLS_ECP_PF_COMPRESSED or #MBEDTLS_ECP_PF_UNCOMPRESSED. - * \param olen The address at which to store the length in Bytes - * of the data written. - * \param buf The target buffer. This must be a writable buffer of - * length \p blen Bytes. - * \param blen The length of the target buffer \p buf in Bytes. + * \param grp ECP group used + * \param pt Point to export + * \param format Export format + * \param olen length of data written + * \param buf Buffer to write to + * \param blen Buffer length * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the input is invalid. - * \return #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL if the target buffer - * is too small to hold the exported point. - * \return Another negative error code on other kinds of failure. + * \return 0 if successful, + * or MBEDTLS_ERR_ECP_BAD_INPUT_DATA + * or MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL */ -int mbedtls_ecp_tls_write_point( const mbedtls_ecp_group *grp, - const mbedtls_ecp_point *pt, - int format, size_t *olen, - unsigned char *buf, size_t blen ); +int mbedtls_ecp_tls_write_point( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt, + int format, size_t *olen, + unsigned char *buf, size_t blen ); /** - * \brief This function sets up an ECP group context - * from a standardized set of domain parameters. + * \brief Set a group using well-known domain parameters * - * \note The index should be a value of the NamedCurve enum, - * as defined in RFC-4492: Elliptic Curve Cryptography - * (ECC) Cipher Suites for Transport Layer Security (TLS), - * usually in the form of an \c MBEDTLS_ECP_DP_XXX macro. + * \param grp Destination group + * \param id Index in the list of well-known domain parameters * - * \param grp The group context to setup. This must be initialized. - * \param id The identifier of the domain parameter set to load. + * \return 0 if successful, + * MBEDTLS_ERR_MPI_XXX if initialization failed + * MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE for unkownn groups * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if \p id doesn't - * correspond to a known group. - * \return Another negative error code on other kinds of failure. + * \note Index should be a value of RFC 4492's enum NamedCurve, + * usually in the form of a MBEDTLS_ECP_DP_XXX macro. */ int mbedtls_ecp_group_load( mbedtls_ecp_group *grp, mbedtls_ecp_group_id id ); /** - * \brief This function sets up an ECP group context from a TLS - * ECParameters record as defined in RFC 4492, Section 5.4. + * \brief Set a group from a TLS ECParameters record * - * \note The read pointer \p buf is updated to point right after - * the ECParameters record on exit. + * \param grp Destination group + * \param buf &(Start of input buffer) + * \param len Buffer length * - * \param grp The group context to setup. This must be initialized. - * \param buf The address of the pointer to the start of the input buffer. - * \param len The length of the input buffer \c *buf in Bytes. + * \note buf is updated to point right after ECParameters on exit * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if input is invalid. - * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the group is not - * recognized. - * \return Another negative error code on other kinds of failure. + * \return 0 if successful, + * MBEDTLS_ERR_MPI_XXX if initialization failed + * MBEDTLS_ERR_ECP_BAD_INPUT_DATA if input is invalid */ -int mbedtls_ecp_tls_read_group( mbedtls_ecp_group *grp, - const unsigned char **buf, size_t len ); +int mbedtls_ecp_tls_read_group( mbedtls_ecp_group *grp, const unsigned char **buf, size_t len ); /** - * \brief This function extracts an elliptic curve group ID from a - * TLS ECParameters record as defined in RFC 4492, Section 5.4. + * \brief Write the TLS ECParameters record for a group * - * \note The read pointer \p buf is updated to point right after - * the ECParameters record on exit. + * \param grp ECP group used + * \param olen Number of bytes actually written + * \param buf Buffer to write to + * \param blen Buffer length * - * \param grp The address at which to store the group id. - * This must not be \c NULL. - * \param buf The address of the pointer to the start of the input buffer. - * \param len The length of the input buffer \c *buf in Bytes. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if input is invalid. - * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the group is not - * recognized. - * \return Another negative error code on other kinds of failure. + * \return 0 if successful, + * or MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL */ -int mbedtls_ecp_tls_read_group_id( mbedtls_ecp_group_id *grp, - const unsigned char **buf, - size_t len ); -/** - * \brief This function exports an elliptic curve as a TLS - * ECParameters record as defined in RFC 4492, Section 5.4. - * - * \param grp The ECP group to be exported. - * This must be initialized and have group parameters - * set, for example through mbedtls_ecp_group_load(). - * \param olen The address at which to store the number of Bytes written. - * This must not be \c NULL. - * \param buf The buffer to write to. This must be a writable buffer - * of length \p blen Bytes. - * \param blen The length of the output buffer \p buf in Bytes. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL if the output - * buffer is too small to hold the exported group. - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_ecp_tls_write_group( const mbedtls_ecp_group *grp, - size_t *olen, - unsigned char *buf, size_t blen ); +int mbedtls_ecp_tls_write_group( const mbedtls_ecp_group *grp, size_t *olen, + unsigned char *buf, size_t blen ); /** - * \brief This function performs a scalar multiplication of a point - * by an integer: \p R = \p m * \p P. + * \brief Multiplication by an integer: R = m * P + * (Not thread-safe to use same group in multiple threads) * - * It is not thread-safe to use same group in multiple threads. + * \note In order to prevent timing attacks, this function + * executes the exact same sequence of (base field) + * operations for any valid m. It avoids any if-branch or + * array index depending on the value of m. * - * \note To prevent timing attacks, this function - * executes the exact same sequence of base-field - * operations for any valid \p m. It avoids any if-branch or - * array index depending on the value of \p m. + * \note If f_rng is not NULL, it is used to randomize intermediate + * results in order to prevent potential timing attacks + * targeting these results. It is recommended to always + * provide a non-NULL f_rng (the overhead is negligible). * - * \note If \p f_rng is not NULL, it is used to randomize - * intermediate results to prevent potential timing attacks - * targeting these results. We recommend always providing - * a non-NULL \p f_rng. The overhead is negligible. + * \param grp ECP group + * \param R Destination point + * \param m Integer by which to multiply + * \param P Point to multiply + * \param f_rng RNG function (see notes) + * \param p_rng RNG parameter * - * \param grp The ECP group to use. - * This must be initialized and have group parameters - * set, for example through mbedtls_ecp_group_load(). - * \param R The point in which to store the result of the calculation. - * This must be initialized. - * \param m The integer by which to multiply. This must be initialized. - * \param P The point to multiply. This must be initialized. - * \param f_rng The RNG function. This may be \c NULL if randomization - * of intermediate results isn't desired (discouraged). - * \param p_rng The RNG context to be passed to \p p_rng. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_INVALID_KEY if \p m is not a valid private - * key, or \p P is not a valid public key. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. - * \return Another negative error code on other kinds of failure. + * \return 0 if successful, + * MBEDTLS_ERR_ECP_INVALID_KEY if m is not a valid privkey + * or P is not a valid pubkey, + * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed */ int mbedtls_ecp_mul( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, const mbedtls_mpi *m, const mbedtls_ecp_point *P, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); /** - * \brief This function performs multiplication of a point by - * an integer: \p R = \p m * \p P in a restartable way. + * \brief Multiplication and addition of two points by integers: + * R = m * P + n * Q + * (Not thread-safe to use same group in multiple threads) * - * \see mbedtls_ecp_mul() + * \note In contrast to mbedtls_ecp_mul(), this function does not guarantee + * a constant execution flow and timing. * - * \note This function does the same as \c mbedtls_ecp_mul(), but - * it can return early and restart according to the limit set - * with \c mbedtls_ecp_set_max_ops() to reduce blocking. + * \param grp ECP group + * \param R Destination point + * \param m Integer by which to multiply P + * \param P Point to multiply by m + * \param n Integer by which to multiply Q + * \param Q Point to be multiplied by n * - * \param grp The ECP group to use. - * This must be initialized and have group parameters - * set, for example through mbedtls_ecp_group_load(). - * \param R The point in which to store the result of the calculation. - * This must be initialized. - * \param m The integer by which to multiply. This must be initialized. - * \param P The point to multiply. This must be initialized. - * \param f_rng The RNG function. This may be \c NULL if randomization - * of intermediate results isn't desired (discouraged). - * \param p_rng The RNG context to be passed to \p p_rng. - * \param rs_ctx The restart context (NULL disables restart). - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_INVALID_KEY if \p m is not a valid private - * key, or \p P is not a valid public key. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. - * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of - * operations was reached: see \c mbedtls_ecp_set_max_ops(). - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_ecp_mul_restartable( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, - const mbedtls_mpi *m, const mbedtls_ecp_point *P, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, - mbedtls_ecp_restart_ctx *rs_ctx ); - -/** - * \brief This function performs multiplication and addition of two - * points by integers: \p R = \p m * \p P + \p n * \p Q - * - * It is not thread-safe to use same group in multiple threads. - * - * \note In contrast to mbedtls_ecp_mul(), this function does not - * guarantee a constant execution flow and timing. - * - * \param grp The ECP group to use. - * This must be initialized and have group parameters - * set, for example through mbedtls_ecp_group_load(). - * \param R The point in which to store the result of the calculation. - * This must be initialized. - * \param m The integer by which to multiply \p P. - * This must be initialized. - * \param P The point to multiply by \p m. This must be initialized. - * \param n The integer by which to multiply \p Q. - * This must be initialized. - * \param Q The point to be multiplied by \p n. - * This must be initialized. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_INVALID_KEY if \p m or \p n are not - * valid private keys, or \p P or \p Q are not valid public - * keys. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. - * \return Another negative error code on other kinds of failure. + * \return 0 if successful, + * MBEDTLS_ERR_ECP_INVALID_KEY if m or n is not a valid privkey + * or P or Q is not a valid pubkey, + * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed */ int mbedtls_ecp_muladd( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, const mbedtls_mpi *m, const mbedtls_ecp_point *P, const mbedtls_mpi *n, const mbedtls_ecp_point *Q ); /** - * \brief This function performs multiplication and addition of two - * points by integers: \p R = \p m * \p P + \p n * \p Q in a - * restartable way. + * \brief Check that a point is a valid public key on this curve * - * \see \c mbedtls_ecp_muladd() + * \param grp Curve/group the point should belong to + * \param pt Point to check * - * \note This function works the same as \c mbedtls_ecp_muladd(), - * but it can return early and restart according to the limit - * set with \c mbedtls_ecp_set_max_ops() to reduce blocking. + * \return 0 if point is a valid public key, + * MBEDTLS_ERR_ECP_INVALID_KEY otherwise. * - * \param grp The ECP group to use. - * This must be initialized and have group parameters - * set, for example through mbedtls_ecp_group_load(). - * \param R The point in which to store the result of the calculation. - * This must be initialized. - * \param m The integer by which to multiply \p P. - * This must be initialized. - * \param P The point to multiply by \p m. This must be initialized. - * \param n The integer by which to multiply \p Q. - * This must be initialized. - * \param Q The point to be multiplied by \p n. - * This must be initialized. - * \param rs_ctx The restart context (NULL disables restart). + * \note This function only checks the point is non-zero, has valid + * coordinates and lies on the curve, but not that it is + * indeed a multiple of G. This is additional check is more + * expensive, isn't required by standards, and shouldn't be + * necessary if the group used has a small cofactor. In + * particular, it is useless for the NIST groups which all + * have a cofactor of 1. * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_INVALID_KEY if \p m or \p n are not - * valid private keys, or \p P or \p Q are not valid public - * keys. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. - * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of - * operations was reached: see \c mbedtls_ecp_set_max_ops(). - * \return Another negative error code on other kinds of failure. + * \note Uses bare components rather than an mbedtls_ecp_keypair structure + * in order to ease use with other structures such as + * mbedtls_ecdh_context of mbedtls_ecdsa_context. */ -int mbedtls_ecp_muladd_restartable( - mbedtls_ecp_group *grp, mbedtls_ecp_point *R, - const mbedtls_mpi *m, const mbedtls_ecp_point *P, - const mbedtls_mpi *n, const mbedtls_ecp_point *Q, - mbedtls_ecp_restart_ctx *rs_ctx ); +int mbedtls_ecp_check_pubkey( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt ); /** - * \brief This function checks that a point is a valid public key - * on this curve. + * \brief Check that an mbedtls_mpi is a valid private key for this curve * - * It only checks that the point is non-zero, has - * valid coordinates and lies on the curve. It does not verify - * that it is indeed a multiple of \p G. This additional - * check is computationally more expensive, is not required - * by standards, and should not be necessary if the group - * used has a small cofactor. In particular, it is useless for - * the NIST groups which all have a cofactor of 1. + * \param grp Group used + * \param d Integer to check * - * \note This function uses bare components rather than an - * ::mbedtls_ecp_keypair structure, to ease use with other - * structures, such as ::mbedtls_ecdh_context or - * ::mbedtls_ecdsa_context. + * \return 0 if point is a valid private key, + * MBEDTLS_ERR_ECP_INVALID_KEY otherwise. * - * \param grp The ECP group the point should belong to. - * This must be initialized and have group parameters - * set, for example through mbedtls_ecp_group_load(). - * \param pt The point to check. This must be initialized. - * - * \return \c 0 if the point is a valid public key. - * \return #MBEDTLS_ERR_ECP_INVALID_KEY if the point is not - * a valid public key for the given curve. - * \return Another negative error code on other kinds of failure. + * \note Uses bare components rather than an mbedtls_ecp_keypair structure + * in order to ease use with other structures such as + * mbedtls_ecdh_context of mbedtls_ecdsa_context. */ -int mbedtls_ecp_check_pubkey( const mbedtls_ecp_group *grp, - const mbedtls_ecp_point *pt ); +int mbedtls_ecp_check_privkey( const mbedtls_ecp_group *grp, const mbedtls_mpi *d ); /** - * \brief This function checks that an \p mbedtls_mpi is a - * valid private key for this curve. + * \brief Generate a keypair with configurable base point * - * \note This function uses bare components rather than an - * ::mbedtls_ecp_keypair structure to ease use with other - * structures, such as ::mbedtls_ecdh_context or - * ::mbedtls_ecdsa_context. + * \param grp ECP group + * \param G Chosen base point + * \param d Destination MPI (secret part) + * \param Q Destination point (public part) + * \param f_rng RNG function + * \param p_rng RNG parameter * - * \param grp The ECP group the private key should belong to. - * This must be initialized and have group parameters - * set, for example through mbedtls_ecp_group_load(). - * \param d The integer to check. This must be initialized. + * \return 0 if successful, + * or a MBEDTLS_ERR_ECP_XXX or MBEDTLS_MPI_XXX error code * - * \return \c 0 if the point is a valid private key. - * \return #MBEDTLS_ERR_ECP_INVALID_KEY if the point is not a valid - * private key for the given curve. - * \return Another negative error code on other kinds of failure. + * \note Uses bare components rather than an mbedtls_ecp_keypair structure + * in order to ease use with other structures such as + * mbedtls_ecdh_context of mbedtls_ecdsa_context. */ -int mbedtls_ecp_check_privkey( const mbedtls_ecp_group *grp, - const mbedtls_mpi *d ); - -/** - * \brief This function generates a private key. - * - * \param grp The ECP group to generate a private key for. - * This must be initialized and have group parameters - * set, for example through mbedtls_ecp_group_load(). - * \param d The destination MPI (secret part). This must be initialized. - * \param f_rng The RNG function. This must not be \c NULL. - * \param p_rng The RNG parameter to be passed to \p f_rng. This may be - * \c NULL if \p f_rng doesn't need a context argument. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX error code - * on failure. - */ -int mbedtls_ecp_gen_privkey( const mbedtls_ecp_group *grp, - mbedtls_mpi *d, +int mbedtls_ecp_gen_keypair_base( mbedtls_ecp_group *grp, + const mbedtls_ecp_point *G, + mbedtls_mpi *d, mbedtls_ecp_point *Q, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); /** - * \brief This function generates a keypair with a configurable base - * point. + * \brief Generate a keypair * - * \note This function uses bare components rather than an - * ::mbedtls_ecp_keypair structure to ease use with other - * structures, such as ::mbedtls_ecdh_context or - * ::mbedtls_ecdsa_context. + * \param grp ECP group + * \param d Destination MPI (secret part) + * \param Q Destination point (public part) + * \param f_rng RNG function + * \param p_rng RNG parameter * - * \param grp The ECP group to generate a key pair for. - * This must be initialized and have group parameters - * set, for example through mbedtls_ecp_group_load(). - * \param G The base point to use. This must be initialized - * and belong to \p grp. It replaces the default base - * point \c grp->G used by mbedtls_ecp_gen_keypair(). - * \param d The destination MPI (secret part). - * This must be initialized. - * \param Q The destination point (public part). - * This must be initialized. - * \param f_rng The RNG function. This must not be \c NULL. - * \param p_rng The RNG context to be passed to \p f_rng. This may - * be \c NULL if \p f_rng doesn't need a context argument. + * \return 0 if successful, + * or a MBEDTLS_ERR_ECP_XXX or MBEDTLS_MPI_XXX error code * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX error code - * on failure. + * \note Uses bare components rather than an mbedtls_ecp_keypair structure + * in order to ease use with other structures such as + * mbedtls_ecdh_context of mbedtls_ecdsa_context. */ -int mbedtls_ecp_gen_keypair_base( mbedtls_ecp_group *grp, - const mbedtls_ecp_point *G, - mbedtls_mpi *d, mbedtls_ecp_point *Q, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ); +int mbedtls_ecp_gen_keypair( mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp_point *Q, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ); /** - * \brief This function generates an ECP keypair. + * \brief Generate a keypair * - * \note This function uses bare components rather than an - * ::mbedtls_ecp_keypair structure to ease use with other - * structures, such as ::mbedtls_ecdh_context or - * ::mbedtls_ecdsa_context. + * \param grp_id ECP group identifier + * \param key Destination keypair + * \param f_rng RNG function + * \param p_rng RNG parameter * - * \param grp The ECP group to generate a key pair for. - * This must be initialized and have group parameters - * set, for example through mbedtls_ecp_group_load(). - * \param d The destination MPI (secret part). - * This must be initialized. - * \param Q The destination point (public part). - * This must be initialized. - * \param f_rng The RNG function. This must not be \c NULL. - * \param p_rng The RNG context to be passed to \p f_rng. This may - * be \c NULL if \p f_rng doesn't need a context argument. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX error code - * on failure. - */ -int mbedtls_ecp_gen_keypair( mbedtls_ecp_group *grp, mbedtls_mpi *d, - mbedtls_ecp_point *Q, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ); - -/** - * \brief This function generates an ECP key. - * - * \param grp_id The ECP group identifier. - * \param key The destination key. This must be initialized. - * \param f_rng The RNG function to use. This must not be \c NULL. - * \param p_rng The RNG context to be passed to \p f_rng. This may - * be \c NULL if \p f_rng doesn't need a context argument. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX error code - * on failure. + * \return 0 if successful, + * or a MBEDTLS_ERR_ECP_XXX or MBEDTLS_MPI_XXX error code */ int mbedtls_ecp_gen_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ); + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); /** - * \brief This function checks that the keypair objects - * \p pub and \p prv have the same group and the - * same public point, and that the private key in - * \p prv is consistent with the public key. + * \brief Check a public-private key pair * - * \param pub The keypair structure holding the public key. This - * must be initialized. If it contains a private key, that - * part is ignored. - * \param prv The keypair structure holding the full keypair. - * This must be initialized. + * \param pub Keypair structure holding a public key + * \param prv Keypair structure holding a private (plus public) key * - * \return \c 0 on success, meaning that the keys are valid and match. - * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the keys are invalid or do not match. - * \return An \c MBEDTLS_ERR_ECP_XXX or an \c MBEDTLS_ERR_MPI_XXX - * error code on calculation failure. + * \return 0 if successful (keys are valid and match), or + * MBEDTLS_ERR_ECP_BAD_INPUT_DATA, or + * a MBEDTLS_ERR_ECP_XXX or MBEDTLS_ERR_MPI_XXX code. */ -int mbedtls_ecp_check_pub_priv( const mbedtls_ecp_keypair *pub, - const mbedtls_ecp_keypair *prv ); +int mbedtls_ecp_check_pub_priv( const mbedtls_ecp_keypair *pub, const mbedtls_ecp_keypair *prv ); #if defined(MBEDTLS_SELF_TEST) /** - * \brief The ECP checkup routine. + * \brief Checkup routine * - * \return \c 0 on success. - * \return \c 1 on failure. + * \return 0 if successful, or 1 if a test failed */ int mbedtls_ecp_self_test( int verbose ); @@ -1129,4 +685,8 @@ int mbedtls_ecp_self_test( int verbose ); } #endif +#else /* MBEDTLS_ECP_ALT */ +#include "ecp_alt.h" +#endif /* MBEDTLS_ECP_ALT */ + #endif /* ecp.h */ diff --git a/APP_Framework/Framework/security/mbedtls/ecp_curves.c b/APP_Framework/Framework/security/mbedtls/ecp_curves.c new file mode 100644 index 000000000..99089001c --- /dev/null +++ b/APP_Framework/Framework/security/mbedtls/ecp_curves.c @@ -0,0 +1,1329 @@ +/* + * Elliptic curves over GF(p): curve-specific data and functions + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_ECP_C) + +#include "ecp.h" + +#include + +#if !defined(MBEDTLS_ECP_ALT) + +#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ + !defined(inline) && !defined(__cplusplus) +#define inline __inline +#endif + +/* + * Conversion macros for embedded constants: + * build lists of mbedtls_mpi_uint's from lists of unsigned char's grouped by 8, 4 or 2 + */ +#if defined(MBEDTLS_HAVE_INT32) + +#define BYTES_TO_T_UINT_4( a, b, c, d ) \ + ( (mbedtls_mpi_uint) a << 0 ) | \ + ( (mbedtls_mpi_uint) b << 8 ) | \ + ( (mbedtls_mpi_uint) c << 16 ) | \ + ( (mbedtls_mpi_uint) d << 24 ) + +#define BYTES_TO_T_UINT_2( a, b ) \ + BYTES_TO_T_UINT_4( a, b, 0, 0 ) + +#define BYTES_TO_T_UINT_8( a, b, c, d, e, f, g, h ) \ + BYTES_TO_T_UINT_4( a, b, c, d ), \ + BYTES_TO_T_UINT_4( e, f, g, h ) + +#else /* 64-bits */ + +#define BYTES_TO_T_UINT_8( a, b, c, d, e, f, g, h ) \ + ( (mbedtls_mpi_uint) a << 0 ) | \ + ( (mbedtls_mpi_uint) b << 8 ) | \ + ( (mbedtls_mpi_uint) c << 16 ) | \ + ( (mbedtls_mpi_uint) d << 24 ) | \ + ( (mbedtls_mpi_uint) e << 32 ) | \ + ( (mbedtls_mpi_uint) f << 40 ) | \ + ( (mbedtls_mpi_uint) g << 48 ) | \ + ( (mbedtls_mpi_uint) h << 56 ) + +#define BYTES_TO_T_UINT_4( a, b, c, d ) \ + BYTES_TO_T_UINT_8( a, b, c, d, 0, 0, 0, 0 ) + +#define BYTES_TO_T_UINT_2( a, b ) \ + BYTES_TO_T_UINT_8( a, b, 0, 0, 0, 0, 0, 0 ) + +#endif /* bits in mbedtls_mpi_uint */ + +/* + * Note: the constants are in little-endian order + * to be directly usable in MPIs + */ + +/* + * Domain parameters for secp192r1 + */ +#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) +static const mbedtls_mpi_uint secp192r1_p[] = { + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), +}; +static const mbedtls_mpi_uint secp192r1_b[] = { + BYTES_TO_T_UINT_8( 0xB1, 0xB9, 0x46, 0xC1, 0xEC, 0xDE, 0xB8, 0xFE ), + BYTES_TO_T_UINT_8( 0x49, 0x30, 0x24, 0x72, 0xAB, 0xE9, 0xA7, 0x0F ), + BYTES_TO_T_UINT_8( 0xE7, 0x80, 0x9C, 0xE5, 0x19, 0x05, 0x21, 0x64 ), +}; +static const mbedtls_mpi_uint secp192r1_gx[] = { + BYTES_TO_T_UINT_8( 0x12, 0x10, 0xFF, 0x82, 0xFD, 0x0A, 0xFF, 0xF4 ), + BYTES_TO_T_UINT_8( 0x00, 0x88, 0xA1, 0x43, 0xEB, 0x20, 0xBF, 0x7C ), + BYTES_TO_T_UINT_8( 0xF6, 0x90, 0x30, 0xB0, 0x0E, 0xA8, 0x8D, 0x18 ), +}; +static const mbedtls_mpi_uint secp192r1_gy[] = { + BYTES_TO_T_UINT_8( 0x11, 0x48, 0x79, 0x1E, 0xA1, 0x77, 0xF9, 0x73 ), + BYTES_TO_T_UINT_8( 0xD5, 0xCD, 0x24, 0x6B, 0xED, 0x11, 0x10, 0x63 ), + BYTES_TO_T_UINT_8( 0x78, 0xDA, 0xC8, 0xFF, 0x95, 0x2B, 0x19, 0x07 ), +}; +static const mbedtls_mpi_uint secp192r1_n[] = { + BYTES_TO_T_UINT_8( 0x31, 0x28, 0xD2, 0xB4, 0xB1, 0xC9, 0x6B, 0x14 ), + BYTES_TO_T_UINT_8( 0x36, 0xF8, 0xDE, 0x99, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), +}; +#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */ + +/* + * Domain parameters for secp224r1 + */ +#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) +static const mbedtls_mpi_uint secp224r1_p[] = { + BYTES_TO_T_UINT_8( 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ), + BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ), +}; +static const mbedtls_mpi_uint secp224r1_b[] = { + BYTES_TO_T_UINT_8( 0xB4, 0xFF, 0x55, 0x23, 0x43, 0x39, 0x0B, 0x27 ), + BYTES_TO_T_UINT_8( 0xBA, 0xD8, 0xBF, 0xD7, 0xB7, 0xB0, 0x44, 0x50 ), + BYTES_TO_T_UINT_8( 0x56, 0x32, 0x41, 0xF5, 0xAB, 0xB3, 0x04, 0x0C ), + BYTES_TO_T_UINT_4( 0x85, 0x0A, 0x05, 0xB4 ), +}; +static const mbedtls_mpi_uint secp224r1_gx[] = { + BYTES_TO_T_UINT_8( 0x21, 0x1D, 0x5C, 0x11, 0xD6, 0x80, 0x32, 0x34 ), + BYTES_TO_T_UINT_8( 0x22, 0x11, 0xC2, 0x56, 0xD3, 0xC1, 0x03, 0x4A ), + BYTES_TO_T_UINT_8( 0xB9, 0x90, 0x13, 0x32, 0x7F, 0xBF, 0xB4, 0x6B ), + BYTES_TO_T_UINT_4( 0xBD, 0x0C, 0x0E, 0xB7 ), +}; +static const mbedtls_mpi_uint secp224r1_gy[] = { + BYTES_TO_T_UINT_8( 0x34, 0x7E, 0x00, 0x85, 0x99, 0x81, 0xD5, 0x44 ), + BYTES_TO_T_UINT_8( 0x64, 0x47, 0x07, 0x5A, 0xA0, 0x75, 0x43, 0xCD ), + BYTES_TO_T_UINT_8( 0xE6, 0xDF, 0x22, 0x4C, 0xFB, 0x23, 0xF7, 0xB5 ), + BYTES_TO_T_UINT_4( 0x88, 0x63, 0x37, 0xBD ), +}; +static const mbedtls_mpi_uint secp224r1_n[] = { + BYTES_TO_T_UINT_8( 0x3D, 0x2A, 0x5C, 0x5C, 0x45, 0x29, 0xDD, 0x13 ), + BYTES_TO_T_UINT_8( 0x3E, 0xF0, 0xB8, 0xE0, 0xA2, 0x16, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_4( 0xFF, 0xFF, 0xFF, 0xFF ), +}; +#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */ + +/* + * Domain parameters for secp256r1 + */ +#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) +static const mbedtls_mpi_uint secp256r1_p[] = { + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ), + BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ), + BYTES_TO_T_UINT_8( 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ), +}; +static const mbedtls_mpi_uint secp256r1_b[] = { + BYTES_TO_T_UINT_8( 0x4B, 0x60, 0xD2, 0x27, 0x3E, 0x3C, 0xCE, 0x3B ), + BYTES_TO_T_UINT_8( 0xF6, 0xB0, 0x53, 0xCC, 0xB0, 0x06, 0x1D, 0x65 ), + BYTES_TO_T_UINT_8( 0xBC, 0x86, 0x98, 0x76, 0x55, 0xBD, 0xEB, 0xB3 ), + BYTES_TO_T_UINT_8( 0xE7, 0x93, 0x3A, 0xAA, 0xD8, 0x35, 0xC6, 0x5A ), +}; +static const mbedtls_mpi_uint secp256r1_gx[] = { + BYTES_TO_T_UINT_8( 0x96, 0xC2, 0x98, 0xD8, 0x45, 0x39, 0xA1, 0xF4 ), + BYTES_TO_T_UINT_8( 0xA0, 0x33, 0xEB, 0x2D, 0x81, 0x7D, 0x03, 0x77 ), + BYTES_TO_T_UINT_8( 0xF2, 0x40, 0xA4, 0x63, 0xE5, 0xE6, 0xBC, 0xF8 ), + BYTES_TO_T_UINT_8( 0x47, 0x42, 0x2C, 0xE1, 0xF2, 0xD1, 0x17, 0x6B ), +}; +static const mbedtls_mpi_uint secp256r1_gy[] = { + BYTES_TO_T_UINT_8( 0xF5, 0x51, 0xBF, 0x37, 0x68, 0x40, 0xB6, 0xCB ), + BYTES_TO_T_UINT_8( 0xCE, 0x5E, 0x31, 0x6B, 0x57, 0x33, 0xCE, 0x2B ), + BYTES_TO_T_UINT_8( 0x16, 0x9E, 0x0F, 0x7C, 0x4A, 0xEB, 0xE7, 0x8E ), + BYTES_TO_T_UINT_8( 0x9B, 0x7F, 0x1A, 0xFE, 0xE2, 0x42, 0xE3, 0x4F ), +}; +static const mbedtls_mpi_uint secp256r1_n[] = { + BYTES_TO_T_UINT_8( 0x51, 0x25, 0x63, 0xFC, 0xC2, 0xCA, 0xB9, 0xF3 ), + BYTES_TO_T_UINT_8( 0x84, 0x9E, 0x17, 0xA7, 0xAD, 0xFA, 0xE6, 0xBC ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ), +}; +#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */ + +/* + * Domain parameters for secp384r1 + */ +#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) +static const mbedtls_mpi_uint secp384r1_p[] = { + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ), + BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), +}; +static const mbedtls_mpi_uint secp384r1_b[] = { + BYTES_TO_T_UINT_8( 0xEF, 0x2A, 0xEC, 0xD3, 0xED, 0xC8, 0x85, 0x2A ), + BYTES_TO_T_UINT_8( 0x9D, 0xD1, 0x2E, 0x8A, 0x8D, 0x39, 0x56, 0xC6 ), + BYTES_TO_T_UINT_8( 0x5A, 0x87, 0x13, 0x50, 0x8F, 0x08, 0x14, 0x03 ), + BYTES_TO_T_UINT_8( 0x12, 0x41, 0x81, 0xFE, 0x6E, 0x9C, 0x1D, 0x18 ), + BYTES_TO_T_UINT_8( 0x19, 0x2D, 0xF8, 0xE3, 0x6B, 0x05, 0x8E, 0x98 ), + BYTES_TO_T_UINT_8( 0xE4, 0xE7, 0x3E, 0xE2, 0xA7, 0x2F, 0x31, 0xB3 ), +}; +static const mbedtls_mpi_uint secp384r1_gx[] = { + BYTES_TO_T_UINT_8( 0xB7, 0x0A, 0x76, 0x72, 0x38, 0x5E, 0x54, 0x3A ), + BYTES_TO_T_UINT_8( 0x6C, 0x29, 0x55, 0xBF, 0x5D, 0xF2, 0x02, 0x55 ), + BYTES_TO_T_UINT_8( 0x38, 0x2A, 0x54, 0x82, 0xE0, 0x41, 0xF7, 0x59 ), + BYTES_TO_T_UINT_8( 0x98, 0x9B, 0xA7, 0x8B, 0x62, 0x3B, 0x1D, 0x6E ), + BYTES_TO_T_UINT_8( 0x74, 0xAD, 0x20, 0xF3, 0x1E, 0xC7, 0xB1, 0x8E ), + BYTES_TO_T_UINT_8( 0x37, 0x05, 0x8B, 0xBE, 0x22, 0xCA, 0x87, 0xAA ), +}; +static const mbedtls_mpi_uint secp384r1_gy[] = { + BYTES_TO_T_UINT_8( 0x5F, 0x0E, 0xEA, 0x90, 0x7C, 0x1D, 0x43, 0x7A ), + BYTES_TO_T_UINT_8( 0x9D, 0x81, 0x7E, 0x1D, 0xCE, 0xB1, 0x60, 0x0A ), + BYTES_TO_T_UINT_8( 0xC0, 0xB8, 0xF0, 0xB5, 0x13, 0x31, 0xDA, 0xE9 ), + BYTES_TO_T_UINT_8( 0x7C, 0x14, 0x9A, 0x28, 0xBD, 0x1D, 0xF4, 0xF8 ), + BYTES_TO_T_UINT_8( 0x29, 0xDC, 0x92, 0x92, 0xBF, 0x98, 0x9E, 0x5D ), + BYTES_TO_T_UINT_8( 0x6F, 0x2C, 0x26, 0x96, 0x4A, 0xDE, 0x17, 0x36 ), +}; +static const mbedtls_mpi_uint secp384r1_n[] = { + BYTES_TO_T_UINT_8( 0x73, 0x29, 0xC5, 0xCC, 0x6A, 0x19, 0xEC, 0xEC ), + BYTES_TO_T_UINT_8( 0x7A, 0xA7, 0xB0, 0x48, 0xB2, 0x0D, 0x1A, 0x58 ), + BYTES_TO_T_UINT_8( 0xDF, 0x2D, 0x37, 0xF4, 0x81, 0x4D, 0x63, 0xC7 ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), +}; +#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */ + +/* + * Domain parameters for secp521r1 + */ +#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) +static const mbedtls_mpi_uint secp521r1_p[] = { + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_2( 0xFF, 0x01 ), +}; +static const mbedtls_mpi_uint secp521r1_b[] = { + BYTES_TO_T_UINT_8( 0x00, 0x3F, 0x50, 0x6B, 0xD4, 0x1F, 0x45, 0xEF ), + BYTES_TO_T_UINT_8( 0xF1, 0x34, 0x2C, 0x3D, 0x88, 0xDF, 0x73, 0x35 ), + BYTES_TO_T_UINT_8( 0x07, 0xBF, 0xB1, 0x3B, 0xBD, 0xC0, 0x52, 0x16 ), + BYTES_TO_T_UINT_8( 0x7B, 0x93, 0x7E, 0xEC, 0x51, 0x39, 0x19, 0x56 ), + BYTES_TO_T_UINT_8( 0xE1, 0x09, 0xF1, 0x8E, 0x91, 0x89, 0xB4, 0xB8 ), + BYTES_TO_T_UINT_8( 0xF3, 0x15, 0xB3, 0x99, 0x5B, 0x72, 0xDA, 0xA2 ), + BYTES_TO_T_UINT_8( 0xEE, 0x40, 0x85, 0xB6, 0xA0, 0x21, 0x9A, 0x92 ), + BYTES_TO_T_UINT_8( 0x1F, 0x9A, 0x1C, 0x8E, 0x61, 0xB9, 0x3E, 0x95 ), + BYTES_TO_T_UINT_2( 0x51, 0x00 ), +}; +static const mbedtls_mpi_uint secp521r1_gx[] = { + BYTES_TO_T_UINT_8( 0x66, 0xBD, 0xE5, 0xC2, 0x31, 0x7E, 0x7E, 0xF9 ), + BYTES_TO_T_UINT_8( 0x9B, 0x42, 0x6A, 0x85, 0xC1, 0xB3, 0x48, 0x33 ), + BYTES_TO_T_UINT_8( 0xDE, 0xA8, 0xFF, 0xA2, 0x27, 0xC1, 0x1D, 0xFE ), + BYTES_TO_T_UINT_8( 0x28, 0x59, 0xE7, 0xEF, 0x77, 0x5E, 0x4B, 0xA1 ), + BYTES_TO_T_UINT_8( 0xBA, 0x3D, 0x4D, 0x6B, 0x60, 0xAF, 0x28, 0xF8 ), + BYTES_TO_T_UINT_8( 0x21, 0xB5, 0x3F, 0x05, 0x39, 0x81, 0x64, 0x9C ), + BYTES_TO_T_UINT_8( 0x42, 0xB4, 0x95, 0x23, 0x66, 0xCB, 0x3E, 0x9E ), + BYTES_TO_T_UINT_8( 0xCD, 0xE9, 0x04, 0x04, 0xB7, 0x06, 0x8E, 0x85 ), + BYTES_TO_T_UINT_2( 0xC6, 0x00 ), +}; +static const mbedtls_mpi_uint secp521r1_gy[] = { + BYTES_TO_T_UINT_8( 0x50, 0x66, 0xD1, 0x9F, 0x76, 0x94, 0xBE, 0x88 ), + BYTES_TO_T_UINT_8( 0x40, 0xC2, 0x72, 0xA2, 0x86, 0x70, 0x3C, 0x35 ), + BYTES_TO_T_UINT_8( 0x61, 0x07, 0xAD, 0x3F, 0x01, 0xB9, 0x50, 0xC5 ), + BYTES_TO_T_UINT_8( 0x40, 0x26, 0xF4, 0x5E, 0x99, 0x72, 0xEE, 0x97 ), + BYTES_TO_T_UINT_8( 0x2C, 0x66, 0x3E, 0x27, 0x17, 0xBD, 0xAF, 0x17 ), + BYTES_TO_T_UINT_8( 0x68, 0x44, 0x9B, 0x57, 0x49, 0x44, 0xF5, 0x98 ), + BYTES_TO_T_UINT_8( 0xD9, 0x1B, 0x7D, 0x2C, 0xB4, 0x5F, 0x8A, 0x5C ), + BYTES_TO_T_UINT_8( 0x04, 0xC0, 0x3B, 0x9A, 0x78, 0x6A, 0x29, 0x39 ), + BYTES_TO_T_UINT_2( 0x18, 0x01 ), +}; +static const mbedtls_mpi_uint secp521r1_n[] = { + BYTES_TO_T_UINT_8( 0x09, 0x64, 0x38, 0x91, 0x1E, 0xB7, 0x6F, 0xBB ), + BYTES_TO_T_UINT_8( 0xAE, 0x47, 0x9C, 0x89, 0xB8, 0xC9, 0xB5, 0x3B ), + BYTES_TO_T_UINT_8( 0xD0, 0xA5, 0x09, 0xF7, 0x48, 0x01, 0xCC, 0x7F ), + BYTES_TO_T_UINT_8( 0x6B, 0x96, 0x2F, 0xBF, 0x83, 0x87, 0x86, 0x51 ), + BYTES_TO_T_UINT_8( 0xFA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_2( 0xFF, 0x01 ), +}; +#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) +static const mbedtls_mpi_uint secp192k1_p[] = { + BYTES_TO_T_UINT_8( 0x37, 0xEE, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), +}; +static const mbedtls_mpi_uint secp192k1_a[] = { + BYTES_TO_T_UINT_2( 0x00, 0x00 ), +}; +static const mbedtls_mpi_uint secp192k1_b[] = { + BYTES_TO_T_UINT_2( 0x03, 0x00 ), +}; +static const mbedtls_mpi_uint secp192k1_gx[] = { + BYTES_TO_T_UINT_8( 0x7D, 0x6C, 0xE0, 0xEA, 0xB1, 0xD1, 0xA5, 0x1D ), + BYTES_TO_T_UINT_8( 0x34, 0xF4, 0xB7, 0x80, 0x02, 0x7D, 0xB0, 0x26 ), + BYTES_TO_T_UINT_8( 0xAE, 0xE9, 0x57, 0xC0, 0x0E, 0xF1, 0x4F, 0xDB ), +}; +static const mbedtls_mpi_uint secp192k1_gy[] = { + BYTES_TO_T_UINT_8( 0x9D, 0x2F, 0x5E, 0xD9, 0x88, 0xAA, 0x82, 0x40 ), + BYTES_TO_T_UINT_8( 0x34, 0x86, 0xBE, 0x15, 0xD0, 0x63, 0x41, 0x84 ), + BYTES_TO_T_UINT_8( 0xA7, 0x28, 0x56, 0x9C, 0x6D, 0x2F, 0x2F, 0x9B ), +}; +static const mbedtls_mpi_uint secp192k1_n[] = { + BYTES_TO_T_UINT_8( 0x8D, 0xFD, 0xDE, 0x74, 0x6A, 0x46, 0x69, 0x0F ), + BYTES_TO_T_UINT_8( 0x17, 0xFC, 0xF2, 0x26, 0xFE, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), +}; +#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) +static const mbedtls_mpi_uint secp224k1_p[] = { + BYTES_TO_T_UINT_8( 0x6D, 0xE5, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_4( 0xFF, 0xFF, 0xFF, 0xFF ), +}; +static const mbedtls_mpi_uint secp224k1_a[] = { + BYTES_TO_T_UINT_2( 0x00, 0x00 ), +}; +static const mbedtls_mpi_uint secp224k1_b[] = { + BYTES_TO_T_UINT_2( 0x05, 0x00 ), +}; +static const mbedtls_mpi_uint secp224k1_gx[] = { + BYTES_TO_T_UINT_8( 0x5C, 0xA4, 0xB7, 0xB6, 0x0E, 0x65, 0x7E, 0x0F ), + BYTES_TO_T_UINT_8( 0xA9, 0x75, 0x70, 0xE4, 0xE9, 0x67, 0xA4, 0x69 ), + BYTES_TO_T_UINT_8( 0xA1, 0x28, 0xFC, 0x30, 0xDF, 0x99, 0xF0, 0x4D ), + BYTES_TO_T_UINT_4( 0x33, 0x5B, 0x45, 0xA1 ), +}; +static const mbedtls_mpi_uint secp224k1_gy[] = { + BYTES_TO_T_UINT_8( 0xA5, 0x61, 0x6D, 0x55, 0xDB, 0x4B, 0xCA, 0xE2 ), + BYTES_TO_T_UINT_8( 0x59, 0xBD, 0xB0, 0xC0, 0xF7, 0x19, 0xE3, 0xF7 ), + BYTES_TO_T_UINT_8( 0xD6, 0xFB, 0xCA, 0x82, 0x42, 0x34, 0xBA, 0x7F ), + BYTES_TO_T_UINT_4( 0xED, 0x9F, 0x08, 0x7E ), +}; +static const mbedtls_mpi_uint secp224k1_n[] = { + BYTES_TO_T_UINT_8( 0xF7, 0xB1, 0x9F, 0x76, 0x71, 0xA9, 0xF0, 0xCA ), + BYTES_TO_T_UINT_8( 0x84, 0x61, 0xEC, 0xD2, 0xE8, 0xDC, 0x01, 0x00 ), + BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ), + BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ), +}; +#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) +static const mbedtls_mpi_uint secp256k1_p[] = { + BYTES_TO_T_UINT_8( 0x2F, 0xFC, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), +}; +static const mbedtls_mpi_uint secp256k1_a[] = { + BYTES_TO_T_UINT_2( 0x00, 0x00 ), +}; +static const mbedtls_mpi_uint secp256k1_b[] = { + BYTES_TO_T_UINT_2( 0x07, 0x00 ), +}; +static const mbedtls_mpi_uint secp256k1_gx[] = { + BYTES_TO_T_UINT_8( 0x98, 0x17, 0xF8, 0x16, 0x5B, 0x81, 0xF2, 0x59 ), + BYTES_TO_T_UINT_8( 0xD9, 0x28, 0xCE, 0x2D, 0xDB, 0xFC, 0x9B, 0x02 ), + BYTES_TO_T_UINT_8( 0x07, 0x0B, 0x87, 0xCE, 0x95, 0x62, 0xA0, 0x55 ), + BYTES_TO_T_UINT_8( 0xAC, 0xBB, 0xDC, 0xF9, 0x7E, 0x66, 0xBE, 0x79 ), +}; +static const mbedtls_mpi_uint secp256k1_gy[] = { + BYTES_TO_T_UINT_8( 0xB8, 0xD4, 0x10, 0xFB, 0x8F, 0xD0, 0x47, 0x9C ), + BYTES_TO_T_UINT_8( 0x19, 0x54, 0x85, 0xA6, 0x48, 0xB4, 0x17, 0xFD ), + BYTES_TO_T_UINT_8( 0xA8, 0x08, 0x11, 0x0E, 0xFC, 0xFB, 0xA4, 0x5D ), + BYTES_TO_T_UINT_8( 0x65, 0xC4, 0xA3, 0x26, 0x77, 0xDA, 0x3A, 0x48 ), +}; +static const mbedtls_mpi_uint secp256k1_n[] = { + BYTES_TO_T_UINT_8( 0x41, 0x41, 0x36, 0xD0, 0x8C, 0x5E, 0xD2, 0xBF ), + BYTES_TO_T_UINT_8( 0x3B, 0xA0, 0x48, 0xAF, 0xE6, 0xDC, 0xAE, 0xBA ), + BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), +}; +#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */ + +/* + * Domain parameters for brainpoolP256r1 (RFC 5639 3.4) + */ +#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) +static const mbedtls_mpi_uint brainpoolP256r1_p[] = { + BYTES_TO_T_UINT_8( 0x77, 0x53, 0x6E, 0x1F, 0x1D, 0x48, 0x13, 0x20 ), + BYTES_TO_T_UINT_8( 0x28, 0x20, 0x26, 0xD5, 0x23, 0xF6, 0x3B, 0x6E ), + BYTES_TO_T_UINT_8( 0x72, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E ), + BYTES_TO_T_UINT_8( 0xBC, 0xA9, 0xEE, 0xA1, 0xDB, 0x57, 0xFB, 0xA9 ), +}; +static const mbedtls_mpi_uint brainpoolP256r1_a[] = { + BYTES_TO_T_UINT_8( 0xD9, 0xB5, 0x30, 0xF3, 0x44, 0x4B, 0x4A, 0xE9 ), + BYTES_TO_T_UINT_8( 0x6C, 0x5C, 0xDC, 0x26, 0xC1, 0x55, 0x80, 0xFB ), + BYTES_TO_T_UINT_8( 0xE7, 0xFF, 0x7A, 0x41, 0x30, 0x75, 0xF6, 0xEE ), + BYTES_TO_T_UINT_8( 0x57, 0x30, 0x2C, 0xFC, 0x75, 0x09, 0x5A, 0x7D ), +}; +static const mbedtls_mpi_uint brainpoolP256r1_b[] = { + BYTES_TO_T_UINT_8( 0xB6, 0x07, 0x8C, 0xFF, 0x18, 0xDC, 0xCC, 0x6B ), + BYTES_TO_T_UINT_8( 0xCE, 0xE1, 0xF7, 0x5C, 0x29, 0x16, 0x84, 0x95 ), + BYTES_TO_T_UINT_8( 0xBF, 0x7C, 0xD7, 0xBB, 0xD9, 0xB5, 0x30, 0xF3 ), + BYTES_TO_T_UINT_8( 0x44, 0x4B, 0x4A, 0xE9, 0x6C, 0x5C, 0xDC, 0x26 ), +}; +static const mbedtls_mpi_uint brainpoolP256r1_gx[] = { + BYTES_TO_T_UINT_8( 0x62, 0x32, 0xCE, 0x9A, 0xBD, 0x53, 0x44, 0x3A ), + BYTES_TO_T_UINT_8( 0xC2, 0x23, 0xBD, 0xE3, 0xE1, 0x27, 0xDE, 0xB9 ), + BYTES_TO_T_UINT_8( 0xAF, 0xB7, 0x81, 0xFC, 0x2F, 0x48, 0x4B, 0x2C ), + BYTES_TO_T_UINT_8( 0xCB, 0x57, 0x7E, 0xCB, 0xB9, 0xAE, 0xD2, 0x8B ), +}; +static const mbedtls_mpi_uint brainpoolP256r1_gy[] = { + BYTES_TO_T_UINT_8( 0x97, 0x69, 0x04, 0x2F, 0xC7, 0x54, 0x1D, 0x5C ), + BYTES_TO_T_UINT_8( 0x54, 0x8E, 0xED, 0x2D, 0x13, 0x45, 0x77, 0xC2 ), + BYTES_TO_T_UINT_8( 0xC9, 0x1D, 0x61, 0x14, 0x1A, 0x46, 0xF8, 0x97 ), + BYTES_TO_T_UINT_8( 0xFD, 0xC4, 0xDA, 0xC3, 0x35, 0xF8, 0x7E, 0x54 ), +}; +static const mbedtls_mpi_uint brainpoolP256r1_n[] = { + BYTES_TO_T_UINT_8( 0xA7, 0x56, 0x48, 0x97, 0x82, 0x0E, 0x1E, 0x90 ), + BYTES_TO_T_UINT_8( 0xF7, 0xA6, 0x61, 0xB5, 0xA3, 0x7A, 0x39, 0x8C ), + BYTES_TO_T_UINT_8( 0x71, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E ), + BYTES_TO_T_UINT_8( 0xBC, 0xA9, 0xEE, 0xA1, 0xDB, 0x57, 0xFB, 0xA9 ), +}; +#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */ + +/* + * Domain parameters for brainpoolP384r1 (RFC 5639 3.6) + */ +#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) +static const mbedtls_mpi_uint brainpoolP384r1_p[] = { + BYTES_TO_T_UINT_8( 0x53, 0xEC, 0x07, 0x31, 0x13, 0x00, 0x47, 0x87 ), + BYTES_TO_T_UINT_8( 0x71, 0x1A, 0x1D, 0x90, 0x29, 0xA7, 0xD3, 0xAC ), + BYTES_TO_T_UINT_8( 0x23, 0x11, 0xB7, 0x7F, 0x19, 0xDA, 0xB1, 0x12 ), + BYTES_TO_T_UINT_8( 0xB4, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15 ), + BYTES_TO_T_UINT_8( 0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F ), + BYTES_TO_T_UINT_8( 0x28, 0x6D, 0x38, 0xA3, 0x82, 0x1E, 0xB9, 0x8C ), +}; +static const mbedtls_mpi_uint brainpoolP384r1_a[] = { + BYTES_TO_T_UINT_8( 0x26, 0x28, 0xCE, 0x22, 0xDD, 0xC7, 0xA8, 0x04 ), + BYTES_TO_T_UINT_8( 0xEB, 0xD4, 0x3A, 0x50, 0x4A, 0x81, 0xA5, 0x8A ), + BYTES_TO_T_UINT_8( 0x0F, 0xF9, 0x91, 0xBA, 0xEF, 0x65, 0x91, 0x13 ), + BYTES_TO_T_UINT_8( 0x87, 0x27, 0xB2, 0x4F, 0x8E, 0xA2, 0xBE, 0xC2 ), + BYTES_TO_T_UINT_8( 0xA0, 0xAF, 0x05, 0xCE, 0x0A, 0x08, 0x72, 0x3C ), + BYTES_TO_T_UINT_8( 0x0C, 0x15, 0x8C, 0x3D, 0xC6, 0x82, 0xC3, 0x7B ), +}; +static const mbedtls_mpi_uint brainpoolP384r1_b[] = { + BYTES_TO_T_UINT_8( 0x11, 0x4C, 0x50, 0xFA, 0x96, 0x86, 0xB7, 0x3A ), + BYTES_TO_T_UINT_8( 0x94, 0xC9, 0xDB, 0x95, 0x02, 0x39, 0xB4, 0x7C ), + BYTES_TO_T_UINT_8( 0xD5, 0x62, 0xEB, 0x3E, 0xA5, 0x0E, 0x88, 0x2E ), + BYTES_TO_T_UINT_8( 0xA6, 0xD2, 0xDC, 0x07, 0xE1, 0x7D, 0xB7, 0x2F ), + BYTES_TO_T_UINT_8( 0x7C, 0x44, 0xF0, 0x16, 0x54, 0xB5, 0x39, 0x8B ), + BYTES_TO_T_UINT_8( 0x26, 0x28, 0xCE, 0x22, 0xDD, 0xC7, 0xA8, 0x04 ), +}; +static const mbedtls_mpi_uint brainpoolP384r1_gx[] = { + BYTES_TO_T_UINT_8( 0x1E, 0xAF, 0xD4, 0x47, 0xE2, 0xB2, 0x87, 0xEF ), + BYTES_TO_T_UINT_8( 0xAA, 0x46, 0xD6, 0x36, 0x34, 0xE0, 0x26, 0xE8 ), + BYTES_TO_T_UINT_8( 0xE8, 0x10, 0xBD, 0x0C, 0xFE, 0xCA, 0x7F, 0xDB ), + BYTES_TO_T_UINT_8( 0xE3, 0x4F, 0xF1, 0x7E, 0xE7, 0xA3, 0x47, 0x88 ), + BYTES_TO_T_UINT_8( 0x6B, 0x3F, 0xC1, 0xB7, 0x81, 0x3A, 0xA6, 0xA2 ), + BYTES_TO_T_UINT_8( 0xFF, 0x45, 0xCF, 0x68, 0xF0, 0x64, 0x1C, 0x1D ), +}; +static const mbedtls_mpi_uint brainpoolP384r1_gy[] = { + BYTES_TO_T_UINT_8( 0x15, 0x53, 0x3C, 0x26, 0x41, 0x03, 0x82, 0x42 ), + BYTES_TO_T_UINT_8( 0x11, 0x81, 0x91, 0x77, 0x21, 0x46, 0x46, 0x0E ), + BYTES_TO_T_UINT_8( 0x28, 0x29, 0x91, 0xF9, 0x4F, 0x05, 0x9C, 0xE1 ), + BYTES_TO_T_UINT_8( 0x64, 0x58, 0xEC, 0xFE, 0x29, 0x0B, 0xB7, 0x62 ), + BYTES_TO_T_UINT_8( 0x52, 0xD5, 0xCF, 0x95, 0x8E, 0xEB, 0xB1, 0x5C ), + BYTES_TO_T_UINT_8( 0xA4, 0xC2, 0xF9, 0x20, 0x75, 0x1D, 0xBE, 0x8A ), +}; +static const mbedtls_mpi_uint brainpoolP384r1_n[] = { + BYTES_TO_T_UINT_8( 0x65, 0x65, 0x04, 0xE9, 0x02, 0x32, 0x88, 0x3B ), + BYTES_TO_T_UINT_8( 0x10, 0xC3, 0x7F, 0x6B, 0xAF, 0xB6, 0x3A, 0xCF ), + BYTES_TO_T_UINT_8( 0xA7, 0x25, 0x04, 0xAC, 0x6C, 0x6E, 0x16, 0x1F ), + BYTES_TO_T_UINT_8( 0xB3, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15 ), + BYTES_TO_T_UINT_8( 0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F ), + BYTES_TO_T_UINT_8( 0x28, 0x6D, 0x38, 0xA3, 0x82, 0x1E, 0xB9, 0x8C ), +}; +#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */ + +/* + * Domain parameters for brainpoolP512r1 (RFC 5639 3.7) + */ +#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) +static const mbedtls_mpi_uint brainpoolP512r1_p[] = { + BYTES_TO_T_UINT_8( 0xF3, 0x48, 0x3A, 0x58, 0x56, 0x60, 0xAA, 0x28 ), + BYTES_TO_T_UINT_8( 0x85, 0xC6, 0x82, 0x2D, 0x2F, 0xFF, 0x81, 0x28 ), + BYTES_TO_T_UINT_8( 0xE6, 0x80, 0xA3, 0xE6, 0x2A, 0xA1, 0xCD, 0xAE ), + BYTES_TO_T_UINT_8( 0x42, 0x68, 0xC6, 0x9B, 0x00, 0x9B, 0x4D, 0x7D ), + BYTES_TO_T_UINT_8( 0x71, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6 ), + BYTES_TO_T_UINT_8( 0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB ), + BYTES_TO_T_UINT_8( 0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F ), + BYTES_TO_T_UINT_8( 0x8B, 0xC4, 0xE9, 0xDB, 0xB8, 0x9D, 0xDD, 0xAA ), +}; +static const mbedtls_mpi_uint brainpoolP512r1_a[] = { + BYTES_TO_T_UINT_8( 0xCA, 0x94, 0xFC, 0x77, 0x4D, 0xAC, 0xC1, 0xE7 ), + BYTES_TO_T_UINT_8( 0xB9, 0xC7, 0xF2, 0x2B, 0xA7, 0x17, 0x11, 0x7F ), + BYTES_TO_T_UINT_8( 0xB5, 0xC8, 0x9A, 0x8B, 0xC9, 0xF1, 0x2E, 0x0A ), + BYTES_TO_T_UINT_8( 0xA1, 0x3A, 0x25, 0xA8, 0x5A, 0x5D, 0xED, 0x2D ), + BYTES_TO_T_UINT_8( 0xBC, 0x63, 0x98, 0xEA, 0xCA, 0x41, 0x34, 0xA8 ), + BYTES_TO_T_UINT_8( 0x10, 0x16, 0xF9, 0x3D, 0x8D, 0xDD, 0xCB, 0x94 ), + BYTES_TO_T_UINT_8( 0xC5, 0x4C, 0x23, 0xAC, 0x45, 0x71, 0x32, 0xE2 ), + BYTES_TO_T_UINT_8( 0x89, 0x3B, 0x60, 0x8B, 0x31, 0xA3, 0x30, 0x78 ), +}; +static const mbedtls_mpi_uint brainpoolP512r1_b[] = { + BYTES_TO_T_UINT_8( 0x23, 0xF7, 0x16, 0x80, 0x63, 0xBD, 0x09, 0x28 ), + BYTES_TO_T_UINT_8( 0xDD, 0xE5, 0xBA, 0x5E, 0xB7, 0x50, 0x40, 0x98 ), + BYTES_TO_T_UINT_8( 0x67, 0x3E, 0x08, 0xDC, 0xCA, 0x94, 0xFC, 0x77 ), + BYTES_TO_T_UINT_8( 0x4D, 0xAC, 0xC1, 0xE7, 0xB9, 0xC7, 0xF2, 0x2B ), + BYTES_TO_T_UINT_8( 0xA7, 0x17, 0x11, 0x7F, 0xB5, 0xC8, 0x9A, 0x8B ), + BYTES_TO_T_UINT_8( 0xC9, 0xF1, 0x2E, 0x0A, 0xA1, 0x3A, 0x25, 0xA8 ), + BYTES_TO_T_UINT_8( 0x5A, 0x5D, 0xED, 0x2D, 0xBC, 0x63, 0x98, 0xEA ), + BYTES_TO_T_UINT_8( 0xCA, 0x41, 0x34, 0xA8, 0x10, 0x16, 0xF9, 0x3D ), +}; +static const mbedtls_mpi_uint brainpoolP512r1_gx[] = { + BYTES_TO_T_UINT_8( 0x22, 0xF8, 0xB9, 0xBC, 0x09, 0x22, 0x35, 0x8B ), + BYTES_TO_T_UINT_8( 0x68, 0x5E, 0x6A, 0x40, 0x47, 0x50, 0x6D, 0x7C ), + BYTES_TO_T_UINT_8( 0x5F, 0x7D, 0xB9, 0x93, 0x7B, 0x68, 0xD1, 0x50 ), + BYTES_TO_T_UINT_8( 0x8D, 0xD4, 0xD0, 0xE2, 0x78, 0x1F, 0x3B, 0xFF ), + BYTES_TO_T_UINT_8( 0x8E, 0x09, 0xD0, 0xF4, 0xEE, 0x62, 0x3B, 0xB4 ), + BYTES_TO_T_UINT_8( 0xC1, 0x16, 0xD9, 0xB5, 0x70, 0x9F, 0xED, 0x85 ), + BYTES_TO_T_UINT_8( 0x93, 0x6A, 0x4C, 0x9C, 0x2E, 0x32, 0x21, 0x5A ), + BYTES_TO_T_UINT_8( 0x64, 0xD9, 0x2E, 0xD8, 0xBD, 0xE4, 0xAE, 0x81 ), +}; +static const mbedtls_mpi_uint brainpoolP512r1_gy[] = { + BYTES_TO_T_UINT_8( 0x92, 0x08, 0xD8, 0x3A, 0x0F, 0x1E, 0xCD, 0x78 ), + BYTES_TO_T_UINT_8( 0x06, 0x54, 0xF0, 0xA8, 0x2F, 0x2B, 0xCA, 0xD1 ), + BYTES_TO_T_UINT_8( 0xAE, 0x63, 0x27, 0x8A, 0xD8, 0x4B, 0xCA, 0x5B ), + BYTES_TO_T_UINT_8( 0x5E, 0x48, 0x5F, 0x4A, 0x49, 0xDE, 0xDC, 0xB2 ), + BYTES_TO_T_UINT_8( 0x11, 0x81, 0x1F, 0x88, 0x5B, 0xC5, 0x00, 0xA0 ), + BYTES_TO_T_UINT_8( 0x1A, 0x7B, 0xA5, 0x24, 0x00, 0xF7, 0x09, 0xF2 ), + BYTES_TO_T_UINT_8( 0xFD, 0x22, 0x78, 0xCF, 0xA9, 0xBF, 0xEA, 0xC0 ), + BYTES_TO_T_UINT_8( 0xEC, 0x32, 0x63, 0x56, 0x5D, 0x38, 0xDE, 0x7D ), +}; +static const mbedtls_mpi_uint brainpoolP512r1_n[] = { + BYTES_TO_T_UINT_8( 0x69, 0x00, 0xA9, 0x9C, 0x82, 0x96, 0x87, 0xB5 ), + BYTES_TO_T_UINT_8( 0xDD, 0xDA, 0x5D, 0x08, 0x81, 0xD3, 0xB1, 0x1D ), + BYTES_TO_T_UINT_8( 0x47, 0x10, 0xAC, 0x7F, 0x19, 0x61, 0x86, 0x41 ), + BYTES_TO_T_UINT_8( 0x19, 0x26, 0xA9, 0x4C, 0x41, 0x5C, 0x3E, 0x55 ), + BYTES_TO_T_UINT_8( 0x70, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6 ), + BYTES_TO_T_UINT_8( 0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB ), + BYTES_TO_T_UINT_8( 0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F ), + BYTES_TO_T_UINT_8( 0x8B, 0xC4, 0xE9, 0xDB, 0xB8, 0x9D, 0xDD, 0xAA ), +}; +#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */ + +/* + * Create an MPI from embedded constants + * (assumes len is an exact multiple of sizeof mbedtls_mpi_uint) + */ +static inline void ecp_mpi_load( mbedtls_mpi *X, const mbedtls_mpi_uint *p, size_t len ) +{ + X->s = 1; + X->n = len / sizeof( mbedtls_mpi_uint ); + X->p = (mbedtls_mpi_uint *) p; +} + +/* + * Set an MPI to static value 1 + */ +static inline void ecp_mpi_set1( mbedtls_mpi *X ) +{ + static mbedtls_mpi_uint one[] = { 1 }; + X->s = 1; + X->n = 1; + X->p = one; +} + +/* + * Make group available from embedded constants + */ +static int ecp_group_load( mbedtls_ecp_group *grp, + const mbedtls_mpi_uint *p, size_t plen, + const mbedtls_mpi_uint *a, size_t alen, + const mbedtls_mpi_uint *b, size_t blen, + const mbedtls_mpi_uint *gx, size_t gxlen, + const mbedtls_mpi_uint *gy, size_t gylen, + const mbedtls_mpi_uint *n, size_t nlen) +{ + ecp_mpi_load( &grp->P, p, plen ); + if( a != NULL ) + ecp_mpi_load( &grp->A, a, alen ); + ecp_mpi_load( &grp->B, b, blen ); + ecp_mpi_load( &grp->N, n, nlen ); + + ecp_mpi_load( &grp->G.X, gx, gxlen ); + ecp_mpi_load( &grp->G.Y, gy, gylen ); + ecp_mpi_set1( &grp->G.Z ); + + grp->pbits = mbedtls_mpi_bitlen( &grp->P ); + grp->nbits = mbedtls_mpi_bitlen( &grp->N ); + + grp->h = 1; + + return( 0 ); +} + +#if defined(MBEDTLS_ECP_NIST_OPTIM) +/* Forward declarations */ +#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) +static int ecp_mod_p192( mbedtls_mpi * ); +#endif +#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) +static int ecp_mod_p224( mbedtls_mpi * ); +#endif +#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) +static int ecp_mod_p256( mbedtls_mpi * ); +#endif +#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) +static int ecp_mod_p384( mbedtls_mpi * ); +#endif +#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) +static int ecp_mod_p521( mbedtls_mpi * ); +#endif + +#define NIST_MODP( P ) grp->modp = ecp_mod_ ## P; +#else +#define NIST_MODP( P ) +#endif /* MBEDTLS_ECP_NIST_OPTIM */ + +/* Additional forward declarations */ +#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) +static int ecp_mod_p255( mbedtls_mpi * ); +#endif +#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) +static int ecp_mod_p192k1( mbedtls_mpi * ); +#endif +#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) +static int ecp_mod_p224k1( mbedtls_mpi * ); +#endif +#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) +static int ecp_mod_p256k1( mbedtls_mpi * ); +#endif + +#define LOAD_GROUP_A( G ) ecp_group_load( grp, \ + G ## _p, sizeof( G ## _p ), \ + G ## _a, sizeof( G ## _a ), \ + G ## _b, sizeof( G ## _b ), \ + G ## _gx, sizeof( G ## _gx ), \ + G ## _gy, sizeof( G ## _gy ), \ + G ## _n, sizeof( G ## _n ) ) + +#define LOAD_GROUP( G ) ecp_group_load( grp, \ + G ## _p, sizeof( G ## _p ), \ + NULL, 0, \ + G ## _b, sizeof( G ## _b ), \ + G ## _gx, sizeof( G ## _gx ), \ + G ## _gy, sizeof( G ## _gy ), \ + G ## _n, sizeof( G ## _n ) ) + +#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) +/* + * Specialized function for creating the Curve25519 group + */ +static int ecp_use_curve25519( mbedtls_ecp_group *grp ) +{ + int ret; + + /* Actually ( A + 2 ) / 4 */ + MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &grp->A, 16, "01DB42" ) ); + + /* P = 2^255 - 19 */ + MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->P, 1 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &grp->P, 255 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &grp->P, &grp->P, 19 ) ); + grp->pbits = mbedtls_mpi_bitlen( &grp->P ); + + /* Y intentionaly not set, since we use x/z coordinates. + * This is used as a marker to identify Montgomery curves! */ + MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->G.X, 9 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->G.Z, 1 ) ); + mbedtls_mpi_free( &grp->G.Y ); + + /* Actually, the required msb for private keys */ + grp->nbits = 254; + +cleanup: + if( ret != 0 ) + mbedtls_ecp_group_free( grp ); + + return( ret ); +} +#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */ + +/* + * Set a group using well-known domain parameters + */ +int mbedtls_ecp_group_load( mbedtls_ecp_group *grp, mbedtls_ecp_group_id id ) +{ + mbedtls_ecp_group_free( grp ); + + grp->id = id; + + switch( id ) + { +#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) + case MBEDTLS_ECP_DP_SECP192R1: + NIST_MODP( p192 ); + return( LOAD_GROUP( secp192r1 ) ); +#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) + case MBEDTLS_ECP_DP_SECP224R1: + NIST_MODP( p224 ); + return( LOAD_GROUP( secp224r1 ) ); +#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) + case MBEDTLS_ECP_DP_SECP256R1: + NIST_MODP( p256 ); + return( LOAD_GROUP( secp256r1 ) ); +#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) + case MBEDTLS_ECP_DP_SECP384R1: + NIST_MODP( p384 ); + return( LOAD_GROUP( secp384r1 ) ); +#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) + case MBEDTLS_ECP_DP_SECP521R1: + NIST_MODP( p521 ); + return( LOAD_GROUP( secp521r1 ) ); +#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) + case MBEDTLS_ECP_DP_SECP192K1: + grp->modp = ecp_mod_p192k1; + return( LOAD_GROUP_A( secp192k1 ) ); +#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) + case MBEDTLS_ECP_DP_SECP224K1: + grp->modp = ecp_mod_p224k1; + return( LOAD_GROUP_A( secp224k1 ) ); +#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) + case MBEDTLS_ECP_DP_SECP256K1: + grp->modp = ecp_mod_p256k1; + return( LOAD_GROUP_A( secp256k1 ) ); +#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) + case MBEDTLS_ECP_DP_BP256R1: + return( LOAD_GROUP_A( brainpoolP256r1 ) ); +#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) + case MBEDTLS_ECP_DP_BP384R1: + return( LOAD_GROUP_A( brainpoolP384r1 ) ); +#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) + case MBEDTLS_ECP_DP_BP512R1: + return( LOAD_GROUP_A( brainpoolP512r1 ) ); +#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) + case MBEDTLS_ECP_DP_CURVE25519: + grp->modp = ecp_mod_p255; + return( ecp_use_curve25519( grp ) ); +#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */ + + default: + mbedtls_ecp_group_free( grp ); + return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE ); + } +} + +#if defined(MBEDTLS_ECP_NIST_OPTIM) +/* + * Fast reduction modulo the primes used by the NIST curves. + * + * These functions are critical for speed, but not needed for correct + * operations. So, we make the choice to heavily rely on the internals of our + * bignum library, which creates a tight coupling between these functions and + * our MPI implementation. However, the coupling between the ECP module and + * MPI remains loose, since these functions can be deactivated at will. + */ + +#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) +/* + * Compared to the way things are presented in FIPS 186-3 D.2, + * we proceed in columns, from right (least significant chunk) to left, + * adding chunks to N in place, and keeping a carry for the next chunk. + * This avoids moving things around in memory, and uselessly adding zeros, + * compared to the more straightforward, line-oriented approach. + * + * For this prime we need to handle data in chunks of 64 bits. + * Since this is always a multiple of our basic mbedtls_mpi_uint, we can + * use a mbedtls_mpi_uint * to designate such a chunk, and small loops to handle it. + */ + +/* Add 64-bit chunks (dst += src) and update carry */ +static inline void add64( mbedtls_mpi_uint *dst, mbedtls_mpi_uint *src, mbedtls_mpi_uint *carry ) +{ + unsigned char i; + mbedtls_mpi_uint c = 0; + for( i = 0; i < 8 / sizeof( mbedtls_mpi_uint ); i++, dst++, src++ ) + { + *dst += c; c = ( *dst < c ); + *dst += *src; c += ( *dst < *src ); + } + *carry += c; +} + +/* Add carry to a 64-bit chunk and update carry */ +static inline void carry64( mbedtls_mpi_uint *dst, mbedtls_mpi_uint *carry ) +{ + unsigned char i; + for( i = 0; i < 8 / sizeof( mbedtls_mpi_uint ); i++, dst++ ) + { + *dst += *carry; + *carry = ( *dst < *carry ); + } +} + +#define WIDTH 8 / sizeof( mbedtls_mpi_uint ) +#define A( i ) N->p + i * WIDTH +#define ADD( i ) add64( p, A( i ), &c ) +#define NEXT p += WIDTH; carry64( p, &c ) +#define LAST p += WIDTH; *p = c; while( ++p < end ) *p = 0 + +/* + * Fast quasi-reduction modulo p192 (FIPS 186-3 D.2.1) + */ +static int ecp_mod_p192( mbedtls_mpi *N ) +{ + int ret; + mbedtls_mpi_uint c = 0; + mbedtls_mpi_uint *p, *end; + + /* Make sure we have enough blocks so that A(5) is legal */ + MBEDTLS_MPI_CHK( mbedtls_mpi_grow( N, 6 * WIDTH ) ); + + p = N->p; + end = p + N->n; + + ADD( 3 ); ADD( 5 ); NEXT; // A0 += A3 + A5 + ADD( 3 ); ADD( 4 ); ADD( 5 ); NEXT; // A1 += A3 + A4 + A5 + ADD( 4 ); ADD( 5 ); LAST; // A2 += A4 + A5 + +cleanup: + return( ret ); +} + +#undef WIDTH +#undef A +#undef ADD +#undef NEXT +#undef LAST +#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) +/* + * The reader is advised to first understand ecp_mod_p192() since the same + * general structure is used here, but with additional complications: + * (1) chunks of 32 bits, and (2) subtractions. + */ + +/* + * For these primes, we need to handle data in chunks of 32 bits. + * This makes it more complicated if we use 64 bits limbs in MPI, + * which prevents us from using a uniform access method as for p192. + * + * So, we define a mini abstraction layer to access 32 bit chunks, + * load them in 'cur' for work, and store them back from 'cur' when done. + * + * While at it, also define the size of N in terms of 32-bit chunks. + */ +#define LOAD32 cur = A( i ); + +#if defined(MBEDTLS_HAVE_INT32) /* 32 bit */ + +#define MAX32 N->n +#define A( j ) N->p[j] +#define STORE32 N->p[i] = cur; + +#else /* 64-bit */ + +#define MAX32 N->n * 2 +#define A( j ) j % 2 ? (uint32_t)( N->p[j/2] >> 32 ) : (uint32_t)( N->p[j/2] ) +#define STORE32 \ + if( i % 2 ) { \ + N->p[i/2] &= 0x00000000FFFFFFFF; \ + N->p[i/2] |= ((mbedtls_mpi_uint) cur) << 32; \ + } else { \ + N->p[i/2] &= 0xFFFFFFFF00000000; \ + N->p[i/2] |= (mbedtls_mpi_uint) cur; \ + } + +#endif /* sizeof( mbedtls_mpi_uint ) */ + +/* + * Helpers for addition and subtraction of chunks, with signed carry. + */ +static inline void add32( uint32_t *dst, uint32_t src, signed char *carry ) +{ + *dst += src; + *carry += ( *dst < src ); +} + +static inline void sub32( uint32_t *dst, uint32_t src, signed char *carry ) +{ + *carry -= ( *dst < src ); + *dst -= src; +} + +#define ADD( j ) add32( &cur, A( j ), &c ); +#define SUB( j ) sub32( &cur, A( j ), &c ); + +/* + * Helpers for the main 'loop' + * (see fix_negative for the motivation of C) + */ +#define INIT( b ) \ + int ret; \ + signed char c = 0, cc; \ + uint32_t cur; \ + size_t i = 0, bits = b; \ + mbedtls_mpi C; \ + mbedtls_mpi_uint Cp[ b / 8 / sizeof( mbedtls_mpi_uint) + 1 ]; \ + \ + C.s = 1; \ + C.n = b / 8 / sizeof( mbedtls_mpi_uint) + 1; \ + C.p = Cp; \ + memset( Cp, 0, C.n * sizeof( mbedtls_mpi_uint ) ); \ + \ + MBEDTLS_MPI_CHK( mbedtls_mpi_grow( N, b * 2 / 8 / sizeof( mbedtls_mpi_uint ) ) ); \ + LOAD32; + +#define NEXT \ + STORE32; i++; LOAD32; \ + cc = c; c = 0; \ + if( cc < 0 ) \ + sub32( &cur, -cc, &c ); \ + else \ + add32( &cur, cc, &c ); \ + +#define LAST \ + STORE32; i++; \ + cur = c > 0 ? c : 0; STORE32; \ + cur = 0; while( ++i < MAX32 ) { STORE32; } \ + if( c < 0 ) fix_negative( N, c, &C, bits ); + +/* + * If the result is negative, we get it in the form + * c * 2^(bits + 32) + N, with c negative and N positive shorter than 'bits' + */ +static inline int fix_negative( mbedtls_mpi *N, signed char c, mbedtls_mpi *C, size_t bits ) +{ + int ret; + + /* C = - c * 2^(bits + 32) */ +#if !defined(MBEDTLS_HAVE_INT64) + ((void) bits); +#else + if( bits == 224 ) + C->p[ C->n - 1 ] = ((mbedtls_mpi_uint) -c) << 32; + else +#endif + C->p[ C->n - 1 ] = (mbedtls_mpi_uint) -c; + + /* N = - ( C - N ) */ + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( N, C, N ) ); + N->s = -1; + +cleanup: + + return( ret ); +} + +#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) +/* + * Fast quasi-reduction modulo p224 (FIPS 186-3 D.2.2) + */ +static int ecp_mod_p224( mbedtls_mpi *N ) +{ + INIT( 224 ); + + SUB( 7 ); SUB( 11 ); NEXT; // A0 += -A7 - A11 + SUB( 8 ); SUB( 12 ); NEXT; // A1 += -A8 - A12 + SUB( 9 ); SUB( 13 ); NEXT; // A2 += -A9 - A13 + SUB( 10 ); ADD( 7 ); ADD( 11 ); NEXT; // A3 += -A10 + A7 + A11 + SUB( 11 ); ADD( 8 ); ADD( 12 ); NEXT; // A4 += -A11 + A8 + A12 + SUB( 12 ); ADD( 9 ); ADD( 13 ); NEXT; // A5 += -A12 + A9 + A13 + SUB( 13 ); ADD( 10 ); LAST; // A6 += -A13 + A10 + +cleanup: + return( ret ); +} +#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) +/* + * Fast quasi-reduction modulo p256 (FIPS 186-3 D.2.3) + */ +static int ecp_mod_p256( mbedtls_mpi *N ) +{ + INIT( 256 ); + + ADD( 8 ); ADD( 9 ); + SUB( 11 ); SUB( 12 ); SUB( 13 ); SUB( 14 ); NEXT; // A0 + + ADD( 9 ); ADD( 10 ); + SUB( 12 ); SUB( 13 ); SUB( 14 ); SUB( 15 ); NEXT; // A1 + + ADD( 10 ); ADD( 11 ); + SUB( 13 ); SUB( 14 ); SUB( 15 ); NEXT; // A2 + + ADD( 11 ); ADD( 11 ); ADD( 12 ); ADD( 12 ); ADD( 13 ); + SUB( 15 ); SUB( 8 ); SUB( 9 ); NEXT; // A3 + + ADD( 12 ); ADD( 12 ); ADD( 13 ); ADD( 13 ); ADD( 14 ); + SUB( 9 ); SUB( 10 ); NEXT; // A4 + + ADD( 13 ); ADD( 13 ); ADD( 14 ); ADD( 14 ); ADD( 15 ); + SUB( 10 ); SUB( 11 ); NEXT; // A5 + + ADD( 14 ); ADD( 14 ); ADD( 15 ); ADD( 15 ); ADD( 14 ); ADD( 13 ); + SUB( 8 ); SUB( 9 ); NEXT; // A6 + + ADD( 15 ); ADD( 15 ); ADD( 15 ); ADD( 8 ); + SUB( 10 ); SUB( 11 ); SUB( 12 ); SUB( 13 ); LAST; // A7 + +cleanup: + return( ret ); +} +#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) +/* + * Fast quasi-reduction modulo p384 (FIPS 186-3 D.2.4) + */ +static int ecp_mod_p384( mbedtls_mpi *N ) +{ + INIT( 384 ); + + ADD( 12 ); ADD( 21 ); ADD( 20 ); + SUB( 23 ); NEXT; // A0 + + ADD( 13 ); ADD( 22 ); ADD( 23 ); + SUB( 12 ); SUB( 20 ); NEXT; // A2 + + ADD( 14 ); ADD( 23 ); + SUB( 13 ); SUB( 21 ); NEXT; // A2 + + ADD( 15 ); ADD( 12 ); ADD( 20 ); ADD( 21 ); + SUB( 14 ); SUB( 22 ); SUB( 23 ); NEXT; // A3 + + ADD( 21 ); ADD( 21 ); ADD( 16 ); ADD( 13 ); ADD( 12 ); ADD( 20 ); ADD( 22 ); + SUB( 15 ); SUB( 23 ); SUB( 23 ); NEXT; // A4 + + ADD( 22 ); ADD( 22 ); ADD( 17 ); ADD( 14 ); ADD( 13 ); ADD( 21 ); ADD( 23 ); + SUB( 16 ); NEXT; // A5 + + ADD( 23 ); ADD( 23 ); ADD( 18 ); ADD( 15 ); ADD( 14 ); ADD( 22 ); + SUB( 17 ); NEXT; // A6 + + ADD( 19 ); ADD( 16 ); ADD( 15 ); ADD( 23 ); + SUB( 18 ); NEXT; // A7 + + ADD( 20 ); ADD( 17 ); ADD( 16 ); + SUB( 19 ); NEXT; // A8 + + ADD( 21 ); ADD( 18 ); ADD( 17 ); + SUB( 20 ); NEXT; // A9 + + ADD( 22 ); ADD( 19 ); ADD( 18 ); + SUB( 21 ); NEXT; // A10 + + ADD( 23 ); ADD( 20 ); ADD( 19 ); + SUB( 22 ); LAST; // A11 + +cleanup: + return( ret ); +} +#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */ + +#undef A +#undef LOAD32 +#undef STORE32 +#undef MAX32 +#undef INIT +#undef NEXT +#undef LAST + +#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED || + MBEDTLS_ECP_DP_SECP256R1_ENABLED || + MBEDTLS_ECP_DP_SECP384R1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) +/* + * Here we have an actual Mersenne prime, so things are more straightforward. + * However, chunks are aligned on a 'weird' boundary (521 bits). + */ + +/* Size of p521 in terms of mbedtls_mpi_uint */ +#define P521_WIDTH ( 521 / 8 / sizeof( mbedtls_mpi_uint ) + 1 ) + +/* Bits to keep in the most significant mbedtls_mpi_uint */ +#define P521_MASK 0x01FF + +/* + * Fast quasi-reduction modulo p521 (FIPS 186-3 D.2.5) + * Write N as A1 + 2^521 A0, return A0 + A1 + */ +static int ecp_mod_p521( mbedtls_mpi *N ) +{ + int ret; + size_t i; + mbedtls_mpi M; + mbedtls_mpi_uint Mp[P521_WIDTH + 1]; + /* Worst case for the size of M is when mbedtls_mpi_uint is 16 bits: + * we need to hold bits 513 to 1056, which is 34 limbs, that is + * P521_WIDTH + 1. Otherwise P521_WIDTH is enough. */ + + if( N->n < P521_WIDTH ) + return( 0 ); + + /* M = A1 */ + M.s = 1; + M.n = N->n - ( P521_WIDTH - 1 ); + if( M.n > P521_WIDTH + 1 ) + M.n = P521_WIDTH + 1; + M.p = Mp; + memcpy( Mp, N->p + P521_WIDTH - 1, M.n * sizeof( mbedtls_mpi_uint ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, 521 % ( 8 * sizeof( mbedtls_mpi_uint ) ) ) ); + + /* N = A0 */ + N->p[P521_WIDTH - 1] &= P521_MASK; + for( i = P521_WIDTH; i < N->n; i++ ) + N->p[i] = 0; + + /* N = A0 + A1 */ + MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) ); + +cleanup: + return( ret ); +} + +#undef P521_WIDTH +#undef P521_MASK +#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */ + +#endif /* MBEDTLS_ECP_NIST_OPTIM */ + +#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) + +/* Size of p255 in terms of mbedtls_mpi_uint */ +#define P255_WIDTH ( 255 / 8 / sizeof( mbedtls_mpi_uint ) + 1 ) + +/* + * Fast quasi-reduction modulo p255 = 2^255 - 19 + * Write N as A0 + 2^255 A1, return A0 + 19 * A1 + */ +static int ecp_mod_p255( mbedtls_mpi *N ) +{ + int ret; + size_t i; + mbedtls_mpi M; + mbedtls_mpi_uint Mp[P255_WIDTH + 2]; + + if( N->n < P255_WIDTH ) + return( 0 ); + + /* M = A1 */ + M.s = 1; + M.n = N->n - ( P255_WIDTH - 1 ); + if( M.n > P255_WIDTH + 1 ) + M.n = P255_WIDTH + 1; + M.p = Mp; + memset( Mp, 0, sizeof Mp ); + memcpy( Mp, N->p + P255_WIDTH - 1, M.n * sizeof( mbedtls_mpi_uint ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, 255 % ( 8 * sizeof( mbedtls_mpi_uint ) ) ) ); + M.n++; /* Make room for multiplication by 19 */ + + /* N = A0 */ + MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( N, 255, 0 ) ); + for( i = P255_WIDTH; i < N->n; i++ ) + N->p[i] = 0; + + /* N = A0 + 19 * A1 */ + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &M, &M, 19 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) ); + +cleanup: + return( ret ); +} +#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) +/* + * Fast quasi-reduction modulo P = 2^s - R, + * with R about 33 bits, used by the Koblitz curves. + * + * Write N as A0 + 2^224 A1, return A0 + R * A1. + * Actually do two passes, since R is big. + */ +#define P_KOBLITZ_MAX ( 256 / 8 / sizeof( mbedtls_mpi_uint ) ) // Max limbs in P +#define P_KOBLITZ_R ( 8 / sizeof( mbedtls_mpi_uint ) ) // Limbs in R +static inline int ecp_mod_koblitz( mbedtls_mpi *N, mbedtls_mpi_uint *Rp, size_t p_limbs, + size_t adjust, size_t shift, mbedtls_mpi_uint mask ) +{ + int ret; + size_t i; + mbedtls_mpi M, R; + mbedtls_mpi_uint Mp[P_KOBLITZ_MAX + P_KOBLITZ_R + 1]; + + if( N->n < p_limbs ) + return( 0 ); + + /* Init R */ + R.s = 1; + R.p = Rp; + R.n = P_KOBLITZ_R; + + /* Common setup for M */ + M.s = 1; + M.p = Mp; + + /* M = A1 */ + M.n = N->n - ( p_limbs - adjust ); + if( M.n > p_limbs + adjust ) + M.n = p_limbs + adjust; + memset( Mp, 0, sizeof Mp ); + memcpy( Mp, N->p + p_limbs - adjust, M.n * sizeof( mbedtls_mpi_uint ) ); + if( shift != 0 ) + MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, shift ) ); + M.n += R.n; /* Make room for multiplication by R */ + + /* N = A0 */ + if( mask != 0 ) + N->p[p_limbs - 1] &= mask; + for( i = p_limbs; i < N->n; i++ ) + N->p[i] = 0; + + /* N = A0 + R * A1 */ + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &M, &M, &R ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) ); + + /* Second pass */ + + /* M = A1 */ + M.n = N->n - ( p_limbs - adjust ); + if( M.n > p_limbs + adjust ) + M.n = p_limbs + adjust; + memset( Mp, 0, sizeof Mp ); + memcpy( Mp, N->p + p_limbs - adjust, M.n * sizeof( mbedtls_mpi_uint ) ); + if( shift != 0 ) + MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, shift ) ); + M.n += R.n; /* Make room for multiplication by R */ + + /* N = A0 */ + if( mask != 0 ) + N->p[p_limbs - 1] &= mask; + for( i = p_limbs; i < N->n; i++ ) + N->p[i] = 0; + + /* N = A0 + R * A1 */ + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &M, &M, &R ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) ); + +cleanup: + return( ret ); +} +#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED) || + MBEDTLS_ECP_DP_SECP224K1_ENABLED) || + MBEDTLS_ECP_DP_SECP256K1_ENABLED) */ + +#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) +/* + * Fast quasi-reduction modulo p192k1 = 2^192 - R, + * with R = 2^32 + 2^12 + 2^8 + 2^7 + 2^6 + 2^3 + 1 = 0x0100001119 + */ +static int ecp_mod_p192k1( mbedtls_mpi *N ) +{ + static mbedtls_mpi_uint Rp[] = { + BYTES_TO_T_UINT_8( 0xC9, 0x11, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ) }; + + return( ecp_mod_koblitz( N, Rp, 192 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0, 0 ) ); +} +#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) +/* + * Fast quasi-reduction modulo p224k1 = 2^224 - R, + * with R = 2^32 + 2^12 + 2^11 + 2^9 + 2^7 + 2^4 + 2 + 1 = 0x0100001A93 + */ +static int ecp_mod_p224k1( mbedtls_mpi *N ) +{ + static mbedtls_mpi_uint Rp[] = { + BYTES_TO_T_UINT_8( 0x93, 0x1A, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ) }; + +#if defined(MBEDTLS_HAVE_INT64) + return( ecp_mod_koblitz( N, Rp, 4, 1, 32, 0xFFFFFFFF ) ); +#else + return( ecp_mod_koblitz( N, Rp, 224 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0, 0 ) ); +#endif +} + +#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) +/* + * Fast quasi-reduction modulo p256k1 = 2^256 - R, + * with R = 2^32 + 2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1 = 0x01000003D1 + */ +static int ecp_mod_p256k1( mbedtls_mpi *N ) +{ + static mbedtls_mpi_uint Rp[] = { + BYTES_TO_T_UINT_8( 0xD1, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ) }; + return( ecp_mod_koblitz( N, Rp, 256 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0, 0 ) ); +} +#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */ + +#endif /* !MBEDTLS_ECP_ALT */ + +#endif /* MBEDTLS_ECP_C */ diff --git a/APP_Framework/Framework/security/mbedtls/entropy.c b/APP_Framework/Framework/security/mbedtls/entropy.c index e9075efc3..4585e4470 100644 --- a/APP_Framework/Framework/security/mbedtls/entropy.c +++ b/APP_Framework/Framework/security/mbedtls/entropy.c @@ -35,7 +35,6 @@ #include "entropy.h" #include "entropy_poll.h" -#include "platform_util.h" #include @@ -43,7 +42,9 @@ #include #endif +#if defined(MBEDTLS_ENTROPY_NV_SEED) #include "platform.h" +#endif #if defined(MBEDTLS_SELF_TEST) #if defined(MBEDTLS_PLATFORM_C) @@ -58,6 +59,11 @@ #include "havege.h" #endif +/* 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 ENTROPY_MAX_LOOP 256 /**< Maximum amount to loop before error */ void mbedtls_entropy_init( mbedtls_entropy_context *ctx ) @@ -134,7 +140,7 @@ void mbedtls_entropy_free( mbedtls_entropy_context *ctx ) ctx->initial_entropy_run = 0; #endif ctx->source_count = 0; - mbedtls_platform_zeroize( ctx->source, sizeof( ctx->source ) ); + mbedtls_zeroize( ctx->source, sizeof( ctx->source ) ); ctx->accumulator_started = 0; } @@ -142,11 +148,7 @@ int mbedtls_entropy_add_source( mbedtls_entropy_context *ctx, mbedtls_entropy_f_source_ptr f_source, void *p_source, size_t threshold, int strong ) { - int idx, ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; - volatile mbedtls_entropy_f_source_ptr f_source_dup = f_source; - volatile void *p_source_dup = p_source; - volatile size_t threshold_dup = threshold; - volatile int strong_dup = strong; + int idx, ret = 0; #if defined(MBEDTLS_THREADING_C) if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) @@ -166,7 +168,6 @@ int mbedtls_entropy_add_source( mbedtls_entropy_context *ctx, ctx->source[idx].strong = strong; ctx->source_count++; - ret = 0; exit: #if defined(MBEDTLS_THREADING_C) @@ -174,11 +175,6 @@ exit: return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); #endif - if( f_source_dup != f_source || p_source_dup != p_source || - threshold_dup != threshold || strong_dup != strong ) - { - ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; - } return( ret ); } @@ -192,9 +188,8 @@ static int entropy_update( mbedtls_entropy_context *ctx, unsigned char source_id unsigned char tmp[MBEDTLS_ENTROPY_BLOCK_SIZE]; size_t use_len = len; const unsigned char *p = data; - int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; - volatile const unsigned char *data_dup = data; - volatile size_t len_dup = len; + int ret = 0; + if( use_len > MBEDTLS_ENTROPY_BLOCK_SIZE ) { #if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR) @@ -237,19 +232,15 @@ static int entropy_update( mbedtls_entropy_context *ctx, unsigned char source_id #endif cleanup: - mbedtls_platform_zeroize( tmp, sizeof( tmp ) ); + mbedtls_zeroize( tmp, sizeof( tmp ) ); - if( len_dup != len || data_dup != data ) - { - ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; - } return( ret ); } int mbedtls_entropy_update_manual( mbedtls_entropy_context *ctx, const unsigned char *data, size_t len ) { - int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; + int ret; #if defined(MBEDTLS_THREADING_C) if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) @@ -271,9 +262,7 @@ int mbedtls_entropy_update_manual( mbedtls_entropy_context *ctx, */ static int entropy_gather_internal( mbedtls_entropy_context *ctx ) { - int i; - volatile int ret = MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE; - volatile int have_one_strong_fi = MBEDTLS_ENTROPY_SOURCE_WEAK; + int ret, i, have_one_strong = 0; unsigned char buf[MBEDTLS_ENTROPY_MAX_GATHER]; size_t olen; @@ -285,16 +274,8 @@ static int entropy_gather_internal( mbedtls_entropy_context *ctx ) */ for( i = 0; i < ctx->source_count; i++ ) { - volatile int strong_fi = ctx->source[i].strong; - if( strong_fi == MBEDTLS_ENTROPY_SOURCE_STRONG ) - { - mbedtls_platform_random_delay(); - - if( strong_fi == MBEDTLS_ENTROPY_SOURCE_STRONG ) - have_one_strong_fi = MBEDTLS_ENTROPY_SOURCE_STRONG; - else - return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); - } + if( ctx->source[i].strong == MBEDTLS_ENTROPY_SOURCE_STRONG ) + have_one_strong = 1; olen = 0; if( ( ret = ctx->source[i].f_source( ctx->source[i].p_source, @@ -315,24 +296,13 @@ static int entropy_gather_internal( mbedtls_entropy_context *ctx ) } } + if( have_one_strong == 0 ) + ret = MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE; + cleanup: - mbedtls_platform_zeroize( buf, sizeof( buf ) ); + mbedtls_zeroize( buf, sizeof( buf ) ); - if( have_one_strong_fi == MBEDTLS_ENTROPY_SOURCE_STRONG ) - { - mbedtls_platform_random_delay(); - if( have_one_strong_fi == MBEDTLS_ENTROPY_SOURCE_STRONG ) - { - return( ret ); - } - else - { - return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); - } - - } - - return( MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE ); + return( ret ); } /* @@ -340,7 +310,7 @@ cleanup: */ int mbedtls_entropy_gather( mbedtls_entropy_context *ctx ) { - int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; + int ret; #if defined(MBEDTLS_THREADING_C) if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) @@ -359,13 +329,9 @@ int mbedtls_entropy_gather( mbedtls_entropy_context *ctx ) int mbedtls_entropy_func( void *data, unsigned char *output, size_t len ) { - int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; - int count = 0, i, done; + int ret, count = 0, i, done; mbedtls_entropy_context *ctx = (mbedtls_entropy_context *) data; unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE]; - volatile void *data_dup = data; - volatile unsigned char *output_dup = output; - volatile size_t len_dup = len; if( len > MBEDTLS_ENTROPY_BLOCK_SIZE ) return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); @@ -462,22 +428,18 @@ int mbedtls_entropy_func( void *data, unsigned char *output, size_t len ) for( i = 0; i < ctx->source_count; i++ ) ctx->source[i].size = 0; - if( output == mbedtls_platform_memcpy( output, buf, len ) ) - { - ret = 0; - } + memcpy( output, buf, len ); + + ret = 0; exit: - mbedtls_platform_zeroize( buf, sizeof( buf ) ); + mbedtls_zeroize( buf, sizeof( buf ) ); #if defined(MBEDTLS_THREADING_C) if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); #endif - if( data_dup != data || len_dup != len || output_dup != output ) - { - ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; - } + return( ret ); } @@ -495,7 +457,7 @@ int mbedtls_entropy_update_nv_seed( mbedtls_entropy_context *ctx ) return( MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR ); /* Manually update the remaining stream with a separator value to diverge */ - mbedtls_platform_memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE ); + memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE ); ret = mbedtls_entropy_update_manual( ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE ); return( ret ); @@ -524,7 +486,7 @@ int mbedtls_entropy_write_seed_file( mbedtls_entropy_context *ctx, const char *p ret = 0; exit: - mbedtls_platform_zeroize( buf, sizeof( buf ) ); + mbedtls_zeroize( buf, sizeof( buf ) ); fclose( f ); return( ret ); @@ -554,7 +516,7 @@ int mbedtls_entropy_update_seed_file( mbedtls_entropy_context *ctx, const char * fclose( f ); - mbedtls_platform_zeroize( buf, sizeof( buf ) ); + mbedtls_zeroize( buf, sizeof( buf ) ); if( ret != 0 ) return( ret ); @@ -573,7 +535,7 @@ static int entropy_dummy_source( void *data, unsigned char *output, { ((void) data); - mbedtls_platform_memset( output, 0x2a, len ); + memset( output, 0x2a, len ); *olen = len; return( 0 ); @@ -644,8 +606,8 @@ int mbedtls_entropy_source_self_test( int verbose ) if( verbose != 0 ) mbedtls_printf( " ENTROPY_BIAS test: " ); - mbedtls_platform_memset( buf0, 0x00, sizeof( buf0 ) ); - mbedtls_platform_memset( buf1, 0x00, sizeof( buf1 ) ); + memset( buf0, 0x00, sizeof( buf0 ) ); + memset( buf1, 0x00, sizeof( buf1 ) ); if( ( ret = mbedtls_entropy_source_self_test_gather( buf0, sizeof( buf0 ) ) ) != 0 ) goto cleanup; diff --git a/APP_Framework/Framework/security/mbedtls/entropy.h b/APP_Framework/Framework/security/mbedtls/entropy.h index 52cb6a0e5..fcb4d0255 100644 --- a/APP_Framework/Framework/security/mbedtls/entropy.h +++ b/APP_Framework/Framework/security/mbedtls/entropy.h @@ -83,8 +83,8 @@ #define MBEDTLS_ENTROPY_MAX_SEED_SIZE 1024 /**< Maximum size of seed we read from seed file */ #define MBEDTLS_ENTROPY_SOURCE_MANUAL MBEDTLS_ENTROPY_MAX_SOURCES -#define MBEDTLS_ENTROPY_SOURCE_STRONG 0x7F /**< Entropy source is strong */ -#define MBEDTLS_ENTROPY_SOURCE_WEAK 0x0 /**< Entropy source is weak */ +#define MBEDTLS_ENTROPY_SOURCE_STRONG 1 /**< Entropy source is strong */ +#define MBEDTLS_ENTROPY_SOURCE_WEAK 0 /**< Entropy source is weak */ #ifdef __cplusplus extern "C" { @@ -107,7 +107,7 @@ typedef int (*mbedtls_entropy_f_source_ptr)(void *data, unsigned char *output, s /** * \brief Entropy source state */ -typedef struct mbedtls_entropy_source_state +typedef struct { mbedtls_entropy_f_source_ptr f_source; /**< The entropy source callback */ void * p_source; /**< The callback data pointer */ @@ -120,7 +120,7 @@ mbedtls_entropy_source_state; /** * \brief Entropy context structure */ -typedef struct mbedtls_entropy_context +typedef struct { int accumulator_started; #if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR) @@ -166,7 +166,7 @@ void mbedtls_entropy_free( mbedtls_entropy_context *ctx ); * \param threshold Minimum required from source before entropy is released * ( with mbedtls_entropy_func() ) (in bytes) * \param strong MBEDTLS_ENTROPY_SOURCE_STRONG or - * MBEDTLS_ENTROPY_SOURCE_WEAK. + * MBEDTSL_ENTROPY_SOURCE_WEAK. * At least one strong source needs to be added. * Weaker sources (such as the cycle counter) can be used as * a complement. diff --git a/APP_Framework/Framework/security/mbedtls/entropy_poll.c b/APP_Framework/Framework/security/mbedtls/entropy_poll.c new file mode 100644 index 000000000..48b8b42f0 --- /dev/null +++ b/APP_Framework/Framework/security/mbedtls/entropy_poll.c @@ -0,0 +1,229 @@ +/* + * Platform-specific and custom entropy polling functions + * + * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_ENTROPY_C) + +#include "entropy.h" +#include "entropy_poll.h" + +#if defined(MBEDTLS_TIMING_C) +#include +#include "timing.h" +#endif +#if defined(MBEDTLS_HAVEGE_C) +#include "havege.h" +#endif +#if defined(MBEDTLS_ENTROPY_NV_SEED) +#include "platform.h" +#endif + +#if !defined(MBEDTLS_NO_PLATFORM_ENTROPY) + +#if !defined(unix) && !defined(__unix__) && !defined(__unix) && \ + !defined(__APPLE__) && !defined(_WIN32) +#error "Platform entropy sources only work on Unix and Windows, see MBEDTLS_NO_PLATFORM_ENTROPY in config.h" +#endif + +#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) + +#if !defined(_WIN32_WINNT) +#define _WIN32_WINNT 0x0400 +#endif +#include +#include + +int mbedtls_platform_entropy_poll( void *data, unsigned char *output, size_t len, + size_t *olen ) +{ + HCRYPTPROV provider; + ((void) data); + *olen = 0; + + if( CryptAcquireContext( &provider, NULL, NULL, + PROV_RSA_FULL, CRYPT_VERIFYCONTEXT ) == FALSE ) + { + return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); + } + + if( CryptGenRandom( provider, (DWORD) len, output ) == FALSE ) + { + CryptReleaseContext( provider, 0 ); + return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); + } + + CryptReleaseContext( provider, 0 ); + *olen = len; + + return( 0 ); +} +#else /* _WIN32 && !EFIX64 && !EFI32 */ + +/* + * Test for Linux getrandom() support. + * Since there is no wrapper in the libc yet, use the generic syscall wrapper + * available in GNU libc and compatible libc's (eg uClibc). + */ +#if defined(__linux__) && defined(__GLIBC__) +#include +#include +#if defined(SYS_getrandom) +#define HAVE_GETRANDOM +#include + +static int getrandom_wrapper( void *buf, size_t buflen, unsigned int flags ) +{ + /* MemSan cannot understand that the syscall writes to the buffer */ +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) + memset( buf, 0, buflen ); +#endif +#endif + return( syscall( SYS_getrandom, buf, buflen, flags ) ); +} +#endif /* SYS_getrandom */ +#endif /* __linux__ */ + +#include + +int mbedtls_platform_entropy_poll( void *data, + unsigned char *output, size_t len, size_t *olen ) +{ + FILE *file; + size_t read_len; + int ret; + ((void) data); + +#if defined(HAVE_GETRANDOM) + ret = getrandom_wrapper( output, len, 0 ); + if( ret >= 0 ) + { + *olen = ret; + return( 0 ); + } + else if( errno != ENOSYS ) + return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); + /* Fall through if the system call isn't known. */ +#else + ((void) ret); +#endif /* HAVE_GETRANDOM */ + + *olen = 0; + + file = fopen( "/dev/urandom", "rb" ); + if( file == NULL ) + return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); + + read_len = fread( output, 1, len, file ); + if( read_len != len ) + { + fclose( file ); + return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); + } + + fclose( file ); + *olen = len; + + return( 0 ); +} +#endif /* _WIN32 && !EFIX64 && !EFI32 */ +#endif /* !MBEDTLS_NO_PLATFORM_ENTROPY */ + +#if defined(MBEDTLS_TEST_NULL_ENTROPY) +int mbedtls_null_entropy_poll( void *data, + unsigned char *output, size_t len, size_t *olen ) +{ + ((void) data); + ((void) output); + *olen = 0; + + if( len < sizeof(unsigned char) ) + return( 0 ); + + *olen = sizeof(unsigned char); + + return( 0 ); +} +#endif + +#if defined(MBEDTLS_TIMING_C) +int mbedtls_hardclock_poll( void *data, + unsigned char *output, size_t len, size_t *olen ) +{ + unsigned long timer = mbedtls_timing_hardclock(); + ((void) data); + *olen = 0; + + if( len < sizeof(unsigned long) ) + return( 0 ); + + memcpy( output, &timer, sizeof(unsigned long) ); + *olen = sizeof(unsigned long); + + return( 0 ); +} +#endif /* MBEDTLS_TIMING_C */ + +#if defined(MBEDTLS_HAVEGE_C) +int mbedtls_havege_poll( void *data, + unsigned char *output, size_t len, size_t *olen ) +{ + mbedtls_havege_state *hs = (mbedtls_havege_state *) data; + *olen = 0; + + if( mbedtls_havege_random( hs, output, len ) != 0 ) + return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); + + *olen = len; + + return( 0 ); +} +#endif /* MBEDTLS_HAVEGE_C */ + +#if defined(MBEDTLS_ENTROPY_NV_SEED) +int mbedtls_nv_seed_poll( void *data, + unsigned char *output, size_t len, size_t *olen ) +{ + unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE]; + size_t use_len = MBEDTLS_ENTROPY_BLOCK_SIZE; + ((void) data); + + memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE ); + + if( mbedtls_nv_seed_read( buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) < 0 ) + return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); + + if( len < use_len ) + use_len = len; + + memcpy( output, buf, use_len ); + *olen = use_len; + + return( 0 ); +} +#endif /* MBEDTLS_ENTROPY_NV_SEED */ + +#endif /* MBEDTLS_ENTROPY_C */ diff --git a/APP_Framework/Framework/security/mbedtls/error.c b/APP_Framework/Framework/security/mbedtls/error.c new file mode 100644 index 000000000..05f6b91e8 --- /dev/null +++ b/APP_Framework/Framework/security/mbedtls/error.c @@ -0,0 +1,822 @@ +/* + * Error message information + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_ERROR_C) || defined(MBEDTLS_ERROR_STRERROR_DUMMY) +#include "error.h" +#include +#endif + +#if defined(MBEDTLS_PLATFORM_C) +#include "platform.h" +#else +#define mbedtls_snprintf snprintf +#define mbedtls_time_t time_t +#endif + +#if defined(MBEDTLS_ERROR_C) + +#include + +#if defined(MBEDTLS_AES_C) +#include "aes.h" +#endif + +#if defined(MBEDTLS_ARC4_C) +#include "arc4.h" +#endif + +#if defined(MBEDTLS_BASE64_C) +#include "base64.h" +#endif + +#if defined(MBEDTLS_BIGNUM_C) +#include "bignum.h" +#endif + +#if defined(MBEDTLS_BLOWFISH_C) +#include "blowfish.h" +#endif + +#if defined(MBEDTLS_CAMELLIA_C) +#include "camellia.h" +#endif + +#if defined(MBEDTLS_CCM_C) +#include "ccm.h" +#endif + +#if defined(MBEDTLS_CIPHER_C) +#include "cipher.h" +#endif + +#if defined(MBEDTLS_CMAC_C) +#include "cmac.h" +#endif + +#if defined(MBEDTLS_CTR_DRBG_C) +#include "ctr_drbg.h" +#endif + +#if defined(MBEDTLS_DES_C) +#include "des.h" +#endif + +#if defined(MBEDTLS_DHM_C) +#include "dhm.h" +#endif + +#if defined(MBEDTLS_ECP_C) +#include "ecp.h" +#endif + +#if defined(MBEDTLS_ENTROPY_C) +#include "entropy.h" +#endif + +#if defined(MBEDTLS_GCM_C) +#include "gcm.h" +#endif + +#if defined(MBEDTLS_HMAC_DRBG_C) +#include "hmac_drbg.h" +#endif + +#if defined(MBEDTLS_MD_C) +#include "md.h" +#endif + +#if defined(MBEDTLS_MD2_C) +#include "md2.h" +#endif + +#if defined(MBEDTLS_MD4_C) +#include "md4.h" +#endif + +#if defined(MBEDTLS_MD5_C) +#include "md5.h" +#endif + +#if defined(MBEDTLS_NET_C) +#include "net_sockets.h" +#endif + +#if defined(MBEDTLS_OID_C) +#include "oid.h" +#endif + +#if defined(MBEDTLS_PADLOCK_C) +#include "padlock.h" +#endif + +#if defined(MBEDTLS_PEM_PARSE_C) || defined(MBEDTLS_PEM_WRITE_C) +#include "pem.h" +#endif + +#if defined(MBEDTLS_PK_C) +#include "pk.h" +#endif + +#if defined(MBEDTLS_PKCS12_C) +#include "pkcs12.h" +#endif + +#if defined(MBEDTLS_PKCS5_C) +#include "pkcs5.h" +#endif + +#if defined(MBEDTLS_RIPEMD160_C) +#include "ripemd160.h" +#endif + +#if defined(MBEDTLS_RSA_C) +#include "rsa.h" +#endif + +#if defined(MBEDTLS_SHA1_C) +#include "sha1.h" +#endif + +#if defined(MBEDTLS_SHA256_C) +#include "sha256.h" +#endif + +#if defined(MBEDTLS_SHA512_C) +#include "sha512.h" +#endif + +#if defined(MBEDTLS_SSL_TLS_C) +#include "ssl.h" +#endif + +#if defined(MBEDTLS_THREADING_C) +#include "threading.h" +#endif + +#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C) +#include "x509.h" +#endif + +#if defined(MBEDTLS_XTEA_C) +#include "xtea.h" +#endif + + +void mbedtls_strerror( int ret, char *buf, size_t buflen ) +{ + size_t len; + int use_ret; + + if( buflen == 0 ) + return; + + memset( buf, 0x00, buflen ); + + if( ret < 0 ) + ret = -ret; + + if( ret & 0xFF80 ) + { + use_ret = ret & 0xFF80; + + // High level error codes + // + // BEGIN generated code +#if defined(MBEDTLS_CIPHER_C) + if( use_ret == -(MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE) ) + mbedtls_snprintf( buf, buflen, "CIPHER - The selected feature is not available" ); + if( use_ret == -(MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA) ) + mbedtls_snprintf( buf, buflen, "CIPHER - Bad input parameters" ); + if( use_ret == -(MBEDTLS_ERR_CIPHER_ALLOC_FAILED) ) + mbedtls_snprintf( buf, buflen, "CIPHER - Failed to allocate memory" ); + if( use_ret == -(MBEDTLS_ERR_CIPHER_INVALID_PADDING) ) + mbedtls_snprintf( buf, buflen, "CIPHER - Input data contains invalid padding and is rejected" ); + if( use_ret == -(MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED) ) + mbedtls_snprintf( buf, buflen, "CIPHER - Decryption of block requires a full block" ); + if( use_ret == -(MBEDTLS_ERR_CIPHER_AUTH_FAILED) ) + mbedtls_snprintf( buf, buflen, "CIPHER - Authentication failed (for AEAD modes)" ); + if( use_ret == -(MBEDTLS_ERR_CIPHER_INVALID_CONTEXT) ) + mbedtls_snprintf( buf, buflen, "CIPHER - The context is invalid. For example, because it was freed" ); + if( use_ret == -(MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED) ) + mbedtls_snprintf( buf, buflen, "CIPHER - Cipher hardware accelerator failed" ); +#endif /* MBEDTLS_CIPHER_C */ + +#if defined(MBEDTLS_DHM_C) + if( use_ret == -(MBEDTLS_ERR_DHM_BAD_INPUT_DATA) ) + mbedtls_snprintf( buf, buflen, "DHM - Bad input parameters" ); + if( use_ret == -(MBEDTLS_ERR_DHM_READ_PARAMS_FAILED) ) + mbedtls_snprintf( buf, buflen, "DHM - Reading of the DHM parameters failed" ); + if( use_ret == -(MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED) ) + mbedtls_snprintf( buf, buflen, "DHM - Making of the DHM parameters failed" ); + if( use_ret == -(MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED) ) + mbedtls_snprintf( buf, buflen, "DHM - Reading of the public values failed" ); + if( use_ret == -(MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED) ) + mbedtls_snprintf( buf, buflen, "DHM - Making of the public value failed" ); + if( use_ret == -(MBEDTLS_ERR_DHM_CALC_SECRET_FAILED) ) + mbedtls_snprintf( buf, buflen, "DHM - Calculation of the DHM secret failed" ); + if( use_ret == -(MBEDTLS_ERR_DHM_INVALID_FORMAT) ) + mbedtls_snprintf( buf, buflen, "DHM - The ASN.1 data is not formatted correctly" ); + if( use_ret == -(MBEDTLS_ERR_DHM_ALLOC_FAILED) ) + mbedtls_snprintf( buf, buflen, "DHM - Allocation of memory failed" ); + if( use_ret == -(MBEDTLS_ERR_DHM_FILE_IO_ERROR) ) + mbedtls_snprintf( buf, buflen, "DHM - Read or write of file failed" ); + if( use_ret == -(MBEDTLS_ERR_DHM_HW_ACCEL_FAILED) ) + mbedtls_snprintf( buf, buflen, "DHM - DHM hardware accelerator failed" ); + if( use_ret == -(MBEDTLS_ERR_DHM_SET_GROUP_FAILED) ) + mbedtls_snprintf( buf, buflen, "DHM - Setting the modulus and generator failed" ); +#endif /* MBEDTLS_DHM_C */ + +#if defined(MBEDTLS_ECP_C) + if( use_ret == -(MBEDTLS_ERR_ECP_BAD_INPUT_DATA) ) + mbedtls_snprintf( buf, buflen, "ECP - Bad input parameters to function" ); + if( use_ret == -(MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL) ) + mbedtls_snprintf( buf, buflen, "ECP - The buffer is too small to write to" ); + if( use_ret == -(MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE) ) + mbedtls_snprintf( buf, buflen, "ECP - Requested curve not available" ); + if( use_ret == -(MBEDTLS_ERR_ECP_VERIFY_FAILED) ) + mbedtls_snprintf( buf, buflen, "ECP - The signature is not valid" ); + if( use_ret == -(MBEDTLS_ERR_ECP_ALLOC_FAILED) ) + mbedtls_snprintf( buf, buflen, "ECP - Memory allocation failed" ); + if( use_ret == -(MBEDTLS_ERR_ECP_RANDOM_FAILED) ) + mbedtls_snprintf( buf, buflen, "ECP - Generation of random value, such as (ephemeral) key, failed" ); + if( use_ret == -(MBEDTLS_ERR_ECP_INVALID_KEY) ) + mbedtls_snprintf( buf, buflen, "ECP - Invalid private or public key" ); + if( use_ret == -(MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH) ) + mbedtls_snprintf( buf, buflen, "ECP - The buffer contains a valid signature followed by more data" ); + if( use_ret == -(MBEDTLS_ERR_ECP_HW_ACCEL_FAILED) ) + mbedtls_snprintf( buf, buflen, "ECP - ECP hardware accelerator failed" ); +#endif /* MBEDTLS_ECP_C */ + +#if defined(MBEDTLS_MD_C) + if( use_ret == -(MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE) ) + mbedtls_snprintf( buf, buflen, "MD - The selected feature is not available" ); + if( use_ret == -(MBEDTLS_ERR_MD_BAD_INPUT_DATA) ) + mbedtls_snprintf( buf, buflen, "MD - Bad input parameters to function" ); + if( use_ret == -(MBEDTLS_ERR_MD_ALLOC_FAILED) ) + mbedtls_snprintf( buf, buflen, "MD - Failed to allocate memory" ); + if( use_ret == -(MBEDTLS_ERR_MD_FILE_IO_ERROR) ) + mbedtls_snprintf( buf, buflen, "MD - Opening or reading of file failed" ); + if( use_ret == -(MBEDTLS_ERR_MD_HW_ACCEL_FAILED) ) + mbedtls_snprintf( buf, buflen, "MD - MD hardware accelerator failed" ); +#endif /* MBEDTLS_MD_C */ + +#if defined(MBEDTLS_PEM_PARSE_C) || defined(MBEDTLS_PEM_WRITE_C) + if( use_ret == -(MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) ) + mbedtls_snprintf( buf, buflen, "PEM - No PEM header or footer found" ); + if( use_ret == -(MBEDTLS_ERR_PEM_INVALID_DATA) ) + mbedtls_snprintf( buf, buflen, "PEM - PEM string is not as expected" ); + if( use_ret == -(MBEDTLS_ERR_PEM_ALLOC_FAILED) ) + mbedtls_snprintf( buf, buflen, "PEM - Failed to allocate memory" ); + if( use_ret == -(MBEDTLS_ERR_PEM_INVALID_ENC_IV) ) + mbedtls_snprintf( buf, buflen, "PEM - RSA IV is not in hex-format" ); + if( use_ret == -(MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG) ) + mbedtls_snprintf( buf, buflen, "PEM - Unsupported key encryption algorithm" ); + if( use_ret == -(MBEDTLS_ERR_PEM_PASSWORD_REQUIRED) ) + mbedtls_snprintf( buf, buflen, "PEM - Private key password can't be empty" ); + if( use_ret == -(MBEDTLS_ERR_PEM_PASSWORD_MISMATCH) ) + mbedtls_snprintf( buf, buflen, "PEM - Given private key password does not allow for correct decryption" ); + if( use_ret == -(MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE) ) + mbedtls_snprintf( buf, buflen, "PEM - Unavailable feature, e.g. hashing/encryption combination" ); + if( use_ret == -(MBEDTLS_ERR_PEM_BAD_INPUT_DATA) ) + mbedtls_snprintf( buf, buflen, "PEM - Bad input parameters to function" ); +#endif /* MBEDTLS_PEM_PARSE_C || MBEDTLS_PEM_WRITE_C */ + +#if defined(MBEDTLS_PK_C) + if( use_ret == -(MBEDTLS_ERR_PK_ALLOC_FAILED) ) + mbedtls_snprintf( buf, buflen, "PK - Memory allocation failed" ); + if( use_ret == -(MBEDTLS_ERR_PK_TYPE_MISMATCH) ) + mbedtls_snprintf( buf, buflen, "PK - Type mismatch, eg attempt to encrypt with an ECDSA key" ); + if( use_ret == -(MBEDTLS_ERR_PK_BAD_INPUT_DATA) ) + mbedtls_snprintf( buf, buflen, "PK - Bad input parameters to function" ); + if( use_ret == -(MBEDTLS_ERR_PK_FILE_IO_ERROR) ) + mbedtls_snprintf( buf, buflen, "PK - Read/write of file failed" ); + if( use_ret == -(MBEDTLS_ERR_PK_KEY_INVALID_VERSION) ) + mbedtls_snprintf( buf, buflen, "PK - Unsupported key version" ); + if( use_ret == -(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT) ) + mbedtls_snprintf( buf, buflen, "PK - Invalid key tag or value" ); + if( use_ret == -(MBEDTLS_ERR_PK_UNKNOWN_PK_ALG) ) + mbedtls_snprintf( buf, buflen, "PK - Key algorithm is unsupported (only RSA and EC are supported)" ); + if( use_ret == -(MBEDTLS_ERR_PK_PASSWORD_REQUIRED) ) + mbedtls_snprintf( buf, buflen, "PK - Private key password can't be empty" ); + if( use_ret == -(MBEDTLS_ERR_PK_PASSWORD_MISMATCH) ) + mbedtls_snprintf( buf, buflen, "PK - Given private key password does not allow for correct decryption" ); + if( use_ret == -(MBEDTLS_ERR_PK_INVALID_PUBKEY) ) + mbedtls_snprintf( buf, buflen, "PK - The pubkey tag or value is invalid (only RSA and EC are supported)" ); + if( use_ret == -(MBEDTLS_ERR_PK_INVALID_ALG) ) + mbedtls_snprintf( buf, buflen, "PK - The algorithm tag or value is invalid" ); + if( use_ret == -(MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE) ) + mbedtls_snprintf( buf, buflen, "PK - Elliptic curve is unsupported (only NIST curves are supported)" ); + if( use_ret == -(MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE) ) + mbedtls_snprintf( buf, buflen, "PK - Unavailable feature, e.g. RSA disabled for RSA key" ); + if( use_ret == -(MBEDTLS_ERR_PK_SIG_LEN_MISMATCH) ) + mbedtls_snprintf( buf, buflen, "PK - The buffer contains a valid signature followed by more data" ); + if( use_ret == -(MBEDTLS_ERR_PK_HW_ACCEL_FAILED) ) + mbedtls_snprintf( buf, buflen, "PK - PK hardware accelerator failed" ); +#endif /* MBEDTLS_PK_C */ + +#if defined(MBEDTLS_PKCS12_C) + if( use_ret == -(MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA) ) + mbedtls_snprintf( buf, buflen, "PKCS12 - Bad input parameters to function" ); + if( use_ret == -(MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE) ) + mbedtls_snprintf( buf, buflen, "PKCS12 - Feature not available, e.g. unsupported encryption scheme" ); + if( use_ret == -(MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT) ) + mbedtls_snprintf( buf, buflen, "PKCS12 - PBE ASN.1 data not as expected" ); + if( use_ret == -(MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH) ) + mbedtls_snprintf( buf, buflen, "PKCS12 - Given private key password does not allow for correct decryption" ); +#endif /* MBEDTLS_PKCS12_C */ + +#if defined(MBEDTLS_PKCS5_C) + if( use_ret == -(MBEDTLS_ERR_PKCS5_BAD_INPUT_DATA) ) + mbedtls_snprintf( buf, buflen, "PKCS5 - Bad input parameters to function" ); + if( use_ret == -(MBEDTLS_ERR_PKCS5_INVALID_FORMAT) ) + mbedtls_snprintf( buf, buflen, "PKCS5 - Unexpected ASN.1 data" ); + if( use_ret == -(MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE) ) + mbedtls_snprintf( buf, buflen, "PKCS5 - Requested encryption or digest alg not available" ); + if( use_ret == -(MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH) ) + mbedtls_snprintf( buf, buflen, "PKCS5 - Given private key password does not allow for correct decryption" ); +#endif /* MBEDTLS_PKCS5_C */ + +#if defined(MBEDTLS_RSA_C) + if( use_ret == -(MBEDTLS_ERR_RSA_BAD_INPUT_DATA) ) + mbedtls_snprintf( buf, buflen, "RSA - Bad input parameters to function" ); + if( use_ret == -(MBEDTLS_ERR_RSA_INVALID_PADDING) ) + mbedtls_snprintf( buf, buflen, "RSA - Input data contains invalid padding and is rejected" ); + if( use_ret == -(MBEDTLS_ERR_RSA_KEY_GEN_FAILED) ) + mbedtls_snprintf( buf, buflen, "RSA - Something failed during generation of a key" ); + if( use_ret == -(MBEDTLS_ERR_RSA_KEY_CHECK_FAILED) ) + mbedtls_snprintf( buf, buflen, "RSA - Key failed to pass the validity check of the library" ); + if( use_ret == -(MBEDTLS_ERR_RSA_PUBLIC_FAILED) ) + mbedtls_snprintf( buf, buflen, "RSA - The public key operation failed" ); + if( use_ret == -(MBEDTLS_ERR_RSA_PRIVATE_FAILED) ) + mbedtls_snprintf( buf, buflen, "RSA - The private key operation failed" ); + if( use_ret == -(MBEDTLS_ERR_RSA_VERIFY_FAILED) ) + mbedtls_snprintf( buf, buflen, "RSA - The PKCS#1 verification failed" ); + if( use_ret == -(MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE) ) + mbedtls_snprintf( buf, buflen, "RSA - The output buffer for decryption is not large enough" ); + if( use_ret == -(MBEDTLS_ERR_RSA_RNG_FAILED) ) + mbedtls_snprintf( buf, buflen, "RSA - The random generator failed to generate non-zeros" ); + if( use_ret == -(MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION) ) + mbedtls_snprintf( buf, buflen, "RSA - The implementation does not offer the requested operation, for example, because of security violations or lack of functionality" ); + if( use_ret == -(MBEDTLS_ERR_RSA_HW_ACCEL_FAILED) ) + mbedtls_snprintf( buf, buflen, "RSA - RSA hardware accelerator failed" ); +#endif /* MBEDTLS_RSA_C */ + +#if defined(MBEDTLS_SSL_TLS_C) + if( use_ret == -(MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE) ) + mbedtls_snprintf( buf, buflen, "SSL - The requested feature is not available" ); + if( use_ret == -(MBEDTLS_ERR_SSL_BAD_INPUT_DATA) ) + mbedtls_snprintf( buf, buflen, "SSL - Bad input parameters to function" ); + if( use_ret == -(MBEDTLS_ERR_SSL_INVALID_MAC) ) + mbedtls_snprintf( buf, buflen, "SSL - Verification of the message MAC failed" ); + if( use_ret == -(MBEDTLS_ERR_SSL_INVALID_RECORD) ) + mbedtls_snprintf( buf, buflen, "SSL - An invalid SSL record was received" ); + if( use_ret == -(MBEDTLS_ERR_SSL_CONN_EOF) ) + mbedtls_snprintf( buf, buflen, "SSL - The connection indicated an EOF" ); + if( use_ret == -(MBEDTLS_ERR_SSL_UNKNOWN_CIPHER) ) + mbedtls_snprintf( buf, buflen, "SSL - An unknown cipher was received" ); + if( use_ret == -(MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN) ) + mbedtls_snprintf( buf, buflen, "SSL - The server has no ciphersuites in common with the client" ); + if( use_ret == -(MBEDTLS_ERR_SSL_NO_RNG) ) + mbedtls_snprintf( buf, buflen, "SSL - No RNG was provided to the SSL module" ); + if( use_ret == -(MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE) ) + mbedtls_snprintf( buf, buflen, "SSL - No client certification received from the client, but required by the authentication mode" ); + if( use_ret == -(MBEDTLS_ERR_SSL_CERTIFICATE_TOO_LARGE) ) + mbedtls_snprintf( buf, buflen, "SSL - Our own certificate(s) is/are too large to send in an SSL message" ); + if( use_ret == -(MBEDTLS_ERR_SSL_CERTIFICATE_REQUIRED) ) + mbedtls_snprintf( buf, buflen, "SSL - The own certificate is not set, but needed by the server" ); + if( use_ret == -(MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED) ) + mbedtls_snprintf( buf, buflen, "SSL - The own private key or pre-shared key is not set, but needed" ); + if( use_ret == -(MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED) ) + mbedtls_snprintf( buf, buflen, "SSL - No CA Chain is set, but required to operate" ); + if( use_ret == -(MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE) ) + mbedtls_snprintf( buf, buflen, "SSL - An unexpected message was received from our peer" ); + if( use_ret == -(MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE) ) + { + mbedtls_snprintf( buf, buflen, "SSL - A fatal alert message was received from our peer" ); + return; + } + if( use_ret == -(MBEDTLS_ERR_SSL_PEER_VERIFY_FAILED) ) + mbedtls_snprintf( buf, buflen, "SSL - Verification of our peer failed" ); + if( use_ret == -(MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) ) + mbedtls_snprintf( buf, buflen, "SSL - The peer notified us that the connection is going to be closed" ); + if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO) ) + mbedtls_snprintf( buf, buflen, "SSL - Processing of the ClientHello handshake message failed" ); + if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO) ) + mbedtls_snprintf( buf, buflen, "SSL - Processing of the ServerHello handshake message failed" ); + if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE) ) + mbedtls_snprintf( buf, buflen, "SSL - Processing of the Certificate handshake message failed" ); + if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST) ) + mbedtls_snprintf( buf, buflen, "SSL - Processing of the CertificateRequest handshake message failed" ); + if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE) ) + mbedtls_snprintf( buf, buflen, "SSL - Processing of the ServerKeyExchange handshake message failed" ); + if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO_DONE) ) + mbedtls_snprintf( buf, buflen, "SSL - Processing of the ServerHelloDone handshake message failed" ); + if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE) ) + mbedtls_snprintf( buf, buflen, "SSL - Processing of the ClientKeyExchange handshake message failed" ); + if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP) ) + mbedtls_snprintf( buf, buflen, "SSL - Processing of the ClientKeyExchange handshake message failed in DHM / ECDH Read Public" ); + if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS) ) + mbedtls_snprintf( buf, buflen, "SSL - Processing of the ClientKeyExchange handshake message failed in DHM / ECDH Calculate Secret" ); + if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY) ) + mbedtls_snprintf( buf, buflen, "SSL - Processing of the CertificateVerify handshake message failed" ); + if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CHANGE_CIPHER_SPEC) ) + mbedtls_snprintf( buf, buflen, "SSL - Processing of the ChangeCipherSpec handshake message failed" ); + if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_FINISHED) ) + mbedtls_snprintf( buf, buflen, "SSL - Processing of the Finished handshake message failed" ); + if( use_ret == -(MBEDTLS_ERR_SSL_ALLOC_FAILED) ) + mbedtls_snprintf( buf, buflen, "SSL - Memory allocation failed" ); + if( use_ret == -(MBEDTLS_ERR_SSL_HW_ACCEL_FAILED) ) + mbedtls_snprintf( buf, buflen, "SSL - Hardware acceleration function returned with error" ); + if( use_ret == -(MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH) ) + mbedtls_snprintf( buf, buflen, "SSL - Hardware acceleration function skipped / left alone data" ); + if( use_ret == -(MBEDTLS_ERR_SSL_COMPRESSION_FAILED) ) + mbedtls_snprintf( buf, buflen, "SSL - Processing of the compression / decompression failed" ); + if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION) ) + mbedtls_snprintf( buf, buflen, "SSL - Handshake protocol not within min/max boundaries" ); + if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET) ) + mbedtls_snprintf( buf, buflen, "SSL - Processing of the NewSessionTicket handshake message failed" ); + if( use_ret == -(MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED) ) + mbedtls_snprintf( buf, buflen, "SSL - Session ticket has expired" ); + if( use_ret == -(MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH) ) + mbedtls_snprintf( buf, buflen, "SSL - Public key type mismatch (eg, asked for RSA key exchange and presented EC key)" ); + if( use_ret == -(MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY) ) + mbedtls_snprintf( buf, buflen, "SSL - Unknown identity received (eg, PSK identity)" ); + if( use_ret == -(MBEDTLS_ERR_SSL_INTERNAL_ERROR) ) + mbedtls_snprintf( buf, buflen, "SSL - Internal error (eg, unexpected failure in lower-level module)" ); + if( use_ret == -(MBEDTLS_ERR_SSL_COUNTER_WRAPPING) ) + mbedtls_snprintf( buf, buflen, "SSL - A counter would wrap (eg, too many messages exchanged)" ); + if( use_ret == -(MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO) ) + mbedtls_snprintf( buf, buflen, "SSL - Unexpected message at ServerHello in renegotiation" ); + if( use_ret == -(MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED) ) + mbedtls_snprintf( buf, buflen, "SSL - DTLS client must retry for hello verification" ); + if( use_ret == -(MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL) ) + mbedtls_snprintf( buf, buflen, "SSL - A buffer is too small to receive or write a message" ); + if( use_ret == -(MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE) ) + mbedtls_snprintf( buf, buflen, "SSL - None of the common ciphersuites is usable (eg, no suitable certificate, see debug messages)" ); + if( use_ret == -(MBEDTLS_ERR_SSL_WANT_READ) ) + mbedtls_snprintf( buf, buflen, "SSL - Connection requires a read call" ); + if( use_ret == -(MBEDTLS_ERR_SSL_WANT_WRITE) ) + mbedtls_snprintf( buf, buflen, "SSL - Connection requires a write call" ); + if( use_ret == -(MBEDTLS_ERR_SSL_TIMEOUT) ) + mbedtls_snprintf( buf, buflen, "SSL - The operation timed out" ); + if( use_ret == -(MBEDTLS_ERR_SSL_CLIENT_RECONNECT) ) + mbedtls_snprintf( buf, buflen, "SSL - The client initiated a reconnect from the same port" ); + if( use_ret == -(MBEDTLS_ERR_SSL_UNEXPECTED_RECORD) ) + mbedtls_snprintf( buf, buflen, "SSL - Record header looks valid but is not expected" ); + if( use_ret == -(MBEDTLS_ERR_SSL_NON_FATAL) ) + mbedtls_snprintf( buf, buflen, "SSL - The alert message received indicates a non-fatal error" ); + if( use_ret == -(MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH) ) + mbedtls_snprintf( buf, buflen, "SSL - Couldn't set the hash for verifying CertificateVerify" ); +#endif /* MBEDTLS_SSL_TLS_C */ + +#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C) + if( use_ret == -(MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE) ) + mbedtls_snprintf( buf, buflen, "X509 - Unavailable feature, e.g. RSA hashing/encryption combination" ); + if( use_ret == -(MBEDTLS_ERR_X509_UNKNOWN_OID) ) + mbedtls_snprintf( buf, buflen, "X509 - Requested OID is unknown" ); + if( use_ret == -(MBEDTLS_ERR_X509_INVALID_FORMAT) ) + mbedtls_snprintf( buf, buflen, "X509 - The CRT/CRL/CSR format is invalid, e.g. different type expected" ); + if( use_ret == -(MBEDTLS_ERR_X509_INVALID_VERSION) ) + mbedtls_snprintf( buf, buflen, "X509 - The CRT/CRL/CSR version element is invalid" ); + if( use_ret == -(MBEDTLS_ERR_X509_INVALID_SERIAL) ) + mbedtls_snprintf( buf, buflen, "X509 - The serial tag or value is invalid" ); + if( use_ret == -(MBEDTLS_ERR_X509_INVALID_ALG) ) + mbedtls_snprintf( buf, buflen, "X509 - The algorithm tag or value is invalid" ); + if( use_ret == -(MBEDTLS_ERR_X509_INVALID_NAME) ) + mbedtls_snprintf( buf, buflen, "X509 - The name tag or value is invalid" ); + if( use_ret == -(MBEDTLS_ERR_X509_INVALID_DATE) ) + mbedtls_snprintf( buf, buflen, "X509 - The date tag or value is invalid" ); + if( use_ret == -(MBEDTLS_ERR_X509_INVALID_SIGNATURE) ) + mbedtls_snprintf( buf, buflen, "X509 - The signature tag or value invalid" ); + if( use_ret == -(MBEDTLS_ERR_X509_INVALID_EXTENSIONS) ) + mbedtls_snprintf( buf, buflen, "X509 - The extension tag or value is invalid" ); + if( use_ret == -(MBEDTLS_ERR_X509_UNKNOWN_VERSION) ) + mbedtls_snprintf( buf, buflen, "X509 - CRT/CRL/CSR has an unsupported version number" ); + if( use_ret == -(MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG) ) + mbedtls_snprintf( buf, buflen, "X509 - Signature algorithm (oid) is unsupported" ); + if( use_ret == -(MBEDTLS_ERR_X509_SIG_MISMATCH) ) + mbedtls_snprintf( buf, buflen, "X509 - Signature algorithms do not match. (see \\c ::mbedtls_x509_crt sig_oid)" ); + if( use_ret == -(MBEDTLS_ERR_X509_CERT_VERIFY_FAILED) ) + mbedtls_snprintf( buf, buflen, "X509 - Certificate verification failed, e.g. CRL, CA or signature check failed" ); + if( use_ret == -(MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT) ) + mbedtls_snprintf( buf, buflen, "X509 - Format not recognized as DER or PEM" ); + if( use_ret == -(MBEDTLS_ERR_X509_BAD_INPUT_DATA) ) + mbedtls_snprintf( buf, buflen, "X509 - Input invalid" ); + if( use_ret == -(MBEDTLS_ERR_X509_ALLOC_FAILED) ) + mbedtls_snprintf( buf, buflen, "X509 - Allocation of memory failed" ); + if( use_ret == -(MBEDTLS_ERR_X509_FILE_IO_ERROR) ) + mbedtls_snprintf( buf, buflen, "X509 - Read/write of file failed" ); + if( use_ret == -(MBEDTLS_ERR_X509_BUFFER_TOO_SMALL) ) + mbedtls_snprintf( buf, buflen, "X509 - Destination buffer is too small" ); + if( use_ret == -(MBEDTLS_ERR_X509_FATAL_ERROR) ) + mbedtls_snprintf( buf, buflen, "X509 - A fatal error occured, eg the chain is too long or the vrfy callback failed" ); +#endif /* MBEDTLS_X509_USE_C || MBEDTLS_X509_CREATE_C */ + // END generated code + + if( strlen( buf ) == 0 ) + mbedtls_snprintf( buf, buflen, "UNKNOWN ERROR CODE (%04X)", use_ret ); + } + + use_ret = ret & ~0xFF80; + + if( use_ret == 0 ) + return; + + // If high level code is present, make a concatenation between both + // error strings. + // + len = strlen( buf ); + + if( len > 0 ) + { + if( buflen - len < 5 ) + return; + + mbedtls_snprintf( buf + len, buflen - len, " : " ); + + buf += len + 3; + buflen -= len + 3; + } + + // Low level error codes + // + // BEGIN generated code +#if defined(MBEDTLS_AES_C) + if( use_ret == -(MBEDTLS_ERR_AES_INVALID_KEY_LENGTH) ) + mbedtls_snprintf( buf, buflen, "AES - Invalid key length" ); + if( use_ret == -(MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH) ) + mbedtls_snprintf( buf, buflen, "AES - Invalid data input length" ); + if( use_ret == -(MBEDTLS_ERR_AES_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 */ + +#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( use_ret == -(MBEDTLS_ERR_ASN1_OUT_OF_DATA) ) + mbedtls_snprintf( buf, buflen, "ASN1 - Out of data when parsing an ASN1 data structure" ); + if( use_ret == -(MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) ) + mbedtls_snprintf( buf, buflen, "ASN1 - ASN1 tag was of an unexpected value" ); + if( use_ret == -(MBEDTLS_ERR_ASN1_INVALID_LENGTH) ) + mbedtls_snprintf( buf, buflen, "ASN1 - Error when trying to determine the length or invalid length" ); + if( use_ret == -(MBEDTLS_ERR_ASN1_LENGTH_MISMATCH) ) + mbedtls_snprintf( buf, buflen, "ASN1 - Actual length differs from expected length" ); + if( use_ret == -(MBEDTLS_ERR_ASN1_INVALID_DATA) ) + mbedtls_snprintf( buf, buflen, "ASN1 - Data is invalid. (not used)" ); + if( use_ret == -(MBEDTLS_ERR_ASN1_ALLOC_FAILED) ) + mbedtls_snprintf( buf, buflen, "ASN1 - Memory allocation failed" ); + if( use_ret == -(MBEDTLS_ERR_ASN1_BUF_TOO_SMALL) ) + mbedtls_snprintf( buf, buflen, "ASN1 - Buffer too small when writing ASN.1 data structure" ); +#endif /* MBEDTLS_ASN1_PARSE_C */ + +#if defined(MBEDTLS_BASE64_C) + if( use_ret == -(MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL) ) + mbedtls_snprintf( buf, buflen, "BASE64 - Output buffer too small" ); + if( use_ret == -(MBEDTLS_ERR_BASE64_INVALID_CHARACTER) ) + mbedtls_snprintf( buf, buflen, "BASE64 - Invalid character in input" ); +#endif /* MBEDTLS_BASE64_C */ + +#if defined(MBEDTLS_BIGNUM_C) + if( use_ret == -(MBEDTLS_ERR_MPI_FILE_IO_ERROR) ) + mbedtls_snprintf( buf, buflen, "BIGNUM - An error occurred while reading from or writing to a file" ); + if( use_ret == -(MBEDTLS_ERR_MPI_BAD_INPUT_DATA) ) + mbedtls_snprintf( buf, buflen, "BIGNUM - Bad input parameters to function" ); + if( use_ret == -(MBEDTLS_ERR_MPI_INVALID_CHARACTER) ) + mbedtls_snprintf( buf, buflen, "BIGNUM - There is an invalid character in the digit string" ); + if( use_ret == -(MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL) ) + mbedtls_snprintf( buf, buflen, "BIGNUM - The buffer is too small to write to" ); + if( use_ret == -(MBEDTLS_ERR_MPI_NEGATIVE_VALUE) ) + mbedtls_snprintf( buf, buflen, "BIGNUM - The input arguments are negative or result in illegal output" ); + if( use_ret == -(MBEDTLS_ERR_MPI_DIVISION_BY_ZERO) ) + mbedtls_snprintf( buf, buflen, "BIGNUM - The input argument for division is zero, which is not allowed" ); + if( use_ret == -(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE) ) + mbedtls_snprintf( buf, buflen, "BIGNUM - The input arguments are not acceptable" ); + if( use_ret == -(MBEDTLS_ERR_MPI_ALLOC_FAILED) ) + mbedtls_snprintf( buf, buflen, "BIGNUM - Memory allocation failed" ); +#endif /* MBEDTLS_BIGNUM_C */ + +#if defined(MBEDTLS_BLOWFISH_C) + if( use_ret == -(MBEDTLS_ERR_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) ) + mbedtls_snprintf( buf, buflen, "BLOWFISH - Invalid data input length" ); +#endif /* MBEDTLS_BLOWFISH_C */ + +#if defined(MBEDTLS_CAMELLIA_C) + if( use_ret == -(MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH) ) + mbedtls_snprintf( buf, buflen, "CAMELLIA - Invalid key length" ); + if( use_ret == -(MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH) ) + mbedtls_snprintf( buf, buflen, "CAMELLIA - Invalid data input length" ); + if( use_ret == -(MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED) ) + mbedtls_snprintf( buf, buflen, "CAMELLIA - Camellia hardware accelerator failed" ); +#endif /* MBEDTLS_CAMELLIA_C */ + +#if defined(MBEDTLS_CCM_C) + if( use_ret == -(MBEDTLS_ERR_CCM_BAD_INPUT) ) + mbedtls_snprintf( buf, buflen, "CCM - Bad input parameters to the function" ); + if( use_ret == -(MBEDTLS_ERR_CCM_AUTH_FAILED) ) + mbedtls_snprintf( buf, buflen, "CCM - Authenticated decryption failed" ); + if( use_ret == -(MBEDTLS_ERR_CCM_HW_ACCEL_FAILED) ) + mbedtls_snprintf( buf, buflen, "CCM - CCM hardware accelerator failed" ); +#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( use_ret == -(MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED) ) + mbedtls_snprintf( buf, buflen, "CTR_DRBG - The entropy source failed" ); + if( use_ret == -(MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG) ) + mbedtls_snprintf( buf, buflen, "CTR_DRBG - The requested random buffer length is too big" ); + if( use_ret == -(MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG) ) + mbedtls_snprintf( buf, buflen, "CTR_DRBG - The input (entropy + additional data) is too large" ); + if( use_ret == -(MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR) ) + mbedtls_snprintf( buf, buflen, "CTR_DRBG - Read or write error in file" ); +#endif /* MBEDTLS_CTR_DRBG_C */ + +#if defined(MBEDTLS_DES_C) + if( use_ret == -(MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH) ) + mbedtls_snprintf( buf, buflen, "DES - The data input has an invalid length" ); + if( use_ret == -(MBEDTLS_ERR_DES_HW_ACCEL_FAILED) ) + mbedtls_snprintf( buf, buflen, "DES - DES hardware accelerator failed" ); +#endif /* MBEDTLS_DES_C */ + +#if defined(MBEDTLS_ENTROPY_C) + if( use_ret == -(MBEDTLS_ERR_ENTROPY_SOURCE_FAILED) ) + mbedtls_snprintf( buf, buflen, "ENTROPY - Critical entropy source failure" ); + if( use_ret == -(MBEDTLS_ERR_ENTROPY_MAX_SOURCES) ) + mbedtls_snprintf( buf, buflen, "ENTROPY - No more sources can be added" ); + if( use_ret == -(MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED) ) + mbedtls_snprintf( buf, buflen, "ENTROPY - No sources have been added to poll" ); + if( use_ret == -(MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE) ) + mbedtls_snprintf( buf, buflen, "ENTROPY - No strong sources have been added to poll" ); + if( use_ret == -(MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR) ) + mbedtls_snprintf( buf, buflen, "ENTROPY - Read/write error in file" ); +#endif /* MBEDTLS_ENTROPY_C */ + +#if defined(MBEDTLS_GCM_C) + if( use_ret == -(MBEDTLS_ERR_GCM_AUTH_FAILED) ) + mbedtls_snprintf( buf, buflen, "GCM - Authenticated decryption failed" ); + if( use_ret == -(MBEDTLS_ERR_GCM_HW_ACCEL_FAILED) ) + mbedtls_snprintf( buf, buflen, "GCM - GCM hardware accelerator failed" ); + if( use_ret == -(MBEDTLS_ERR_GCM_BAD_INPUT) ) + mbedtls_snprintf( buf, buflen, "GCM - Bad input parameters to function" ); +#endif /* MBEDTLS_GCM_C */ + +#if defined(MBEDTLS_HMAC_DRBG_C) + if( use_ret == -(MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG) ) + mbedtls_snprintf( buf, buflen, "HMAC_DRBG - Too many random requested in single call" ); + if( use_ret == -(MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG) ) + mbedtls_snprintf( buf, buflen, "HMAC_DRBG - Input too large (Entropy + additional)" ); + if( use_ret == -(MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR) ) + mbedtls_snprintf( buf, buflen, "HMAC_DRBG - Read/write error in file" ); + if( use_ret == -(MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED) ) + mbedtls_snprintf( buf, buflen, "HMAC_DRBG - The entropy source failed" ); +#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( use_ret == -(MBEDTLS_ERR_NET_SOCKET_FAILED) ) + mbedtls_snprintf( buf, buflen, "NET - Failed to open a socket" ); + if( use_ret == -(MBEDTLS_ERR_NET_CONNECT_FAILED) ) + mbedtls_snprintf( buf, buflen, "NET - The connection to the given server / port failed" ); + if( use_ret == -(MBEDTLS_ERR_NET_BIND_FAILED) ) + mbedtls_snprintf( buf, buflen, "NET - Binding of the socket failed" ); + if( use_ret == -(MBEDTLS_ERR_NET_LISTEN_FAILED) ) + mbedtls_snprintf( buf, buflen, "NET - Could not listen on the socket" ); + if( use_ret == -(MBEDTLS_ERR_NET_ACCEPT_FAILED) ) + mbedtls_snprintf( buf, buflen, "NET - Could not accept the incoming connection" ); + if( use_ret == -(MBEDTLS_ERR_NET_RECV_FAILED) ) + mbedtls_snprintf( buf, buflen, "NET - Reading information from the socket failed" ); + if( use_ret == -(MBEDTLS_ERR_NET_SEND_FAILED) ) + mbedtls_snprintf( buf, buflen, "NET - Sending information through the socket failed" ); + if( use_ret == -(MBEDTLS_ERR_NET_CONN_RESET) ) + mbedtls_snprintf( buf, buflen, "NET - Connection was reset by peer" ); + if( use_ret == -(MBEDTLS_ERR_NET_UNKNOWN_HOST) ) + mbedtls_snprintf( buf, buflen, "NET - Failed to get an IP address for the given hostname" ); + if( use_ret == -(MBEDTLS_ERR_NET_BUFFER_TOO_SMALL) ) + mbedtls_snprintf( buf, buflen, "NET - Buffer is too small to hold the data" ); + if( use_ret == -(MBEDTLS_ERR_NET_INVALID_CONTEXT) ) + mbedtls_snprintf( buf, buflen, "NET - The context is invalid, eg because it was free()ed" ); +#endif /* MBEDTLS_NET_C */ + +#if defined(MBEDTLS_OID_C) + if( use_ret == -(MBEDTLS_ERR_OID_NOT_FOUND) ) + mbedtls_snprintf( buf, buflen, "OID - OID is not found" ); + if( use_ret == -(MBEDTLS_ERR_OID_BUF_TOO_SMALL) ) + mbedtls_snprintf( buf, buflen, "OID - output buffer is too small" ); +#endif /* MBEDTLS_OID_C */ + +#if defined(MBEDTLS_PADLOCK_C) + if( use_ret == -(MBEDTLS_ERR_PADLOCK_DATA_MISALIGNED) ) + mbedtls_snprintf( buf, buflen, "PADLOCK - Input data should be aligned" ); +#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( use_ret == -(MBEDTLS_ERR_THREADING_FEATURE_UNAVAILABLE) ) + mbedtls_snprintf( buf, buflen, "THREADING - The selected feature is not available" ); + if( use_ret == -(MBEDTLS_ERR_THREADING_BAD_INPUT_DATA) ) + mbedtls_snprintf( buf, buflen, "THREADING - Bad input parameters to function" ); + if( use_ret == -(MBEDTLS_ERR_THREADING_MUTEX_ERROR) ) + mbedtls_snprintf( buf, buflen, "THREADING - Locking / unlocking / free failed with error code" ); +#endif /* MBEDTLS_THREADING_C */ + +#if defined(MBEDTLS_XTEA_C) + if( use_ret == -(MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH) ) + mbedtls_snprintf( buf, buflen, "XTEA - The data input has an invalid length" ); + if( use_ret == -(MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED) ) + mbedtls_snprintf( buf, buflen, "XTEA - XTEA hardware accelerator failed" ); +#endif /* MBEDTLS_XTEA_C */ + // END generated code + + if( strlen( buf ) != 0 ) + return; + + mbedtls_snprintf( buf, buflen, "UNKNOWN ERROR CODE (%04X)", use_ret ); +} + +#else /* MBEDTLS_ERROR_C */ + +#if defined(MBEDTLS_ERROR_STRERROR_DUMMY) + +/* + * Provide an non-function in case MBEDTLS_ERROR_C is not defined + */ +void mbedtls_strerror( int ret, char *buf, size_t buflen ) +{ + ((void) ret); + + if( buflen > 0 ) + buf[0] = '\0'; +} + +#endif /* MBEDTLS_ERROR_STRERROR_DUMMY */ + +#endif /* MBEDTLS_ERROR_C */ diff --git a/APP_Framework/Framework/security/mbedtls/error.h b/APP_Framework/Framework/security/mbedtls/error.h index 9696f178b..ef22bc684 100644 --- a/APP_Framework/Framework/security/mbedtls/error.h +++ b/APP_Framework/Framework/security/mbedtls/error.h @@ -4,7 +4,7 @@ * \brief Error to string translation */ /* - * Copyright (C) 2006-2018, ARM Limited, All Rights Reserved + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -59,7 +59,7 @@ * GCM 3 0x0012-0x0014 0x0013-0x0013 * BLOWFISH 3 0x0016-0x0018 0x0017-0x0017 * THREADING 3 0x001A-0x001E - * AES 5 0x0020-0x0022 0x0021-0x0025 + * AES 4 0x0020-0x0022 0x0023-0x0025 * CAMELLIA 3 0x0024-0x0026 0x0027-0x0027 * XTEA 2 0x0028-0x0028 0x0029-0x0029 * BASE64 2 0x002A-0x002C @@ -68,8 +68,7 @@ * DES 2 0x0032-0x0032 0x0033-0x0033 * CTR_DBRG 4 0x0034-0x003A * ENTROPY 3 0x003C-0x0040 0x003D-0x003F - * NET 13 0x0042-0x0052 0x0043-0x0049 - * ARIA 4 0x0058-0x005E + * NET 11 0x0042-0x0052 0x0043-0x0045 * ASN1 7 0x0060-0x006C * CMAC 1 0x007A-0x007A * PBKDF2 1 0x007C-0x007C @@ -80,13 +79,9 @@ * MD4 1 0x002D-0x002D * MD5 1 0x002F-0x002F * RIPEMD160 1 0x0031-0x0031 - * SHA1 1 0x0035-0x0035 0x0073-0x0073 - * SHA256 1 0x0037-0x0037 0x0074-0x0074 - * SHA512 1 0x0039-0x0039 0x0075-0x0075 - * CHACHA20 3 0x0051-0x0055 - * POLY1305 3 0x0057-0x005B - * CHACHAPOLY 2 0x0054-0x0056 - * PLATFORM 4 0x0070-0x0072 0x0071-0x0071 0x0076-0x0076 + * SHA1 1 0x0035-0x0035 + * SHA256 1 0x0037-0x0037 + * SHA512 1 0x0039-0x0039 * * High-level module nr (3 bits - 0x0...-0x7...) * Name ID Nr of Errors @@ -97,13 +92,11 @@ * DHM 3 11 * PK 3 15 (Started from top) * RSA 4 11 - * ECP 4 10 (Started from top) + * ECP 4 9 (Started from top) * MD 5 5 - * HKDF 5 1 (Started from top) - * SSL 5 1 (Started from 0x5F00) - * CIPHER 6 8 (Started from 0x6080) - * SSL 6 24 (Started from top, plus 0x6000) - * SSL 7 32 + * CIPHER 6 8 + * SSL 6 17 (Started from top) + * SSL 7 31 * * Module dependent error code (5 bits 0x.00.-0x.F8.) */ diff --git a/APP_Framework/Framework/security/mbedtls/gcm.c b/APP_Framework/Framework/security/mbedtls/gcm.c new file mode 100644 index 000000000..e1a2bfe17 --- /dev/null +++ b/APP_Framework/Framework/security/mbedtls/gcm.c @@ -0,0 +1,958 @@ +/* + * NIST SP800-38D compliant GCM implementation + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +/* + * http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf + * + * See also: + * [MGV] http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf + * + * We use the algorithm described as Shoup's method with 4-bit tables in + * [MGV] 4.1, pp. 12-13, to enhance speed without using too much memory. + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_GCM_C) + +#include "gcm.h" + +#include + +#if defined(MBEDTLS_AESNI_C) +#include "aesni.h" +#endif + +#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) +#include "aes.h" +#if defined(MBEDTLS_PLATFORM_C) +#include "platform.h" +#else +#include +#define mbedtls_printf printf +#endif /* MBEDTLS_PLATFORM_C */ +#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ + +#if !defined(MBEDTLS_GCM_ALT) + +/* + * 32-bit integer manipulation macros (big endian) + */ +#ifndef GET_UINT32_BE +#define GET_UINT32_BE(n,b,i) \ +{ \ + (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ + | ( (uint32_t) (b)[(i) + 1] << 16 ) \ + | ( (uint32_t) (b)[(i) + 2] << 8 ) \ + | ( (uint32_t) (b)[(i) + 3] ); \ +} +#endif + +#ifndef PUT_UINT32_BE +#define PUT_UINT32_BE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) ); \ +} +#endif + +/* 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; +} + +/* + * Initialize a context + */ +void mbedtls_gcm_init( mbedtls_gcm_context *ctx ) +{ + memset( ctx, 0, sizeof( mbedtls_gcm_context ) ); +} + +/* + * Precompute small multiples of H, that is set + * HH[i] || HL[i] = H times i, + * where i is seen as a field element as in [MGV], ie high-order bits + * correspond to low powers of P. The result is stored in the same way, that + * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL + * corresponds to P^127. + */ +static int gcm_gen_table( mbedtls_gcm_context *ctx ) +{ + int ret, i, j; + uint64_t hi, lo; + uint64_t vl, vh; + unsigned char h[16]; + size_t olen = 0; + + memset( h, 0, 16 ); + if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 ) + return( ret ); + + /* pack h as two 64-bits ints, big-endian */ + GET_UINT32_BE( hi, h, 0 ); + GET_UINT32_BE( lo, h, 4 ); + vh = (uint64_t) hi << 32 | lo; + + GET_UINT32_BE( hi, h, 8 ); + GET_UINT32_BE( lo, h, 12 ); + vl = (uint64_t) hi << 32 | lo; + + /* 8 = 1000 corresponds to 1 in GF(2^128) */ + ctx->HL[8] = vl; + ctx->HH[8] = vh; + +#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64) + /* With CLMUL support, we need only h, not the rest of the table */ + if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) ) + return( 0 ); +#endif + + /* 0 corresponds to 0 in GF(2^128) */ + ctx->HH[0] = 0; + ctx->HL[0] = 0; + + for( i = 4; i > 0; i >>= 1 ) + { + uint32_t T = ( vl & 1 ) * 0xe1000000U; + vl = ( vh << 63 ) | ( vl >> 1 ); + vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32); + + ctx->HL[i] = vl; + ctx->HH[i] = vh; + } + + for( i = 2; i <= 8; i *= 2 ) + { + uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i; + vh = *HiH; + vl = *HiL; + for( j = 1; j < i; j++ ) + { + HiH[j] = vh ^ ctx->HH[j]; + HiL[j] = vl ^ ctx->HL[j]; + } + } + + return( 0 ); +} + +int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx, + mbedtls_cipher_id_t cipher, + const unsigned char *key, + unsigned int keybits ) +{ + int ret; + const mbedtls_cipher_info_t *cipher_info; + + cipher_info = mbedtls_cipher_info_from_values( cipher, keybits, MBEDTLS_MODE_ECB ); + if( cipher_info == NULL ) + return( MBEDTLS_ERR_GCM_BAD_INPUT ); + + if( cipher_info->block_size != 16 ) + return( MBEDTLS_ERR_GCM_BAD_INPUT ); + + mbedtls_cipher_free( &ctx->cipher_ctx ); + + if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 ) + return( ret ); + + if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits, + MBEDTLS_ENCRYPT ) ) != 0 ) + { + return( ret ); + } + + if( ( ret = gcm_gen_table( ctx ) ) != 0 ) + return( ret ); + + return( 0 ); +} + +/* + * Shoup's method for multiplication use this table with + * last4[x] = x times P^128 + * where x and last4[x] are seen as elements of GF(2^128) as in [MGV] + */ +static const uint64_t last4[16] = +{ + 0x0000, 0x1c20, 0x3840, 0x2460, + 0x7080, 0x6ca0, 0x48c0, 0x54e0, + 0xe100, 0xfd20, 0xd940, 0xc560, + 0x9180, 0x8da0, 0xa9c0, 0xb5e0 +}; + +/* + * Sets output to x times H using the precomputed tables. + * x and output are seen as elements of GF(2^128) as in [MGV]. + */ +static void gcm_mult( mbedtls_gcm_context *ctx, const unsigned char x[16], + unsigned char output[16] ) +{ + int i = 0; + unsigned char lo, hi, rem; + uint64_t zh, zl; + +#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64) + if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) ) { + unsigned char h[16]; + + PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 ); + PUT_UINT32_BE( ctx->HH[8], h, 4 ); + PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 ); + PUT_UINT32_BE( ctx->HL[8], h, 12 ); + + mbedtls_aesni_gcm_mult( output, x, h ); + return; + } +#endif /* MBEDTLS_AESNI_C && MBEDTLS_HAVE_X86_64 */ + + lo = x[15] & 0xf; + + zh = ctx->HH[lo]; + zl = ctx->HL[lo]; + + for( i = 15; i >= 0; i-- ) + { + lo = x[i] & 0xf; + hi = x[i] >> 4; + + if( i != 15 ) + { + rem = (unsigned char) zl & 0xf; + zl = ( zh << 60 ) | ( zl >> 4 ); + zh = ( zh >> 4 ); + zh ^= (uint64_t) last4[rem] << 48; + zh ^= ctx->HH[lo]; + zl ^= ctx->HL[lo]; + + } + + rem = (unsigned char) zl & 0xf; + zl = ( zh << 60 ) | ( zl >> 4 ); + zh = ( zh >> 4 ); + zh ^= (uint64_t) last4[rem] << 48; + zh ^= ctx->HH[hi]; + zl ^= ctx->HL[hi]; + } + + PUT_UINT32_BE( zh >> 32, output, 0 ); + PUT_UINT32_BE( zh, output, 4 ); + PUT_UINT32_BE( zl >> 32, output, 8 ); + PUT_UINT32_BE( zl, output, 12 ); +} + +int mbedtls_gcm_starts( mbedtls_gcm_context *ctx, + int mode, + const unsigned char *iv, + size_t iv_len, + const unsigned char *add, + size_t add_len ) +{ + int ret; + unsigned char work_buf[16]; + size_t i; + const unsigned char *p; + size_t use_len, olen = 0; + + /* IV and AD are limited to 2^64 bits, so 2^61 bytes */ + /* IV is not allowed to be zero length */ + if( iv_len == 0 || + ( (uint64_t) iv_len ) >> 61 != 0 || + ( (uint64_t) add_len ) >> 61 != 0 ) + { + return( MBEDTLS_ERR_GCM_BAD_INPUT ); + } + + memset( ctx->y, 0x00, sizeof(ctx->y) ); + memset( ctx->buf, 0x00, sizeof(ctx->buf) ); + + ctx->mode = mode; + ctx->len = 0; + ctx->add_len = 0; + + if( iv_len == 12 ) + { + memcpy( ctx->y, iv, iv_len ); + ctx->y[15] = 1; + } + else + { + memset( work_buf, 0x00, 16 ); + PUT_UINT32_BE( iv_len * 8, work_buf, 12 ); + + p = iv; + while( iv_len > 0 ) + { + use_len = ( iv_len < 16 ) ? iv_len : 16; + + for( i = 0; i < use_len; i++ ) + ctx->y[i] ^= p[i]; + + gcm_mult( ctx, ctx->y, ctx->y ); + + iv_len -= use_len; + p += use_len; + } + + for( i = 0; i < 16; i++ ) + ctx->y[i] ^= work_buf[i]; + + gcm_mult( ctx, ctx->y, ctx->y ); + } + + if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ctx->base_ectr, + &olen ) ) != 0 ) + { + return( ret ); + } + + ctx->add_len = add_len; + p = add; + while( add_len > 0 ) + { + use_len = ( add_len < 16 ) ? add_len : 16; + + for( i = 0; i < use_len; i++ ) + ctx->buf[i] ^= p[i]; + + gcm_mult( ctx, ctx->buf, ctx->buf ); + + add_len -= use_len; + p += use_len; + } + + return( 0 ); +} + +int mbedtls_gcm_update( mbedtls_gcm_context *ctx, + size_t length, + const unsigned char *input, + unsigned char *output ) +{ + int ret; + unsigned char ectr[16]; + size_t i; + const unsigned char *p; + unsigned char *out_p = output; + size_t use_len, olen = 0; + + if( output > input && (size_t) ( output - input ) < length ) + return( MBEDTLS_ERR_GCM_BAD_INPUT ); + + /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes + * Also check for possible overflow */ + if( ctx->len + length < ctx->len || + (uint64_t) ctx->len + length > 0xFFFFFFFE0ull ) + { + return( MBEDTLS_ERR_GCM_BAD_INPUT ); + } + + ctx->len += length; + + p = input; + while( length > 0 ) + { + use_len = ( length < 16 ) ? length : 16; + + for( i = 16; i > 12; i-- ) + if( ++ctx->y[i - 1] != 0 ) + break; + + if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr, + &olen ) ) != 0 ) + { + return( ret ); + } + + for( i = 0; i < use_len; i++ ) + { + if( ctx->mode == MBEDTLS_GCM_DECRYPT ) + ctx->buf[i] ^= p[i]; + out_p[i] = ectr[i] ^ p[i]; + if( ctx->mode == MBEDTLS_GCM_ENCRYPT ) + ctx->buf[i] ^= out_p[i]; + } + + gcm_mult( ctx, ctx->buf, ctx->buf ); + + length -= use_len; + p += use_len; + out_p += use_len; + } + + return( 0 ); +} + +int mbedtls_gcm_finish( mbedtls_gcm_context *ctx, + unsigned char *tag, + size_t tag_len ) +{ + unsigned char work_buf[16]; + size_t i; + uint64_t orig_len = ctx->len * 8; + uint64_t orig_add_len = ctx->add_len * 8; + + if( tag_len > 16 || tag_len < 4 ) + return( MBEDTLS_ERR_GCM_BAD_INPUT ); + + memcpy( tag, ctx->base_ectr, tag_len ); + + if( orig_len || orig_add_len ) + { + memset( work_buf, 0x00, 16 ); + + PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 ); + PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 ); + PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 ); + PUT_UINT32_BE( ( orig_len ), work_buf, 12 ); + + for( i = 0; i < 16; i++ ) + ctx->buf[i] ^= work_buf[i]; + + gcm_mult( ctx, ctx->buf, ctx->buf ); + + for( i = 0; i < tag_len; i++ ) + tag[i] ^= ctx->buf[i]; + } + + return( 0 ); +} + +int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx, + int mode, + size_t length, + const unsigned char *iv, + size_t iv_len, + const unsigned char *add, + size_t add_len, + const unsigned char *input, + unsigned char *output, + size_t tag_len, + unsigned char *tag ) +{ + int ret; + + if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 ) + return( ret ); + + if( ( ret = mbedtls_gcm_update( ctx, length, input, output ) ) != 0 ) + return( ret ); + + if( ( ret = mbedtls_gcm_finish( ctx, tag, tag_len ) ) != 0 ) + return( ret ); + + return( 0 ); +} + +int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx, + size_t length, + const unsigned char *iv, + size_t iv_len, + const unsigned char *add, + size_t add_len, + const unsigned char *tag, + size_t tag_len, + const unsigned char *input, + unsigned char *output ) +{ + int ret; + unsigned char check_tag[16]; + size_t i; + int diff; + + if( ( ret = mbedtls_gcm_crypt_and_tag( ctx, MBEDTLS_GCM_DECRYPT, length, + iv, iv_len, add, add_len, + input, output, tag_len, check_tag ) ) != 0 ) + { + return( ret ); + } + + /* Check tag in "constant-time" */ + for( diff = 0, i = 0; i < tag_len; i++ ) + diff |= tag[i] ^ check_tag[i]; + + if( diff != 0 ) + { + mbedtls_zeroize( output, length ); + return( MBEDTLS_ERR_GCM_AUTH_FAILED ); + } + + return( 0 ); +} + +void mbedtls_gcm_free( mbedtls_gcm_context *ctx ) +{ + mbedtls_cipher_free( &ctx->cipher_ctx ); + mbedtls_zeroize( ctx, sizeof( mbedtls_gcm_context ) ); +} + +#endif /* !MBEDTLS_GCM_ALT */ + +#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) +/* + * AES-GCM test vectors from: + * + * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip + */ +#define MAX_TESTS 6 + +static const int key_index[MAX_TESTS] = + { 0, 0, 1, 1, 1, 1 }; + +static const unsigned char key[MAX_TESTS][32] = +{ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 }, +}; + +static const size_t iv_len[MAX_TESTS] = + { 12, 12, 12, 12, 8, 60 }; + +static const int iv_index[MAX_TESTS] = + { 0, 0, 1, 1, 1, 2 }; + +static const unsigned char iv[MAX_TESTS][64] = +{ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 }, + { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88 }, + { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5, + 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa, + 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1, + 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28, + 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39, + 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54, + 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57, + 0xa6, 0x37, 0xb3, 0x9b }, +}; + +static const size_t add_len[MAX_TESTS] = + { 0, 0, 0, 20, 20, 20 }; + +static const int add_index[MAX_TESTS] = + { 0, 0, 0, 1, 1, 1 }; + +static const unsigned char additional[MAX_TESTS][64] = +{ + { 0x00 }, + { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xab, 0xad, 0xda, 0xd2 }, +}; + +static const size_t pt_len[MAX_TESTS] = + { 0, 16, 64, 60, 60, 60 }; + +static const int pt_index[MAX_TESTS] = + { 0, 0, 1, 1, 1, 1 }; + +static const unsigned char pt[MAX_TESTS][64] = +{ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 }, +}; + +static const unsigned char ct[MAX_TESTS * 3][64] = +{ + { 0x00 }, + { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92, + 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 }, + { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, + 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, + 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, + 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, + 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, + 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, + 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, + 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 }, + { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, + 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, + 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, + 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, + 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, + 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, + 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, + 0x3d, 0x58, 0xe0, 0x91 }, + { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a, + 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55, + 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8, + 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23, + 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2, + 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42, + 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07, + 0xc2, 0x3f, 0x45, 0x98 }, + { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6, + 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94, + 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8, + 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7, + 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90, + 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f, + 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03, + 0x4c, 0x34, 0xae, 0xe5 }, + { 0x00 }, + { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41, + 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 }, + { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41, + 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57, + 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84, + 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c, + 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25, + 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47, + 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9, + 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 }, + { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41, + 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57, + 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84, + 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c, + 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25, + 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47, + 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9, + 0xcc, 0xda, 0x27, 0x10 }, + { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54, + 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8, + 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f, + 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57, + 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75, + 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9, + 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f, + 0xa0, 0xf0, 0x62, 0xf7 }, + { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c, + 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff, + 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef, + 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45, + 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9, + 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3, + 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7, + 0xe9, 0xb7, 0x37, 0x3b }, + { 0x00 }, + { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e, + 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 }, + { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, + 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d, + 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9, + 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa, + 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d, + 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38, + 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a, + 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad }, + { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, + 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d, + 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9, + 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa, + 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d, + 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38, + 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a, + 0xbc, 0xc9, 0xf6, 0x62 }, + { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32, + 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb, + 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa, + 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0, + 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0, + 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78, + 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99, + 0xf4, 0x7c, 0x9b, 0x1f }, + { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1, + 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20, + 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19, + 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4, + 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45, + 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde, + 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e, + 0x44, 0xae, 0x7e, 0x3f }, +}; + +static const unsigned char tag[MAX_TESTS * 3][16] = +{ + { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61, + 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a }, + { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd, + 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf }, + { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6, + 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 }, + { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb, + 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 }, + { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85, + 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb }, + { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa, + 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 }, + { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b, + 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 }, + { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab, + 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb }, + { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf, + 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 }, + { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f, + 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c }, + { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24, + 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 }, + { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb, + 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 }, + { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9, + 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b }, + { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0, + 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 }, + { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd, + 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c }, + { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68, + 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b }, + { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4, + 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 }, + { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0, + 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a }, +}; + +int mbedtls_gcm_self_test( int verbose ) +{ + mbedtls_gcm_context ctx; + unsigned char buf[64]; + unsigned char tag_buf[16]; + int i, j, ret; + mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES; + + for( j = 0; j < 3; j++ ) + { + int key_len = 128 + 64 * j; + + for( i = 0; i < MAX_TESTS; i++ ) + { + mbedtls_gcm_init( &ctx ); + + if( verbose != 0 ) + mbedtls_printf( " AES-GCM-%3d #%d (%s): ", + key_len, i, "enc" ); + + 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, + pt_len[i], + iv[iv_index[i]], iv_len[i], + additional[add_index[i]], add_len[i], + pt[pt_index[i]], buf, 16, tag_buf ); + if( ret != 0 ) + goto exit; + + if ( memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 || + memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 ) + { + ret = 1; + goto exit; + } + + mbedtls_gcm_free( &ctx ); + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + + mbedtls_gcm_init( &ctx ); + + if( verbose != 0 ) + mbedtls_printf( " AES-GCM-%3d #%d (%s): ", + key_len, i, "dec" ); + + 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, + pt_len[i], + iv[iv_index[i]], iv_len[i], + additional[add_index[i]], add_len[i], + ct[j * 6 + i], buf, 16, tag_buf ); + + if( ret != 0 ) + goto exit; + + if( memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 || + memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 ) + { + ret = 1; + goto exit; + } + + mbedtls_gcm_free( &ctx ); + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + + mbedtls_gcm_init( &ctx ); + + if( verbose != 0 ) + mbedtls_printf( " AES-GCM-%3d #%d split (%s): ", + key_len, i, "enc" ); + + 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, + iv[iv_index[i]], iv_len[i], + additional[add_index[i]], add_len[i] ); + if( ret != 0 ) + goto exit; + + if( pt_len[i] > 32 ) + { + size_t rest_len = pt_len[i] - 32; + ret = mbedtls_gcm_update( &ctx, 32, pt[pt_index[i]], buf ); + if( ret != 0 ) + goto exit; + + ret = mbedtls_gcm_update( &ctx, rest_len, pt[pt_index[i]] + 32, + buf + 32 ); + if( ret != 0 ) + goto exit; + } + else + { + ret = mbedtls_gcm_update( &ctx, pt_len[i], pt[pt_index[i]], buf ); + if( ret != 0 ) + goto exit; + } + + ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 ); + if( ret != 0 ) + goto exit; + + if( memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 || + memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 ) + { + ret = 1; + goto exit; + } + + mbedtls_gcm_free( &ctx ); + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + + mbedtls_gcm_init( &ctx ); + + if( verbose != 0 ) + mbedtls_printf( " AES-GCM-%3d #%d split (%s): ", + key_len, i, "dec" ); + + 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, + iv[iv_index[i]], iv_len[i], + additional[add_index[i]], add_len[i] ); + if( ret != 0 ) + goto exit; + + if( pt_len[i] > 32 ) + { + size_t rest_len = pt_len[i] - 32; + ret = mbedtls_gcm_update( &ctx, 32, ct[j * 6 + i], buf ); + if( ret != 0 ) + goto exit; + + ret = mbedtls_gcm_update( &ctx, rest_len, ct[j * 6 + i] + 32, + buf + 32 ); + if( ret != 0 ) + goto exit; + } + else + { + ret = mbedtls_gcm_update( &ctx, pt_len[i], ct[j * 6 + i], + buf ); + if( ret != 0 ) + goto exit; + } + + ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 ); + if( ret != 0 ) + goto exit; + + if( memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 || + memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 ) + { + ret = 1; + goto exit; + } + + mbedtls_gcm_free( &ctx ); + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + } + } + + if( verbose != 0 ) + mbedtls_printf( "\n" ); + + 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_GCM_C */ diff --git a/APP_Framework/Framework/security/mbedtls/gcm.h b/APP_Framework/Framework/security/mbedtls/gcm.h index fd130abd7..bd258aae5 100644 --- a/APP_Framework/Framework/security/mbedtls/gcm.h +++ b/APP_Framework/Framework/security/mbedtls/gcm.h @@ -1,11 +1,9 @@ /** * \file gcm.h * - * \brief This file contains GCM definitions and functions. - * - * The Galois/Counter Mode (GCM) for 128-bit block ciphers is defined - * in D. McGrew, J. Viega, The Galois/Counter Mode of Operation - * (GCM), Natl. Inst. Stand. Technol. + * \brief Galois/Counter Mode (GCM) for 128-bit block ciphers, as defined + * in D. McGrew, J. Viega, The Galois/Counter Mode of Operation + * (GCM), Natl. Inst. Stand. Technol. * * For more information on GCM, see NIST SP 800-38D: Recommendation for * Block Cipher Modes of Operation: Galois/Counter Mode (GCM) and GMAC. @@ -47,23 +45,19 @@ #define MBEDTLS_GCM_DECRYPT 0 #define MBEDTLS_ERR_GCM_AUTH_FAILED -0x0012 /**< Authenticated decryption failed. */ - -/* MBEDTLS_ERR_GCM_HW_ACCEL_FAILED is deprecated and should not be used. */ #define MBEDTLS_ERR_GCM_HW_ACCEL_FAILED -0x0013 /**< GCM hardware accelerator failed. */ - #define MBEDTLS_ERR_GCM_BAD_INPUT -0x0014 /**< Bad input parameters to function. */ +#if !defined(MBEDTLS_GCM_ALT) + #ifdef __cplusplus extern "C" { #endif -#if !defined(MBEDTLS_GCM_ALT) - /** * \brief The GCM context structure. */ -typedef struct mbedtls_gcm_context -{ +typedef struct { mbedtls_cipher_context_t cipher_ctx; /*!< The cipher context used. */ uint64_t HL[16]; /*!< Precalculated HTable low. */ uint64_t HH[16]; /*!< Precalculated HTable high. */ @@ -78,10 +72,6 @@ typedef struct mbedtls_gcm_context } mbedtls_gcm_context; -#else /* !MBEDTLS_GCM_ALT */ -#include "gcm_alt.h" -#endif /* !MBEDTLS_GCM_ALT */ - /** * \brief This function initializes the specified GCM context, * to make references valid, and prepares the context @@ -91,7 +81,7 @@ mbedtls_gcm_context; * cipher, nor set the key. For this purpose, use * mbedtls_gcm_setkey(). * - * \param ctx The GCM context to initialize. This must not be \c NULL. + * \param ctx The GCM context to initialize. */ void mbedtls_gcm_init( mbedtls_gcm_context *ctx ); @@ -99,17 +89,15 @@ void mbedtls_gcm_init( mbedtls_gcm_context *ctx ); * \brief This function associates a GCM context with a * cipher algorithm and a key. * - * \param ctx The GCM context. This must be initialized. + * \param ctx The GCM context to initialize. * \param cipher The 128-bit block cipher to use. - * \param key The encryption key. This must be a readable buffer of at - * least \p keybits bits. + * \param key The encryption key. * \param keybits The key size in bits. Valid options are: *
    • 128 bits
    • *
    • 192 bits
    • *
    • 256 bits
    * - * \return \c 0 on success. - * \return A cipher-specific error code on failure. + * \return \c 0 on success, or a cipher specific error code. */ int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx, mbedtls_cipher_id_t cipher, @@ -119,18 +107,17 @@ int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx, /** * \brief This function performs GCM encryption or decryption of a buffer. * - * \note For encryption, the output buffer can be the same as the - * input buffer. 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. + * \note For encryption, the output buffer can be the same as the input buffer. + * 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. * * \warning When this function performs a decryption, it outputs the * authentication tag and does not verify that the data is * authentic. You should use this function to perform encryption * only. For decryption, use mbedtls_gcm_auth_decrypt() instead. * - * \param ctx The GCM context to use for encryption or decryption. This - * must be initialized. + * \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 @@ -144,28 +131,22 @@ int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx, * 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. This must be a readable buffer of - * at least \p iv_len Bytes. + * \param iv The initialization vector. * \param iv_len The length of the IV. - * \param add The buffer holding the additional data. This must be of at - * least that size in Bytes. + * \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. If \p length is greater - * than zero, this must be a readable buffer of at least that - * size in Bytes. - * \param output The buffer for holding the output data. If \p length is greater - * than zero, this must be a writable buffer of at least that - * size in Bytes. + * \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. This must be a readable - * buffer of at least \p tag_len Bytes. + * \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 or pointers are - * not valid or a cipher-specific error code if the encryption - * or decryption failed. + * \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 mode, @@ -183,34 +164,28 @@ int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx, * \brief This function performs a GCM authenticated decryption of a * buffer. * - * \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. + * \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. * - * \param ctx The GCM context. This must be initialized. + * \param ctx The GCM context. * \param length The length of the ciphertext to decrypt, which is also * the length of the decrypted plaintext. - * \param iv The initialization vector. This must be a readable buffer - * of at least \p iv_len Bytes. + * \param iv The initialization vector. * \param iv_len The length of the IV. - * \param add The buffer holding the additional data. This must be of at - * least that size in Bytes. + * \param add The buffer holding the additional data. * \param add_len The length of the additional data. - * \param tag The buffer holding the tag to verify. This must be a - * readable buffer of at least \p tag_len Bytes. + * \param tag The buffer holding the tag to verify. * \param tag_len The length of the tag to verify. - * \param input The buffer holding the ciphertext. If \p length is greater - * than zero, this must be a readable buffer of at least that - * size. - * \param output The buffer for holding the decrypted plaintext. If \p length - * is greater than zero, this must be a writable buffer of at - * least that size. + * \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 \c 0 if successful and authenticated. * \return #MBEDTLS_ERR_GCM_AUTH_FAILED if the tag does not match. - * \return #MBEDTLS_ERR_GCM_BAD_INPUT if the lengths or pointers are - * not valid or a cipher-specific error code if the decryption - * failed. + * \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, size_t length, @@ -227,18 +202,15 @@ int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx, * \brief This function starts a GCM encryption or decryption * operation. * - * \param ctx The GCM context. This must be initialized. + * \param ctx The GCM context. * \param mode The operation to perform: #MBEDTLS_GCM_ENCRYPT or * #MBEDTLS_GCM_DECRYPT. - * \param iv The initialization vector. This must be a readable buffer of - * at least \p iv_len Bytes. + * \param iv The initialization vector. * \param iv_len The length of the IV. - * \param add The buffer holding the additional data, or \c NULL - * if \p add_len is \c 0. - * \param add_len The length of the additional data. If \c 0, - * \p add may be \c NULL. + * \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 \c 0 on success. + * \return \c 0 on success. */ int mbedtls_gcm_starts( mbedtls_gcm_context *ctx, int mode, @@ -255,22 +227,16 @@ int mbedtls_gcm_starts( mbedtls_gcm_context *ctx, * 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. + * \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. * - * \param ctx The GCM context. This must be initialized. - * \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 The buffer holding the input data. If \p length is greater - * than zero, this must be a readable buffer of at least that - * size in Bytes. - * \param output The buffer for holding the output data. If \p length is - * greater than zero, this must be a writable buffer of at - * least that size in Bytes. + * \param ctx The GCM context. + * \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 The buffer holding the input data. + * \param output The buffer for holding the output data. * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_GCM_BAD_INPUT on failure. + * \return \c 0 on success, or #MBEDTLS_ERR_GCM_BAD_INPUT on failure. */ int mbedtls_gcm_update( mbedtls_gcm_context *ctx, size_t length, @@ -284,14 +250,11 @@ int mbedtls_gcm_update( mbedtls_gcm_context *ctx, * It wraps up the GCM stream, and generates the * tag. The tag can have a maximum length of 16 Bytes. * - * \param ctx The GCM context. This must be initialized. - * \param tag The buffer for holding the tag. This must be a readable - * buffer of at least \p tag_len Bytes. - * \param tag_len The length of the tag to generate. This must be at least - * four. + * \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. - * \return #MBEDTLS_ERR_GCM_BAD_INPUT on failure. + * \return \c 0 on success, or #MBEDTLS_ERR_GCM_BAD_INPUT on failure. */ int mbedtls_gcm_finish( mbedtls_gcm_context *ctx, unsigned char *tag, @@ -301,23 +264,29 @@ int mbedtls_gcm_finish( mbedtls_gcm_context *ctx, * \brief This function clears a GCM context and the underlying * cipher sub-context. * - * \param ctx The GCM context to clear. If this is \c NULL, the call has - * no effect. Otherwise, this must be initialized. + * \param ctx The GCM context to clear. */ void mbedtls_gcm_free( mbedtls_gcm_context *ctx ); -#if defined(MBEDTLS_SELF_TEST) +#ifdef __cplusplus +} +#endif + +#else /* !MBEDTLS_GCM_ALT */ +#include "gcm_alt.h" +#endif /* !MBEDTLS_GCM_ALT */ + +#ifdef __cplusplus +extern "C" { +#endif /** * \brief The GCM checkup routine. * - * \return \c 0 on success. - * \return \c 1 on failure. + * \return \c 0 on success, or \c 1 on failure. */ int mbedtls_gcm_self_test( int verbose ); -#endif /* MBEDTLS_SELF_TEST */ - #ifdef __cplusplus } #endif diff --git a/APP_Framework/Framework/security/mbedtls/havege.c b/APP_Framework/Framework/security/mbedtls/havege.c new file mode 100644 index 000000000..0b71adbb5 --- /dev/null +++ b/APP_Framework/Framework/security/mbedtls/havege.c @@ -0,0 +1,245 @@ +/** + * \brief HAVEGE: HArdware Volatile Entropy Gathering and Expansion + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +/* + * The HAVEGE RNG was designed by Andre Seznec in 2002. + * + * http://www.irisa.fr/caps/projects/hipsor/publi.php + * + * Contact: seznec(at)irisa_dot_fr - orocheco(at)irisa_dot_fr + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_HAVEGE_C) + +#include "havege.h" +#include "timing.h" + +#include + +/* 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; +} + +/* ------------------------------------------------------------------------ + * On average, one iteration accesses two 8-word blocks in the havege WALK + * table, and generates 16 words in the RES array. + * + * The data read in the WALK table is updated and permuted after each use. + * The result of the hardware clock counter read is used for this update. + * + * 25 conditional tests are present. The conditional tests are grouped in + * two nested groups of 12 conditional tests and 1 test that controls the + * permutation; on average, there should be 6 tests executed and 3 of them + * should be mispredicted. + * ------------------------------------------------------------------------ + */ + +#define SWAP(X,Y) { int *T = X; X = Y; Y = T; } + +#define TST1_ENTER if( PTEST & 1 ) { PTEST ^= 3; PTEST >>= 1; +#define TST2_ENTER if( PTEST & 1 ) { PTEST ^= 3; PTEST >>= 1; + +#define TST1_LEAVE U1++; } +#define TST2_LEAVE U2++; } + +#define ONE_ITERATION \ + \ + PTEST = PT1 >> 20; \ + \ + TST1_ENTER TST1_ENTER TST1_ENTER TST1_ENTER \ + TST1_ENTER TST1_ENTER TST1_ENTER TST1_ENTER \ + TST1_ENTER TST1_ENTER TST1_ENTER TST1_ENTER \ + \ + TST1_LEAVE TST1_LEAVE TST1_LEAVE TST1_LEAVE \ + TST1_LEAVE TST1_LEAVE TST1_LEAVE TST1_LEAVE \ + TST1_LEAVE TST1_LEAVE TST1_LEAVE TST1_LEAVE \ + \ + PTX = (PT1 >> 18) & 7; \ + PT1 &= 0x1FFF; \ + PT2 &= 0x1FFF; \ + CLK = (int) mbedtls_timing_hardclock(); \ + \ + i = 0; \ + A = &WALK[PT1 ]; RES[i++] ^= *A; \ + B = &WALK[PT2 ]; RES[i++] ^= *B; \ + C = &WALK[PT1 ^ 1]; RES[i++] ^= *C; \ + D = &WALK[PT2 ^ 4]; RES[i++] ^= *D; \ + \ + IN = (*A >> (1)) ^ (*A << (31)) ^ CLK; \ + *A = (*B >> (2)) ^ (*B << (30)) ^ CLK; \ + *B = IN ^ U1; \ + *C = (*C >> (3)) ^ (*C << (29)) ^ CLK; \ + *D = (*D >> (4)) ^ (*D << (28)) ^ CLK; \ + \ + A = &WALK[PT1 ^ 2]; RES[i++] ^= *A; \ + B = &WALK[PT2 ^ 2]; RES[i++] ^= *B; \ + C = &WALK[PT1 ^ 3]; RES[i++] ^= *C; \ + D = &WALK[PT2 ^ 6]; RES[i++] ^= *D; \ + \ + if( PTEST & 1 ) SWAP( A, C ); \ + \ + IN = (*A >> (5)) ^ (*A << (27)) ^ CLK; \ + *A = (*B >> (6)) ^ (*B << (26)) ^ CLK; \ + *B = IN; CLK = (int) mbedtls_timing_hardclock(); \ + *C = (*C >> (7)) ^ (*C << (25)) ^ CLK; \ + *D = (*D >> (8)) ^ (*D << (24)) ^ CLK; \ + \ + A = &WALK[PT1 ^ 4]; \ + B = &WALK[PT2 ^ 1]; \ + \ + PTEST = PT2 >> 1; \ + \ + PT2 = (RES[(i - 8) ^ PTY] ^ WALK[PT2 ^ PTY ^ 7]); \ + PT2 = ((PT2 & 0x1FFF) & (~8)) ^ ((PT1 ^ 8) & 0x8); \ + PTY = (PT2 >> 10) & 7; \ + \ + TST2_ENTER TST2_ENTER TST2_ENTER TST2_ENTER \ + TST2_ENTER TST2_ENTER TST2_ENTER TST2_ENTER \ + TST2_ENTER TST2_ENTER TST2_ENTER TST2_ENTER \ + \ + TST2_LEAVE TST2_LEAVE TST2_LEAVE TST2_LEAVE \ + TST2_LEAVE TST2_LEAVE TST2_LEAVE TST2_LEAVE \ + TST2_LEAVE TST2_LEAVE TST2_LEAVE TST2_LEAVE \ + \ + C = &WALK[PT1 ^ 5]; \ + D = &WALK[PT2 ^ 5]; \ + \ + RES[i++] ^= *A; \ + RES[i++] ^= *B; \ + RES[i++] ^= *C; \ + RES[i++] ^= *D; \ + \ + IN = (*A >> ( 9)) ^ (*A << (23)) ^ CLK; \ + *A = (*B >> (10)) ^ (*B << (22)) ^ CLK; \ + *B = IN ^ U2; \ + *C = (*C >> (11)) ^ (*C << (21)) ^ CLK; \ + *D = (*D >> (12)) ^ (*D << (20)) ^ CLK; \ + \ + A = &WALK[PT1 ^ 6]; RES[i++] ^= *A; \ + B = &WALK[PT2 ^ 3]; RES[i++] ^= *B; \ + C = &WALK[PT1 ^ 7]; RES[i++] ^= *C; \ + D = &WALK[PT2 ^ 7]; RES[i++] ^= *D; \ + \ + IN = (*A >> (13)) ^ (*A << (19)) ^ CLK; \ + *A = (*B >> (14)) ^ (*B << (18)) ^ CLK; \ + *B = IN; \ + *C = (*C >> (15)) ^ (*C << (17)) ^ CLK; \ + *D = (*D >> (16)) ^ (*D << (16)) ^ CLK; \ + \ + PT1 = ( RES[( i - 8 ) ^ PTX] ^ \ + WALK[PT1 ^ PTX ^ 7] ) & (~1); \ + PT1 ^= (PT2 ^ 0x10) & 0x10; \ + \ + for( n++, i = 0; i < 16; i++ ) \ + hs->pool[n % MBEDTLS_HAVEGE_COLLECT_SIZE] ^= RES[i]; + +/* + * Entropy gathering function + */ +static void havege_fill( mbedtls_havege_state *hs ) +{ + int i, n = 0; + int U1, U2, *A, *B, *C, *D; + int PT1, PT2, *WALK, RES[16]; + int PTX, PTY, CLK, PTEST, IN; + + WALK = hs->WALK; + PT1 = hs->PT1; + PT2 = hs->PT2; + + PTX = U1 = 0; + PTY = U2 = 0; + + (void)PTX; + + memset( RES, 0, sizeof( RES ) ); + + while( n < MBEDTLS_HAVEGE_COLLECT_SIZE * 4 ) + { + ONE_ITERATION + ONE_ITERATION + ONE_ITERATION + ONE_ITERATION + } + + hs->PT1 = PT1; + hs->PT2 = PT2; + + hs->offset[0] = 0; + hs->offset[1] = MBEDTLS_HAVEGE_COLLECT_SIZE / 2; +} + +/* + * HAVEGE initialization + */ +void mbedtls_havege_init( mbedtls_havege_state *hs ) +{ + memset( hs, 0, sizeof( mbedtls_havege_state ) ); + + havege_fill( hs ); +} + +void mbedtls_havege_free( mbedtls_havege_state *hs ) +{ + if( hs == NULL ) + return; + + mbedtls_zeroize( hs, sizeof( mbedtls_havege_state ) ); +} + +/* + * HAVEGE rand function + */ +int mbedtls_havege_random( void *p_rng, unsigned char *buf, size_t len ) +{ + int val; + size_t use_len; + mbedtls_havege_state *hs = (mbedtls_havege_state *) p_rng; + unsigned char *p = buf; + + while( len > 0 ) + { + use_len = len; + if( use_len > sizeof(int) ) + use_len = sizeof(int); + + if( hs->offset[1] >= MBEDTLS_HAVEGE_COLLECT_SIZE ) + havege_fill( hs ); + + val = hs->pool[hs->offset[0]++]; + val ^= hs->pool[hs->offset[1]++]; + + memcpy( p, &val, use_len ); + + len -= use_len; + p += use_len; + } + + return( 0 ); +} + +#endif /* MBEDTLS_HAVEGE_C */ diff --git a/APP_Framework/Framework/security/mbedtls/havege.h b/APP_Framework/Framework/security/mbedtls/havege.h index 4c1c86087..e6bf6fae8 100644 --- a/APP_Framework/Framework/security/mbedtls/havege.h +++ b/APP_Framework/Framework/security/mbedtls/havege.h @@ -41,7 +41,7 @@ extern "C" { /** * \brief HAVEGE state structure */ -typedef struct mbedtls_havege_state +typedef struct { int PT1, PT2, offset[2]; int pool[MBEDTLS_HAVEGE_COLLECT_SIZE]; diff --git a/APP_Framework/Framework/security/mbedtls/hkdf.h b/APP_Framework/Framework/security/mbedtls/hkdf.h deleted file mode 100644 index 4fc897efb..000000000 --- a/APP_Framework/Framework/security/mbedtls/hkdf.h +++ /dev/null @@ -1,141 +0,0 @@ -/** - * \file hkdf.h - * - * \brief This file contains the HKDF interface. - * - * The HMAC-based Extract-and-Expand Key Derivation Function (HKDF) is - * specified by RFC 5869. - */ -/* - * Copyright (C) 2016-2019, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -#ifndef MBEDTLS_HKDF_H -#define MBEDTLS_HKDF_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "md.h" - -/** - * \name HKDF Error codes - * \{ - */ -#define MBEDTLS_ERR_HKDF_BAD_INPUT_DATA -0x5F80 /**< Bad input parameters to function. */ -/* \} name */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief This is the HMAC-based Extract-and-Expand Key Derivation Function - * (HKDF). - * - * \param md A hash function; md.size denotes the length of the hash - * function output in bytes. - * \param salt An optional salt value (a non-secret random value); - * if the salt is not provided, a string of all zeros of - * md.size length is used as the salt. - * \param salt_len The length in bytes of the optional \p salt. - * \param ikm The input keying material. - * \param ikm_len The length in bytes of \p ikm. - * \param info An optional context and application specific information - * string. This can be a zero-length string. - * \param info_len The length of \p info in bytes. - * \param okm The output keying material of \p okm_len bytes. - * \param okm_len The length of the output keying material in bytes. This - * must be less than or equal to 255 * md.size bytes. - * - * \return 0 on success. - * \return #MBEDTLS_ERR_HKDF_BAD_INPUT_DATA when the parameters are invalid. - * \return An MBEDTLS_ERR_MD_* error for errors returned from the underlying - * MD layer. - */ -int mbedtls_hkdf( mbedtls_md_handle_t md, const unsigned char *salt, - size_t salt_len, const unsigned char *ikm, size_t ikm_len, - const unsigned char *info, size_t info_len, - unsigned char *okm, size_t okm_len ); - -/** - * \brief Take the input keying material \p ikm and extract from it a - * fixed-length pseudorandom key \p prk. - * - * \warning This function should only be used if the security of it has been - * studied and established in that particular context (eg. TLS 1.3 - * key schedule). For standard HKDF security guarantees use - * \c mbedtls_hkdf instead. - * - * \param md A hash function; md.size denotes the length of the - * hash function output in bytes. - * \param salt An optional salt value (a non-secret random value); - * if the salt is not provided, a string of all zeros - * of md.size length is used as the salt. - * \param salt_len The length in bytes of the optional \p salt. - * \param ikm The input keying material. - * \param ikm_len The length in bytes of \p ikm. - * \param[out] prk A pseudorandom key of at least md.size bytes. - * - * \return 0 on success. - * \return #MBEDTLS_ERR_HKDF_BAD_INPUT_DATA when the parameters are invalid. - * \return An MBEDTLS_ERR_MD_* error for errors returned from the underlying - * MD layer. - */ -int mbedtls_hkdf_extract( mbedtls_md_handle_t md, - const unsigned char *salt, size_t salt_len, - const unsigned char *ikm, size_t ikm_len, - unsigned char *prk ); - -/** - * \brief Expand the supplied \p prk into several additional pseudorandom - * keys, which is the output of the HKDF. - * - * \warning This function should only be used if the security of it has been - * studied and established in that particular context (eg. TLS 1.3 - * key schedule). For standard HKDF security guarantees use - * \c mbedtls_hkdf instead. - * - * \param md A hash function; md.size denotes the length of the hash - * function output in bytes. - * \param prk A pseudorandom key of at least md.size bytes. \p prk is - * usually the output from the HKDF extract step. - * \param prk_len The length in bytes of \p prk. - * \param info An optional context and application specific information - * string. This can be a zero-length string. - * \param info_len The length of \p info in bytes. - * \param okm The output keying material of \p okm_len bytes. - * \param okm_len The length of the output keying material in bytes. This - * must be less than or equal to 255 * md.size bytes. - * - * \return 0 on success. - * \return #MBEDTLS_ERR_HKDF_BAD_INPUT_DATA when the parameters are invalid. - * \return An MBEDTLS_ERR_MD_* error for errors returned from the underlying - * MD layer. - */ -int mbedtls_hkdf_expand( mbedtls_md_handle_t md, const unsigned char *prk, - size_t prk_len, const unsigned char *info, - size_t info_len, unsigned char *okm, size_t okm_len ); - -#ifdef __cplusplus -} -#endif - -#endif /* hkdf.h */ diff --git a/APP_Framework/Framework/security/mbedtls/hmac_drbg.c b/APP_Framework/Framework/security/mbedtls/hmac_drbg.c new file mode 100644 index 000000000..31dbb2178 --- /dev/null +++ b/APP_Framework/Framework/security/mbedtls/hmac_drbg.c @@ -0,0 +1,581 @@ +/* + * HMAC_DRBG implementation (NIST SP 800-90) + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +/* + * The NIST SP 800-90A DRBGs are described in the following publication. + * http://csrc.nist.gov/publications/nistpubs/800-90A/SP800-90A.pdf + * References below are based on rev. 1 (January 2012). + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_HMAC_DRBG_C) + +#include "hmac_drbg.h" + +#include + +#if defined(MBEDTLS_FS_IO) +#include +#endif + +#if defined(MBEDTLS_SELF_TEST) +#if defined(MBEDTLS_PLATFORM_C) +#include "platform.h" +#else +#include +#define mbedtls_printf printf +#endif /* MBEDTLS_SELF_TEST */ +#endif /* MBEDTLS_PLATFORM_C */ + +/* 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; +} + +/* + * HMAC_DRBG context initialization + */ +void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx ) +{ + memset( ctx, 0, sizeof( mbedtls_hmac_drbg_context ) ); + +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_init( &ctx->mutex ); +#endif +} + +/* + * HMAC_DRBG update, using optional additional data (10.1.2.2) + */ +int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx, + const unsigned char *additional, + size_t add_len ) +{ + size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info ); + unsigned char rounds = ( additional != NULL && add_len != 0 ) ? 2 : 1; + unsigned char sep[1]; + unsigned char K[MBEDTLS_MD_MAX_SIZE]; + int ret; + + for( sep[0] = 0; sep[0] < rounds; sep[0]++ ) + { + /* Step 1 or 4 */ + if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 ) + goto exit; + if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx, + ctx->V, md_len ) ) != 0 ) + goto exit; + if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx, + sep, 1 ) ) != 0 ) + goto exit; + if( rounds == 2 ) + { + if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx, + additional, add_len ) ) != 0 ) + goto exit; + } + if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, K ) ) != 0 ) + goto exit; + + /* Step 2 or 5 */ + if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, K, md_len ) ) != 0 ) + goto exit; + if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx, + ctx->V, md_len ) ) != 0 ) + goto exit; + if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 ) + goto exit; + } + +exit: + mbedtls_zeroize( K, sizeof( K ) ); + return( ret ); +} + +void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx, + const unsigned char *additional, + size_t add_len ) +{ + (void) mbedtls_hmac_drbg_update_ret( ctx, additional, add_len ); +} + +/* + * Simplified HMAC_DRBG initialisation (for use with deterministic ECDSA) + */ +int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx, + const mbedtls_md_info_t * md_info, + const unsigned char *data, size_t data_len ) +{ + int ret; + + if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 ) + return( ret ); + + /* + * Set initial working state. + * Use the V memory location, which is currently all 0, to initialize the + * MD context with an all-zero key. Then set V to its initial value. + */ + if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, + mbedtls_md_get_size( md_info ) ) ) != 0 ) + return( ret ); + memset( ctx->V, 0x01, mbedtls_md_get_size( md_info ) ); + + if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, data, data_len ) ) != 0 ) + return( ret ); + + return( 0 ); +} + +/* + * HMAC_DRBG reseeding: 10.1.2.4 (arabic) + 9.2 (Roman) + */ +int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx, + const unsigned char *additional, size_t len ) +{ + unsigned char seed[MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT]; + size_t seedlen; + int ret; + + /* III. Check input length */ + if( len > MBEDTLS_HMAC_DRBG_MAX_INPUT || + ctx->entropy_len + len > MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT ) + { + return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG ); + } + + memset( seed, 0, MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT ); + + /* IV. Gather entropy_len bytes of entropy for the seed */ + if( ( ret = ctx->f_entropy( ctx->p_entropy, + seed, ctx->entropy_len ) ) != 0 ) + return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED ); + + seedlen = ctx->entropy_len; + + /* 1. Concatenate entropy and additional data if any */ + if( additional != NULL && len != 0 ) + { + memcpy( seed + seedlen, additional, len ); + seedlen += len; + } + + /* 2. Update state */ + if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, seed, seedlen ) ) != 0 ) + goto exit; + + /* 3. Reset reseed_counter */ + ctx->reseed_counter = 1; + +exit: + /* 4. Done */ + mbedtls_zeroize( seed, seedlen ); + return( ret ); +} + +/* + * HMAC_DRBG initialisation (10.1.2.3 + 9.1) + */ +int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx, + const mbedtls_md_info_t * md_info, + int (*f_entropy)(void *, unsigned char *, size_t), + void *p_entropy, + const unsigned char *custom, + size_t len ) +{ + int ret; + size_t entropy_len, md_size; + + if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 ) + return( ret ); + + md_size = mbedtls_md_get_size( md_info ); + + /* + * Set initial working state. + * Use the V memory location, which is currently all 0, to initialize the + * MD context with an all-zero key. Then set V to its initial value. + */ + if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, md_size ) ) != 0 ) + return( ret ); + memset( ctx->V, 0x01, md_size ); + + ctx->f_entropy = f_entropy; + ctx->p_entropy = p_entropy; + + ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL; + + /* + * See SP800-57 5.6.1 (p. 65-66) for the security strength provided by + * each hash function, then according to SP800-90A rev1 10.1 table 2, + * min_entropy_len (in bits) is security_strength. + * + * (This also matches the sizes used in the NIST test vectors.) + */ + entropy_len = md_size <= 20 ? 16 : /* 160-bits hash -> 128 bits */ + md_size <= 28 ? 24 : /* 224-bits hash -> 192 bits */ + 32; /* better (256+) -> 256 bits */ + + /* + * For initialisation, use more entropy to emulate a nonce + * (Again, matches test vectors.) + */ + ctx->entropy_len = entropy_len * 3 / 2; + + if( ( ret = mbedtls_hmac_drbg_reseed( ctx, custom, len ) ) != 0 ) + return( ret ); + + ctx->entropy_len = entropy_len; + + return( 0 ); +} + +/* + * Set prediction resistance + */ +void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx, + int resistance ) +{ + ctx->prediction_resistance = resistance; +} + +/* + * Set entropy length grabbed for reseeds + */ +void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx, size_t len ) +{ + ctx->entropy_len = len; +} + +/* + * Set reseed interval + */ +void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx, int interval ) +{ + ctx->reseed_interval = interval; +} + +/* + * HMAC_DRBG random function with optional additional data: + * 10.1.2.5 (arabic) + 9.3 (Roman) + */ +int mbedtls_hmac_drbg_random_with_add( void *p_rng, + unsigned char *output, size_t out_len, + const unsigned char *additional, size_t add_len ) +{ + int ret; + mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng; + size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info ); + size_t left = out_len; + unsigned char *out = output; + + /* II. Check request length */ + if( out_len > MBEDTLS_HMAC_DRBG_MAX_REQUEST ) + return( MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG ); + + /* III. Check input length */ + if( add_len > MBEDTLS_HMAC_DRBG_MAX_INPUT ) + return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG ); + + /* 1. (aka VII and IX) Check reseed counter and PR */ + if( ctx->f_entropy != NULL && /* For no-reseeding instances */ + ( ctx->prediction_resistance == MBEDTLS_HMAC_DRBG_PR_ON || + ctx->reseed_counter > ctx->reseed_interval ) ) + { + if( ( ret = mbedtls_hmac_drbg_reseed( ctx, additional, add_len ) ) != 0 ) + return( ret ); + + add_len = 0; /* VII.4 */ + } + + /* 2. Use additional data if any */ + if( additional != NULL && add_len != 0 ) + { + if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, + additional, add_len ) ) != 0 ) + goto exit; + } + + /* 3, 4, 5. Generate bytes */ + while( left != 0 ) + { + size_t use_len = left > md_len ? md_len : left; + + if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 ) + goto exit; + if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx, + ctx->V, md_len ) ) != 0 ) + goto exit; + if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 ) + goto exit; + + memcpy( out, ctx->V, use_len ); + out += use_len; + left -= use_len; + } + + /* 6. Update */ + if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, + additional, add_len ) ) != 0 ) + goto exit; + + /* 7. Update reseed counter */ + ctx->reseed_counter++; + +exit: + /* 8. Done */ + return( ret ); +} + +/* + * HMAC_DRBG random function + */ +int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len ) +{ + int ret; + mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng; + +#if defined(MBEDTLS_THREADING_C) + if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) + return( ret ); +#endif + + ret = mbedtls_hmac_drbg_random_with_add( ctx, output, out_len, NULL, 0 ); + +#if defined(MBEDTLS_THREADING_C) + if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) + return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); +#endif + + return( ret ); +} + +/* + * Free an HMAC_DRBG context + */ +void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx ) +{ + if( ctx == NULL ) + return; + +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_free( &ctx->mutex ); +#endif + mbedtls_md_free( &ctx->md_ctx ); + mbedtls_zeroize( ctx, sizeof( mbedtls_hmac_drbg_context ) ); +} + +#if defined(MBEDTLS_FS_IO) +int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path ) +{ + int ret; + FILE *f; + unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ]; + + if( ( f = fopen( path, "wb" ) ) == NULL ) + return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR ); + + if( ( ret = mbedtls_hmac_drbg_random( ctx, buf, sizeof( buf ) ) ) != 0 ) + goto exit; + + if( fwrite( buf, 1, sizeof( buf ), f ) != sizeof( buf ) ) + { + ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR; + goto exit; + } + + ret = 0; + +exit: + fclose( f ); + mbedtls_zeroize( buf, sizeof( buf ) ); + + return( ret ); +} + +int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path ) +{ + int ret = 0; + FILE *f; + size_t n; + unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ]; + + if( ( f = fopen( path, "rb" ) ) == NULL ) + return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR ); + + fseek( f, 0, SEEK_END ); + n = (size_t) ftell( f ); + fseek( f, 0, SEEK_SET ); + + if( n > MBEDTLS_HMAC_DRBG_MAX_INPUT ) + { + fclose( f ); + return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG ); + } + + if( fread( buf, 1, n, f ) != n ) + ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR; + else + ret = mbedtls_hmac_drbg_update_ret( ctx, buf, n ); + + fclose( f ); + + mbedtls_zeroize( buf, sizeof( buf ) ); + + if( ret != 0 ) + return( ret ); + + return( mbedtls_hmac_drbg_write_seed_file( ctx, path ) ); +} +#endif /* MBEDTLS_FS_IO */ + + +#if defined(MBEDTLS_SELF_TEST) + +#if !defined(MBEDTLS_SHA1_C) +/* Dummy checkup routine */ +int mbedtls_hmac_drbg_self_test( int verbose ) +{ + (void) verbose; + return( 0 ); +} +#else + +#define OUTPUT_LEN 80 + +/* From a NIST PR=true test vector */ +static const unsigned char entropy_pr[] = { + 0xa0, 0xc9, 0xab, 0x58, 0xf1, 0xe2, 0xe5, 0xa4, 0xde, 0x3e, 0xbd, 0x4f, + 0xf7, 0x3e, 0x9c, 0x5b, 0x64, 0xef, 0xd8, 0xca, 0x02, 0x8c, 0xf8, 0x11, + 0x48, 0xa5, 0x84, 0xfe, 0x69, 0xab, 0x5a, 0xee, 0x42, 0xaa, 0x4d, 0x42, + 0x17, 0x60, 0x99, 0xd4, 0x5e, 0x13, 0x97, 0xdc, 0x40, 0x4d, 0x86, 0xa3, + 0x7b, 0xf5, 0x59, 0x54, 0x75, 0x69, 0x51, 0xe4 }; +static const unsigned char result_pr[OUTPUT_LEN] = { + 0x9a, 0x00, 0xa2, 0xd0, 0x0e, 0xd5, 0x9b, 0xfe, 0x31, 0xec, 0xb1, 0x39, + 0x9b, 0x60, 0x81, 0x48, 0xd1, 0x96, 0x9d, 0x25, 0x0d, 0x3c, 0x1e, 0x94, + 0x10, 0x10, 0x98, 0x12, 0x93, 0x25, 0xca, 0xb8, 0xfc, 0xcc, 0x2d, 0x54, + 0x73, 0x19, 0x70, 0xc0, 0x10, 0x7a, 0xa4, 0x89, 0x25, 0x19, 0x95, 0x5e, + 0x4b, 0xc6, 0x00, 0x1d, 0x7f, 0x4e, 0x6a, 0x2b, 0xf8, 0xa3, 0x01, 0xab, + 0x46, 0x05, 0x5c, 0x09, 0xa6, 0x71, 0x88, 0xf1, 0xa7, 0x40, 0xee, 0xf3, + 0xe1, 0x5c, 0x02, 0x9b, 0x44, 0xaf, 0x03, 0x44 }; + +/* From a NIST PR=false test vector */ +static const unsigned char entropy_nopr[] = { + 0x79, 0x34, 0x9b, 0xbf, 0x7c, 0xdd, 0xa5, 0x79, 0x95, 0x57, 0x86, 0x66, + 0x21, 0xc9, 0x13, 0x83, 0x11, 0x46, 0x73, 0x3a, 0xbf, 0x8c, 0x35, 0xc8, + 0xc7, 0x21, 0x5b, 0x5b, 0x96, 0xc4, 0x8e, 0x9b, 0x33, 0x8c, 0x74, 0xe3, + 0xe9, 0x9d, 0xfe, 0xdf }; +static const unsigned char result_nopr[OUTPUT_LEN] = { + 0xc6, 0xa1, 0x6a, 0xb8, 0xd4, 0x20, 0x70, 0x6f, 0x0f, 0x34, 0xab, 0x7f, + 0xec, 0x5a, 0xdc, 0xa9, 0xd8, 0xca, 0x3a, 0x13, 0x3e, 0x15, 0x9c, 0xa6, + 0xac, 0x43, 0xc6, 0xf8, 0xa2, 0xbe, 0x22, 0x83, 0x4a, 0x4c, 0x0a, 0x0a, + 0xff, 0xb1, 0x0d, 0x71, 0x94, 0xf1, 0xc1, 0xa5, 0xcf, 0x73, 0x22, 0xec, + 0x1a, 0xe0, 0x96, 0x4e, 0xd4, 0xbf, 0x12, 0x27, 0x46, 0xe0, 0x87, 0xfd, + 0xb5, 0xb3, 0xe9, 0x1b, 0x34, 0x93, 0xd5, 0xbb, 0x98, 0xfa, 0xed, 0x49, + 0xe8, 0x5f, 0x13, 0x0f, 0xc8, 0xa4, 0x59, 0xb7 }; + +/* "Entropy" from buffer */ +static size_t test_offset; +static int hmac_drbg_self_test_entropy( void *data, + unsigned char *buf, size_t len ) +{ + const unsigned char *p = data; + memcpy( buf, p + test_offset, len ); + test_offset += len; + return( 0 ); +} + +#define CHK( c ) if( (c) != 0 ) \ + { \ + if( verbose != 0 ) \ + mbedtls_printf( "failed\n" ); \ + return( 1 ); \ + } + +/* + * Checkup routine for HMAC_DRBG with SHA-1 + */ +int mbedtls_hmac_drbg_self_test( int verbose ) +{ + mbedtls_hmac_drbg_context ctx; + unsigned char buf[OUTPUT_LEN]; + const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 ); + + mbedtls_hmac_drbg_init( &ctx ); + + /* + * PR = True + */ + if( verbose != 0 ) + mbedtls_printf( " HMAC_DRBG (PR = True) : " ); + + test_offset = 0; + CHK( mbedtls_hmac_drbg_seed( &ctx, md_info, + hmac_drbg_self_test_entropy, (void *) entropy_pr, + NULL, 0 ) ); + mbedtls_hmac_drbg_set_prediction_resistance( &ctx, MBEDTLS_HMAC_DRBG_PR_ON ); + CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) ); + CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) ); + CHK( memcmp( buf, result_pr, OUTPUT_LEN ) ); + mbedtls_hmac_drbg_free( &ctx ); + + mbedtls_hmac_drbg_free( &ctx ); + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + + /* + * PR = False + */ + if( verbose != 0 ) + mbedtls_printf( " HMAC_DRBG (PR = False) : " ); + + mbedtls_hmac_drbg_init( &ctx ); + + test_offset = 0; + CHK( mbedtls_hmac_drbg_seed( &ctx, md_info, + hmac_drbg_self_test_entropy, (void *) entropy_nopr, + NULL, 0 ) ); + CHK( mbedtls_hmac_drbg_reseed( &ctx, NULL, 0 ) ); + CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) ); + CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) ); + CHK( memcmp( buf, result_nopr, OUTPUT_LEN ) ); + mbedtls_hmac_drbg_free( &ctx ); + + mbedtls_hmac_drbg_free( &ctx ); + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + + if( verbose != 0 ) + mbedtls_printf( "\n" ); + + return( 0 ); +} +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_SELF_TEST */ + +#endif /* MBEDTLS_HMAC_DRBG_C */ diff --git a/APP_Framework/Framework/security/mbedtls/hmac_drbg.h b/APP_Framework/Framework/security/mbedtls/hmac_drbg.h index 19a7c44e9..f58b1e31d 100644 --- a/APP_Framework/Framework/security/mbedtls/hmac_drbg.h +++ b/APP_Framework/Framework/security/mbedtls/hmac_drbg.h @@ -1,14 +1,10 @@ /** * \file hmac_drbg.h * - * \brief The HMAC_DRBG pseudorandom generator. - * - * This module implements the HMAC_DRBG pseudorandom generator described - * in NIST SP 800-90A: Recommendation for Random Number Generation Using - * Deterministic Random Bit Generators. + * \brief HMAC_DRBG (NIST SP 800-90A) */ /* - * Copyright (C) 2006-2019, ARM Limited, All Rights Reserved + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -74,11 +70,8 @@ /* \} name SECTION: Module settings */ -#define MBEDTLS_HMAC_DRBG_PR_OFF 0x55555555 /**< No prediction resistance */ -#define MBEDTLS_HMAC_DRBG_PR_ON 0x2AAAAAAA /**< Prediction resistance enabled */ - -#define MBEDTLS_HMAC_DRBG_RESEED 0x78547854 /**< Default environment, reseeding enabled */ -#define MBEDTLS_HMAC_DRBG_NO_RESEED 0x07AB87F0 /**< Reseeding disabled, no f_entropy required */ +#define MBEDTLS_HMAC_DRBG_PR_OFF 0 /**< No prediction resistance */ +#define MBEDTLS_HMAC_DRBG_PR_ON 1 /**< Prediction resistance enabled */ #ifdef __cplusplus extern "C" { @@ -87,14 +80,14 @@ extern "C" { /** * HMAC_DRBG context. */ -typedef struct mbedtls_hmac_drbg_context +typedef struct { - /* Working state: the key K is not stored explicitly, + /* Working state: the key K is not stored explicitely, * but is implied by the HMAC context */ mbedtls_md_context_t md_ctx; /*!< HMAC context (inc. K) */ unsigned char V[MBEDTLS_MD_MAX_SIZE]; /*!< V in the spec */ int reseed_counter; /*!< reseed counter */ - int reseed_flag; /*!< disables reseeding if set to MBEDTLS_HMAC_DRBG_NO_RESEED */ + /* Administrative state */ size_t entropy_len; /*!< entropy bytes grabbed on each (re)seed */ int prediction_resistance; /*!< enable prediction resistance (Automatic @@ -111,75 +104,41 @@ typedef struct mbedtls_hmac_drbg_context } mbedtls_hmac_drbg_context; /** - * \brief HMAC_DRBG context initialization. + * \brief HMAC_DRBG context initialization + * Makes the context ready for mbedtls_hmac_drbg_seed(), + * mbedtls_hmac_drbg_seed_buf() or + * mbedtls_hmac_drbg_free(). * - * This function makes the context ready for mbedtls_hmac_drbg_seed(), - * mbedtls_hmac_drbg_seed_buf() or mbedtls_hmac_drbg_free(). - * - * \param ctx HMAC_DRBG context to be initialized. + * \param ctx HMAC_DRBG context to be initialized */ void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx ); /** - * \brief HMAC_DRBG initial seeding. + * \brief HMAC_DRBG initial seeding + * Seed and setup entropy source for future reseeds. * - * Set the initial seed and set up the entropy source for future reseeds. + * \param ctx HMAC_DRBG context to be seeded + * \param md_info MD algorithm to use for HMAC_DRBG + * \param f_entropy Entropy callback (p_entropy, buffer to fill, buffer + * length) + * \param p_entropy Entropy context + * \param custom Personalization data (Device specific identifiers) + * (Can be NULL) + * \param len Length of personalization data * - * A typical choice for the \p f_entropy and \p p_entropy parameters is - * to use the entropy module: - * - \p f_entropy is mbedtls_entropy_func(); - * - \p p_entropy is an instance of ::mbedtls_entropy_context initialized - * with mbedtls_entropy_init() (which registers the platform's default - * entropy sources). - * - * You can provide a personalization string in addition to the - * entropy source, to make this instantiation as unique as possible. - * - * \note By default, the security strength as defined by NIST is: - * - 128 bits if \p md_info is SHA-1; - * - 192 bits if \p md_info is SHA-224; - * - 256 bits if \p md_info is SHA-256, SHA-384 or SHA-512. + * \note The "security strength" as defined by NIST is set to: + * 128 bits if md_alg is SHA-1, + * 192 bits if md_alg is SHA-224, + * 256 bits if md_alg is SHA-256 or higher. * Note that SHA-256 is just as efficient as SHA-224. - * The security strength can be reduced if a smaller - * entropy length is set with - * mbedtls_hmac_drbg_set_entropy_len(). * - * \note The default entropy length is the security strength - * (converted from bits to bytes). You can override - * it by calling mbedtls_hmac_drbg_set_entropy_len(). - * - * \note During the initial seeding, this function calls - * the entropy source to obtain a nonce - * whose length is half the entropy length. - * - * \param ctx HMAC_DRBG context to be seeded. - * \param md_info MD algorithm to use for HMAC_DRBG. - * \param f_entropy The entropy callback, taking as arguments the - * \p p_entropy context, the buffer to fill, and the - * length of the buffer. - * \p f_entropy is always called with a length that is - * less than or equal to the entropy length. - * \param p_entropy The entropy context to pass to \p f_entropy. - * \param custom The personalization string. - * This can be \c NULL, in which case the personalization - * string is empty regardless of the value of \p len. - * \param len The length of the personalization string. - * This must be at most #MBEDTLS_HMAC_DRBG_MAX_INPUT - * and also at most - * #MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT - \p entropy_len * 3 / 2 - * where \p entropy_len is the entropy length - * described above. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA if \p md_info is - * invalid. - * \return #MBEDTLS_ERR_MD_ALLOC_FAILED if there was not enough - * memory to allocate context data. - * \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED - * if the call to \p f_entropy failed. + * \return 0 if successful, or + * MBEDTLS_ERR_MD_BAD_INPUT_DATA, or + * MBEDTLS_ERR_MD_ALLOC_FAILED, or + * MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED. */ int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx, - mbedtls_md_handle_t md_info, + const mbedtls_md_info_t * md_info, int (*f_entropy)(void *, unsigned char *, size_t), void *p_entropy, const unsigned char *custom, @@ -187,150 +146,115 @@ int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx, /** * \brief Initilisation of simpified HMAC_DRBG (never reseeds). + * (For use with deterministic ECDSA.) * - * This function is meant for use in algorithms that need a pseudorandom - * input such as deterministic ECDSA. + * \param ctx HMAC_DRBG context to be initialised + * \param md_info MD algorithm to use for HMAC_DRBG + * \param data Concatenation of entropy string and additional data + * \param data_len Length of data in bytes * - * \param ctx HMAC_DRBG context to be initialised. - * \param md_info MD algorithm to use for HMAC_DRBG. - * \param data Concatenation of the initial entropy string and - * the additional data. - * \param data_len Length of \p data in bytes. - * - * \return \c 0 if successful. or - * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA if \p md_info is - * invalid. - * \return #MBEDTLS_ERR_MD_ALLOC_FAILED if there was not enough - * memory to allocate context data. + * \return 0 if successful, or + * MBEDTLS_ERR_MD_BAD_INPUT_DATA, or + * MBEDTLS_ERR_MD_ALLOC_FAILED. */ int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx, - mbedtls_md_handle_t md_info, + const mbedtls_md_info_t * md_info, const unsigned char *data, size_t data_len ); /** - * \brief This function turns prediction resistance on or off. - * The default value is off. + * \brief Enable / disable prediction resistance (Default: Off) * - * \note If enabled, entropy is gathered at the beginning of - * every call to mbedtls_hmac_drbg_random_with_add() - * or mbedtls_hmac_drbg_random(). - * Only use this if your entropy source has sufficient - * throughput. + * Note: If enabled, entropy is used for ctx->entropy_len before each call! + * Only use this if you have ample supply of good entropy! * - * \param ctx The HMAC_DRBG context. - * \param resistance #MBEDTLS_HMAC_DRBG_PR_ON or #MBEDTLS_HMAC_DRBG_PR_OFF. + * \param ctx HMAC_DRBG context + * \param resistance MBEDTLS_HMAC_DRBG_PR_ON or MBEDTLS_HMAC_DRBG_PR_OFF */ void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx, int resistance ); /** - * \brief This function turns reseeding on or off. - * Default value is on. + * \brief Set the amount of entropy grabbed on each reseed + * (Default: given by the security strength, which + * depends on the hash used, see \c mbedtls_hmac_drbg_init() ) * - * \note If set to MBEDTLS_HMAC_DRBG_NO_RESEED, this function - * disables reseeding, providing a no_reseed environment. - * f_entropy can then be null. - * - * \param ctx The HMAC_DRBG context. - * \param reseed_flag #MBEDTLS_HMAC_DRBG_NO_RESEED or #MBEDTLS_HMAC_DRBG_RESEED + * \param ctx HMAC_DRBG context + * \param len Amount of entropy to grab, in bytes */ -void mbedtls_hmac_drbg_set_reseeding( mbedtls_hmac_drbg_context *ctx, - int reseed_flag ); +void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx, + size_t len ); /** - * \brief This function sets the amount of entropy grabbed on each - * seed or reseed. + * \brief Set the reseed interval + * (Default: MBEDTLS_HMAC_DRBG_RESEED_INTERVAL) * - * See the documentation of mbedtls_hmac_drbg_seed() for the default value. - * - * \param ctx The HMAC_DRBG context. - * \param len The amount of entropy to grab, in bytes. - * - * \return \c 0 if \p len is valid, MBEDTLS_HMAC_DRBG_MAX_INPUT otherwise. - */ -int mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx, - size_t len ); - -/** - * \brief Set the reseed interval. - * - * The reseed interval is the number of calls to mbedtls_hmac_drbg_random() - * or mbedtls_hmac_drbg_random_with_add() after which the entropy function - * is called again. - * - * The default value is #MBEDTLS_HMAC_DRBG_RESEED_INTERVAL. - * - * \param ctx The HMAC_DRBG context. - * \param interval The reseed interval. + * \param ctx HMAC_DRBG context + * \param interval Reseed interval */ void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx, int interval ); /** - * \brief This function updates the state of the HMAC_DRBG context. + * \brief HMAC_DRBG update state * - * \param ctx The HMAC_DRBG context. - * \param additional The data to update the state with. - * If this is \c NULL, there is no additional data. - * \param add_len Length of \p additional in bytes. - * Unused if \p additional is \c NULL. + * \param ctx HMAC_DRBG context + * \param additional Additional data to update state with, or NULL + * \param add_len Length of additional data, or 0 * * \return \c 0 on success, or an error from the underlying - * hash calculation or - * MBEDTLS_ERR_PLATFORM_FAULT_DETECTED. + * hash calculation. + * + * \note Additional data is optional, pass NULL and 0 as second + * third argument if no additional data is being used. */ int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx, const unsigned char *additional, size_t add_len ); /** - * \brief This function reseeds the HMAC_DRBG context, that is - * extracts data from the entropy source. + * \brief HMAC_DRBG update state * - * \param ctx The HMAC_DRBG context. - * \param additional Additional data to add to the state. - * If this is \c NULL, there is no additional data - * and \p len should be \c 0. - * \param len The length of the additional data. - * This must be at most #MBEDTLS_HMAC_DRBG_MAX_INPUT - * and also at most - * #MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT - \p entropy_len - * where \p entropy_len is the entropy length - * (see mbedtls_hmac_drbg_set_entropy_len()). + * \warning This function cannot report errors. You should use + * mbedtls_hmac_drbg_update_ret() instead. * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED - * if a call to the entropy function failed. + * \param ctx HMAC_DRBG context + * \param additional Additional data to update state with, or NULL + * \param add_len Length of additional data, or 0 + * + * \note Additional data is optional, pass NULL and 0 as second + * third argument if no additional data is being used. + */ +void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx, + const unsigned char *additional, + size_t add_len ); + +/** + * \brief HMAC_DRBG reseeding (extracts data from entropy source) + * + * \param ctx HMAC_DRBG context + * \param additional Additional data to add to state (Can be NULL) + * \param len Length of additional data + * + * \return 0 if successful, or + * MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED */ int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx, const unsigned char *additional, size_t len ); /** - * \brief This function updates an HMAC_DRBG instance with additional - * data and uses it to generate random data. + * \brief HMAC_DRBG generate random with additional update input * - * This function automatically reseeds if the reseed counter is exceeded - * or prediction resistance is enabled. + * Note: Automatically reseeds if reseed_counter is reached or PR is enabled. * - * \param p_rng The HMAC_DRBG context. This must be a pointer to a - * #mbedtls_hmac_drbg_context structure. - * \param output The buffer to fill. - * \param output_len The length of the buffer in bytes. - * This must be at most #MBEDTLS_HMAC_DRBG_MAX_REQUEST. - * \param additional Additional data to update with. - * If this is \c NULL, there is no additional data - * and \p add_len should be \c 0. - * \param add_len The length of the additional data. - * This must be at most #MBEDTLS_HMAC_DRBG_MAX_INPUT. + * \param p_rng HMAC_DRBG context + * \param output Buffer to fill + * \param output_len Length of the buffer + * \param additional Additional data to update with (can be NULL) + * \param add_len Length of additional data (can be 0) * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED - * if a call to the entropy source failed. - * \return #MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG if - * \p output_len > #MBEDTLS_HMAC_DRBG_MAX_REQUEST. - * \return #MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG if - * \p add_len > #MBEDTLS_HMAC_DRBG_MAX_INPUT. - * \return #MBEDTLS_ERR_PLATFORM_FAULT_DETECTED if - * a logical fault is detected. + * \return 0 if successful, or + * MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED, or + * MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG, or + * MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG. */ int mbedtls_hmac_drbg_random_with_add( void *p_rng, unsigned char *output, size_t output_len, @@ -338,85 +262,49 @@ int mbedtls_hmac_drbg_random_with_add( void *p_rng, size_t add_len ); /** - * \brief This function uses HMAC_DRBG to generate random data. + * \brief HMAC_DRBG generate random * - * This function automatically reseeds if the reseed counter is exceeded - * or prediction resistance is enabled. + * Note: Automatically reseeds if reseed_counter is reached or PR is enabled. * - * \param p_rng The HMAC_DRBG context. This must be a pointer to a - * #mbedtls_hmac_drbg_context structure. - * \param output The buffer to fill. - * \param out_len The length of the buffer in bytes. - * This must be at most #MBEDTLS_HMAC_DRBG_MAX_REQUEST. + * \param p_rng HMAC_DRBG context + * \param output Buffer to fill + * \param out_len Length of the buffer * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED - * if a call to the entropy source failed. - * \return #MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG if - * \p out_len > #MBEDTLS_HMAC_DRBG_MAX_REQUEST. - * \return #MBEDTLS_ERR_PLATFORM_FAULT_DETECTED if - * a logical fault is detected. + * \return 0 if successful, or + * MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED, or + * MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG */ int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len ); /** * \brief Free an HMAC_DRBG context * - * \param ctx The HMAC_DRBG context to free. + * \param ctx HMAC_DRBG context to free. */ void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx ); -#if ! defined(MBEDTLS_DEPRECATED_REMOVED) -#if defined(MBEDTLS_DEPRECATED_WARNING) -#define MBEDTLS_DEPRECATED __attribute__((deprecated)) -#else -#define MBEDTLS_DEPRECATED -#endif -/** - * \brief This function updates the state of the HMAC_DRBG context. - * - * \deprecated Superseded by mbedtls_hmac_drbg_update_ret() - * in 2.16.0. - * - * \param ctx The HMAC_DRBG context. - * \param additional The data to update the state with. - * If this is \c NULL, there is no additional data. - * \param add_len Length of \p additional in bytes. - * Unused if \p additional is \c NULL. - */ -MBEDTLS_DEPRECATED void mbedtls_hmac_drbg_update( - mbedtls_hmac_drbg_context *ctx, - const unsigned char *additional, size_t add_len ); -#undef MBEDTLS_DEPRECATED -#endif /* !MBEDTLS_DEPRECATED_REMOVED */ - #if defined(MBEDTLS_FS_IO) /** - * \brief This function writes a seed file. + * \brief Write a seed file * - * \param ctx The HMAC_DRBG context. - * \param path The name of the file. + * \param ctx HMAC_DRBG context + * \param path Name of the file * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR on file error. - * \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED on reseed - * failure. + * \return 0 if successful, 1 on file error, or + * MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED */ int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path ); /** - * \brief This function reads and updates a seed file. The seed - * is added to this instance. + * \brief Read and update a seed file. Seed is added to this + * instance * - * \param ctx The HMAC_DRBG context. - * \param path The name of the file. + * \param ctx HMAC_DRBG context + * \param path Name of the file * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR on file error. - * \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED on - * reseed failure. - * \return #MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG if the existing - * seed file is too large. + * \return 0 if successful, 1 on file error, + * MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED or + * MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG */ int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path ); #endif /* MBEDTLS_FS_IO */ @@ -424,10 +312,9 @@ int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const ch #if defined(MBEDTLS_SELF_TEST) /** - * \brief The HMAC_DRBG Checkup routine. + * \brief Checkup routine * - * \return \c 0 if successful. - * \return \c 1 if the test failed. + * \return 0 if successful, or 1 if the test failed */ int mbedtls_hmac_drbg_self_test( int verbose ); #endif diff --git a/APP_Framework/Framework/security/mbedtls/key.pem b/APP_Framework/Framework/security/mbedtls/key.pem new file mode 100644 index 000000000..e19056062 --- /dev/null +++ b/APP_Framework/Framework/security/mbedtls/key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEoQIBAAKCAQBrQixost2wJXnBQBB9lV0gg4KLrM+ilC/VF7oKXVuth66ReeYH +qDzkjvi2+sexoRyPm0Tz7lB2YGSzD+hF8IKKM4BlqPacExlZt+yQLpzDUJA5+etu +gb/9yuYOig4UujIDElIeu101vCNlMSEN6iKIaNgknNmO2Wrkr3vsDUy/RzOxcwly +jN4lm3vvkZz9PmO466+S6rx/RUYPs1gx+Uos4TT3wSxbkH8u61Hq4VMhCaFZwRgQ +Qoa3M0yrnyguJa2iqqZIRk1A7VULrH0975+9IXgcBImTdT5sXgLgkoSzzC0C5HX/ +dryiSElWNukLUfxnC2dMoyrb5qI6CWYz3/NPAgMBAAECggEAEL9XYc2z8cIYPcV8 +Da/Zx67hHmAQV6ldwp8ezGmBXBoYdtyav01UnLd6PE/yCFlItV+gJ5ppc+JfNtpg +ATOpnlymSrlUMFCHH8wpIuY0UgbtTjAow6t8x+r7ev+xbSkZkAM3UVceGbrTqARA +zgRl+fis7yKSkcx+9VA1QElfV2pZ3fp1LzLmY36M+kzZaou5us+qoJOb6JIZ+jHY +sqhIErWKKbltAFLnmBQaLkeig7PyzHtO2Hoqt7yz2SOEkji2S/Qfk8jPxglQtXtw +tf56UcvsnzI/78lKo80dK1fHtrqDNfjLtAbw2RttsJ8HH6hxIccBJQjKVhp+UsuE +LBH8OQKBgQCwVx3nTj3AKwaU1xc+Y/E5TCcerMX1pZeIhmL4NH/q+QtuxBN85lw+ +hE0mQjw2L55jteYWX8/0L9/lVceevp4TtaGQ3vfASB6+VBUMVIvSefrmFsvwzgC2 +QTAvQvv+rJUuJF7rvhvExWK2qfA3pb4rYuPT/KP46edtD0tlgiMJiwKBgQCbthZP +tOF6O2cI2PBbdjlR/Q57BykK5G+PJbNFLyiZMT4y5QKM3Y2EA0+ip9LzFLtCCEV/ +B8HFinep71ANLqc8JSnRV5XCqZNax//B7mN3/0XubjiX63m5jNOw1JOrkO2lnwDI +TVjx6FkBxcz3U9N9gO+9PXxfFCytl5IS0SfNzQKBgB+ySQm+opLcKP6v+tmYFU/7 +RDzbSWnyLd64aSm8JhISWd+7FtWogoQqO8PYvAHxZUL++zCiYDrAMDqExLDgCoH4 +b+YebeH+FKiZbH8e41Md4d9h0Z6jKLWZ2hNksu8ADoCQwQ8WyN8Bq9CxkyAthpU9 +3T3Jd5/SS2rrCN5iGfIpAoGALEQUja5HV19hyDMcCXRPkU5WeoUrlswgJtq53xYr +/XjxTLisA+3MGFZ0ojIBl1cycPA3CYjj/kuB/05oPIchxchu3fN/QKrCmFE5FSG3 +J1rrv3+YGSA5J5WwbJnSLTjzRl0wdMEAYy0BeK6JuVocSpaIEQ1UuRbcKLFpNm49 +WZUCgYAJTRgepWC9id5guhKjccnUTpcOgaiV7RbNS9Ba2/4LPhRCaxsmy43L8IwV +NFinvdsjheeD/uk684dva7LE7BefpMtMHkIIZVIyKX8yO0KtooAkbwOWUsDhuIE1 +H5cyam3QiPJPIUe1+3qI+YafSJEqL3qo5nVJrPAU48wpYW04Ag== +-----END RSA PRIVATE KEY----- \ No newline at end of file diff --git a/APP_Framework/Framework/security/mbedtls/key.pub b/APP_Framework/Framework/security/mbedtls/key.pub new file mode 100644 index 000000000..52692b385 --- /dev/null +++ b/APP_Framework/Framework/security/mbedtls/key.pub @@ -0,0 +1,9 @@ +-----BEGIN PUBLIC KEY----- +MIIBITANBgkqhkiG9w0BAQEFAAOCAQ4AMIIBCQKCAQBrQixost2wJXnBQBB9lV0g +g4KLrM+ilC/VF7oKXVuth66ReeYHqDzkjvi2+sexoRyPm0Tz7lB2YGSzD+hF8IKK +M4BlqPacExlZt+yQLpzDUJA5+etugb/9yuYOig4UujIDElIeu101vCNlMSEN6iKI +aNgknNmO2Wrkr3vsDUy/RzOxcwlyjN4lm3vvkZz9PmO466+S6rx/RUYPs1gx+Uos +4TT3wSxbkH8u61Hq4VMhCaFZwRgQQoa3M0yrnyguJa2iqqZIRk1A7VULrH0975+9 +IXgcBImTdT5sXgLgkoSzzC0C5HX/dryiSElWNukLUfxnC2dMoyrb5qI6CWYz3/NP +AgMBAAE= +-----END PUBLIC KEY----- \ No newline at end of file diff --git a/APP_Framework/Framework/security/mbedtls/md.c b/APP_Framework/Framework/security/mbedtls/md.c index abfedee93..a7861a29e 100644 --- a/APP_Framework/Framework/security/mbedtls/md.c +++ b/APP_Framework/Framework/security/mbedtls/md.c @@ -32,8 +32,7 @@ #if defined(MBEDTLS_MD_C) #include "md.h" -#include "platform.h" -#include "platform_util.h" +#include "md_internal.h" #if defined(MBEDTLS_PLATFORM_C) #include "platform.h" @@ -49,176 +48,10 @@ #include #endif -#if !defined(MBEDTLS_MD_SINGLE_HASH) -/* - * - * Definitions of MD information structures for various digests. - * - */ - -/* - * MD-2 - */ -#if defined(MBEDTLS_MD2_C) -static const mbedtls_md_info_t mbedtls_md2_info = { - MBEDTLS_MD_MD2, - "MD2", - 16, - 16, - mbedtls_md2_starts_wrap, - mbedtls_md2_update_wrap, - mbedtls_md2_finish_wrap, - mbedtls_md2_ret, - mbedtls_md2_ctx_alloc, - mbedtls_md2_ctx_free, - mbedtls_md2_clone_wrap, - mbedtls_md2_process_wrap, -}; -#endif /* MBEDTLS_MD2_C */ - -/* - * MD-4 - */ - -#if defined(MBEDTLS_MD4_C) -static const mbedtls_md_info_t mbedtls_md4_info = { - MBEDTLS_MD_MD4, - "MD4", - 16, - 64, - mbedtls_md4_starts_wrap, - mbedtls_md4_update_wrap, - mbedtls_md4_finish_wrap, - mbedtls_md4_ret, - mbedtls_md4_ctx_alloc, - mbedtls_md4_ctx_free, - mbedtls_md4_clone_wrap, - mbedtls_md4_process_wrap, -}; -#endif /* MBEDTLS_MD4_C */ - -/* - * MD-5 - */ - -#if defined(MBEDTLS_MD5_C) -static const mbedtls_md_info_t mbedtls_md5_info = { - MBEDTLS_MD_MD5, - "MD5", - 16, - 64, - mbedtls_md5_starts_wrap, - mbedtls_md5_update_wrap, - mbedtls_md5_finish_wrap, - mbedtls_md5_ret, - mbedtls_md5_ctx_alloc, - mbedtls_md5_ctx_free, - mbedtls_md5_clone_wrap, - mbedtls_md5_process_wrap, -}; -#endif /* MBEDTLS_MD5_C */ - -/* - * RIPEMD-160 - */ - -#if defined(MBEDTLS_RIPEMD160_C) -static const mbedtls_md_info_t mbedtls_ripemd160_info = { - MBEDTLS_MD_RIPEMD160, - "RIPEMD160", - 20, - 64, - mbedtls_ripemd160_starts_wrap, - mbedtls_ripemd160_update_wrap, - mbedtls_ripemd160_finish_wrap, - mbedtls_ripemd160_ret, - mbedtls_ripemd160_ctx_alloc, - mbedtls_ripemd160_ctx_free, - mbedtls_ripemd160_clone_wrap, - mbedtls_ripemd160_process_wrap, -}; -#endif /* MBEDTLS_RIPEMD160_C */ - -/* - * SHA-1 - */ - -#if defined(MBEDTLS_SHA1_C) -static const mbedtls_md_info_t mbedtls_sha1_info = { - MBEDTLS_MD_SHA1, - "SHA1", - 20, - 64, - mbedtls_sha1_starts_wrap, - mbedtls_sha1_update_wrap, - mbedtls_sha1_finish_wrap, - mbedtls_sha1_ret, - mbedtls_sha1_ctx_alloc, - mbedtls_sha1_ctx_free, - mbedtls_sha1_clone_wrap, - mbedtls_sha1_process_wrap, -}; -#endif /* MBEDTLS_SHA1_C */ - -/* - * SHA-224 and SHA-256 - */ - -#if defined(MBEDTLS_SHA256_C) -#if !defined(MBEDTLS_SHA256_NO_SHA224) -static const mbedtls_md_info_t mbedtls_sha224_info = { - MBEDTLS_MD_SHA224, - "SHA224", - 28, - 64, - mbedtls_sha224_starts_wrap, - mbedtls_sha224_update_wrap, - mbedtls_sha224_finish_wrap, - mbedtls_sha224_wrap, - mbedtls_sha224_ctx_alloc, - mbedtls_sha224_ctx_free, - mbedtls_sha224_clone_wrap, - mbedtls_sha224_process_wrap, -}; -#endif /* !MBEDTLS_SHA256_NO_SHA224 */ -static const mbedtls_md_info_t mbedtls_sha256_info = - MBEDTLS_MD_INFO( MBEDTLS_MD_INFO_SHA256 ); -#endif /* MBEDTLS_SHA256_C */ - -/* - * SHA-384 and SHA-512 - */ - -#if defined(MBEDTLS_SHA512_C) -static const mbedtls_md_info_t mbedtls_sha384_info = { - MBEDTLS_MD_SHA384, - "SHA384", - 48, - 128, - mbedtls_sha384_starts_wrap, - mbedtls_sha384_update_wrap, - mbedtls_sha384_finish_wrap, - mbedtls_sha384_wrap, - mbedtls_sha384_ctx_alloc, - mbedtls_sha384_ctx_free, - mbedtls_sha384_clone_wrap, - mbedtls_sha384_process_wrap, -}; -static const mbedtls_md_info_t mbedtls_sha512_info = { - MBEDTLS_MD_SHA512, - "SHA512", - 64, - 128, - mbedtls_sha512_starts_wrap, - mbedtls_sha384_update_wrap, - mbedtls_sha384_finish_wrap, - mbedtls_sha512_wrap, - mbedtls_sha384_ctx_alloc, - mbedtls_sha384_ctx_free, - mbedtls_sha384_clone_wrap, - mbedtls_sha384_process_wrap, -}; -#endif /* MBEDTLS_SHA512_C */ +/* 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; +} /* * Reminder: update profiles in x509_crt.c when adding a new hash! @@ -232,10 +65,8 @@ static const int supported_digests[] = { #if defined(MBEDTLS_SHA256_C) MBEDTLS_MD_SHA256, -#if !defined(MBEDTLS_SHA256_NO_SHA224) MBEDTLS_MD_SHA224, #endif -#endif /* MBEDTLS_SHA256_C */ #if defined(MBEDTLS_SHA1_C) MBEDTLS_MD_SHA1, @@ -265,7 +96,7 @@ const int *mbedtls_md_list( void ) return( supported_digests ); } -mbedtls_md_handle_t mbedtls_md_info_from_string( const char *md_name ) +const mbedtls_md_info_t *mbedtls_md_info_from_string( const char *md_name ) { if( NULL == md_name ) return( NULL ); @@ -292,13 +123,11 @@ mbedtls_md_handle_t mbedtls_md_info_from_string( const char *md_name ) return mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 ); #endif #if defined(MBEDTLS_SHA256_C) -#if !defined(MBEDTLS_SHA256_NO_SHA224) if( !strcmp( "SHA224", md_name ) ) return mbedtls_md_info_from_type( MBEDTLS_MD_SHA224 ); -#endif if( !strcmp( "SHA256", md_name ) ) return mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 ); -#endif /* MBEDTLS_SHA256_C */ +#endif #if defined(MBEDTLS_SHA512_C) if( !strcmp( "SHA384", md_name ) ) return mbedtls_md_info_from_type( MBEDTLS_MD_SHA384 ); @@ -308,7 +137,7 @@ mbedtls_md_handle_t mbedtls_md_info_from_string( const char *md_name ) return( NULL ); } -mbedtls_md_handle_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 ) { switch( md_type ) { @@ -333,13 +162,11 @@ mbedtls_md_handle_t mbedtls_md_info_from_type( mbedtls_md_type_t md_type ) return( &mbedtls_sha1_info ); #endif #if defined(MBEDTLS_SHA256_C) -#if !defined(MBEDTLS_SHA256_NO_SHA224) case MBEDTLS_MD_SHA224: return( &mbedtls_sha224_info ); -#endif case MBEDTLS_MD_SHA256: return( &mbedtls_sha256_info ); -#endif /* MBEDTLS_SHA256_C */ +#endif #if defined(MBEDTLS_SHA512_C) case MBEDTLS_MD_SHA384: return( &mbedtls_sha384_info ); @@ -351,127 +178,108 @@ mbedtls_md_handle_t mbedtls_md_info_from_type( mbedtls_md_type_t md_type ) } } -#else /* MBEDTLS_MD_SINGLE_HASH */ - -const int *mbedtls_md_list( void ) -{ - static int single_hash[2] = - { MBEDTLS_MD_INFO_TYPE( MBEDTLS_MD_SINGLE_HASH ), - MBEDTLS_MD_INVALID_HANDLE }; - - return( single_hash ); -} - -mbedtls_md_handle_t mbedtls_md_info_from_string( const char *md_name ) -{ - static const char * const hash_name = - MBEDTLS_MD_INFO_NAME( MBEDTLS_MD_SINGLE_HASH ); - - if( md_name != NULL && strcmp( hash_name, md_name ) == 0 ) - return( MBEDTLS_MD_UNIQUE_VALID_HANDLE ); - - return( MBEDTLS_MD_INVALID_HANDLE ); -} - -mbedtls_md_handle_t mbedtls_md_info_from_type( mbedtls_md_type_t md_type ) -{ - static const mbedtls_md_type_t hash_type = - MBEDTLS_MD_INFO_TYPE( MBEDTLS_MD_SINGLE_HASH ); - - if( hash_type == md_type ) - return( MBEDTLS_MD_UNIQUE_VALID_HANDLE ); - - return( MBEDTLS_MD_INVALID_HANDLE ); -} - -#endif /* MBEDTLS_MD_SINGLE_HASH */ - void mbedtls_md_init( mbedtls_md_context_t *ctx ) { memset( ctx, 0, sizeof( mbedtls_md_context_t ) ); - -#if defined(MBEDTLS_MD_SINGLE_HASH) - mbedtls_md_info_init( mbedtls_md_get_handle( ctx ), - ctx->md_ctx ); -#endif } void mbedtls_md_free( mbedtls_md_context_t *ctx ) { - if( ctx == NULL || mbedtls_md_get_handle( ctx ) == MBEDTLS_MD_INVALID_HANDLE ) + if( ctx == NULL || ctx->md_info == NULL ) return; -#if !defined(MBEDTLS_MD_SINGLE_HASH) if( ctx->md_ctx != NULL ) - { - mbedtls_md_info_ctx_free( mbedtls_md_get_handle( ctx ), ctx->md_ctx ); - } + ctx->md_info->ctx_free_func( ctx->md_ctx ); if( ctx->hmac_ctx != NULL ) { - mbedtls_platform_zeroize( ctx->hmac_ctx, - 2 * mbedtls_md_info_block_size( mbedtls_md_get_handle( ctx ) ) ); + mbedtls_zeroize( ctx->hmac_ctx, 2 * ctx->md_info->block_size ); mbedtls_free( ctx->hmac_ctx ); } -#endif /* MBEDTLS_MD_SINGLE_HASH */ - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md_context_t ) ); + mbedtls_zeroize( ctx, sizeof( mbedtls_md_context_t ) ); } int mbedtls_md_clone( mbedtls_md_context_t *dst, const mbedtls_md_context_t *src ) { - if( dst == NULL || mbedtls_md_get_handle( dst ) == MBEDTLS_MD_INVALID_HANDLE || - src == NULL || mbedtls_md_get_handle( src ) == MBEDTLS_MD_INVALID_HANDLE || - mbedtls_md_get_handle( dst ) != mbedtls_md_get_handle( src ) ) + if( dst == NULL || dst->md_info == NULL || + src == NULL || src->md_info == NULL || + dst->md_info != src->md_info ) { return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); } - mbedtls_md_info_clone( mbedtls_md_get_handle( dst ), - dst->md_ctx, src->md_ctx ); + dst->md_info->clone_func( dst->md_ctx, src->md_ctx ); + return( 0 ); } #if ! defined(MBEDTLS_DEPRECATED_REMOVED) -int mbedtls_md_init_ctx( mbedtls_md_context_t *ctx, mbedtls_md_handle_t md_info ) +int mbedtls_md_init_ctx( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info ) { return mbedtls_md_setup( ctx, md_info, 1 ); } #endif -#if !defined(MBEDTLS_MD_SINGLE_HASH) -int mbedtls_md_setup( mbedtls_md_context_t *ctx, mbedtls_md_handle_t md_info, int hmac ) +int mbedtls_md_setup( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac ) { - return( mbedtls_md_setup_internal( ctx, md_info, hmac ) ); + if( md_info == NULL || ctx == NULL ) + return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); + + if( ( ctx->md_ctx = md_info->ctx_alloc_func() ) == NULL ) + return( MBEDTLS_ERR_MD_ALLOC_FAILED ); + + if( hmac != 0 ) + { + ctx->hmac_ctx = mbedtls_calloc( 2, md_info->block_size ); + if( ctx->hmac_ctx == NULL ) + { + md_info->ctx_free_func( ctx->md_ctx ); + return( MBEDTLS_ERR_MD_ALLOC_FAILED ); + } + } + + ctx->md_info = md_info; + + return( 0 ); } int mbedtls_md_starts( mbedtls_md_context_t *ctx ) { - return( mbedtls_md_starts_internal( ctx ) ); + if( ctx == NULL || ctx->md_info == NULL ) + return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); + + return( ctx->md_info->starts_func( ctx->md_ctx ) ); } -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 ) { - return( mbedtls_md_update_internal( ctx, input, ilen ) ); + if( ctx == NULL || ctx->md_info == NULL ) + return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); + + return( ctx->md_info->update_func( ctx->md_ctx, input, ilen ) ); } int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output ) { - return( mbedtls_md_finish_internal( ctx, output ) ); + if( ctx == NULL || ctx->md_info == NULL ) + return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); + + return( ctx->md_info->finish_func( ctx->md_ctx, output ) ); } -int mbedtls_md( mbedtls_md_handle_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 ) { - return( mbedtls_md_internal( md_info, input, ilen, output ) ); + if( md_info == NULL ) + return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); + + return( md_info->digest_func( input, ilen, output ) ); } -#endif /* !MBEDTLS_MD_SINGLE_HASH */ #if defined(MBEDTLS_FS_IO) -int mbedtls_md_file( mbedtls_md_handle_t md_info, const char *path, unsigned char *output ) +int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path, unsigned char *output ) { int ret; FILE *f; @@ -479,7 +287,7 @@ int mbedtls_md_file( mbedtls_md_handle_t md_info, const char *path, unsigned cha mbedtls_md_context_t ctx; unsigned char buf[1024]; - if( md_info == MBEDTLS_MD_INVALID_HANDLE ) + if( md_info == NULL ) return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); if( ( f = fopen( path, "rb" ) ) == NULL ) @@ -490,30 +298,20 @@ int mbedtls_md_file( mbedtls_md_handle_t md_info, const char *path, unsigned cha if( ( ret = mbedtls_md_setup( &ctx, md_info, 0 ) ) != 0 ) goto cleanup; - ret = mbedtls_md_info_starts( md_info, ctx.md_ctx ); - if( ret != 0 ) + if( ( ret = md_info->starts_func( ctx.md_ctx ) ) != 0 ) goto cleanup; while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) - { - ret = mbedtls_md_info_update( md_info, ctx.md_ctx, - buf, n ); - if( ret != 0 ) + if( ( ret = md_info->update_func( ctx.md_ctx, buf, n ) ) != 0 ) goto cleanup; - } if( ferror( f ) != 0 ) - { ret = MBEDTLS_ERR_MD_FILE_IO_ERROR; - } else - { - ret = mbedtls_md_info_finish( md_info, ctx.md_ctx, - output ); - } + ret = md_info->finish_func( ctx.md_ctx, output ); cleanup: - mbedtls_platform_zeroize( buf, sizeof( buf ) ); + mbedtls_zeroize( buf, sizeof( buf ) ); fclose( f ); mbedtls_md_free( &ctx ); @@ -526,46 +324,29 @@ int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key, int ret; unsigned char sum[MBEDTLS_MD_MAX_SIZE]; unsigned char *ipad, *opad; - size_t i = 0; + size_t i; - mbedtls_md_handle_t md_info; - - if( ctx == NULL ) + if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL ) return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); -#if !defined(MBEDTLS_MD_SINGLE_HASH) - if( ctx->hmac_ctx == NULL ) - return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); -#endif /* !MBEDTLS_MD_SINGLE_HASH */ - - md_info = mbedtls_md_get_handle( ctx ); - if( md_info == MBEDTLS_MD_INVALID_HANDLE ) - return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); - - if( keylen > (size_t) mbedtls_md_info_block_size( md_info ) ) + if( keylen > (size_t) ctx->md_info->block_size ) { - if( ( ret = mbedtls_md_info_starts( md_info, ctx->md_ctx ) ) != 0 ) + if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 ) + goto cleanup; + 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; - if( ( ret = mbedtls_md_info_update( md_info, ctx->md_ctx, - key, keylen ) ) != 0 ) - { - goto cleanup; - } - - if( ( ret = mbedtls_md_info_finish( md_info, ctx->md_ctx, sum ) ) != 0 ) - goto cleanup; - - keylen = mbedtls_md_info_size( md_info ); + keylen = ctx->md_info->size; key = sum; } ipad = (unsigned char *) ctx->hmac_ctx; - opad = (unsigned char *) ctx->hmac_ctx + - mbedtls_md_info_block_size( md_info ); + opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size; - mbedtls_platform_memset( ipad, 0x36, mbedtls_md_info_block_size( md_info ) ); - mbedtls_platform_memset( opad, 0x5C, mbedtls_md_info_block_size( md_info ) ); + memset( ipad, 0x36, ctx->md_info->block_size ); + memset( opad, 0x5C, ctx->md_info->block_size ); for( i = 0; i < keylen; i++ ) { @@ -573,52 +354,24 @@ int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key, opad[i] = (unsigned char)( opad[i] ^ key[i] ); } - if( ( ret = mbedtls_md_info_starts( md_info, ctx->md_ctx ) ) != 0 ) + if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 ) goto cleanup; - - i++; // Use i as flow control - - if( ( ret = mbedtls_md_info_update( md_info, ctx->md_ctx, ipad, - mbedtls_md_info_block_size( md_info ) ) ) != 0 ) - { + if( ( ret = ctx->md_info->update_func( ctx->md_ctx, ipad, + ctx->md_info->block_size ) ) != 0 ) goto cleanup; - } - - i++; // Use i as flow control now cleanup: - mbedtls_platform_zeroize( sum, sizeof( sum ) ); + mbedtls_zeroize( sum, sizeof( sum ) ); - if ( ret != 0 ) - return ret; - - /* Check possible fault injection */ - if ( ( i - 2 ) == keylen ) - return ret; // success, return 0 from ret - - return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); + return( ret ); } -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 ) { - mbedtls_md_handle_t md_info; - - if( ctx == NULL ) + if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL ) return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); -#if !defined(MBEDTLS_MD_SINGLE_HASH) - if( ctx->hmac_ctx == NULL ) - return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); -#endif /* !MBEDTLS_MD_SINGLE_HASH */ - - md_info = mbedtls_md_get_handle( ctx ); - if( md_info == MBEDTLS_MD_INVALID_HANDLE ) - return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); - - return( mbedtls_md_info_update( md_info, - ctx->md_ctx, input, - ilen ) ); + return( ctx->md_info->update_func( ctx->md_ctx, input, ilen ) ); } int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output ) @@ -627,45 +380,22 @@ int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output ) unsigned char tmp[MBEDTLS_MD_MAX_SIZE]; unsigned char *opad; - mbedtls_md_handle_t md_info; - - if( ctx == NULL ) + if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL ) return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); -#if !defined(MBEDTLS_MD_SINGLE_HASH) - if( ctx->hmac_ctx == NULL ) - return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); -#endif /* !MBEDTLS_MD_SINGLE_HASH */ + opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size; - md_info = mbedtls_md_get_handle( ctx ); - if( md_info == MBEDTLS_MD_INVALID_HANDLE ) - return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); - - opad = (unsigned char *) ctx->hmac_ctx + - mbedtls_md_info_block_size( md_info ); - - if( ( ret = mbedtls_md_info_finish( md_info, ctx->md_ctx, tmp ) ) != 0 ) + if( ( ret = ctx->md_info->finish_func( ctx->md_ctx, tmp ) ) != 0 ) return( ret ); - - if( ( ret = mbedtls_md_info_starts( md_info, ctx->md_ctx ) ) != 0 ) + if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 ) return( ret ); - - if( ( ret = mbedtls_md_info_update( md_info, ctx->md_ctx, opad, - mbedtls_md_info_block_size( md_info ) ) ) != 0 ) - { + if( ( ret = ctx->md_info->update_func( ctx->md_ctx, opad, + ctx->md_info->block_size ) ) != 0 ) return( ret ); - } - - if( ( ret = mbedtls_md_info_update( md_info, ctx->md_ctx, tmp, - mbedtls_md_info_size( md_info ) ) ) != 0 ) - { + if( ( ret = ctx->md_info->update_func( ctx->md_ctx, tmp, + ctx->md_info->size ) ) != 0 ) return( ret ); - } - - if( ( ret = mbedtls_md_info_finish( md_info, ctx->md_ctx, output ) ) != 0 ) - return( ret ); - - return( ret ); + return( ctx->md_info->finish_func( ctx->md_ctx, output ) ); } int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx ) @@ -673,33 +403,18 @@ int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx ) int ret; unsigned char *ipad; - mbedtls_md_handle_t md_info; - - if( ctx == NULL ) - return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); - -#if !defined(MBEDTLS_MD_SINGLE_HASH) - if( ctx->hmac_ctx == NULL ) - return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); -#endif /* !MBEDTLS_MD_SINGLE_HASH */ - - md_info = mbedtls_md_get_handle( ctx ); - if( md_info == MBEDTLS_MD_INVALID_HANDLE ) + if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL ) return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); ipad = (unsigned char *) ctx->hmac_ctx; - ret = mbedtls_md_info_starts( md_info, ctx->md_ctx ); - if( ret != 0 ) + if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 ) return( ret ); - - ret = mbedtls_md_info_update( md_info, - ctx->md_ctx, ipad, - mbedtls_md_info_block_size( md_info ) ); - return( ret ); + return( ctx->md_info->update_func( ctx->md_ctx, ipad, + ctx->md_info->block_size ) ); } -int mbedtls_md_hmac( mbedtls_md_handle_t md_info, +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, unsigned char *output ) @@ -707,7 +422,7 @@ int mbedtls_md_hmac( mbedtls_md_handle_t md_info, mbedtls_md_context_t ctx; int ret; - if( md_info == MBEDTLS_MD_INVALID_HANDLE ) + if( md_info == NULL ) return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); mbedtls_md_init( &ctx ); @@ -728,35 +443,36 @@ cleanup: return( ret ); } -#if !defined(MBEDTLS_MD_SINGLE_HASH) int mbedtls_md_process( mbedtls_md_context_t *ctx, const unsigned char *data ) { - return( mbedtls_md_process_internal( ctx, data ) ); -} -#endif /* !MBEDTLS_MD_SINGLE_HASH */ + if( ctx == NULL || ctx->md_info == NULL ) + return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); -unsigned char mbedtls_md_get_size( mbedtls_md_handle_t md_info ) + return( ctx->md_info->process_func( ctx->md_ctx, data ) ); +} + +unsigned char mbedtls_md_get_size( const mbedtls_md_info_t *md_info ) { - if( md_info == MBEDTLS_MD_INVALID_HANDLE ) + if( md_info == NULL ) return( 0 ); - return mbedtls_md_info_size( md_info ); + return md_info->size; } -mbedtls_md_type_t mbedtls_md_get_type( mbedtls_md_handle_t md_info ) +mbedtls_md_type_t mbedtls_md_get_type( const mbedtls_md_info_t *md_info ) { - if( md_info == MBEDTLS_MD_INVALID_HANDLE ) + if( md_info == NULL ) return( MBEDTLS_MD_NONE ); - return mbedtls_md_info_type( md_info ); + return md_info->type; } -const char *mbedtls_md_get_name( mbedtls_md_handle_t md_info ) +const char *mbedtls_md_get_name( const mbedtls_md_info_t *md_info ) { - if( md_info == MBEDTLS_MD_INVALID_HANDLE ) + if( md_info == NULL ) return( NULL ); - return mbedtls_md_info_name( md_info ); + return md_info->name; } #endif /* MBEDTLS_MD_C */ diff --git a/APP_Framework/Framework/security/mbedtls/md.h b/APP_Framework/Framework/security/mbedtls/md.h index 3b847b4a0..06538c382 100644 --- a/APP_Framework/Framework/security/mbedtls/md.h +++ b/APP_Framework/Framework/security/mbedtls/md.h @@ -1,7 +1,7 @@ /** * \file md.h * - * \brief This file contains the generic message-digest wrapper. + * \brief The generic message-digest wrapper. * * \author Adriaan de Jong */ @@ -35,17 +35,10 @@ #include MBEDTLS_CONFIG_FILE #endif -#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ - !defined(inline) && !defined(__cplusplus) -#define inline __inline -#endif - #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_ALLOC_FAILED -0x5180 /**< Failed to allocate memory. */ #define MBEDTLS_ERR_MD_FILE_IO_ERROR -0x5200 /**< Opening or reading of file failed. */ - -/* MBEDTLS_ERR_MD_HW_ACCEL_FAILED is deprecated and should not be used. */ #define MBEDTLS_ERR_MD_HW_ACCEL_FAILED -0x5280 /**< MD hardware accelerator failed. */ #ifdef __cplusplus @@ -53,7 +46,7 @@ extern "C" { #endif /** - * \brief Supported message digests. + * \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 @@ -61,16 +54,16 @@ extern "C" { * */ typedef enum { - MBEDTLS_MD_NONE=0, /**< None. */ - MBEDTLS_MD_MD2, /**< The MD2 message digest. */ - MBEDTLS_MD_MD4, /**< The MD4 message digest. */ - MBEDTLS_MD_MD5, /**< The MD5 message digest. */ - MBEDTLS_MD_SHA1, /**< The SHA-1 message digest. */ - MBEDTLS_MD_SHA224, /**< The SHA-224 message digest. */ - MBEDTLS_MD_SHA256, /**< The SHA-256 message digest. */ - MBEDTLS_MD_SHA384, /**< The SHA-384 message digest. */ - MBEDTLS_MD_SHA512, /**< The SHA-512 message digest. */ - MBEDTLS_MD_RIPEMD160, /**< The RIPEMD-160 message digest. */ + MBEDTLS_MD_NONE=0, + MBEDTLS_MD_MD2, + MBEDTLS_MD_MD4, + MBEDTLS_MD_MD5, + MBEDTLS_MD_SHA1, + MBEDTLS_MD_SHA224, + MBEDTLS_MD_SHA256, + MBEDTLS_MD_SHA384, + MBEDTLS_MD_SHA512, + MBEDTLS_MD_RIPEMD160, } mbedtls_md_type_t; #if defined(MBEDTLS_SHA512_C) @@ -79,78 +72,25 @@ typedef enum { #define MBEDTLS_MD_MAX_SIZE 32 /* longest known is SHA256 or less */ #endif -#if defined(MBEDTLS_SHA512_C) -#define MBEDTLS_MD_MAX_BLOCK_SIZE 128 -#else -#define MBEDTLS_MD_MAX_BLOCK_SIZE 64 -#endif - -#if !defined(MBEDTLS_MD_SINGLE_HASH) - -#define MBEDTLS_MD_INLINABLE_API - /** - * Opaque struct defined in md.c. + * Opaque struct defined in md_internal.h. */ typedef struct mbedtls_md_info_t mbedtls_md_info_t; - -typedef struct mbedtls_md_info_t const * mbedtls_md_handle_t; -#define MBEDTLS_MD_INVALID_HANDLE ( (mbedtls_md_handle_t) NULL ) - -#else /* !MBEDTLS_MD_SINGLE_HASH */ - -#define MBEDTLS_MD_INLINABLE_API MBEDTLS_ALWAYS_INLINE static inline - -typedef int mbedtls_md_handle_t; -#define MBEDTLS_MD_INVALID_HANDLE ( (mbedtls_md_handle_t) 0 ) -#define MBEDTLS_MD_UNIQUE_VALID_HANDLE ( (mbedtls_md_handle_t) 1 ) - -#endif /* !MBEDTLS_MD_SINGLE_HASH */ - -#include "md_internal.h" - /** * The generic message-digest context. */ -typedef struct mbedtls_md_context_t -{ -#if !defined(MBEDTLS_MD_SINGLE_HASH) +typedef struct { /** Information about the associated message digest. */ - mbedtls_md_handle_t md_info; -#endif + const mbedtls_md_info_t *md_info; -#if !defined(MBEDTLS_MD_SINGLE_HASH) /** The digest-specific context. */ void *md_ctx; /** The HMAC part of the context. */ void *hmac_ctx; -#else - unsigned char md_ctx[ sizeof( MBEDTLS_MD_INFO_CTX_TYPE( - MBEDTLS_MD_SINGLE_HASH ) ) ]; - - unsigned char hmac_ctx[ 2 * MBEDTLS_MD_INFO_BLOCKSIZE( - MBEDTLS_MD_SINGLE_HASH ) ]; - -#endif /* MBEDTLS_MD_SINGLE_HASH */ } mbedtls_md_context_t; -#if !defined(MBEDTLS_MD_SINGLE_HASH) -static inline mbedtls_md_handle_t mbedtls_md_get_handle( - struct mbedtls_md_context_t const *ctx ) -{ - return( ctx->md_info ); -} -#else /* !MBEDTLS_MD_SINGLE_HASH */ -static inline mbedtls_md_handle_t mbedtls_md_get_handle( - struct mbedtls_md_context_t const *ctx ) -{ - ((void) ctx); - return( MBEDTLS_MD_UNIQUE_VALID_HANDLE ); -} -#endif /* !MBEDTLS_MD_SINGLE_HASH */ - /** * \brief This function returns the list of digests supported by the * generic digest module. @@ -168,10 +108,10 @@ const int *mbedtls_md_list( void ); * * \param md_name The name of the digest to search for. * - * \return The message-digest information associated with \p md_name. - * \return NULL if the associated message-digest information is not found. + * \return The message-digest information associated with \p md_name, + * or NULL if not found. */ -mbedtls_md_handle_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 This function returns the message-digest information @@ -179,10 +119,10 @@ mbedtls_md_handle_t mbedtls_md_info_from_string( const char *md_name ); * * \param md_type The type of digest to search for. * - * \return The message-digest information associated with \p md_type. - * \return NULL if the associated message-digest information is not found. + * \return The message-digest information associated with \p md_type, + * or NULL if not found. */ -mbedtls_md_handle_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 This function initializes a message-digest context without @@ -228,12 +168,11 @@ void mbedtls_md_free( mbedtls_md_context_t *ctx ); * \param md_info The information structure of the message-digest algorithm * to use. * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification - * failure. - * \return #MBEDTLS_ERR_MD_ALLOC_FAILED on memory-allocation failure. + * \returns \c 0 on success, + * #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter failure, + * #MBEDTLS_ERR_MD_ALLOC_FAILED memory allocation failure. */ -int mbedtls_md_init_ctx( mbedtls_md_context_t *ctx, mbedtls_md_handle_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 #endif /* MBEDTLS_DEPRECATED_REMOVED */ @@ -248,17 +187,14 @@ int mbedtls_md_init_ctx( mbedtls_md_context_t *ctx, mbedtls_md_handle_t md_info * \param ctx The context to set up. * \param md_info The information structure of the message-digest algorithm * to use. - * \param hmac Defines if HMAC is used. 0: HMAC is not used (saves some memory), - * or non-zero: HMAC is used with this context. + * \param hmac
    • 0: HMAC is not used. Saves some memory.
    • + *
    • non-zero: HMAC is used with this context.
    * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification - * failure. - * \return #MBEDTLS_ERR_MD_ALLOC_FAILED on memory-allocation failure. + * \returns \c 0 on success, + * #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter failure, or + * #MBEDTLS_ERR_MD_ALLOC_FAILED on memory allocation failure. */ -MBEDTLS_MD_INLINABLE_API int mbedtls_md_setup( mbedtls_md_context_t *ctx, - mbedtls_md_handle_t md_info, - int hmac ); +int mbedtls_md_setup( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac ); /** * \brief This function clones the state of an message-digest @@ -276,8 +212,8 @@ MBEDTLS_MD_INLINABLE_API int mbedtls_md_setup( mbedtls_md_context_t *ctx, * \param dst The destination context. * \param src The context to be cloned. * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification failure. + * \return \c 0 on success, + * #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter failure. */ int mbedtls_md_clone( mbedtls_md_context_t *dst, const mbedtls_md_context_t *src ); @@ -291,7 +227,7 @@ int mbedtls_md_clone( mbedtls_md_context_t *dst, * * \return The size of the message-digest output in Bytes. */ -unsigned char mbedtls_md_get_size( mbedtls_md_handle_t md_info ); +unsigned char mbedtls_md_get_size( const mbedtls_md_info_t *md_info ); /** * \brief This function extracts the message-digest type from the @@ -302,7 +238,7 @@ unsigned char mbedtls_md_get_size( mbedtls_md_handle_t md_info ); * * \return The type of the message digest. */ -mbedtls_md_type_t mbedtls_md_get_type( mbedtls_md_handle_t md_info ); +mbedtls_md_type_t mbedtls_md_get_type( const mbedtls_md_info_t *md_info ); /** * \brief This function extracts the message-digest name from the @@ -313,7 +249,7 @@ mbedtls_md_type_t mbedtls_md_get_type( mbedtls_md_handle_t md_info ); * * \return The name of the message digest. */ -const char *mbedtls_md_get_name( mbedtls_md_handle_t md_info ); +const char *mbedtls_md_get_name( const mbedtls_md_info_t *md_info ); /** * \brief This function starts a message-digest computation. @@ -324,11 +260,10 @@ const char *mbedtls_md_get_name( mbedtls_md_handle_t md_info ); * * \param ctx The generic message-digest context. * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification - * failure. + * \returns \c 0 on success, #MBEDTLS_ERR_MD_BAD_INPUT_DATA if + * parameter verification fails. */ -MBEDTLS_MD_INLINABLE_API int mbedtls_md_starts( mbedtls_md_context_t *ctx ); +int mbedtls_md_starts( mbedtls_md_context_t *ctx ); /** * \brief This function feeds an input buffer into an ongoing @@ -342,13 +277,10 @@ MBEDTLS_MD_INLINABLE_API int mbedtls_md_starts( mbedtls_md_context_t *ctx ); * \param input The buffer holding the input data. * \param ilen The length of the input data. * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification - * failure. + * \returns \c 0 on success, #MBEDTLS_ERR_MD_BAD_INPUT_DATA if + * parameter verification fails. */ -MBEDTLS_MD_INLINABLE_API 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 This function finishes the digest operation, @@ -364,12 +296,10 @@ MBEDTLS_MD_INLINABLE_API int mbedtls_md_update( mbedtls_md_context_t *ctx, * \param ctx The generic message-digest context. * \param output The buffer for the generic message-digest checksum result. * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification - * failure. + * \returns \c 0 on success, or #MBEDTLS_ERR_MD_BAD_INPUT_DATA if + * parameter verification fails. */ -MBEDTLS_MD_INLINABLE_API 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 This function calculates the message-digest of a buffer, @@ -385,15 +315,11 @@ MBEDTLS_MD_INLINABLE_API int mbedtls_md_finish( mbedtls_md_context_t *ctx, * \param ilen The length of the input data. * \param output The generic message-digest checksum result. * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification - * failure. + * \returns \c 0 on success, or #MBEDTLS_ERR_MD_BAD_INPUT_DATA if + * parameter verification fails. */ -MBEDTLS_MD_INLINABLE_API int mbedtls_md( - mbedtls_md_handle_t md_info, - const unsigned char *input, - size_t ilen, - unsigned char *output ); +int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen, + unsigned char *output ); #if defined(MBEDTLS_FS_IO) /** @@ -408,12 +334,11 @@ MBEDTLS_MD_INLINABLE_API int mbedtls_md( * \param path The input file name. * \param output The generic message-digest checksum result. * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MD_FILE_IO_ERROR on an I/O error accessing - * the file pointed by \p path. - * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA if \p md_info was NULL. + * \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( mbedtls_md_handle_t md_info, const char *path, +int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path, unsigned char *output ); #endif /* MBEDTLS_FS_IO */ @@ -431,9 +356,8 @@ int mbedtls_md_file( mbedtls_md_handle_t md_info, const char *path, * \param key The HMAC secret key. * \param keylen The length of the HMAC key in Bytes. * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification - * failure. + * \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, size_t keylen ); @@ -453,9 +377,8 @@ int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key, * \param input The buffer holding the input data. * \param ilen The length of the input data. * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification - * failure. + * \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, size_t ilen ); @@ -474,9 +397,8 @@ int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *inpu * context. * \param output The generic HMAC checksum result. * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification - * failure. + * \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); @@ -491,9 +413,8 @@ int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output); * \param ctx The message digest context containing an embedded HMAC * context. * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification - * failure. + * \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 ); @@ -515,171 +436,15 @@ int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx ); * \param ilen The length of the input data. * \param output The generic HMAC result. * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification - * failure. + * \returns \c 0 on success, or #MBEDTLS_ERR_MD_BAD_INPUT_DATA if + * parameter verification fails. */ -int mbedtls_md_hmac( mbedtls_md_handle_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, unsigned char *output ); /* Internal use */ -MBEDTLS_MD_INLINABLE_API int mbedtls_md_process( mbedtls_md_context_t *ctx, - const unsigned char *data ); - -/* - * Internal wrapper functions for those MD API functions which should be - * inlined in some but not all configurations. The actual MD API will be - * implemented either here or in md.c, and forward to the wrappers. - */ - -MBEDTLS_ALWAYS_INLINE static inline int mbedtls_md_setup_internal( - mbedtls_md_context_t *ctx, mbedtls_md_handle_t md_info, int hmac ) -{ - if( md_info == MBEDTLS_MD_INVALID_HANDLE || ctx == NULL ) - return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); - -#if !defined(MBEDTLS_MD_SINGLE_HASH) - ctx->md_ctx = mbedtls_md_info_ctx_alloc( md_info ); - if( ctx->md_ctx == NULL ) - return( MBEDTLS_ERR_MD_ALLOC_FAILED ); - - if( hmac != 0 ) - { - ctx->hmac_ctx = mbedtls_calloc( 2, - mbedtls_md_info_block_size( md_info ) ); - if( ctx->hmac_ctx == NULL ) - { - mbedtls_md_info_ctx_free( md_info, ctx->md_ctx); - return( MBEDTLS_ERR_MD_ALLOC_FAILED ); - } - } - - ctx->md_info = md_info; -#else - ((void) hmac); -#endif /* MBEDTLS_MD_SINGLE_HASH */ - - return( 0 ); -} - -MBEDTLS_ALWAYS_INLINE static inline int mbedtls_md_starts_internal( - mbedtls_md_context_t *ctx ) -{ - mbedtls_md_handle_t md_info; - if( ctx == NULL ) - return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); - - md_info = mbedtls_md_get_handle( ctx ); - if( md_info == MBEDTLS_MD_INVALID_HANDLE ) - return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); - - return( mbedtls_md_info_starts( md_info, ctx->md_ctx ) ); -} - -MBEDTLS_ALWAYS_INLINE static inline int mbedtls_md_update_internal( - mbedtls_md_context_t *ctx, - const unsigned char *input, - size_t ilen ) -{ - mbedtls_md_handle_t md_info; - if( ctx == NULL ) - return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); - - md_info = mbedtls_md_get_handle( ctx ); - if( md_info == MBEDTLS_MD_INVALID_HANDLE ) - return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); - - return( mbedtls_md_info_update( md_info, ctx->md_ctx, - input, ilen ) ); -} - -MBEDTLS_ALWAYS_INLINE static inline int mbedtls_md_finish_internal( - mbedtls_md_context_t *ctx, unsigned char *output ) -{ - mbedtls_md_handle_t md_info; - if( ctx == NULL ) - return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); - - md_info = mbedtls_md_get_handle( ctx ); - if( md_info == MBEDTLS_MD_INVALID_HANDLE ) - return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); - - return( mbedtls_md_info_finish( md_info, ctx->md_ctx, - output ) ); -} - -MBEDTLS_ALWAYS_INLINE static inline int mbedtls_md_internal( - mbedtls_md_handle_t md_info, - const unsigned char *input, - size_t ilen, - unsigned char *output ) -{ - if( md_info == MBEDTLS_MD_INVALID_HANDLE ) - return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); - - return( mbedtls_md_info_digest( md_info, input, - ilen, output) ); -} - -MBEDTLS_ALWAYS_INLINE static inline int mbedtls_md_process_internal( - mbedtls_md_context_t *ctx, const unsigned char *data ) -{ - mbedtls_md_handle_t md_info; - if( ctx == NULL ) - return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); - - md_info = mbedtls_md_get_handle( ctx ); - if( md_info == MBEDTLS_MD_INVALID_HANDLE ) - return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); - - return( mbedtls_md_info_process( md_info, ctx->md_ctx, data ) ); -} - -#if defined(MBEDTLS_MD_SINGLE_HASH) - -MBEDTLS_MD_INLINABLE_API int mbedtls_md_setup( - mbedtls_md_context_t *ctx, mbedtls_md_handle_t md_info, int hmac ) -{ - return( mbedtls_md_setup_internal( ctx, md_info, hmac ) ); -} - -MBEDTLS_MD_INLINABLE_API int mbedtls_md_starts( - mbedtls_md_context_t *ctx ) -{ - return( mbedtls_md_starts_internal( ctx ) ); -} - -MBEDTLS_MD_INLINABLE_API int mbedtls_md_update( - mbedtls_md_context_t *ctx, - const unsigned char *input, - size_t ilen ) -{ - return( mbedtls_md_update_internal( ctx, input, ilen ) ); -} - -MBEDTLS_MD_INLINABLE_API int mbedtls_md_finish( - mbedtls_md_context_t *ctx, unsigned char *output ) -{ - return( mbedtls_md_finish_internal( ctx, output ) ); -} - -MBEDTLS_MD_INLINABLE_API int mbedtls_md( - mbedtls_md_handle_t md_info, - const unsigned char *input, - size_t ilen, - unsigned char *output ) -{ - return( mbedtls_md_internal( md_info, input, ilen, output ) ); -} - -MBEDTLS_MD_INLINABLE_API int mbedtls_md_process( - mbedtls_md_context_t *ctx, const unsigned char *data ) -{ - return( mbedtls_md_process_internal( ctx, data ) ); -} - -#endif /* MBEDTLS_MD_SINGLE_HASH */ +int mbedtls_md_process( mbedtls_md_context_t *ctx, const unsigned char *data ); #ifdef __cplusplus } diff --git a/APP_Framework/Framework/security/mbedtls/md2.c b/APP_Framework/Framework/security/mbedtls/md2.c new file mode 100644 index 000000000..7e432e607 --- /dev/null +++ b/APP_Framework/Framework/security/mbedtls/md2.c @@ -0,0 +1,367 @@ +/* + * RFC 1115/1319 compliant MD2 implementation + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +/* + * The MD2 algorithm was designed by Ron Rivest in 1989. + * + * http://www.ietf.org/rfc/rfc1115.txt + * http://www.ietf.org/rfc/rfc1319.txt + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_MD2_C) + +#include "md2.h" + +#include + +#if defined(MBEDTLS_SELF_TEST) +#if defined(MBEDTLS_PLATFORM_C) +#include "platform.h" +#else +#include +#define mbedtls_printf printf +#endif /* MBEDTLS_PLATFORM_C */ +#endif /* MBEDTLS_SELF_TEST */ + +#if !defined(MBEDTLS_MD2_ALT) + +/* 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; +} + +static const unsigned char PI_SUBST[256] = +{ + 0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01, 0x3D, 0x36, + 0x54, 0xA1, 0xEC, 0xF0, 0x06, 0x13, 0x62, 0xA7, 0x05, 0xF3, + 0xC0, 0xC7, 0x73, 0x8C, 0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C, + 0x82, 0xCA, 0x1E, 0x9B, 0x57, 0x3C, 0xFD, 0xD4, 0xE0, 0x16, + 0x67, 0x42, 0x6F, 0x18, 0x8A, 0x17, 0xE5, 0x12, 0xBE, 0x4E, + 0xC4, 0xD6, 0xDA, 0x9E, 0xDE, 0x49, 0xA0, 0xFB, 0xF5, 0x8E, + 0xBB, 0x2F, 0xEE, 0x7A, 0xA9, 0x68, 0x79, 0x91, 0x15, 0xB2, + 0x07, 0x3F, 0x94, 0xC2, 0x10, 0x89, 0x0B, 0x22, 0x5F, 0x21, + 0x80, 0x7F, 0x5D, 0x9A, 0x5A, 0x90, 0x32, 0x27, 0x35, 0x3E, + 0xCC, 0xE7, 0xBF, 0xF7, 0x97, 0x03, 0xFF, 0x19, 0x30, 0xB3, + 0x48, 0xA5, 0xB5, 0xD1, 0xD7, 0x5E, 0x92, 0x2A, 0xAC, 0x56, + 0xAA, 0xC6, 0x4F, 0xB8, 0x38, 0xD2, 0x96, 0xA4, 0x7D, 0xB6, + 0x76, 0xFC, 0x6B, 0xE2, 0x9C, 0x74, 0x04, 0xF1, 0x45, 0x9D, + 0x70, 0x59, 0x64, 0x71, 0x87, 0x20, 0x86, 0x5B, 0xCF, 0x65, + 0xE6, 0x2D, 0xA8, 0x02, 0x1B, 0x60, 0x25, 0xAD, 0xAE, 0xB0, + 0xB9, 0xF6, 0x1C, 0x46, 0x61, 0x69, 0x34, 0x40, 0x7E, 0x0F, + 0x55, 0x47, 0xA3, 0x23, 0xDD, 0x51, 0xAF, 0x3A, 0xC3, 0x5C, + 0xF9, 0xCE, 0xBA, 0xC5, 0xEA, 0x26, 0x2C, 0x53, 0x0D, 0x6E, + 0x85, 0x28, 0x84, 0x09, 0xD3, 0xDF, 0xCD, 0xF4, 0x41, 0x81, + 0x4D, 0x52, 0x6A, 0xDC, 0x37, 0xC8, 0x6C, 0xC1, 0xAB, 0xFA, + 0x24, 0xE1, 0x7B, 0x08, 0x0C, 0xBD, 0xB1, 0x4A, 0x78, 0x88, + 0x95, 0x8B, 0xE3, 0x63, 0xE8, 0x6D, 0xE9, 0xCB, 0xD5, 0xFE, + 0x3B, 0x00, 0x1D, 0x39, 0xF2, 0xEF, 0xB7, 0x0E, 0x66, 0x58, + 0xD0, 0xE4, 0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A, + 0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A, 0xDB, 0x99, + 0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14 +}; + +void mbedtls_md2_init( mbedtls_md2_context *ctx ) +{ + memset( ctx, 0, sizeof( mbedtls_md2_context ) ); +} + +void mbedtls_md2_free( mbedtls_md2_context *ctx ) +{ + if( ctx == NULL ) + return; + + mbedtls_zeroize( ctx, sizeof( mbedtls_md2_context ) ); +} + +void mbedtls_md2_clone( mbedtls_md2_context *dst, + const mbedtls_md2_context *src ) +{ + *dst = *src; +} + +/* + * MD2 context setup + */ +int mbedtls_md2_starts_ret( mbedtls_md2_context *ctx ) +{ + memset( ctx->cksum, 0, 16 ); + memset( ctx->state, 0, 46 ); + memset( ctx->buffer, 0, 16 ); + 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) +int mbedtls_internal_md2_process( mbedtls_md2_context *ctx ) +{ + int i, j; + unsigned char t = 0; + + for( i = 0; i < 16; i++ ) + { + ctx->state[i + 16] = ctx->buffer[i]; + ctx->state[i + 32] = + (unsigned char)( ctx->buffer[i] ^ ctx->state[i]); + } + + for( i = 0; i < 18; i++ ) + { + for( j = 0; j < 48; j++ ) + { + ctx->state[j] = (unsigned char) + ( ctx->state[j] ^ PI_SUBST[t] ); + t = ctx->state[j]; + } + + t = (unsigned char)( t + i ); + } + + t = ctx->cksum[15]; + + for( i = 0; i < 16; i++ ) + { + ctx->cksum[i] = (unsigned char) + ( ctx->cksum[i] ^ PI_SUBST[ctx->buffer[i] ^ t] ); + 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 */ + +/* + * MD2 process buffer + */ +int mbedtls_md2_update_ret( mbedtls_md2_context *ctx, + const unsigned char *input, + size_t ilen ) +{ + int ret; + size_t fill; + + while( ilen > 0 ) + { + if( ilen > 16 - ctx->left ) + fill = 16 - ctx->left; + else + fill = ilen; + + memcpy( ctx->buffer + ctx->left, input, fill ); + + ctx->left += fill; + input += fill; + ilen -= fill; + + if( ctx->left == 16 ) + { + ctx->left = 0; + 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 + */ +int mbedtls_md2_finish_ret( mbedtls_md2_context *ctx, + unsigned char output[16] ) +{ + int ret; + size_t i; + unsigned char x; + + x = (unsigned char)( 16 - ctx->left ); + + for( i = ctx->left; i < 16; i++ ) + ctx->buffer[i] = x; + + if( ( ret = mbedtls_internal_md2_process( ctx ) ) != 0 ) + return( ret ); + + memcpy( ctx->buffer, ctx->cksum, 16 ); + if( ( ret = mbedtls_internal_md2_process( ctx ) ) != 0 ) + return( ret ); + + 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 */ + +/* + * output = MD2( input buffer ) + */ +int mbedtls_md2_ret( const unsigned char *input, + size_t ilen, + unsigned char output[16] ) +{ + int ret; + mbedtls_md2_context ctx; + + mbedtls_md2_init( &ctx ); + + if( ( ret = mbedtls_md2_starts_ret( &ctx ) ) != 0 ) + 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 ); + + 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) + +/* + * RFC 1319 test vectors + */ +static const unsigned char md2_test_str[7][81] = +{ + { "" }, + { "a" }, + { "abc" }, + { "message digest" }, + { "abcdefghijklmnopqrstuvwxyz" }, + { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" }, + { "12345678901234567890123456789012345678901234567890123456789012" + "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] = +{ + { 0x83, 0x50, 0xE5, 0xA3, 0xE2, 0x4C, 0x15, 0x3D, + 0xF2, 0x27, 0x5C, 0x9F, 0x80, 0x69, 0x27, 0x73 }, + { 0x32, 0xEC, 0x01, 0xEC, 0x4A, 0x6D, 0xAC, 0x72, + 0xC0, 0xAB, 0x96, 0xFB, 0x34, 0xC0, 0xB5, 0xD1 }, + { 0xDA, 0x85, 0x3B, 0x0D, 0x3F, 0x88, 0xD9, 0x9B, + 0x30, 0x28, 0x3A, 0x69, 0xE6, 0xDE, 0xD6, 0xBB }, + { 0xAB, 0x4F, 0x49, 0x6B, 0xFB, 0x2A, 0x53, 0x0B, + 0x21, 0x9F, 0xF3, 0x30, 0x31, 0xFE, 0x06, 0xB0 }, + { 0x4E, 0x8D, 0xDF, 0xF3, 0x65, 0x02, 0x92, 0xAB, + 0x5A, 0x41, 0x08, 0xC3, 0xAA, 0x47, 0x94, 0x0B }, + { 0xDA, 0x33, 0xDE, 0xF2, 0xA4, 0x2D, 0xF1, 0x39, + 0x75, 0x35, 0x28, 0x46, 0xC3, 0x03, 0x38, 0xCD }, + { 0xD5, 0x97, 0x6F, 0x79, 0xD8, 0x3D, 0x3A, 0x0D, + 0xC9, 0x80, 0x6C, 0x3C, 0x66, 0xF3, 0xEF, 0xD8 } +}; + +/* + * Checkup routine + */ +int mbedtls_md2_self_test( int verbose ) +{ + int i, ret = 0; + unsigned char md2sum[16]; + + for( i = 0; i < 7; i++ ) + { + if( verbose != 0 ) + mbedtls_printf( " MD2 test #%d: ", i + 1 ); + + ret = mbedtls_md2_ret( md2_test_str[i], md2_test_strlen[i], md2sum ); + if( ret != 0 ) + goto fail; + + if( memcmp( md2sum, md2_test_sum[i], 16 ) != 0 ) + { + ret = 1; + goto fail; + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + } + + if( verbose != 0 ) + mbedtls_printf( "\n" ); + + return( 0 ); + +fail: + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + return( ret ); +} + +#endif /* MBEDTLS_SELF_TEST */ + +#endif /* MBEDTLS_MD2_C */ diff --git a/APP_Framework/Framework/security/mbedtls/md2.h b/APP_Framework/Framework/security/mbedtls/md2.h index fe97cf08d..0fd8b5afc 100644 --- a/APP_Framework/Framework/security/mbedtls/md2.h +++ b/APP_Framework/Framework/security/mbedtls/md2.h @@ -37,17 +37,16 @@ #include -/* MBEDTLS_ERR_MD2_HW_ACCEL_FAILED is deprecated and should not be used. */ #define MBEDTLS_ERR_MD2_HW_ACCEL_FAILED -0x002B /**< MD2 hardware accelerator failed */ -#ifdef __cplusplus -extern "C" { -#endif - #if !defined(MBEDTLS_MD2_ALT) // Regular implementation // +#ifdef __cplusplus +extern "C" { +#endif + /** * \brief MD2 context structure * @@ -56,7 +55,7 @@ extern "C" { * stronger message digests instead. * */ -typedef struct mbedtls_md2_context +typedef struct { unsigned char cksum[16]; /*!< checksum of the data block */ unsigned char state[48]; /*!< intermediate digest state */ @@ -65,10 +64,6 @@ typedef struct mbedtls_md2_context } mbedtls_md2_context; -#else /* MBEDTLS_MD2_ALT */ -#include "md2_alt.h" -#endif /* MBEDTLS_MD2_ALT */ - /** * \brief Initialize MD2 context * @@ -240,6 +235,18 @@ MBEDTLS_DEPRECATED void mbedtls_md2_process( mbedtls_md2_context *ctx ); #undef MBEDTLS_DEPRECATED #endif /* !MBEDTLS_DEPRECATED_REMOVED */ +#ifdef __cplusplus +} +#endif + +#else /* MBEDTLS_MD2_ALT */ +#include "md2_alt.h" +#endif /* MBEDTLS_MD2_ALT */ + +#ifdef __cplusplus +extern "C" { +#endif + /** * \brief Output = MD2( input buffer ) * @@ -283,8 +290,6 @@ MBEDTLS_DEPRECATED void mbedtls_md2( const unsigned char *input, #undef MBEDTLS_DEPRECATED #endif /* !MBEDTLS_DEPRECATED_REMOVED */ -#if defined(MBEDTLS_SELF_TEST) - /** * \brief Checkup routine * @@ -297,8 +302,6 @@ MBEDTLS_DEPRECATED void mbedtls_md2( const unsigned char *input, */ int mbedtls_md2_self_test( int verbose ); -#endif /* MBEDTLS_SELF_TEST */ - #ifdef __cplusplus } #endif diff --git a/APP_Framework/Framework/security/mbedtls/md4.c b/APP_Framework/Framework/security/mbedtls/md4.c new file mode 100644 index 000000000..1c94eed51 --- /dev/null +++ b/APP_Framework/Framework/security/mbedtls/md4.c @@ -0,0 +1,472 @@ +/* + * RFC 1186/1320 compliant MD4 implementation + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +/* + * The MD4 algorithm was designed by Ron Rivest in 1990. + * + * http://www.ietf.org/rfc/rfc1186.txt + * http://www.ietf.org/rfc/rfc1320.txt + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_MD4_C) + +#include "md4.h" + +#include + +#if defined(MBEDTLS_SELF_TEST) +#if defined(MBEDTLS_PLATFORM_C) +#include "platform.h" +#else +#include +#define mbedtls_printf printf +#endif /* MBEDTLS_PLATFORM_C */ +#endif /* MBEDTLS_SELF_TEST */ + +#if !defined(MBEDTLS_MD4_ALT) + +/* 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; +} + +/* + * 32-bit integer manipulation macros (little endian) + */ +#ifndef GET_UINT32_LE +#define GET_UINT32_LE(n,b,i) \ +{ \ + (n) = ( (uint32_t) (b)[(i) ] ) \ + | ( (uint32_t) (b)[(i) + 1] << 8 ) \ + | ( (uint32_t) (b)[(i) + 2] << 16 ) \ + | ( (uint32_t) (b)[(i) + 3] << 24 ); \ +} +#endif + +#ifndef PUT_UINT32_LE +#define PUT_UINT32_LE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \ + (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \ + (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \ + (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \ +} +#endif + +void mbedtls_md4_init( mbedtls_md4_context *ctx ) +{ + memset( ctx, 0, sizeof( mbedtls_md4_context ) ); +} + +void mbedtls_md4_free( mbedtls_md4_context *ctx ) +{ + if( ctx == NULL ) + return; + + mbedtls_zeroize( ctx, sizeof( mbedtls_md4_context ) ); +} + +void mbedtls_md4_clone( mbedtls_md4_context *dst, + const mbedtls_md4_context *src ) +{ + *dst = *src; +} + +/* + * MD4 context setup + */ +int mbedtls_md4_starts_ret( mbedtls_md4_context *ctx ) +{ + ctx->total[0] = 0; + ctx->total[1] = 0; + + ctx->state[0] = 0x67452301; + ctx->state[1] = 0xEFCDAB89; + ctx->state[2] = 0x98BADCFE; + 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) +int mbedtls_internal_md4_process( mbedtls_md4_context *ctx, + const unsigned char data[64] ) +{ + uint32_t X[16], A, B, C, D; + + GET_UINT32_LE( X[ 0], data, 0 ); + GET_UINT32_LE( X[ 1], data, 4 ); + GET_UINT32_LE( X[ 2], data, 8 ); + GET_UINT32_LE( X[ 3], data, 12 ); + GET_UINT32_LE( X[ 4], data, 16 ); + GET_UINT32_LE( X[ 5], data, 20 ); + GET_UINT32_LE( X[ 6], data, 24 ); + GET_UINT32_LE( X[ 7], data, 28 ); + GET_UINT32_LE( X[ 8], data, 32 ); + GET_UINT32_LE( X[ 9], data, 36 ); + GET_UINT32_LE( X[10], data, 40 ); + GET_UINT32_LE( X[11], data, 44 ); + GET_UINT32_LE( X[12], data, 48 ); + GET_UINT32_LE( X[13], data, 52 ); + GET_UINT32_LE( X[14], data, 56 ); + GET_UINT32_LE( X[15], data, 60 ); + +#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) + + A = ctx->state[0]; + B = ctx->state[1]; + C = ctx->state[2]; + D = ctx->state[3]; + +#define F(x, y, z) ((x & y) | ((~x) & z)) +#define P(a,b,c,d,x,s) { a += F(b,c,d) + x; a = S(a,s); } + + P( A, B, C, D, X[ 0], 3 ); + P( D, A, B, C, X[ 1], 7 ); + P( C, D, A, B, X[ 2], 11 ); + P( B, C, D, A, X[ 3], 19 ); + P( A, B, C, D, X[ 4], 3 ); + P( D, A, B, C, X[ 5], 7 ); + P( C, D, A, B, X[ 6], 11 ); + P( B, C, D, A, X[ 7], 19 ); + P( A, B, C, D, X[ 8], 3 ); + P( D, A, B, C, X[ 9], 7 ); + P( C, D, A, B, X[10], 11 ); + P( B, C, D, A, X[11], 19 ); + P( A, B, C, D, X[12], 3 ); + P( D, A, B, C, X[13], 7 ); + P( C, D, A, B, X[14], 11 ); + P( B, C, D, A, X[15], 19 ); + +#undef P +#undef F + +#define F(x,y,z) ((x & y) | (x & z) | (y & z)) +#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x5A827999; a = S(a,s); } + + P( A, B, C, D, X[ 0], 3 ); + P( D, A, B, C, X[ 4], 5 ); + P( C, D, A, B, X[ 8], 9 ); + P( B, C, D, A, X[12], 13 ); + P( A, B, C, D, X[ 1], 3 ); + P( D, A, B, C, X[ 5], 5 ); + P( C, D, A, B, X[ 9], 9 ); + P( B, C, D, A, X[13], 13 ); + P( A, B, C, D, X[ 2], 3 ); + P( D, A, B, C, X[ 6], 5 ); + P( C, D, A, B, X[10], 9 ); + P( B, C, D, A, X[14], 13 ); + P( A, B, C, D, X[ 3], 3 ); + P( D, A, B, C, X[ 7], 5 ); + P( C, D, A, B, X[11], 9 ); + P( B, C, D, A, X[15], 13 ); + +#undef P +#undef F + +#define F(x,y,z) (x ^ y ^ z) +#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x6ED9EBA1; a = S(a,s); } + + P( A, B, C, D, X[ 0], 3 ); + P( D, A, B, C, X[ 8], 9 ); + P( C, D, A, B, X[ 4], 11 ); + P( B, C, D, A, X[12], 15 ); + P( A, B, C, D, X[ 2], 3 ); + P( D, A, B, C, X[10], 9 ); + P( C, D, A, B, X[ 6], 11 ); + P( B, C, D, A, X[14], 15 ); + P( A, B, C, D, X[ 1], 3 ); + P( D, A, B, C, X[ 9], 9 ); + P( C, D, A, B, X[ 5], 11 ); + P( B, C, D, A, X[13], 15 ); + P( A, B, C, D, X[ 3], 3 ); + P( D, A, B, C, X[11], 9 ); + P( C, D, A, B, X[ 7], 11 ); + P( B, C, D, A, X[15], 15 ); + +#undef F +#undef P + + ctx->state[0] += A; + ctx->state[1] += B; + ctx->state[2] += C; + 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 */ + +/* + * MD4 process buffer + */ +int mbedtls_md4_update_ret( mbedtls_md4_context *ctx, + const unsigned char *input, + size_t ilen ) +{ + int ret; + size_t fill; + uint32_t left; + + if( ilen == 0 ) + return( 0 ); + + left = ctx->total[0] & 0x3F; + fill = 64 - left; + + ctx->total[0] += (uint32_t) ilen; + ctx->total[0] &= 0xFFFFFFFF; + + if( ctx->total[0] < (uint32_t) ilen ) + ctx->total[1]++; + + if( left && ilen >= fill ) + { + memcpy( (void *) (ctx->buffer + left), + (void *) input, fill ); + + if( ( ret = mbedtls_internal_md4_process( ctx, ctx->buffer ) ) != 0 ) + return( ret ); + + input += fill; + ilen -= fill; + left = 0; + } + + while( ilen >= 64 ) + { + if( ( ret = mbedtls_internal_md4_process( ctx, input ) ) != 0 ) + return( ret ); + + input += 64; + ilen -= 64; + } + + if( ilen > 0 ) + { + memcpy( (void *) (ctx->buffer + left), + (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] = +{ + 0x80, 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 +}; + +/* + * MD4 final digest + */ +int mbedtls_md4_finish_ret( mbedtls_md4_context *ctx, + unsigned char output[16] ) +{ + int ret; + uint32_t last, padn; + uint32_t high, low; + unsigned char msglen[8]; + + high = ( ctx->total[0] >> 29 ) + | ( ctx->total[1] << 3 ); + low = ( ctx->total[0] << 3 ); + + PUT_UINT32_LE( low, msglen, 0 ); + PUT_UINT32_LE( high, msglen, 4 ); + + last = ctx->total[0] & 0x3F; + padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); + + ret = mbedtls_md4_update_ret( ctx, (unsigned char *)md4_padding, padn ); + 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[1], output, 4 ); + PUT_UINT32_LE( ctx->state[2], output, 8 ); + 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 */ + +/* + * output = MD4( input buffer ) + */ +int mbedtls_md4_ret( const unsigned char *input, + size_t ilen, + unsigned char output[16] ) +{ + int ret; + mbedtls_md4_context ctx; + + mbedtls_md4_init( &ctx ); + + if( ( ret = mbedtls_md4_starts_ret( &ctx ) ) != 0 ) + 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 ); + + 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) + +/* + * RFC 1320 test vectors + */ +static const unsigned char md4_test_str[7][81] = +{ + { "" }, + { "a" }, + { "abc" }, + { "message digest" }, + { "abcdefghijklmnopqrstuvwxyz" }, + { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" }, + { "12345678901234567890123456789012345678901234567890123456789012" + "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] = +{ + { 0x31, 0xD6, 0xCF, 0xE0, 0xD1, 0x6A, 0xE9, 0x31, + 0xB7, 0x3C, 0x59, 0xD7, 0xE0, 0xC0, 0x89, 0xC0 }, + { 0xBD, 0xE5, 0x2C, 0xB3, 0x1D, 0xE3, 0x3E, 0x46, + 0x24, 0x5E, 0x05, 0xFB, 0xDB, 0xD6, 0xFB, 0x24 }, + { 0xA4, 0x48, 0x01, 0x7A, 0xAF, 0x21, 0xD8, 0x52, + 0x5F, 0xC1, 0x0A, 0xE8, 0x7A, 0xA6, 0x72, 0x9D }, + { 0xD9, 0x13, 0x0A, 0x81, 0x64, 0x54, 0x9F, 0xE8, + 0x18, 0x87, 0x48, 0x06, 0xE1, 0xC7, 0x01, 0x4B }, + { 0xD7, 0x9E, 0x1C, 0x30, 0x8A, 0xA5, 0xBB, 0xCD, + 0xEE, 0xA8, 0xED, 0x63, 0xDF, 0x41, 0x2D, 0xA9 }, + { 0x04, 0x3F, 0x85, 0x82, 0xF2, 0x41, 0xDB, 0x35, + 0x1C, 0xE6, 0x27, 0xE1, 0x53, 0xE7, 0xF0, 0xE4 }, + { 0xE3, 0x3B, 0x4D, 0xDC, 0x9C, 0x38, 0xF2, 0x19, + 0x9C, 0x3E, 0x7B, 0x16, 0x4F, 0xCC, 0x05, 0x36 } +}; + +/* + * Checkup routine + */ +int mbedtls_md4_self_test( int verbose ) +{ + int i, ret = 0; + unsigned char md4sum[16]; + + for( i = 0; i < 7; i++ ) + { + if( verbose != 0 ) + mbedtls_printf( " MD4 test #%d: ", i + 1 ); + + ret = mbedtls_md4_ret( md4_test_str[i], md4_test_strlen[i], md4sum ); + if( ret != 0 ) + goto fail; + + if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 ) + { + ret = 1; + goto fail; + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + } + + if( verbose != 0 ) + mbedtls_printf( "\n" ); + + return( 0 ); + +fail: + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + return( ret ); +} + +#endif /* MBEDTLS_SELF_TEST */ + +#endif /* MBEDTLS_MD4_C */ diff --git a/APP_Framework/Framework/security/mbedtls/md4.h b/APP_Framework/Framework/security/mbedtls/md4.h index ce703c0ba..23fa95e46 100644 --- a/APP_Framework/Framework/security/mbedtls/md4.h +++ b/APP_Framework/Framework/security/mbedtls/md4.h @@ -38,17 +38,16 @@ #include #include -/* MBEDTLS_ERR_MD4_HW_ACCEL_FAILED is deprecated and should not be used. */ #define MBEDTLS_ERR_MD4_HW_ACCEL_FAILED -0x002D /**< MD4 hardware accelerator failed */ -#ifdef __cplusplus -extern "C" { -#endif - #if !defined(MBEDTLS_MD4_ALT) // Regular implementation // +#ifdef __cplusplus +extern "C" { +#endif + /** * \brief MD4 context structure * @@ -57,7 +56,7 @@ extern "C" { * stronger message digests instead. * */ -typedef struct mbedtls_md4_context +typedef struct { uint32_t total[2]; /*!< number of bytes processed */ uint32_t state[4]; /*!< intermediate digest state */ @@ -65,10 +64,6 @@ typedef struct mbedtls_md4_context } mbedtls_md4_context; -#else /* MBEDTLS_MD4_ALT */ -#include "md4_alt.h" -#endif /* MBEDTLS_MD4_ALT */ - /** * \brief Initialize MD4 context * @@ -243,6 +238,18 @@ MBEDTLS_DEPRECATED void mbedtls_md4_process( mbedtls_md4_context *ctx, #undef MBEDTLS_DEPRECATED #endif /* !MBEDTLS_DEPRECATED_REMOVED */ +#ifdef __cplusplus +} +#endif + +#else /* MBEDTLS_MD4_ALT */ +#include "md4_alt.h" +#endif /* MBEDTLS_MD4_ALT */ + +#ifdef __cplusplus +extern "C" { +#endif + /** * \brief Output = MD4( input buffer ) * @@ -288,8 +295,6 @@ MBEDTLS_DEPRECATED void mbedtls_md4( const unsigned char *input, #undef MBEDTLS_DEPRECATED #endif /* !MBEDTLS_DEPRECATED_REMOVED */ -#if defined(MBEDTLS_SELF_TEST) - /** * \brief Checkup routine * @@ -302,8 +307,6 @@ MBEDTLS_DEPRECATED void mbedtls_md4( const unsigned char *input, */ int mbedtls_md4_self_test( int verbose ); -#endif /* MBEDTLS_SELF_TEST */ - #ifdef __cplusplus } #endif diff --git a/APP_Framework/Framework/security/mbedtls/md5.c b/APP_Framework/Framework/security/mbedtls/md5.c index c8d6fb473..77cf7ebab 100644 --- a/APP_Framework/Framework/security/mbedtls/md5.c +++ b/APP_Framework/Framework/security/mbedtls/md5.c @@ -33,7 +33,6 @@ #if defined(MBEDTLS_MD5_C) #include "md5.h" -#include "platform_util.h" #include @@ -48,6 +47,11 @@ #if !defined(MBEDTLS_MD5_ALT) +/* 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; +} + /* * 32-bit integer manipulation macros (little endian) */ @@ -73,7 +77,7 @@ void mbedtls_md5_init( mbedtls_md5_context *ctx ) { - mbedtls_platform_memset( ctx, 0, sizeof( mbedtls_md5_context ) ); + memset( ctx, 0, sizeof( mbedtls_md5_context ) ); } void mbedtls_md5_free( mbedtls_md5_context *ctx ) @@ -81,7 +85,7 @@ void mbedtls_md5_free( mbedtls_md5_context *ctx ) if( ctx == NULL ) return; - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md5_context ) ); + mbedtls_zeroize( ctx, sizeof( mbedtls_md5_context ) ); } void mbedtls_md5_clone( mbedtls_md5_context *dst, @@ -136,22 +140,19 @@ int mbedtls_internal_md5_process( mbedtls_md5_context *ctx, GET_UINT32_LE( X[14], data, 56 ); GET_UINT32_LE( X[15], data, 60 ); -#define S(x,n) \ - ( ( (x) << (n) ) | ( ( (x) & 0xFFFFFFFF) >> ( 32 - (n) ) ) ) +#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) -#define P(a,b,c,d,k,s,t) \ - do \ - { \ - (a) += F((b),(c),(d)) + X[(k)] + (t); \ - (a) = S((a),(s)) + (b); \ - } while( 0 ) +#define P(a,b,c,d,k,s,t) \ +{ \ + a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \ +} A = ctx->state[0]; B = ctx->state[1]; C = ctx->state[2]; D = ctx->state[3]; -#define F(x,y,z) ((z) ^ ((x) & ((y) ^ (z)))) +#define F(x,y,z) (z ^ (x & (y ^ z))) P( A, B, C, D, 0, 7, 0xD76AA478 ); P( D, A, B, C, 1, 12, 0xE8C7B756 ); @@ -172,7 +173,7 @@ int mbedtls_internal_md5_process( mbedtls_md5_context *ctx, #undef F -#define F(x,y,z) ((y) ^ ((z) & ((x) ^ (y)))) +#define F(x,y,z) (y ^ (z & (x ^ y))) P( A, B, C, D, 1, 5, 0xF61E2562 ); P( D, A, B, C, 6, 9, 0xC040B340 ); @@ -193,7 +194,7 @@ int mbedtls_internal_md5_process( mbedtls_md5_context *ctx, #undef F -#define F(x,y,z) ((x) ^ (y) ^ (z)) +#define F(x,y,z) (x ^ y ^ z) P( A, B, C, D, 5, 4, 0xFFFA3942 ); P( D, A, B, C, 8, 11, 0x8771F681 ); @@ -214,7 +215,7 @@ int mbedtls_internal_md5_process( mbedtls_md5_context *ctx, #undef F -#define F(x,y,z) ((y) ^ ((x) | ~(z))) +#define F(x,y,z) (y ^ (x | ~z)) P( A, B, C, D, 0, 6, 0xF4292244 ); P( D, A, B, C, 7, 10, 0x432AFF97 ); @@ -277,7 +278,7 @@ int mbedtls_md5_update_ret( mbedtls_md5_context *ctx, if( left && ilen >= fill ) { - mbedtls_platform_memcpy( (void *) (ctx->buffer + left), input, fill ); + memcpy( (void *) (ctx->buffer + left), input, fill ); if( ( ret = mbedtls_internal_md5_process( ctx, ctx->buffer ) ) != 0 ) return( ret ); @@ -297,7 +298,7 @@ int mbedtls_md5_update_ret( mbedtls_md5_context *ctx, if( ilen > 0 ) { - mbedtls_platform_memcpy( (void *) (ctx->buffer + left), input, ilen ); + memcpy( (void *) (ctx->buffer + left), input, ilen ); } return( 0 ); @@ -332,17 +333,17 @@ int mbedtls_md5_finish_ret( mbedtls_md5_context *ctx, if( used <= 56 ) { /* Enough room for padding + length in current block */ - mbedtls_platform_memset( ctx->buffer + used, 0, 56 - used ); + memset( ctx->buffer + used, 0, 56 - used ); } else { /* We'll need an extra block */ - mbedtls_platform_memset( ctx->buffer + used, 0, 64 - used ); + memset( ctx->buffer + used, 0, 64 - used ); if( ( ret = mbedtls_internal_md5_process( ctx, ctx->buffer ) ) != 0 ) return( ret ); - mbedtls_platform_memset( ctx->buffer, 0, 56 ); + memset( ctx->buffer, 0, 56 ); } /* diff --git a/APP_Framework/Framework/security/mbedtls/md5.h b/APP_Framework/Framework/security/mbedtls/md5.h index 6eed6cc86..06ea4c5d4 100644 --- a/APP_Framework/Framework/security/mbedtls/md5.h +++ b/APP_Framework/Framework/security/mbedtls/md5.h @@ -37,17 +37,16 @@ #include #include -/* MBEDTLS_ERR_MD5_HW_ACCEL_FAILED is deprecated and should not be used. */ #define MBEDTLS_ERR_MD5_HW_ACCEL_FAILED -0x002F /**< MD5 hardware accelerator failed */ -#ifdef __cplusplus -extern "C" { -#endif - #if !defined(MBEDTLS_MD5_ALT) // Regular implementation // +#ifdef __cplusplus +extern "C" { +#endif + /** * \brief MD5 context structure * @@ -56,7 +55,7 @@ extern "C" { * stronger message digests instead. * */ -typedef struct mbedtls_md5_context +typedef struct { uint32_t total[2]; /*!< number of bytes processed */ uint32_t state[4]; /*!< intermediate digest state */ @@ -64,10 +63,6 @@ typedef struct mbedtls_md5_context } mbedtls_md5_context; -#else /* MBEDTLS_MD5_ALT */ -#include "md5_alt.h" -#endif /* MBEDTLS_MD5_ALT */ - /** * \brief Initialize MD5 context * @@ -243,6 +238,18 @@ MBEDTLS_DEPRECATED void mbedtls_md5_process( mbedtls_md5_context *ctx, #undef MBEDTLS_DEPRECATED #endif /* !MBEDTLS_DEPRECATED_REMOVED */ +#ifdef __cplusplus +} +#endif + +#else /* MBEDTLS_MD5_ALT */ +#include "md5_alt.h" +#endif /* MBEDTLS_MD5_ALT */ + +#ifdef __cplusplus +extern "C" { +#endif + /** * \brief Output = MD5( input buffer ) * @@ -288,8 +295,6 @@ MBEDTLS_DEPRECATED void mbedtls_md5( const unsigned char *input, #undef MBEDTLS_DEPRECATED #endif /* !MBEDTLS_DEPRECATED_REMOVED */ -#if defined(MBEDTLS_SELF_TEST) - /** * \brief Checkup routine * @@ -302,8 +307,6 @@ MBEDTLS_DEPRECATED void mbedtls_md5( const unsigned char *input, */ int mbedtls_md5_self_test( int verbose ); -#endif /* MBEDTLS_SELF_TEST */ - #ifdef __cplusplus } #endif diff --git a/APP_Framework/Framework/security/mbedtls/md_internal.h b/APP_Framework/Framework/security/mbedtls/md_internal.h index 12240083d..04de48291 100644 --- a/APP_Framework/Framework/security/mbedtls/md_internal.h +++ b/APP_Framework/Framework/security/mbedtls/md_internal.h @@ -1,12 +1,14 @@ - /** +/** * \file md_internal.h * - * \brief This file contains the generic message-digest wrapper. + * \brief Message digest wrappers. + * + * \warning This in an internal header. Do not include directly. * * \author Adriaan de Jong */ /* - * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -21,157 +23,27 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * This file is part of Mbed TLS (https://tls.mbed.org) + * This file is part of mbed TLS (https://tls.mbed.org) */ +#ifndef MBEDTLS_MD_WRAP_H +#define MBEDTLS_MD_WRAP_H -#ifndef MBEDTLS_MD_INTERNAL_H -#define MBEDTLS_MD_INTERNAL_H - -#if defined(MBEDTLS_MD2_C) -#include "md2.h" -#endif - -#if defined(MBEDTLS_MD4_C) -#include "md4.h" -#endif - -#if defined(MBEDTLS_MD5_C) -#include "md5.h" -#endif - -#if defined(MBEDTLS_RIPEMD160_C) -#include "ripemd160.h" -#endif - -#if defined(MBEDTLS_SHA1_C) -#include "sha1.h" -#endif - -#if defined(MBEDTLS_SHA256_C) -#include "sha256.h" -#endif - -#if defined(MBEDTLS_SHA512_C) -#include "sha512.h" -#endif - -#include "platform_util.h" - -#if defined(MBEDTLS_PLATFORM_C) -#include "platform.h" +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" #else -#include -#define mbedtls_calloc calloc -#define mbedtls_free free +#include MBEDTLS_CONFIG_FILE #endif +#include "md.h" + #ifdef __cplusplus extern "C" { #endif -#define MBEDTLS_MD_WRAPPER MBEDTLS_ALWAYS_INLINE static inline - -/* - * Message-digest information macro definition - */ - -/* Dummy definition to keep check-names.sh happy - don't uncomment */ -//#define MBEDTLS_MD_INFO_SHA256 - -/* SHA-256 */ -static inline void mbedtls_md_sha256_init_free_dummy( void* ctx ) -{ - /* Zero-initialization can be skipped. */ - ((void) ctx); -} -#define MBEDTLS_MD_INFO_SHA256_TYPE MBEDTLS_MD_SHA256 -#define MBEDTLS_MD_INFO_SHA256_CTX_TYPE mbedtls_sha256_context -#if defined(MBEDTLS_MD_SINGLE_HASH) && !defined(MBEDTLS_SHA256_ALT) -/* mbedtls_md_sha256_init() only zeroizes, which is redundant - * because mbedtls_md_context is zeroized in mbedtls_md_init(), - * and the mbedtls_sha256_context is embedded in mbedtls_md_context_t. */ -#define MBEDTLS_MD_INFO_SHA256_INIT_FUNC mbedtls_md_sha256_init_free_dummy -#else -#define MBEDTLS_MD_INFO_SHA256_INIT_FUNC mbedtls_sha256_init -#endif /* MBEDTLS_MD_SINGLE_HASH && !MBEDTLS_SHA256_ALT */ -#define MBEDTLS_MD_INFO_SHA256_NAME "SHA256" -#define MBEDTLS_MD_INFO_SHA256_SIZE 32 -#define MBEDTLS_MD_INFO_SHA256_BLOCKSIZE 64 -#define MBEDTLS_MD_INFO_SHA256_STARTS_FUNC mbedtls_sha256_starts_wrap -#define MBEDTLS_MD_INFO_SHA256_UPDATE_FUNC mbedtls_sha224_update_wrap -#define MBEDTLS_MD_INFO_SHA256_FINISH_FUNC mbedtls_sha224_finish_wrap -#define MBEDTLS_MD_INFO_SHA256_DIGEST_FUNC mbedtls_sha256_wrap -#define MBEDTLS_MD_INFO_SHA256_ALLOC_FUNC mbedtls_sha224_ctx_alloc -#if defined(MBEDTLS_MD_SINGLE_HASH) && !defined(MBEDTLS_SHA256_ALT) -/* mbedtls_md_sha256_free() only zeroizes, which is redundant - * because mbedtls_md_context is zeroized in mbedtls_md_init(), - * and the mbedtls_sha256_context is embedded in mbedtls_md_context_t. */ -#define MBEDTLS_MD_INFO_SHA256_FREE_FUNC mbedtls_md_sha256_init_free_dummy -#else -#define MBEDTLS_MD_INFO_SHA256_FREE_FUNC mbedtls_sha224_ctx_free -#endif /* MBEDTLS_MD_SINGLE_HASH && !MBEDTLS_SHA256_ALT */ -#define MBEDTLS_MD_INFO_SHA256_CLONE_FUNC mbedtls_sha224_clone_wrap -#define MBEDTLS_MD_INFO_SHA256_PROCESS_FUNC mbedtls_sha224_process_wrap - -/* - * Helper macros to extract fields from ciphersuites. - */ - -#define MBEDTLS_MD_INFO_CTX_TYPE_T( MD ) MD ## _CTX_TYPE -#define MBEDTLS_MD_INFO_INIT_FUNC_T( MD ) MD ## _INIT_FUNC -#define MBEDTLS_MD_INFO_TYPE_T( MD ) MD ## _TYPE -#define MBEDTLS_MD_INFO_NAME_T( MD ) MD ## _NAME -#define MBEDTLS_MD_INFO_SIZE_T( MD ) MD ## _SIZE -#define MBEDTLS_MD_INFO_BLOCKSIZE_T( MD ) MD ## _BLOCKSIZE -#define MBEDTLS_MD_INFO_STARTS_FUNC_T( MD ) MD ## _STARTS_FUNC -#define MBEDTLS_MD_INFO_UPDATE_FUNC_T( MD ) MD ## _UPDATE_FUNC -#define MBEDTLS_MD_INFO_FINISH_FUNC_T( MD ) MD ## _FINISH_FUNC -#define MBEDTLS_MD_INFO_DIGEST_FUNC_T( MD ) MD ## _DIGEST_FUNC -#define MBEDTLS_MD_INFO_ALLOC_FUNC_T( MD ) MD ## _ALLOC_FUNC -#define MBEDTLS_MD_INFO_FREE_FUNC_T( MD ) MD ## _FREE_FUNC -#define MBEDTLS_MD_INFO_CLONE_FUNC_T( MD ) MD ## _CLONE_FUNC -#define MBEDTLS_MD_INFO_PROCESS_FUNC_T( MD ) MD ## _PROCESS_FUNC - -/* Wrapper around MBEDTLS_MD_INFO_{FIELD}_T() which makes sure that - * the argument is macro-expanded before concatenated with the - * field name. This allows to call these macros as - * MBEDTLS_MD_INFO_{FIELD}( MBEDTLS_MD_SINGLE_HASH ). - * where MBEDTLS_MD_SINGLE_HASH expands to MBEDTLS_MD_INFO_{DIGEST}. */ -#define MBEDTLS_MD_INFO_CTX_TYPE( MD ) MBEDTLS_MD_INFO_CTX_TYPE_T( MD ) -#define MBEDTLS_MD_INFO_INIT_FUNC( MD ) MBEDTLS_MD_INFO_INIT_FUNC_T( MD ) -#define MBEDTLS_MD_INFO_TYPE( MD ) MBEDTLS_MD_INFO_TYPE_T( MD ) -#define MBEDTLS_MD_INFO_NAME( MD ) MBEDTLS_MD_INFO_NAME_T( MD ) -#define MBEDTLS_MD_INFO_SIZE( MD ) MBEDTLS_MD_INFO_SIZE_T( MD ) -#define MBEDTLS_MD_INFO_BLOCKSIZE( MD ) MBEDTLS_MD_INFO_BLOCKSIZE_T( MD ) -#define MBEDTLS_MD_INFO_STARTS_FUNC( MD ) MBEDTLS_MD_INFO_STARTS_FUNC_T( MD ) -#define MBEDTLS_MD_INFO_UPDATE_FUNC( MD ) MBEDTLS_MD_INFO_UPDATE_FUNC_T( MD ) -#define MBEDTLS_MD_INFO_FINISH_FUNC( MD ) MBEDTLS_MD_INFO_FINISH_FUNC_T( MD ) -#define MBEDTLS_MD_INFO_DIGEST_FUNC( MD ) MBEDTLS_MD_INFO_DIGEST_FUNC_T( MD ) -#define MBEDTLS_MD_INFO_ALLOC_FUNC( MD ) MBEDTLS_MD_INFO_ALLOC_FUNC_T( MD ) -#define MBEDTLS_MD_INFO_FREE_FUNC( MD ) MBEDTLS_MD_INFO_FREE_FUNC_T( MD ) -#define MBEDTLS_MD_INFO_CLONE_FUNC( MD ) MBEDTLS_MD_INFO_CLONE_FUNC_T( MD ) -#define MBEDTLS_MD_INFO_PROCESS_FUNC( MD ) MBEDTLS_MD_INFO_PROCESS_FUNC_T( MD ) - /** * Message digest information. * Allows message digest functions to be called in a generic way. */ - -typedef int mbedtls_md_starts_func_t( void *ctx ); -typedef int mbedtls_md_update_func_t( void *ctx, - const unsigned char *input, - size_t ilen ); -typedef int mbedtls_md_finish_func_t( void *ctx, unsigned char *output ); -typedef int mbedtls_md_digest_func_t( const unsigned char *input, - size_t ilen, - unsigned char *output ); -typedef void* mbedtls_md_ctx_alloc_func_t( void ); -typedef void mbedtls_md_ctx_free_func_t( void *ctx ); -typedef void mbedtls_md_clone_func_t( void *st, const void *src ); -typedef int mbedtls_md_process_func_t( void *ctx, - const unsigned char *input ); - -#if !defined(MBEDTLS_MD_SINGLE_HASH) struct mbedtls_md_info_t { /** Digest identifier */ @@ -187,672 +59,57 @@ struct mbedtls_md_info_t int block_size; /** Digest initialisation function */ - mbedtls_md_starts_func_t *starts_func; + int (*starts_func)( void *ctx ); /** Digest update function */ - mbedtls_md_update_func_t *update_func; + int (*update_func)( void *ctx, const unsigned char *input, size_t ilen ); /** Digest finalisation function */ - mbedtls_md_finish_func_t *finish_func; + int (*finish_func)( void *ctx, unsigned char *output ); /** Generic digest function */ - mbedtls_md_digest_func_t *digest_func; + int (*digest_func)( const unsigned char *input, size_t ilen, + unsigned char *output ); /** Allocate a new context */ - mbedtls_md_ctx_alloc_func_t *ctx_alloc_func; + void * (*ctx_alloc_func)( void ); /** Free the given context */ - mbedtls_md_ctx_free_func_t *ctx_free_func; + void (*ctx_free_func)( void *ctx ); /** Clone state from a context */ - mbedtls_md_clone_func_t *clone_func; + void (*clone_func)( void *dst, const void *src ); /** Internal use only */ - mbedtls_md_process_func_t *process_func; + int (*process_func)( void *ctx, const unsigned char *input ); }; -/** - * \brief This macro builds an instance of ::mbedtls_md_info_t - * from an \c MBEDTLS_MD_INFO_XXX identifier. - */ -#define MBEDTLS_MD_INFO( MD ) \ - { MBEDTLS_MD_INFO_TYPE( MD ), \ - MBEDTLS_MD_INFO_NAME( MD ), \ - MBEDTLS_MD_INFO_SIZE( MD ), \ - MBEDTLS_MD_INFO_BLOCKSIZE( MD ), \ - MBEDTLS_MD_INFO_STARTS_FUNC( MD ), \ - MBEDTLS_MD_INFO_UPDATE_FUNC( MD ), \ - MBEDTLS_MD_INFO_FINISH_FUNC( MD ), \ - MBEDTLS_MD_INFO_DIGEST_FUNC( MD ), \ - MBEDTLS_MD_INFO_ALLOC_FUNC( MD ), \ - MBEDTLS_MD_INFO_FREE_FUNC( MD ), \ - MBEDTLS_MD_INFO_CLONE_FUNC( MD ), \ - MBEDTLS_MD_INFO_PROCESS_FUNC( MD ) } - -#endif /* !MBEDTLS_MD_SINGLE_HASH */ - -/* - * - * Definitions of MD information structures for various digests. - * - */ - -/* - * MD-2 - */ - #if defined(MBEDTLS_MD2_C) - -MBEDTLS_MD_WRAPPER int mbedtls_md2_starts_wrap( void *ctx ) -{ - return( mbedtls_md2_starts_ret( (mbedtls_md2_context *) ctx ) ); -} - -MBEDTLS_MD_WRAPPER int mbedtls_md2_update_wrap( void *ctx, const unsigned char *input, - size_t ilen ) -{ - return( mbedtls_md2_update_ret( (mbedtls_md2_context *) ctx, input, ilen ) ); -} - -MBEDTLS_MD_WRAPPER int mbedtls_md2_finish_wrap( void *ctx, unsigned char *output ) -{ - return( mbedtls_md2_finish_ret( (mbedtls_md2_context *) ctx, output ) ); -} - -MBEDTLS_MD_WRAPPER void* mbedtls_md2_ctx_alloc( void ) -{ - void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_md2_context ) ); - - if( ctx != NULL ) - mbedtls_md2_init( (mbedtls_md2_context *) ctx ); - - return( ctx ); -} - -MBEDTLS_MD_WRAPPER void mbedtls_md2_ctx_free( void *ctx ) -{ - mbedtls_md2_free( (mbedtls_md2_context *) ctx ); - mbedtls_free( ctx ); -} - -MBEDTLS_MD_WRAPPER void mbedtls_md2_clone_wrap( void *dst, const void *src ) -{ - mbedtls_md2_clone( (mbedtls_md2_context *) dst, - (const mbedtls_md2_context *) src ); -} - -MBEDTLS_MD_WRAPPER int mbedtls_md2_process_wrap( void *ctx, const unsigned char *data ) -{ - ((void) data); - - return( mbedtls_internal_md2_process( (mbedtls_md2_context *) ctx ) ); -} - -#endif /* MBEDTLS_MD2_C */ - -/* - * MD-4 - */ - +extern const mbedtls_md_info_t mbedtls_md2_info; +#endif #if defined(MBEDTLS_MD4_C) - -MBEDTLS_MD_WRAPPER int mbedtls_md4_starts_wrap( void *ctx ) -{ - return( mbedtls_md4_starts_ret( (mbedtls_md4_context *) ctx ) ); -} - -MBEDTLS_MD_WRAPPER int mbedtls_md4_update_wrap( void *ctx, const unsigned char *input, - size_t ilen ) -{ - return( mbedtls_md4_update_ret( (mbedtls_md4_context *) ctx, input, ilen ) ); -} - -MBEDTLS_MD_WRAPPER int mbedtls_md4_finish_wrap( void *ctx, unsigned char *output ) -{ - return( mbedtls_md4_finish_ret( (mbedtls_md4_context *) ctx, output ) ); -} - -MBEDTLS_MD_WRAPPER void* mbedtls_md4_ctx_alloc( void ) -{ - void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_md4_context ) ); - - if( ctx != NULL ) - mbedtls_md4_init( (mbedtls_md4_context *) ctx ); - - return( ctx ); -} - -MBEDTLS_MD_WRAPPER void mbedtls_md4_ctx_free( void *ctx ) -{ - mbedtls_md4_free( (mbedtls_md4_context *) ctx ); - mbedtls_free( ctx ); -} - -MBEDTLS_MD_WRAPPER void mbedtls_md4_clone_wrap( void *dst, const void *src ) -{ - mbedtls_md4_clone( (mbedtls_md4_context *) dst, - (const mbedtls_md4_context *) src ); -} - -MBEDTLS_MD_WRAPPER int mbedtls_md4_process_wrap( void *ctx, const unsigned char *data ) -{ - return( mbedtls_internal_md4_process( (mbedtls_md4_context *) ctx, data ) ); -} - -#endif /* MBEDTLS_MD4_C */ - -/* - * MD-5 - */ - +extern const mbedtls_md_info_t mbedtls_md4_info; +#endif #if defined(MBEDTLS_MD5_C) - -MBEDTLS_MD_WRAPPER int mbedtls_md5_starts_wrap( void *ctx ) -{ - return( mbedtls_md5_starts_ret( (mbedtls_md5_context *) ctx ) ); -} - -MBEDTLS_MD_WRAPPER int mbedtls_md5_update_wrap( void *ctx, const unsigned char *input, - size_t ilen ) -{ - return( mbedtls_md5_update_ret( (mbedtls_md5_context *) ctx, input, ilen ) ); -} - -MBEDTLS_MD_WRAPPER int mbedtls_md5_finish_wrap( void *ctx, unsigned char *output ) -{ - return( mbedtls_md5_finish_ret( (mbedtls_md5_context *) ctx, output ) ); -} - -MBEDTLS_MD_WRAPPER void* mbedtls_md5_ctx_alloc( void ) -{ - void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_md5_context ) ); - - if( ctx != NULL ) - mbedtls_md5_init( (mbedtls_md5_context *) ctx ); - - return( ctx ); -} - -MBEDTLS_MD_WRAPPER void mbedtls_md5_ctx_free( void *ctx ) -{ - mbedtls_md5_free( (mbedtls_md5_context *) ctx ); - mbedtls_free( ctx ); -} - -MBEDTLS_MD_WRAPPER void mbedtls_md5_clone_wrap( void *dst, const void *src ) -{ - mbedtls_md5_clone( (mbedtls_md5_context *) dst, - (const mbedtls_md5_context *) src ); -} - -MBEDTLS_MD_WRAPPER int mbedtls_md5_process_wrap( void *ctx, const unsigned char *data ) -{ - return( mbedtls_internal_md5_process( (mbedtls_md5_context *) ctx, data ) ); -} - -#endif /* MBEDTLS_MD5_C */ - -/* - * RIPEMD-160 - */ - +extern const mbedtls_md_info_t mbedtls_md5_info; +#endif #if defined(MBEDTLS_RIPEMD160_C) - -MBEDTLS_MD_WRAPPER int mbedtls_ripemd160_starts_wrap( void *ctx ) -{ - return( mbedtls_ripemd160_starts_ret( (mbedtls_ripemd160_context *) ctx ) ); -} - -MBEDTLS_MD_WRAPPER int mbedtls_ripemd160_update_wrap( void *ctx, const unsigned char *input, - size_t ilen ) -{ - return( mbedtls_ripemd160_update_ret( (mbedtls_ripemd160_context *) ctx, - input, ilen ) ); -} - -MBEDTLS_MD_WRAPPER int mbedtls_ripemd160_finish_wrap( void *ctx, unsigned char *output ) -{ - return( mbedtls_ripemd160_finish_ret( (mbedtls_ripemd160_context *) ctx, - output ) ); -} - -MBEDTLS_MD_WRAPPER void* mbedtls_ripemd160_ctx_alloc( void ) -{ - void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ripemd160_context ) ); - - if( ctx != NULL ) - mbedtls_ripemd160_init( (mbedtls_ripemd160_context *) ctx ); - - return( ctx ); -} - -MBEDTLS_MD_WRAPPER void mbedtls_ripemd160_ctx_free( void *ctx ) -{ - mbedtls_ripemd160_free( (mbedtls_ripemd160_context *) ctx ); - mbedtls_free( ctx ); -} - -MBEDTLS_MD_WRAPPER void mbedtls_ripemd160_clone_wrap( void *dst, const void *src ) -{ - mbedtls_ripemd160_clone( (mbedtls_ripemd160_context *) dst, - (const mbedtls_ripemd160_context *) src ); -} - -MBEDTLS_MD_WRAPPER int mbedtls_ripemd160_process_wrap( void *ctx, const unsigned char *data ) -{ - return( mbedtls_internal_ripemd160_process( - (mbedtls_ripemd160_context *) ctx, data ) ); -} - -#endif /* MBEDTLS_RIPEMD160_C */ - -/* - * SHA-1 - */ - +extern const mbedtls_md_info_t mbedtls_ripemd160_info; +#endif #if defined(MBEDTLS_SHA1_C) - -MBEDTLS_MD_WRAPPER int mbedtls_sha1_starts_wrap( void *ctx ) -{ - return( mbedtls_sha1_starts_ret( (mbedtls_sha1_context *) ctx ) ); -} - -MBEDTLS_MD_WRAPPER int mbedtls_sha1_update_wrap( void *ctx, const unsigned char *input, - size_t ilen ) -{ - return( mbedtls_sha1_update_ret( (mbedtls_sha1_context *) ctx, - input, ilen ) ); -} - -MBEDTLS_MD_WRAPPER int mbedtls_sha1_finish_wrap( void *ctx, unsigned char *output ) -{ - return( mbedtls_sha1_finish_ret( (mbedtls_sha1_context *) ctx, output ) ); -} - -MBEDTLS_MD_WRAPPER void* mbedtls_sha1_ctx_alloc( void ) -{ - void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_sha1_context ) ); - - if( ctx != NULL ) - mbedtls_sha1_init( (mbedtls_sha1_context *) ctx ); - - return( ctx ); -} - -MBEDTLS_MD_WRAPPER void mbedtls_sha1_clone_wrap( void *dst, const void *src ) -{ - mbedtls_sha1_clone( (mbedtls_sha1_context *) dst, - (const mbedtls_sha1_context *) src ); -} - -MBEDTLS_MD_WRAPPER void mbedtls_sha1_ctx_free( void *ctx ) -{ - mbedtls_sha1_free( (mbedtls_sha1_context *) ctx ); - mbedtls_free( ctx ); -} - -MBEDTLS_MD_WRAPPER int mbedtls_sha1_process_wrap( void *ctx, const unsigned char *data ) -{ - return( mbedtls_internal_sha1_process( (mbedtls_sha1_context *) ctx, - data ) ); -} - -#endif /* MBEDTLS_SHA1_C */ - -/* - * SHA-224 and SHA-256 - */ - +extern const mbedtls_md_info_t mbedtls_sha1_info; +#endif #if defined(MBEDTLS_SHA256_C) - -#if !defined(MBEDTLS_SHA256_NO_SHA224) -MBEDTLS_MD_WRAPPER int mbedtls_sha224_starts_wrap( void *ctx ) -{ - return( mbedtls_sha256_starts_ret( (mbedtls_sha256_context *) ctx, 1 ) ); -} -#endif /* !MBEDTLS_SHA256_NO_SHA224 */ - -MBEDTLS_MD_WRAPPER int mbedtls_sha224_update_wrap( void *ctx, const unsigned char *input, - size_t ilen ) -{ - return( mbedtls_sha256_update_ret( (mbedtls_sha256_context *) ctx, - input, ilen ) ); -} - -MBEDTLS_MD_WRAPPER int mbedtls_sha224_finish_wrap( void *ctx, unsigned char *output ) -{ - return( mbedtls_sha256_finish_ret( (mbedtls_sha256_context *) ctx, - output ) ); -} - -#if !defined(MBEDTLS_SHA256_NO_SHA224) -MBEDTLS_MD_WRAPPER int mbedtls_sha224_wrap( const unsigned char *input, size_t ilen, - unsigned char *output ) -{ - return( mbedtls_sha256_ret( input, ilen, output, 1 ) ); -} -#endif /* !MBEDTLS_SHA256_NO_SHA224 */ - -MBEDTLS_MD_WRAPPER void* mbedtls_sha224_ctx_alloc( void ) -{ - void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_sha256_context ) ); - - if( ctx != NULL ) - mbedtls_sha256_init( (mbedtls_sha256_context *) ctx ); - - return( ctx ); -} - -MBEDTLS_MD_WRAPPER void mbedtls_sha224_ctx_free( void *ctx ) -{ - mbedtls_sha256_free( (mbedtls_sha256_context *) ctx ); - mbedtls_free( ctx ); -} - -MBEDTLS_MD_WRAPPER void mbedtls_sha224_clone_wrap( void *dst, const void *src ) -{ - mbedtls_sha256_clone( (mbedtls_sha256_context *) dst, - (const mbedtls_sha256_context *) src ); -} - -MBEDTLS_MD_WRAPPER int mbedtls_sha224_process_wrap( void *ctx, const unsigned char *data ) -{ - return( mbedtls_internal_sha256_process( (mbedtls_sha256_context *) ctx, - data ) ); -} - -MBEDTLS_MD_WRAPPER int mbedtls_sha256_starts_wrap( void *ctx ) -{ - return( mbedtls_sha256_starts_ret( (mbedtls_sha256_context *) ctx, 0 ) ); -} - -MBEDTLS_MD_WRAPPER int mbedtls_sha256_wrap( const unsigned char *input, size_t ilen, - unsigned char *output ) -{ - return( mbedtls_sha256_ret( input, ilen, output, 0 ) ); -} - -#endif /* MBEDTLS_SHA256_C */ - -/* - * SHA-384 and SHA-512 - */ - +extern const mbedtls_md_info_t mbedtls_sha224_info; +extern const mbedtls_md_info_t mbedtls_sha256_info; +#endif #if defined(MBEDTLS_SHA512_C) - -MBEDTLS_MD_WRAPPER int mbedtls_sha384_starts_wrap( void *ctx ) -{ - return( mbedtls_sha512_starts_ret( (mbedtls_sha512_context *) ctx, 1 ) ); -} - -MBEDTLS_MD_WRAPPER int mbedtls_sha384_update_wrap( void *ctx, const unsigned char *input, - size_t ilen ) -{ - return( mbedtls_sha512_update_ret( (mbedtls_sha512_context *) ctx, - input, ilen ) ); -} - -MBEDTLS_MD_WRAPPER int mbedtls_sha384_finish_wrap( void *ctx, unsigned char *output ) -{ - return( mbedtls_sha512_finish_ret( (mbedtls_sha512_context *) ctx, - output ) ); -} - -MBEDTLS_MD_WRAPPER int mbedtls_sha384_wrap( const unsigned char *input, size_t ilen, - unsigned char *output ) -{ - return( mbedtls_sha512_ret( input, ilen, output, 1 ) ); -} - -MBEDTLS_MD_WRAPPER void* mbedtls_sha384_ctx_alloc( void ) -{ - void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_sha512_context ) ); - - if( ctx != NULL ) - mbedtls_sha512_init( (mbedtls_sha512_context *) ctx ); - - return( ctx ); -} - -MBEDTLS_MD_WRAPPER void mbedtls_sha384_ctx_free( void *ctx ) -{ - mbedtls_sha512_free( (mbedtls_sha512_context *) ctx ); - mbedtls_free( ctx ); -} - -MBEDTLS_MD_WRAPPER void mbedtls_sha384_clone_wrap( void *dst, const void *src ) -{ - mbedtls_sha512_clone( (mbedtls_sha512_context *) dst, - (const mbedtls_sha512_context *) src ); -} - -MBEDTLS_MD_WRAPPER int mbedtls_sha384_process_wrap( void *ctx, const unsigned char *data ) -{ - return( mbedtls_internal_sha512_process( (mbedtls_sha512_context *) ctx, - data ) ); -} - -MBEDTLS_MD_WRAPPER int mbedtls_sha512_starts_wrap( void *ctx ) -{ - return( mbedtls_sha512_starts_ret( (mbedtls_sha512_context *) ctx, 0 ) ); -} - -MBEDTLS_MD_WRAPPER int mbedtls_sha512_wrap( const unsigned char *input, size_t ilen, - unsigned char *output ) -{ - return( mbedtls_sha512_ret( input, ilen, output, 0 ) ); -} - -#endif /* MBEDTLS_SHA512_C */ - -/* - * Getter functions for MD info structure. - */ - -#if !defined(MBEDTLS_MD_SINGLE_HASH) - -MBEDTLS_ALWAYS_INLINE static inline mbedtls_md_type_t mbedtls_md_info_type( - mbedtls_md_handle_t info ) -{ - return( info->type ); -} - -MBEDTLS_ALWAYS_INLINE static inline const char * mbedtls_md_info_name( - mbedtls_md_handle_t info ) -{ - return( info->name ); -} - -MBEDTLS_ALWAYS_INLINE static inline int mbedtls_md_info_size( - mbedtls_md_handle_t info ) -{ - return( info->size ); -} - -MBEDTLS_ALWAYS_INLINE static inline int mbedtls_md_info_block_size( - mbedtls_md_handle_t info ) -{ - return( info->block_size ); -} - -MBEDTLS_ALWAYS_INLINE static inline int mbedtls_md_info_starts( - mbedtls_md_handle_t info, - void *ctx ) -{ - return( info->starts_func( ctx ) ); -} - -MBEDTLS_ALWAYS_INLINE static inline int mbedtls_md_info_update( - mbedtls_md_handle_t info, - void *ctx, - const unsigned char *input, - size_t ilen ) -{ - return( info->update_func( ctx, input, ilen ) ); -} - -MBEDTLS_ALWAYS_INLINE static inline int mbedtls_md_info_finish( - mbedtls_md_handle_t info, - void *ctx, - unsigned char *output ) -{ - return( info->finish_func( ctx, output ) ); -} - -MBEDTLS_ALWAYS_INLINE static inline int mbedtls_md_info_digest( - mbedtls_md_handle_t info, - const unsigned char *input, - size_t ilen, - unsigned char *output ) -{ - return( info->digest_func( input, ilen, output ) ); -} - -MBEDTLS_ALWAYS_INLINE static inline void* mbedtls_md_info_ctx_alloc( - mbedtls_md_handle_t info ) -{ - return( info->ctx_alloc_func() ); -} - -MBEDTLS_ALWAYS_INLINE static inline void mbedtls_md_info_ctx_free( - mbedtls_md_handle_t info, - void *ctx ) -{ - info->ctx_free_func( ctx ); -} - -MBEDTLS_ALWAYS_INLINE static inline void mbedtls_md_info_clone( - mbedtls_md_handle_t info, - void *dst, - const void *src ) -{ - info->clone_func( dst, src ); -} - -MBEDTLS_ALWAYS_INLINE static inline int mbedtls_md_info_process( - mbedtls_md_handle_t info, - void *ctx, - const unsigned char *input ) -{ - return( info->process_func( ctx, input ) ); -} - -#else /* !MBEDTLS_MD_SINGLE_HASH */ - -MBEDTLS_ALWAYS_INLINE static inline mbedtls_md_type_t mbedtls_md_info_type( - mbedtls_md_handle_t info ) -{ - ((void) info); - return( MBEDTLS_MD_INFO_TYPE( MBEDTLS_MD_SINGLE_HASH ) ); -} - -MBEDTLS_ALWAYS_INLINE static inline const char * mbedtls_md_info_name( - mbedtls_md_handle_t info ) -{ - ((void) info); - return( MBEDTLS_MD_INFO_NAME( MBEDTLS_MD_SINGLE_HASH ) ); -} - -MBEDTLS_ALWAYS_INLINE static inline int mbedtls_md_info_size( - mbedtls_md_handle_t info ) -{ - ((void) info); - return( MBEDTLS_MD_INFO_SIZE( MBEDTLS_MD_SINGLE_HASH ) ); -} - -MBEDTLS_ALWAYS_INLINE static inline int mbedtls_md_info_block_size( - mbedtls_md_handle_t info ) -{ - ((void) info); - return( MBEDTLS_MD_INFO_BLOCKSIZE( MBEDTLS_MD_SINGLE_HASH ) ); -} - -MBEDTLS_ALWAYS_INLINE static inline int mbedtls_md_info_starts( - mbedtls_md_handle_t info, - void *ctx ) -{ - ((void) info); - return( MBEDTLS_MD_INFO_STARTS_FUNC( MBEDTLS_MD_SINGLE_HASH )( ctx ) ); -} - -MBEDTLS_ALWAYS_INLINE static inline int mbedtls_md_info_update( - mbedtls_md_handle_t info, - void *ctx, - const unsigned char *input, - size_t ilen ) -{ - ((void) info); - return( MBEDTLS_MD_INFO_UPDATE_FUNC( MBEDTLS_MD_SINGLE_HASH ) - ( ctx, input, ilen ) ); -} - -MBEDTLS_ALWAYS_INLINE static inline void mbedtls_md_info_init( - mbedtls_md_handle_t info, - void *ctx ) -{ - ((void) info); - MBEDTLS_MD_INFO_INIT_FUNC( MBEDTLS_MD_SINGLE_HASH )( ctx ); -} - -MBEDTLS_ALWAYS_INLINE static inline int mbedtls_md_info_finish( - mbedtls_md_handle_t info, - void *ctx, - unsigned char *output ) -{ - ((void) info); - return( MBEDTLS_MD_INFO_FINISH_FUNC( MBEDTLS_MD_SINGLE_HASH ) - ( ctx, output ) ); -} - -MBEDTLS_ALWAYS_INLINE static inline int mbedtls_md_info_digest( - mbedtls_md_handle_t info, - const unsigned char *input, - size_t ilen, - unsigned char *output ) -{ - ((void) info); - return( MBEDTLS_MD_INFO_DIGEST_FUNC( MBEDTLS_MD_SINGLE_HASH ) - ( input, ilen, output ) ); -} - -MBEDTLS_ALWAYS_INLINE static inline void* mbedtls_md_info_ctx_alloc( - mbedtls_md_handle_t info ) -{ - ((void) info); - return( MBEDTLS_MD_INFO_ALLOC_FUNC( MBEDTLS_MD_SINGLE_HASH )() ); -} - -MBEDTLS_ALWAYS_INLINE static inline void mbedtls_md_info_ctx_free( - mbedtls_md_handle_t info, - void *ctx ) -{ - ((void) info); - MBEDTLS_MD_INFO_FREE_FUNC( MBEDTLS_MD_SINGLE_HASH )( ctx ); -} - -MBEDTLS_ALWAYS_INLINE static inline void mbedtls_md_info_clone( - mbedtls_md_handle_t info, - void *dst, - const void *src ) -{ - ((void) info); - MBEDTLS_MD_INFO_CLONE_FUNC( MBEDTLS_MD_SINGLE_HASH )( dst, src ); -} - -MBEDTLS_ALWAYS_INLINE static inline int mbedtls_md_info_process( - mbedtls_md_handle_t info, - void *ctx, - const unsigned char *input ) -{ - ((void) info); - return( MBEDTLS_MD_INFO_PROCESS_FUNC( MBEDTLS_MD_SINGLE_HASH ) - ( ctx, input ) ); -} - -#endif /* MBEDTLS_MD_SINGLE_HASH */ +extern const mbedtls_md_info_t mbedtls_sha384_info; +extern const mbedtls_md_info_t mbedtls_sha512_info; +#endif #ifdef __cplusplus } #endif -#endif /* MBEDTLS_MD_INTERNAL_H */ +#endif /* MBEDTLS_MD_WRAP_H */ diff --git a/APP_Framework/Framework/security/mbedtls/md_wrap.c b/APP_Framework/Framework/security/mbedtls/md_wrap.c new file mode 100644 index 000000000..5f4e33a99 --- /dev/null +++ b/APP_Framework/Framework/security/mbedtls/md_wrap.c @@ -0,0 +1,586 @@ +/** + * \file md_wrap.c + * + * \brief Generic message digest wrapper for mbed TLS + * + * \author Adriaan de Jong + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_MD_C) + +#include "md_internal.h" + +#if defined(MBEDTLS_MD2_C) +#include "md2.h" +#endif + +#if defined(MBEDTLS_MD4_C) +#include "md4.h" +#endif + +#if defined(MBEDTLS_MD5_C) +#include "md5.h" +#endif + +#if defined(MBEDTLS_RIPEMD160_C) +#include "ripemd160.h" +#endif + +#if defined(MBEDTLS_SHA1_C) +#include "sha1.h" +#endif + +#if defined(MBEDTLS_SHA256_C) +#include "sha256.h" +#endif + +#if defined(MBEDTLS_SHA512_C) +#include "sha512.h" +#endif + +#if defined(MBEDTLS_PLATFORM_C) +#include "platform.h" +#else +#include +#define mbedtls_calloc calloc +#define mbedtls_free free +#endif + +#if defined(MBEDTLS_MD2_C) + +static int md2_starts_wrap( void *ctx ) +{ + return( mbedtls_md2_starts_ret( (mbedtls_md2_context *) ctx ) ); +} + +static int md2_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) +{ + return( mbedtls_md2_update_ret( (mbedtls_md2_context *) ctx, input, ilen ) ); +} + +static int md2_finish_wrap( void *ctx, unsigned char *output ) +{ + return( mbedtls_md2_finish_ret( (mbedtls_md2_context *) ctx, output ) ); +} + +static void *md2_ctx_alloc( void ) +{ + void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_md2_context ) ); + + if( ctx != NULL ) + mbedtls_md2_init( (mbedtls_md2_context *) ctx ); + + return( ctx ); +} + +static void md2_ctx_free( void *ctx ) +{ + mbedtls_md2_free( (mbedtls_md2_context *) ctx ); + mbedtls_free( ctx ); +} + +static void md2_clone_wrap( void *dst, const void *src ) +{ + mbedtls_md2_clone( (mbedtls_md2_context *) dst, + (const mbedtls_md2_context *) src ); +} + +static int md2_process_wrap( void *ctx, const unsigned char *data ) +{ + ((void) data); + + return( mbedtls_internal_md2_process( (mbedtls_md2_context *) ctx ) ); +} + +const mbedtls_md_info_t mbedtls_md2_info = { + MBEDTLS_MD_MD2, + "MD2", + 16, + 16, + md2_starts_wrap, + md2_update_wrap, + md2_finish_wrap, + mbedtls_md2_ret, + md2_ctx_alloc, + md2_ctx_free, + md2_clone_wrap, + md2_process_wrap, +}; + +#endif /* MBEDTLS_MD2_C */ + +#if defined(MBEDTLS_MD4_C) + +static int md4_starts_wrap( void *ctx ) +{ + return( mbedtls_md4_starts_ret( (mbedtls_md4_context *) ctx ) ); +} + +static int md4_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) +{ + return( mbedtls_md4_update_ret( (mbedtls_md4_context *) ctx, input, ilen ) ); +} + +static int md4_finish_wrap( void *ctx, unsigned char *output ) +{ + return( mbedtls_md4_finish_ret( (mbedtls_md4_context *) ctx, output ) ); +} + +static void *md4_ctx_alloc( void ) +{ + void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_md4_context ) ); + + if( ctx != NULL ) + mbedtls_md4_init( (mbedtls_md4_context *) ctx ); + + return( ctx ); +} + +static void md4_ctx_free( void *ctx ) +{ + mbedtls_md4_free( (mbedtls_md4_context *) ctx ); + mbedtls_free( ctx ); +} + +static void md4_clone_wrap( void *dst, const void *src ) +{ + mbedtls_md4_clone( (mbedtls_md4_context *) dst, + (const mbedtls_md4_context *) src ); +} + +static int md4_process_wrap( void *ctx, const unsigned char *data ) +{ + return( mbedtls_internal_md4_process( (mbedtls_md4_context *) ctx, data ) ); +} + +const mbedtls_md_info_t mbedtls_md4_info = { + MBEDTLS_MD_MD4, + "MD4", + 16, + 64, + md4_starts_wrap, + md4_update_wrap, + md4_finish_wrap, + mbedtls_md4_ret, + md4_ctx_alloc, + md4_ctx_free, + md4_clone_wrap, + md4_process_wrap, +}; + +#endif /* MBEDTLS_MD4_C */ + +#if defined(MBEDTLS_MD5_C) + +static int md5_starts_wrap( void *ctx ) +{ + return( mbedtls_md5_starts_ret( (mbedtls_md5_context *) ctx ) ); +} + +static int md5_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) +{ + return( mbedtls_md5_update_ret( (mbedtls_md5_context *) ctx, input, ilen ) ); +} + +static int md5_finish_wrap( void *ctx, unsigned char *output ) +{ + return( mbedtls_md5_finish_ret( (mbedtls_md5_context *) ctx, output ) ); +} + +static void *md5_ctx_alloc( void ) +{ + void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_md5_context ) ); + + if( ctx != NULL ) + mbedtls_md5_init( (mbedtls_md5_context *) ctx ); + + return( ctx ); +} + +static void md5_ctx_free( void *ctx ) +{ + mbedtls_md5_free( (mbedtls_md5_context *) ctx ); + mbedtls_free( ctx ); +} + +static void md5_clone_wrap( void *dst, const void *src ) +{ + mbedtls_md5_clone( (mbedtls_md5_context *) dst, + (const mbedtls_md5_context *) src ); +} + +static int md5_process_wrap( void *ctx, const unsigned char *data ) +{ + return( mbedtls_internal_md5_process( (mbedtls_md5_context *) ctx, data ) ); +} + +const mbedtls_md_info_t mbedtls_md5_info = { + MBEDTLS_MD_MD5, + "MD5", + 16, + 64, + md5_starts_wrap, + md5_update_wrap, + md5_finish_wrap, + mbedtls_md5_ret, + md5_ctx_alloc, + md5_ctx_free, + md5_clone_wrap, + md5_process_wrap, +}; + +#endif /* MBEDTLS_MD5_C */ + +#if defined(MBEDTLS_RIPEMD160_C) + +static int ripemd160_starts_wrap( void *ctx ) +{ + return( mbedtls_ripemd160_starts_ret( (mbedtls_ripemd160_context *) ctx ) ); +} + +static int ripemd160_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) +{ + return( mbedtls_ripemd160_update_ret( (mbedtls_ripemd160_context *) ctx, + input, ilen ) ); +} + +static int ripemd160_finish_wrap( void *ctx, unsigned char *output ) +{ + return( mbedtls_ripemd160_finish_ret( (mbedtls_ripemd160_context *) ctx, + output ) ); +} + +static void *ripemd160_ctx_alloc( void ) +{ + void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ripemd160_context ) ); + + if( ctx != NULL ) + mbedtls_ripemd160_init( (mbedtls_ripemd160_context *) ctx ); + + return( ctx ); +} + +static void ripemd160_ctx_free( void *ctx ) +{ + mbedtls_ripemd160_free( (mbedtls_ripemd160_context *) ctx ); + mbedtls_free( ctx ); +} + +static void ripemd160_clone_wrap( void *dst, const void *src ) +{ + mbedtls_ripemd160_clone( (mbedtls_ripemd160_context *) dst, + (const mbedtls_ripemd160_context *) src ); +} + +static int ripemd160_process_wrap( void *ctx, const unsigned char *data ) +{ + return( mbedtls_internal_ripemd160_process( + (mbedtls_ripemd160_context *) ctx, data ) ); +} + +const mbedtls_md_info_t mbedtls_ripemd160_info = { + MBEDTLS_MD_RIPEMD160, + "RIPEMD160", + 20, + 64, + ripemd160_starts_wrap, + ripemd160_update_wrap, + ripemd160_finish_wrap, + mbedtls_ripemd160_ret, + ripemd160_ctx_alloc, + ripemd160_ctx_free, + ripemd160_clone_wrap, + ripemd160_process_wrap, +}; + +#endif /* MBEDTLS_RIPEMD160_C */ + +#if defined(MBEDTLS_SHA1_C) + +static int sha1_starts_wrap( void *ctx ) +{ + return( mbedtls_sha1_starts_ret( (mbedtls_sha1_context *) ctx ) ); +} + +static int sha1_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) +{ + return( mbedtls_sha1_update_ret( (mbedtls_sha1_context *) ctx, + input, ilen ) ); +} + +static int sha1_finish_wrap( void *ctx, unsigned char *output ) +{ + return( mbedtls_sha1_finish_ret( (mbedtls_sha1_context *) ctx, output ) ); +} + +static void *sha1_ctx_alloc( void ) +{ + void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_sha1_context ) ); + + if( ctx != NULL ) + mbedtls_sha1_init( (mbedtls_sha1_context *) ctx ); + + return( ctx ); +} + +static void sha1_clone_wrap( void *dst, const void *src ) +{ + mbedtls_sha1_clone( (mbedtls_sha1_context *) dst, + (const mbedtls_sha1_context *) src ); +} + +static void sha1_ctx_free( void *ctx ) +{ + mbedtls_sha1_free( (mbedtls_sha1_context *) ctx ); + mbedtls_free( ctx ); +} + +static int sha1_process_wrap( void *ctx, const unsigned char *data ) +{ + return( mbedtls_internal_sha1_process( (mbedtls_sha1_context *) ctx, + data ) ); +} + +const mbedtls_md_info_t mbedtls_sha1_info = { + MBEDTLS_MD_SHA1, + "SHA1", + 20, + 64, + sha1_starts_wrap, + sha1_update_wrap, + sha1_finish_wrap, + mbedtls_sha1_ret, + sha1_ctx_alloc, + sha1_ctx_free, + sha1_clone_wrap, + sha1_process_wrap, +}; + +#endif /* MBEDTLS_SHA1_C */ + +/* + * Wrappers for generic message digests + */ +#if defined(MBEDTLS_SHA256_C) + +static int sha224_starts_wrap( void *ctx ) +{ + return( mbedtls_sha256_starts_ret( (mbedtls_sha256_context *) ctx, 1 ) ); +} + +static int sha224_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) +{ + return( mbedtls_sha256_update_ret( (mbedtls_sha256_context *) ctx, + input, ilen ) ); +} + +static int sha224_finish_wrap( void *ctx, unsigned char *output ) +{ + return( mbedtls_sha256_finish_ret( (mbedtls_sha256_context *) ctx, + output ) ); +} + +static int sha224_wrap( const unsigned char *input, size_t ilen, + unsigned char *output ) +{ + return( mbedtls_sha256_ret( input, ilen, output, 1 ) ); +} + +static void *sha224_ctx_alloc( void ) +{ + void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_sha256_context ) ); + + if( ctx != NULL ) + mbedtls_sha256_init( (mbedtls_sha256_context *) ctx ); + + return( ctx ); +} + +static void sha224_ctx_free( void *ctx ) +{ + mbedtls_sha256_free( (mbedtls_sha256_context *) ctx ); + mbedtls_free( ctx ); +} + +static void sha224_clone_wrap( void *dst, const void *src ) +{ + mbedtls_sha256_clone( (mbedtls_sha256_context *) dst, + (const mbedtls_sha256_context *) src ); +} + +static int sha224_process_wrap( void *ctx, const unsigned char *data ) +{ + return( mbedtls_internal_sha256_process( (mbedtls_sha256_context *) ctx, + data ) ); +} + +const mbedtls_md_info_t mbedtls_sha224_info = { + MBEDTLS_MD_SHA224, + "SHA224", + 28, + 64, + sha224_starts_wrap, + sha224_update_wrap, + sha224_finish_wrap, + sha224_wrap, + sha224_ctx_alloc, + sha224_ctx_free, + sha224_clone_wrap, + sha224_process_wrap, +}; + +static int sha256_starts_wrap( void *ctx ) +{ + return( mbedtls_sha256_starts_ret( (mbedtls_sha256_context *) ctx, 0 ) ); +} + +static int sha256_wrap( const unsigned char *input, size_t ilen, + unsigned char *output ) +{ + return( mbedtls_sha256_ret( input, ilen, output, 0 ) ); +} + +const mbedtls_md_info_t mbedtls_sha256_info = { + MBEDTLS_MD_SHA256, + "SHA256", + 32, + 64, + sha256_starts_wrap, + sha224_update_wrap, + sha224_finish_wrap, + sha256_wrap, + sha224_ctx_alloc, + sha224_ctx_free, + sha224_clone_wrap, + sha224_process_wrap, +}; + +#endif /* MBEDTLS_SHA256_C */ + +#if defined(MBEDTLS_SHA512_C) + +static int sha384_starts_wrap( void *ctx ) +{ + return( mbedtls_sha512_starts_ret( (mbedtls_sha512_context *) ctx, 1 ) ); +} + +static int sha384_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) +{ + return( mbedtls_sha512_update_ret( (mbedtls_sha512_context *) ctx, + input, ilen ) ); +} + +static int sha384_finish_wrap( void *ctx, unsigned char *output ) +{ + return( mbedtls_sha512_finish_ret( (mbedtls_sha512_context *) ctx, + output ) ); +} + +static int sha384_wrap( const unsigned char *input, size_t ilen, + unsigned char *output ) +{ + return( mbedtls_sha512_ret( input, ilen, output, 1 ) ); +} + +static void *sha384_ctx_alloc( void ) +{ + void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_sha512_context ) ); + + if( ctx != NULL ) + mbedtls_sha512_init( (mbedtls_sha512_context *) ctx ); + + return( ctx ); +} + +static void sha384_ctx_free( void *ctx ) +{ + mbedtls_sha512_free( (mbedtls_sha512_context *) ctx ); + mbedtls_free( ctx ); +} + +static void sha384_clone_wrap( void *dst, const void *src ) +{ + mbedtls_sha512_clone( (mbedtls_sha512_context *) dst, + (const mbedtls_sha512_context *) src ); +} + +static int sha384_process_wrap( void *ctx, const unsigned char *data ) +{ + return( mbedtls_internal_sha512_process( (mbedtls_sha512_context *) ctx, + data ) ); +} + +const mbedtls_md_info_t mbedtls_sha384_info = { + MBEDTLS_MD_SHA384, + "SHA384", + 48, + 128, + sha384_starts_wrap, + sha384_update_wrap, + sha384_finish_wrap, + sha384_wrap, + sha384_ctx_alloc, + sha384_ctx_free, + sha384_clone_wrap, + sha384_process_wrap, +}; + +static int sha512_starts_wrap( void *ctx ) +{ + return( mbedtls_sha512_starts_ret( (mbedtls_sha512_context *) ctx, 0 ) ); +} + +static int sha512_wrap( const unsigned char *input, size_t ilen, + unsigned char *output ) +{ + return( mbedtls_sha512_ret( input, ilen, output, 0 ) ); +} + +const mbedtls_md_info_t mbedtls_sha512_info = { + MBEDTLS_MD_SHA512, + "SHA512", + 64, + 128, + sha512_starts_wrap, + sha384_update_wrap, + sha384_finish_wrap, + sha512_wrap, + sha384_ctx_alloc, + sha384_ctx_free, + sha384_clone_wrap, + sha384_process_wrap, +}; + +#endif /* MBEDTLS_SHA512_C */ + +#endif /* MBEDTLS_MD_C */ diff --git a/APP_Framework/Framework/security/mbedtls/memory_buffer_alloc.c b/APP_Framework/Framework/security/mbedtls/memory_buffer_alloc.c new file mode 100644 index 000000000..77f021d1d --- /dev/null +++ b/APP_Framework/Framework/security/mbedtls/memory_buffer_alloc.c @@ -0,0 +1,754 @@ +/* + * Buffer-based memory allocator + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) +#include "memory_buffer_alloc.h" + +/* No need for the header guard as MBEDTLS_MEMORY_BUFFER_ALLOC_C + is dependent upon MBEDTLS_PLATFORM_C */ +#include "platform.h" + +#include + +#if defined(MBEDTLS_MEMORY_BACKTRACE) +#include +#endif + +#if defined(MBEDTLS_THREADING_C) +#include "threading.h" +#endif + +/* 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 MAGIC1 0xFF00AA55 +#define MAGIC2 0xEE119966 +#define MAX_BT 20 + +typedef struct _memory_header memory_header; +struct _memory_header +{ + size_t magic1; + size_t size; + size_t alloc; + memory_header *prev; + memory_header *next; + memory_header *prev_free; + memory_header *next_free; +#if defined(MBEDTLS_MEMORY_BACKTRACE) + char **trace; + size_t trace_count; +#endif + size_t magic2; +}; + +typedef struct +{ + unsigned char *buf; + size_t len; + memory_header *first; + memory_header *first_free; + int verify; +#if defined(MBEDTLS_MEMORY_DEBUG) + size_t alloc_count; + size_t free_count; + size_t total_used; + size_t maximum_used; + size_t header_count; + size_t maximum_header_count; +#endif +#if defined(MBEDTLS_THREADING_C) + mbedtls_threading_mutex_t mutex; +#endif +} +buffer_alloc_ctx; + +static buffer_alloc_ctx heap; + +#if defined(MBEDTLS_MEMORY_DEBUG) +static void debug_header( memory_header *hdr ) +{ +#if defined(MBEDTLS_MEMORY_BACKTRACE) + size_t i; +#endif + + mbedtls_fprintf( stderr, "HDR: PTR(%10zu), PREV(%10zu), NEXT(%10zu), " + "ALLOC(%zu), SIZE(%10zu)\n", + (size_t) hdr, (size_t) hdr->prev, (size_t) hdr->next, + hdr->alloc, hdr->size ); + mbedtls_fprintf( stderr, " FPREV(%10zu), FNEXT(%10zu)\n", + (size_t) hdr->prev_free, (size_t) hdr->next_free ); + +#if defined(MBEDTLS_MEMORY_BACKTRACE) + mbedtls_fprintf( stderr, "TRACE: \n" ); + for( i = 0; i < hdr->trace_count; i++ ) + mbedtls_fprintf( stderr, "%s\n", hdr->trace[i] ); + mbedtls_fprintf( stderr, "\n" ); +#endif +} + +static void debug_chain() +{ + memory_header *cur = heap.first; + + mbedtls_fprintf( stderr, "\nBlock list\n" ); + while( cur != NULL ) + { + debug_header( cur ); + cur = cur->next; + } + + mbedtls_fprintf( stderr, "Free list\n" ); + cur = heap.first_free; + + while( cur != NULL ) + { + debug_header( cur ); + cur = cur->next_free; + } +} +#endif /* MBEDTLS_MEMORY_DEBUG */ + +static int verify_header( memory_header *hdr ) +{ + if( hdr->magic1 != MAGIC1 ) + { +#if defined(MBEDTLS_MEMORY_DEBUG) + mbedtls_fprintf( stderr, "FATAL: MAGIC1 mismatch\n" ); +#endif + return( 1 ); + } + + if( hdr->magic2 != MAGIC2 ) + { +#if defined(MBEDTLS_MEMORY_DEBUG) + mbedtls_fprintf( stderr, "FATAL: MAGIC2 mismatch\n" ); +#endif + return( 1 ); + } + + if( hdr->alloc > 1 ) + { +#if defined(MBEDTLS_MEMORY_DEBUG) + mbedtls_fprintf( stderr, "FATAL: alloc has illegal value\n" ); +#endif + return( 1 ); + } + + if( hdr->prev != NULL && hdr->prev == hdr->next ) + { +#if defined(MBEDTLS_MEMORY_DEBUG) + mbedtls_fprintf( stderr, "FATAL: prev == next\n" ); +#endif + return( 1 ); + } + + if( hdr->prev_free != NULL && hdr->prev_free == hdr->next_free ) + { +#if defined(MBEDTLS_MEMORY_DEBUG) + mbedtls_fprintf( stderr, "FATAL: prev_free == next_free\n" ); +#endif + return( 1 ); + } + + return( 0 ); +} + +static int verify_chain() +{ + memory_header *prv = heap.first, *cur; + + if( prv == NULL || verify_header( prv ) != 0 ) + { +#if defined(MBEDTLS_MEMORY_DEBUG) + mbedtls_fprintf( stderr, "FATAL: verification of first header " + "failed\n" ); +#endif + return( 1 ); + } + + if( heap.first->prev != NULL ) + { +#if defined(MBEDTLS_MEMORY_DEBUG) + mbedtls_fprintf( stderr, "FATAL: verification failed: " + "first->prev != NULL\n" ); +#endif + return( 1 ); + } + + cur = heap.first->next; + + while( cur != NULL ) + { + if( verify_header( cur ) != 0 ) + { +#if defined(MBEDTLS_MEMORY_DEBUG) + mbedtls_fprintf( stderr, "FATAL: verification of header " + "failed\n" ); +#endif + return( 1 ); + } + + if( cur->prev != prv ) + { +#if defined(MBEDTLS_MEMORY_DEBUG) + mbedtls_fprintf( stderr, "FATAL: verification failed: " + "cur->prev != prv\n" ); +#endif + return( 1 ); + } + + prv = cur; + cur = cur->next; + } + + return( 0 ); +} + +static void *buffer_alloc_calloc( size_t n, size_t size ) +{ + memory_header *new, *cur = heap.first_free; + unsigned char *p; + void *ret; + size_t original_len, len; +#if defined(MBEDTLS_MEMORY_BACKTRACE) + void *trace_buffer[MAX_BT]; + size_t trace_cnt; +#endif + + if( heap.buf == NULL || heap.first == NULL ) + return( NULL ); + + original_len = len = n * size; + + if( n == 0 || size == 0 || len / n != size ) + return( NULL ); + else if( len > (size_t)-MBEDTLS_MEMORY_ALIGN_MULTIPLE ) + return( NULL ); + + if( len % MBEDTLS_MEMORY_ALIGN_MULTIPLE ) + { + len -= len % MBEDTLS_MEMORY_ALIGN_MULTIPLE; + len += MBEDTLS_MEMORY_ALIGN_MULTIPLE; + } + + // Find block that fits + // + while( cur != NULL ) + { + if( cur->size >= len ) + break; + + cur = cur->next_free; + } + + if( cur == NULL ) + return( NULL ); + + if( cur->alloc != 0 ) + { +#if defined(MBEDTLS_MEMORY_DEBUG) + mbedtls_fprintf( stderr, "FATAL: block in free_list but allocated " + "data\n" ); +#endif + mbedtls_exit( 1 ); + } + +#if defined(MBEDTLS_MEMORY_DEBUG) + heap.alloc_count++; +#endif + + // Found location, split block if > memory_header + 4 room left + // + if( cur->size - len < sizeof(memory_header) + + MBEDTLS_MEMORY_ALIGN_MULTIPLE ) + { + cur->alloc = 1; + + // Remove from free_list + // + if( cur->prev_free != NULL ) + cur->prev_free->next_free = cur->next_free; + else + heap.first_free = cur->next_free; + + if( cur->next_free != NULL ) + cur->next_free->prev_free = cur->prev_free; + + cur->prev_free = NULL; + cur->next_free = NULL; + +#if defined(MBEDTLS_MEMORY_DEBUG) + heap.total_used += cur->size; + if( heap.total_used > heap.maximum_used ) + heap.maximum_used = heap.total_used; +#endif +#if defined(MBEDTLS_MEMORY_BACKTRACE) + trace_cnt = backtrace( trace_buffer, MAX_BT ); + cur->trace = backtrace_symbols( trace_buffer, trace_cnt ); + cur->trace_count = trace_cnt; +#endif + + if( ( heap.verify & MBEDTLS_MEMORY_VERIFY_ALLOC ) && verify_chain() != 0 ) + mbedtls_exit( 1 ); + + ret = (unsigned char *) cur + sizeof( memory_header ); + memset( ret, 0, original_len ); + + return( ret ); + } + + p = ( (unsigned char *) cur ) + sizeof(memory_header) + len; + new = (memory_header *) p; + + new->size = cur->size - len - sizeof(memory_header); + new->alloc = 0; + new->prev = cur; + new->next = cur->next; +#if defined(MBEDTLS_MEMORY_BACKTRACE) + new->trace = NULL; + new->trace_count = 0; +#endif + new->magic1 = MAGIC1; + new->magic2 = MAGIC2; + + if( new->next != NULL ) + new->next->prev = new; + + // Replace cur with new in free_list + // + new->prev_free = cur->prev_free; + new->next_free = cur->next_free; + if( new->prev_free != NULL ) + new->prev_free->next_free = new; + else + heap.first_free = new; + + if( new->next_free != NULL ) + new->next_free->prev_free = new; + + cur->alloc = 1; + cur->size = len; + cur->next = new; + cur->prev_free = NULL; + cur->next_free = NULL; + +#if defined(MBEDTLS_MEMORY_DEBUG) + heap.header_count++; + if( heap.header_count > heap.maximum_header_count ) + heap.maximum_header_count = heap.header_count; + heap.total_used += cur->size; + if( heap.total_used > heap.maximum_used ) + heap.maximum_used = heap.total_used; +#endif +#if defined(MBEDTLS_MEMORY_BACKTRACE) + trace_cnt = backtrace( trace_buffer, MAX_BT ); + cur->trace = backtrace_symbols( trace_buffer, trace_cnt ); + cur->trace_count = trace_cnt; +#endif + + if( ( heap.verify & MBEDTLS_MEMORY_VERIFY_ALLOC ) && verify_chain() != 0 ) + mbedtls_exit( 1 ); + + ret = (unsigned char *) cur + sizeof( memory_header ); + memset( ret, 0, original_len ); + + return( ret ); +} + +static void buffer_alloc_free( void *ptr ) +{ + memory_header *hdr, *old = NULL; + unsigned char *p = (unsigned char *) ptr; + + if( ptr == NULL || heap.buf == NULL || heap.first == NULL ) + return; + + if( p < heap.buf || p >= heap.buf + heap.len ) + { +#if defined(MBEDTLS_MEMORY_DEBUG) + mbedtls_fprintf( stderr, "FATAL: mbedtls_free() outside of managed " + "space\n" ); +#endif + mbedtls_exit( 1 ); + } + + p -= sizeof(memory_header); + hdr = (memory_header *) p; + + if( verify_header( hdr ) != 0 ) + mbedtls_exit( 1 ); + + if( hdr->alloc != 1 ) + { +#if defined(MBEDTLS_MEMORY_DEBUG) + mbedtls_fprintf( stderr, "FATAL: mbedtls_free() on unallocated " + "data\n" ); +#endif + mbedtls_exit( 1 ); + } + + hdr->alloc = 0; + +#if defined(MBEDTLS_MEMORY_DEBUG) + heap.free_count++; + heap.total_used -= hdr->size; +#endif + +#if defined(MBEDTLS_MEMORY_BACKTRACE) + free( hdr->trace ); + hdr->trace = NULL; + hdr->trace_count = 0; +#endif + + // Regroup with block before + // + if( hdr->prev != NULL && hdr->prev->alloc == 0 ) + { +#if defined(MBEDTLS_MEMORY_DEBUG) + heap.header_count--; +#endif + hdr->prev->size += sizeof(memory_header) + hdr->size; + hdr->prev->next = hdr->next; + old = hdr; + hdr = hdr->prev; + + if( hdr->next != NULL ) + hdr->next->prev = hdr; + + memset( old, 0, sizeof(memory_header) ); + } + + // Regroup with block after + // + if( hdr->next != NULL && hdr->next->alloc == 0 ) + { +#if defined(MBEDTLS_MEMORY_DEBUG) + heap.header_count--; +#endif + hdr->size += sizeof(memory_header) + hdr->next->size; + old = hdr->next; + hdr->next = hdr->next->next; + + if( hdr->prev_free != NULL || hdr->next_free != NULL ) + { + if( hdr->prev_free != NULL ) + hdr->prev_free->next_free = hdr->next_free; + else + heap.first_free = hdr->next_free; + + if( hdr->next_free != NULL ) + hdr->next_free->prev_free = hdr->prev_free; + } + + hdr->prev_free = old->prev_free; + hdr->next_free = old->next_free; + + if( hdr->prev_free != NULL ) + hdr->prev_free->next_free = hdr; + else + heap.first_free = hdr; + + if( hdr->next_free != NULL ) + hdr->next_free->prev_free = hdr; + + if( hdr->next != NULL ) + hdr->next->prev = hdr; + + memset( old, 0, sizeof(memory_header) ); + } + + // Prepend to free_list if we have not merged + // (Does not have to stay in same order as prev / next list) + // + if( old == NULL ) + { + hdr->next_free = heap.first_free; + if( heap.first_free != NULL ) + heap.first_free->prev_free = hdr; + heap.first_free = hdr; + } + + if( ( heap.verify & MBEDTLS_MEMORY_VERIFY_FREE ) && verify_chain() != 0 ) + mbedtls_exit( 1 ); +} + +void mbedtls_memory_buffer_set_verify( int verify ) +{ + heap.verify = verify; +} + +int mbedtls_memory_buffer_alloc_verify() +{ + return verify_chain(); +} + +#if defined(MBEDTLS_MEMORY_DEBUG) +void mbedtls_memory_buffer_alloc_status() +{ + mbedtls_fprintf( stderr, + "Current use: %zu blocks / %zu bytes, max: %zu blocks / " + "%zu bytes (total %zu bytes), alloc / free: %zu / %zu\n", + heap.header_count, heap.total_used, + heap.maximum_header_count, heap.maximum_used, + heap.maximum_header_count * sizeof( memory_header ) + + heap.maximum_used, + heap.alloc_count, heap.free_count ); + + if( heap.first->next == NULL ) + { + mbedtls_fprintf( stderr, "All memory de-allocated in stack buffer\n" ); + } + else + { + mbedtls_fprintf( stderr, "Memory currently allocated:\n" ); + debug_chain(); + } +} + +void mbedtls_memory_buffer_alloc_max_get( size_t *max_used, size_t *max_blocks ) +{ + *max_used = heap.maximum_used; + *max_blocks = heap.maximum_header_count; +} + +void mbedtls_memory_buffer_alloc_max_reset( void ) +{ + heap.maximum_used = 0; + heap.maximum_header_count = 0; +} + +void mbedtls_memory_buffer_alloc_cur_get( size_t *cur_used, size_t *cur_blocks ) +{ + *cur_used = heap.total_used; + *cur_blocks = heap.header_count; +} +#endif /* MBEDTLS_MEMORY_DEBUG */ + +#if defined(MBEDTLS_THREADING_C) +static void *buffer_alloc_calloc_mutexed( size_t n, size_t size ) +{ + void *buf; + if( mbedtls_mutex_lock( &heap.mutex ) != 0 ) + return( NULL ); + buf = buffer_alloc_calloc( n, size ); + if( mbedtls_mutex_unlock( &heap.mutex ) ) + return( NULL ); + return( buf ); +} + +static void buffer_alloc_free_mutexed( void *ptr ) +{ + /* We have to good option here, but corrupting the heap seems + * worse than loosing memory. */ + if( mbedtls_mutex_lock( &heap.mutex ) ) + return; + buffer_alloc_free( ptr ); + (void) mbedtls_mutex_unlock( &heap.mutex ); +} +#endif /* MBEDTLS_THREADING_C */ + +void mbedtls_memory_buffer_alloc_init( unsigned char *buf, size_t len ) +{ + memset( &heap, 0, sizeof( buffer_alloc_ctx ) ); + +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_init( &heap.mutex ); + mbedtls_platform_set_calloc_free( buffer_alloc_calloc_mutexed, + buffer_alloc_free_mutexed ); +#else + mbedtls_platform_set_calloc_free( buffer_alloc_calloc, buffer_alloc_free ); +#endif + + 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 */ + len -= MBEDTLS_MEMORY_ALIGN_MULTIPLE + - (size_t)buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE; + buf += MBEDTLS_MEMORY_ALIGN_MULTIPLE + - (size_t)buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE; + } + + memset( buf, 0, len ); + + heap.buf = buf; + heap.len = len; + + heap.first = (memory_header *)buf; + heap.first->size = len - sizeof( memory_header ); + heap.first->magic1 = MAGIC1; + heap.first->magic2 = MAGIC2; + heap.first_free = heap.first; +} + +void mbedtls_memory_buffer_alloc_free() +{ +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_free( &heap.mutex ); +#endif + mbedtls_zeroize( &heap, sizeof(buffer_alloc_ctx) ); +} + +#if defined(MBEDTLS_SELF_TEST) +static int check_pointer( void *p ) +{ + if( p == NULL ) + return( -1 ); + + if( (size_t) p % MBEDTLS_MEMORY_ALIGN_MULTIPLE != 0 ) + return( -1 ); + + return( 0 ); +} + +static int check_all_free( ) +{ + if( +#if defined(MBEDTLS_MEMORY_DEBUG) + heap.total_used != 0 || +#endif + heap.first != heap.first_free || + (void *) heap.first != (void *) heap.buf ) + { + return( -1 ); + } + + return( 0 ); +} + +#define TEST_ASSERT( condition ) \ + if( ! (condition) ) \ + { \ + if( verbose != 0 ) \ + mbedtls_printf( "failed\n" ); \ + \ + ret = 1; \ + goto cleanup; \ + } + +int mbedtls_memory_buffer_alloc_self_test( int verbose ) +{ + unsigned char buf[1024]; + unsigned char *p, *q, *r, *end; + int ret = 0; + + if( verbose != 0 ) + mbedtls_printf( " MBA test #1 (basic alloc-free cycle): " ); + + mbedtls_memory_buffer_alloc_init( buf, sizeof( buf ) ); + + p = mbedtls_calloc( 1, 1 ); + q = mbedtls_calloc( 1, 128 ); + r = mbedtls_calloc( 1, 16 ); + + TEST_ASSERT( check_pointer( p ) == 0 && + check_pointer( q ) == 0 && + check_pointer( r ) == 0 ); + + mbedtls_free( r ); + mbedtls_free( q ); + mbedtls_free( p ); + + TEST_ASSERT( check_all_free( ) == 0 ); + + /* Memorize end to compare with the next test */ + end = heap.buf + heap.len; + + mbedtls_memory_buffer_alloc_free( ); + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + + if( verbose != 0 ) + mbedtls_printf( " MBA test #2 (buf not aligned): " ); + + mbedtls_memory_buffer_alloc_init( buf + 1, sizeof( buf ) - 1 ); + + TEST_ASSERT( heap.buf + heap.len == end ); + + p = mbedtls_calloc( 1, 1 ); + q = mbedtls_calloc( 1, 128 ); + r = mbedtls_calloc( 1, 16 ); + + TEST_ASSERT( check_pointer( p ) == 0 && + check_pointer( q ) == 0 && + check_pointer( r ) == 0 ); + + mbedtls_free( r ); + mbedtls_free( q ); + mbedtls_free( p ); + + TEST_ASSERT( check_all_free( ) == 0 ); + + mbedtls_memory_buffer_alloc_free( ); + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + + if( verbose != 0 ) + mbedtls_printf( " MBA test #3 (full): " ); + + mbedtls_memory_buffer_alloc_init( buf, sizeof( buf ) ); + + p = mbedtls_calloc( 1, sizeof( buf ) - sizeof( memory_header ) ); + + TEST_ASSERT( check_pointer( p ) == 0 ); + TEST_ASSERT( mbedtls_calloc( 1, 1 ) == NULL ); + + mbedtls_free( p ); + + p = mbedtls_calloc( 1, sizeof( buf ) - 2 * sizeof( memory_header ) - 16 ); + q = mbedtls_calloc( 1, 16 ); + + TEST_ASSERT( check_pointer( p ) == 0 && check_pointer( q ) == 0 ); + TEST_ASSERT( mbedtls_calloc( 1, 1 ) == NULL ); + + mbedtls_free( q ); + + TEST_ASSERT( mbedtls_calloc( 1, 17 ) == NULL ); + + mbedtls_free( p ); + + TEST_ASSERT( check_all_free( ) == 0 ); + + mbedtls_memory_buffer_alloc_free( ); + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + +cleanup: + mbedtls_memory_buffer_alloc_free( ); + + return( ret ); +} +#endif /* MBEDTLS_SELF_TEST */ + +#endif /* MBEDTLS_MEMORY_BUFFER_ALLOC_C */ diff --git a/APP_Framework/Framework/security/mbedtls/names.txt b/APP_Framework/Framework/security/mbedtls/names.txt new file mode 100644 index 000000000..56fa402eb --- /dev/null +++ b/APP_Framework/Framework/security/mbedtls/names.txt @@ -0,0 +1 @@ +aes.c aesni.c arc4.c asn1parse.c asn1write.c base64.c bignum.c blowfish.c camellia.c ccm.c certs.c cipher.c cipher_wrap.c cmac.c ctr_drbg.c debug.c des.c dhm.c ecdh.c ecdsa.c ecjpake.c ecp.c ecp_curves.c entropy.c entropy_poll.c error.c gcm.c havege.c hmac_drbg.c md2.c md4.c md5.c md.c md_wrap.c memory_buffer_alloc.c net_sockets.c oid.c padlock.c pem.c pk.c pkcs11.c pkcs12.c pkcs5.c pkparse.c pk_wrap.c pkwrite.c platform.c ripemd160.c rsa.c rsa_internal.c sha1.c sha256.c sha512.c ssl_cache.c ssl_ciphersuites.c ssl_cli.c ssl_cookie.c ssl_srv.c ssl_ticket.c ssl_tls.c threading.c timing.c version.c version_features.c x509.c x509_create.c x509_crl.c x509_crt.c x509_csr.c x509write_crt.c x509write_csr.c xtea.c \ No newline at end of file diff --git a/APP_Framework/Framework/security/mbedtls/net.h b/APP_Framework/Framework/security/mbedtls/net.h index 2523fc754..8cead58e5 100644 --- a/APP_Framework/Framework/security/mbedtls/net.h +++ b/APP_Framework/Framework/security/mbedtls/net.h @@ -3,7 +3,7 @@ * * \brief Deprecated header file that includes net_sockets.h * - * \deprecated Superseded by net_sockets.h + * \deprecated Superseded by mbedtls/net_sockets.h */ /* * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved @@ -32,6 +32,6 @@ #if !defined(MBEDTLS_DEPRECATED_REMOVED) #include "net_sockets.h" #if defined(MBEDTLS_DEPRECATED_WARNING) -#warning "Deprecated header file: Superseded by net_sockets.h" +#warning "Deprecated header file: Superseded by mbedtls/net_sockets.h" #endif /* MBEDTLS_DEPRECATED_WARNING */ #endif /* !MBEDTLS_DEPRECATED_REMOVED */ diff --git a/APP_Framework/Framework/security/mbedtls/net_sockets.c b/APP_Framework/Framework/security/mbedtls/net_sockets.c new file mode 100644 index 000000000..643af0990 --- /dev/null +++ b/APP_Framework/Framework/security/mbedtls/net_sockets.c @@ -0,0 +1,592 @@ +/* + * TCP/IP or UDP/IP networking functions + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_NET_C) + +#if !defined(unix) && !defined(__unix__) && !defined(__unix) && \ + !defined(__APPLE__) && !defined(_WIN32) +#error "This module only works on Unix and Windows, see MBEDTLS_NET_C in config.h" +#endif + +#if defined(MBEDTLS_PLATFORM_C) +#include "platform.h" +#else +#include +#endif + +#include "net_sockets.h" + +#include + +#if (defined(_WIN32) || defined(_WIN32_WCE)) && !defined(EFIX64) && \ + !defined(EFI32) + +#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0501) +#undef _WIN32_WINNT +/* Enables getaddrinfo() & Co */ +#define _WIN32_WINNT 0x0501 +#endif + +#include + +#include +#include + +#if defined(_MSC_VER) +#if defined(_WIN32_WCE) +#pragma comment( lib, "ws2.lib" ) +#else +#pragma comment( lib, "ws2_32.lib" ) +#endif +#endif /* _MSC_VER */ + +#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 close(fd) closesocket(fd) + +static int wsa_init_done = 0; + +#else /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */ + +/* Some MS functions want int and MSVC warns if we pass size_t, + * but the standard functions use socklen_t, so cast only for MSVC */ +#if defined(_MSC_VER) +#define MSVC_INT_CAST (int) +#else +#define MSVC_INT_CAST +#endif + +#include + +#include + +#include + +/* + * Prepare for using the sockets interface + */ +static int net_prepare( void ) +{ +#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \ + !defined(EFI32) + WSADATA wsaData; + + if( wsa_init_done == 0 ) + { + if( WSAStartup( MAKEWORD(2,0), &wsaData ) != 0 ) + return( MBEDTLS_ERR_NET_SOCKET_FAILED ); + + wsa_init_done = 1; + } +#else +#if !defined(EFIX64) && !defined(EFI32) + signal( SIGPIPE, SIG_IGN ); +#endif +#endif + return( 0 ); +} + +/* + * Initialize a context + */ +void mbedtls_net_init( mbedtls_net_context *ctx ) +{ + ctx->fd = -1; +} + +/* + * Initiate a TCP connection with host:port and the given protocol + */ +int mbedtls_net_connect( mbedtls_net_context *ctx, const char *host, + const char *port, int proto ) +{ + int ret; + struct addrinfo hints, *addr_list, *cur; + + if( ( ret = net_prepare() ) != 0 ) + return( ret ); + + /* Do name resolution with both IPv6 and IPv4 */ + memset( &hints, 0, sizeof( hints ) ); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = proto == MBEDTLS_NET_PROTO_UDP ? SOCK_DGRAM : SOCK_STREAM; + hints.ai_protocol = proto == MBEDTLS_NET_PROTO_UDP ? IPPROTO_UDP : IPPROTO_TCP; + + if( getaddrinfo( host, port, &hints, &addr_list ) != 0 ) + return( MBEDTLS_ERR_NET_UNKNOWN_HOST ); + + /* Try the sockaddrs until a connection succeeds */ + ret = MBEDTLS_ERR_NET_UNKNOWN_HOST; + for( cur = addr_list; cur != NULL; cur = cur->ai_next ) + { + ctx->fd = (int) socket( cur->ai_family, cur->ai_socktype, + cur->ai_protocol ); + if( ctx->fd < 0 ) + { + ret = MBEDTLS_ERR_NET_SOCKET_FAILED; + continue; + } + + if( connect( ctx->fd, cur->ai_addr, MSVC_INT_CAST cur->ai_addrlen ) == 0 ) + { + ret = 0; + break; + } + + close( ctx->fd ); + ret = MBEDTLS_ERR_NET_CONNECT_FAILED; + } + + freeaddrinfo( addr_list ); + + return( ret ); +} + +/* + * Create a listening socket on bind_ip:port + */ +int mbedtls_net_bind( mbedtls_net_context *ctx, const char *bind_ip, const char *port, int proto ) +{ + int n, ret; + struct addrinfo hints, *addr_list, *cur; + + if( ( ret = net_prepare() ) != 0 ) + return( ret ); + + /* Bind to IPv6 and/or IPv4, but only in the desired protocol */ + memset( &hints, 0, sizeof( hints ) ); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = proto == MBEDTLS_NET_PROTO_UDP ? SOCK_DGRAM : SOCK_STREAM; + hints.ai_protocol = proto == MBEDTLS_NET_PROTO_UDP ? IPPROTO_UDP : IPPROTO_TCP; + if( bind_ip == NULL ) + hints.ai_flags = AI_PASSIVE; + + if( getaddrinfo( bind_ip, port, &hints, &addr_list ) != 0 ) + return( MBEDTLS_ERR_NET_UNKNOWN_HOST ); + + /* Try the sockaddrs until a binding succeeds */ + ret = MBEDTLS_ERR_NET_UNKNOWN_HOST; + for( cur = addr_list; cur != NULL; cur = cur->ai_next ) + { + ctx->fd = (int) socket( cur->ai_family, cur->ai_socktype, + cur->ai_protocol ); + if( ctx->fd < 0 ) + { + ret = MBEDTLS_ERR_NET_SOCKET_FAILED; + continue; + } + + n = 1; + if( setsockopt( ctx->fd, SOL_SOCKET, SO_REUSEADDR, + (const char *) &n, sizeof( n ) ) != 0 ) + { + close( ctx->fd ); + ret = MBEDTLS_ERR_NET_SOCKET_FAILED; + continue; + } + + if( bind( ctx->fd, cur->ai_addr, MSVC_INT_CAST cur->ai_addrlen ) != 0 ) + { + close( ctx->fd ); + ret = MBEDTLS_ERR_NET_BIND_FAILED; + continue; + } + + /* Listen only makes sense for TCP */ + if( proto == MBEDTLS_NET_PROTO_TCP ) + { + if( listen( ctx->fd, MBEDTLS_NET_LISTEN_BACKLOG ) != 0 ) + { + close( ctx->fd ); + ret = MBEDTLS_ERR_NET_LISTEN_FAILED; + continue; + } + } + + /* Bind was successful */ + ret = 0; + break; + } + + freeaddrinfo( addr_list ); + + return( ret ); + +} + +#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \ + !defined(EFI32) +/* + * Check if the requested operation would be blocking on a non-blocking socket + * and thus 'failed' with a negative return value. + */ +static int net_would_block( const mbedtls_net_context *ctx ) +{ + ((void) ctx); + return( WSAGetLastError() == WSAEWOULDBLOCK ); +} +#else +/* + * Check if the requested operation would be blocking on a non-blocking socket + * and thus 'failed' with a negative return value. + * + * Note: on a blocking socket this function always returns 0! + */ +static int net_would_block( const mbedtls_net_context *ctx ) +{ + int err = errno; + + /* + * Never return 'WOULD BLOCK' on a non-blocking socket + */ + if( ( fcntl( ctx->fd, F_GETFL ) & O_NONBLOCK ) != O_NONBLOCK ) + { + errno = err; + return( 0 ); + } + + switch( errno = err ) + { +#if defined EAGAIN + case EAGAIN: +#endif +#if defined EWOULDBLOCK && EWOULDBLOCK != EAGAIN + case EWOULDBLOCK: +#endif + return( 1 ); + } + return( 0 ); +} +#endif /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */ + +/* + * Accept a connection from a remote client + */ +int mbedtls_net_accept( mbedtls_net_context *bind_ctx, + mbedtls_net_context *client_ctx, + void *client_ip, size_t buf_size, size_t *ip_len ) +{ + int ret; + int type; + + struct sockaddr_storage client_addr; + +#if defined(__socklen_t_defined) || defined(_SOCKLEN_T) || \ + defined(_SOCKLEN_T_DECLARED) || defined(__DEFINED_socklen_t) + socklen_t n = (socklen_t) sizeof( client_addr ); + socklen_t type_len = (socklen_t) sizeof( type ); +#else + int n = (int) sizeof( client_addr ); + int type_len = (int) sizeof( type ); +#endif + + /* Is this a TCP or UDP socket? */ + if( getsockopt( bind_ctx->fd, SOL_SOCKET, SO_TYPE, + (void *) &type, &type_len ) != 0 || + ( type != SOCK_STREAM && type != SOCK_DGRAM ) ) + { + return( MBEDTLS_ERR_NET_ACCEPT_FAILED ); + } + + if( type == SOCK_STREAM ) + { + /* TCP: actual accept() */ + ret = client_ctx->fd = (int) accept( bind_ctx->fd, + (struct sockaddr *) &client_addr, &n ); + } + else + { + /* UDP: wait for a message, but keep it in the queue */ + char buf[1] = { 0 }; + + ret = (int) recvfrom( bind_ctx->fd, buf, sizeof( buf ), MSG_PEEK, + (struct sockaddr *) &client_addr, &n ); + +#if defined(_WIN32) + if( ret == SOCKET_ERROR && + WSAGetLastError() == WSAEMSGSIZE ) + { + /* We know buf is too small, thanks, just peeking here */ + ret = 0; + } +#endif + } + + if( ret < 0 ) + { + if( net_would_block( bind_ctx ) != 0 ) + return( MBEDTLS_ERR_SSL_WANT_READ ); + + return( MBEDTLS_ERR_NET_ACCEPT_FAILED ); + } + + /* UDP: hijack the listening socket to communicate with the client, + * then bind a new socket to accept new connections */ + if( type != SOCK_STREAM ) + { + struct sockaddr_storage local_addr; + int one = 1; + + if( connect( bind_ctx->fd, (struct sockaddr *) &client_addr, n ) != 0 ) + return( MBEDTLS_ERR_NET_ACCEPT_FAILED ); + + client_ctx->fd = bind_ctx->fd; + bind_ctx->fd = -1; /* In case we exit early */ + + n = sizeof( struct sockaddr_storage ); + if( getsockname( client_ctx->fd, + (struct sockaddr *) &local_addr, &n ) != 0 || + ( bind_ctx->fd = (int) socket( local_addr.ss_family, + SOCK_DGRAM, IPPROTO_UDP ) ) < 0 || + setsockopt( bind_ctx->fd, SOL_SOCKET, SO_REUSEADDR, + (const char *) &one, sizeof( one ) ) != 0 ) + { + return( MBEDTLS_ERR_NET_SOCKET_FAILED ); + } + + if( bind( bind_ctx->fd, (struct sockaddr *) &local_addr, n ) != 0 ) + { + return( MBEDTLS_ERR_NET_BIND_FAILED ); + } + } + + if( client_ip != NULL ) + { + if( client_addr.ss_family == AF_INET ) + { + struct sockaddr_in *addr4 = (struct sockaddr_in *) &client_addr; + *ip_len = sizeof( addr4->sin_addr.s_addr ); + + if( buf_size < *ip_len ) + return( MBEDTLS_ERR_NET_BUFFER_TOO_SMALL ); + + memcpy( client_ip, &addr4->sin_addr.s_addr, *ip_len ); + } + else + { + struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) &client_addr; + *ip_len = sizeof( addr6->sin6_addr.s6_addr ); + + if( buf_size < *ip_len ) + return( MBEDTLS_ERR_NET_BUFFER_TOO_SMALL ); + + memcpy( client_ip, &addr6->sin6_addr.s6_addr, *ip_len); + } + } + + return( 0 ); +} + +/* + * Set the socket blocking or non-blocking + */ +int mbedtls_net_set_block( mbedtls_net_context *ctx ) +{ +#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \ + !defined(EFI32) + u_long n = 0; + return( ioctlsocket( ctx->fd, FIONBIO, &n ) ); +#else + return( fcntl( ctx->fd, F_SETFL, fcntl( ctx->fd, F_GETFL ) & ~O_NONBLOCK ) ); +#endif +} + +int mbedtls_net_set_nonblock( mbedtls_net_context *ctx ) +{ +#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \ + !defined(EFI32) + u_long n = 1; + return( ioctlsocket( ctx->fd, FIONBIO, &n ) ); +#else + return( fcntl( ctx->fd, F_SETFL, fcntl( ctx->fd, F_GETFL ) | O_NONBLOCK ) ); +#endif +} + +/* + * Portable usleep helper + */ +void mbedtls_net_usleep( unsigned long usec ) +{ +#if defined(_WIN32) + Sleep( ( usec + 999 ) / 1000 ); +#else + struct timeval tv; + tv.tv_sec = usec / 1000000; +#if defined(__unix__) || defined(__unix) || \ + ( defined(__APPLE__) && defined(__MACH__) ) + tv.tv_usec = (suseconds_t) usec % 1000000; +#else + tv.tv_usec = usec % 1000000; +#endif + select( 0, NULL, NULL, NULL, &tv ); +#endif +} + +/* + * Read at most 'len' characters + */ +int mbedtls_net_recv( void *ctx, unsigned char *buf, size_t len ) +{ + int ret; + int fd = ((mbedtls_net_context *) ctx)->fd; + + if( fd < 0 ) + return( MBEDTLS_ERR_NET_INVALID_CONTEXT ); + + ret = (int) read( fd, buf, len ); + + if( ret < 0 ) + { + if( net_would_block( ctx ) != 0 ) + return( MBEDTLS_ERR_SSL_WANT_READ ); + +#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \ + !defined(EFI32) + if( WSAGetLastError() == WSAECONNRESET ) + return( MBEDTLS_ERR_NET_CONN_RESET ); +#else + if( errno == EPIPE || errno == ECONNRESET ) + return( MBEDTLS_ERR_NET_CONN_RESET ); + + if( errno == EINTR ) + return( MBEDTLS_ERR_SSL_WANT_READ ); +#endif + + return( MBEDTLS_ERR_NET_RECV_FAILED ); + } + + return( ret ); +} + +/* + * Read at most 'len' characters, blocking for at most 'timeout' ms + */ +int mbedtls_net_recv_timeout( void *ctx, unsigned char *buf, size_t len, + uint32_t timeout ) +{ + int ret; + struct timeval tv; + fd_set read_fds; + int fd = ((mbedtls_net_context *) ctx)->fd; + + if( fd < 0 ) + return( MBEDTLS_ERR_NET_INVALID_CONTEXT ); + + FD_ZERO( &read_fds ); + FD_SET( fd, &read_fds ); + + tv.tv_sec = timeout / 1000; + tv.tv_usec = ( timeout % 1000 ) * 1000; + + ret = select( fd + 1, &read_fds, NULL, NULL, timeout == 0 ? NULL : &tv ); + + /* Zero fds ready means we timed out */ + if( ret == 0 ) + return( MBEDTLS_ERR_SSL_TIMEOUT ); + + if( ret < 0 ) + { +#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \ + !defined(EFI32) + if( WSAGetLastError() == WSAEINTR ) + return( MBEDTLS_ERR_SSL_WANT_READ ); +#else + if( errno == EINTR ) + return( MBEDTLS_ERR_SSL_WANT_READ ); +#endif + + return( MBEDTLS_ERR_NET_RECV_FAILED ); + } + + /* This call will not block */ + return( mbedtls_net_recv( ctx, buf, len ) ); +} + +/* + * Write at most 'len' characters + */ +int mbedtls_net_send( void *ctx, const unsigned char *buf, size_t len ) +{ + int ret; + int fd = ((mbedtls_net_context *) ctx)->fd; + + if( fd < 0 ) + return( MBEDTLS_ERR_NET_INVALID_CONTEXT ); + + ret = (int) write( fd, buf, len ); + + if( ret < 0 ) + { + if( net_would_block( ctx ) != 0 ) + return( MBEDTLS_ERR_SSL_WANT_WRITE ); + +#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \ + !defined(EFI32) + if( WSAGetLastError() == WSAECONNRESET ) + return( MBEDTLS_ERR_NET_CONN_RESET ); +#else + if( errno == EPIPE || errno == ECONNRESET ) + return( MBEDTLS_ERR_NET_CONN_RESET ); + + if( errno == EINTR ) + return( MBEDTLS_ERR_SSL_WANT_WRITE ); +#endif + + return( MBEDTLS_ERR_NET_SEND_FAILED ); + } + + return( ret ); +} + +/* + * Gracefully close the connection + */ +void mbedtls_net_free( mbedtls_net_context *ctx ) +{ + if( ctx->fd == -1 ) + return; + + shutdown( ctx->fd, 2 ); + close( ctx->fd ); + + ctx->fd = -1; +} + +#endif /* MBEDTLS_NET_C */ diff --git a/APP_Framework/Framework/security/mbedtls/net_sockets.h b/APP_Framework/Framework/security/mbedtls/net_sockets.h index 4c7ef00fe..52bb8de7c 100644 --- a/APP_Framework/Framework/security/mbedtls/net_sockets.h +++ b/APP_Framework/Framework/security/mbedtls/net_sockets.h @@ -1,23 +1,7 @@ /** * \file net_sockets.h * - * \brief Network sockets abstraction layer to integrate Mbed TLS into a - * BSD-style sockets API. - * - * The network sockets module provides an example integration of the - * Mbed TLS library into a BSD sockets implementation. The module is - * intended to be an example of how Mbed TLS can be integrated into a - * networking stack, as well as to be Mbed TLS's network integration - * for its supported platforms. - * - * The module is intended only to be used with the Mbed TLS library and - * is not intended to be used by third party application software - * directly. - * - * The supported platforms are as follows: - * * Microsoft Windows and Windows CE - * * POSIX/Unix platforms including Linux, OS X - * + * \brief Network communication functions */ /* * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved @@ -62,17 +46,12 @@ #define MBEDTLS_ERR_NET_UNKNOWN_HOST -0x0052 /**< Failed to get an IP address for the given hostname. */ #define MBEDTLS_ERR_NET_BUFFER_TOO_SMALL -0x0043 /**< Buffer is too small to hold the data. */ #define MBEDTLS_ERR_NET_INVALID_CONTEXT -0x0045 /**< The context is invalid, eg because it was free()ed. */ -#define MBEDTLS_ERR_NET_POLL_FAILED -0x0047 /**< Polling the net context failed. */ -#define MBEDTLS_ERR_NET_BAD_INPUT_DATA -0x0049 /**< Input invalid. */ #define MBEDTLS_NET_LISTEN_BACKLOG 10 /**< The backlog that listen() should use. */ #define MBEDTLS_NET_PROTO_TCP 0 /**< The TCP transport protocol */ #define MBEDTLS_NET_PROTO_UDP 1 /**< The UDP transport protocol */ -#define MBEDTLS_NET_POLL_READ 1 /**< Used in \c mbedtls_net_poll to check for pending data */ -#define MBEDTLS_NET_POLL_WRITE 2 /**< Used in \c mbedtls_net_poll to check if write possible */ - #ifdef __cplusplus extern "C" { #endif @@ -84,7 +63,7 @@ extern "C" { * (eg two file descriptors for combined IPv4 + IPv6 support, or additional * structures for hand-made UDP demultiplexing). */ -typedef struct mbedtls_net_context +typedef struct { int fd; /**< The underlying file descriptor */ } @@ -154,29 +133,6 @@ int mbedtls_net_accept( mbedtls_net_context *bind_ctx, mbedtls_net_context *client_ctx, void *client_ip, size_t buf_size, size_t *ip_len ); -/** - * \brief Check and wait for the context to be ready for read/write - * - * \param ctx Socket to check - * \param rw Bitflag composed of MBEDTLS_NET_POLL_READ and - * MBEDTLS_NET_POLL_WRITE specifying the events - * to wait for: - * - If MBEDTLS_NET_POLL_READ is set, the function - * will return as soon as the net context is available - * for reading. - * - If MBEDTLS_NET_POLL_WRITE is set, the function - * will return as soon as the net context is available - * for writing. - * \param timeout Maximal amount of time to wait before returning, - * in milliseconds. If \c timeout is zero, the - * function returns immediately. If \c timeout is - * -1u, the function blocks potentially indefinitely. - * - * \return Bitmask composed of MBEDTLS_NET_POLL_READ/WRITE - * on success or timeout, or a negative return code otherwise. - */ -int mbedtls_net_poll( mbedtls_net_context *ctx, uint32_t rw, uint32_t timeout ); - /** * \brief Set the socket blocking * diff --git a/APP_Framework/Framework/security/mbedtls/nist_kw.h b/APP_Framework/Framework/security/mbedtls/nist_kw.h deleted file mode 100644 index c94c15a6f..000000000 --- a/APP_Framework/Framework/security/mbedtls/nist_kw.h +++ /dev/null @@ -1,185 +0,0 @@ -/** - * \file nist_kw.h - * - * \brief This file provides an API for key wrapping (KW) and key wrapping with - * padding (KWP) as defined in NIST SP 800-38F. - * https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38F.pdf - * - * Key wrapping specifies a deterministic authenticated-encryption mode - * of operation, according to NIST SP 800-38F: Recommendation for - * Block Cipher Modes of Operation: Methods for Key Wrapping. Its - * purpose is to protect cryptographic keys. - * - * Its equivalent is RFC 3394 for KW, and RFC 5649 for KWP. - * https://tools.ietf.org/html/rfc3394 - * https://tools.ietf.org/html/rfc5649 - * - */ -/* - * Copyright (C) 2018, Arm Limited (or its affiliates), All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * This file is part of Mbed TLS (https://tls.mbed.org) - */ - -#ifndef MBEDTLS_NIST_KW_H -#define MBEDTLS_NIST_KW_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "cipher.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum -{ - MBEDTLS_KW_MODE_KW = 0, - MBEDTLS_KW_MODE_KWP = 1 -} mbedtls_nist_kw_mode_t; - -#if !defined(MBEDTLS_NIST_KW_ALT) -// Regular implementation -// - -/** - * \brief The key wrapping context-type definition. The key wrapping context is passed - * to the APIs called. - * - * \note The definition of this type may change in future library versions. - * Don't make any assumptions on this context! - */ -typedef struct { - mbedtls_cipher_context_t cipher_ctx; /*!< The cipher context used. */ -} mbedtls_nist_kw_context; - -#else /* MBEDTLS_NIST_key wrapping_ALT */ -#include "nist_kw_alt.h" -#endif /* MBEDTLS_NIST_KW_ALT */ - -/** - * \brief This function initializes the specified key wrapping context - * to make references valid and prepare the context - * for mbedtls_nist_kw_setkey() or mbedtls_nist_kw_free(). - * - * \param ctx The key wrapping context to initialize. - * - */ -void mbedtls_nist_kw_init( mbedtls_nist_kw_context *ctx ); - -/** - * \brief This function initializes the key wrapping context set in the - * \p ctx parameter and sets the encryption key. - * - * \param ctx The key wrapping context. - * \param cipher The 128-bit block cipher to use. Only AES is supported. - * \param key The Key Encryption Key (KEK). - * \param keybits The KEK size in bits. This must be acceptable by the cipher. - * \param is_wrap Specify whether the operation within the context is wrapping or unwrapping - * - * \return \c 0 on success. - * \return \c MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA for any invalid input. - * \return \c MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE for 128-bit block ciphers - * which are not supported. - * \return cipher-specific error code on failure of the underlying cipher. - */ -int mbedtls_nist_kw_setkey( mbedtls_nist_kw_context *ctx, - mbedtls_cipher_id_t cipher, - const unsigned char *key, - unsigned int keybits, - const int is_wrap ); - -/** - * \brief This function releases and clears the specified key wrapping context - * and underlying cipher sub-context. - * - * \param ctx The key wrapping context to clear. - */ -void mbedtls_nist_kw_free( mbedtls_nist_kw_context *ctx ); - -/** - * \brief This function encrypts a buffer using key wrapping. - * - * \param ctx The key wrapping context to use for encryption. - * \param mode The key wrapping mode to use (MBEDTLS_KW_MODE_KW or MBEDTLS_KW_MODE_KWP) - * \param input The buffer holding the input data. - * \param in_len The length of the input data in Bytes. - * The input uses units of 8 Bytes called semiblocks. - *
    • For KW mode: a multiple of 8 bytes between 16 and 2^57-8 inclusive.
    • - *
    • For KWP mode: any length between 1 and 2^32-1 inclusive.
    - * \param[out] output The buffer holding the output data. - *
    • For KW mode: Must be at least 8 bytes larger than \p in_len.
    • - *
    • For KWP mode: Must be at least 8 bytes larger rounded up to a multiple of - * 8 bytes for KWP (15 bytes at most).
    - * \param[out] out_len The number of bytes written to the output buffer. \c 0 on failure. - * \param[in] out_size The capacity of the output buffer. - * - * \return \c 0 on success. - * \return \c MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA for invalid input length. - * \return \c MBEDTLS_ERR_PLATFORM_ALLOC_FAILED in case of a memory allocation failure. - * \return cipher-specific error code on failure of the underlying cipher. - */ -int mbedtls_nist_kw_wrap( mbedtls_nist_kw_context *ctx, mbedtls_nist_kw_mode_t mode, - const unsigned char *input, size_t in_len, - unsigned char *output, size_t* out_len, size_t out_size ); - -/** - * \brief This function decrypts a buffer using key wrapping. - * - * \param ctx The key wrapping context to use for decryption. - * \param mode The key wrapping mode to use (MBEDTLS_KW_MODE_KW or MBEDTLS_KW_MODE_KWP) - * \param input The buffer holding the input data. - * \param in_len The length of the input data in Bytes. - * The input uses units of 8 Bytes called semiblocks. - * The input must be a multiple of semiblocks. - *
    • For KW mode: a multiple of 8 bytes between 24 and 2^57 inclusive.
    • - *
    • For KWP mode: a multiple of 8 bytes between 16 and 2^32 inclusive.
    - * \param[out] output The buffer holding the output data. - * The output buffer's minimal length is 8 bytes shorter than \p in_len. - * \param[out] out_len The number of bytes written to the output buffer. \c 0 on failure. - * For KWP mode, the length could be up to 15 bytes shorter than \p in_len, - * depending on how much padding was added to the data. - * \param[in] out_size The capacity of the output buffer. - * - * \return \c 0 on success. - * \return \c MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA for invalid input length. - * \return \c MBEDTLS_ERR_CIPHER_AUTH_FAILED for verification failure of the ciphertext. - * \return cipher-specific error code on failure of the underlying cipher. - */ -int mbedtls_nist_kw_unwrap( mbedtls_nist_kw_context *ctx, mbedtls_nist_kw_mode_t mode, - const unsigned char *input, size_t in_len, - unsigned char *output, size_t* out_len, size_t out_size); - - -#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) -/** - * \brief The key wrapping checkup routine. - * - * \return \c 0 on success. - * \return \c 1 on failure. - */ -int mbedtls_nist_kw_self_test( int verbose ); -#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ - -#ifdef __cplusplus -} -#endif - -#endif /* MBEDTLS_NIST_KW_H */ diff --git a/APP_Framework/Framework/security/mbedtls/oid.c b/APP_Framework/Framework/security/mbedtls/oid.c index 6000b2022..c8436d6c3 100644 --- a/APP_Framework/Framework/security/mbedtls/oid.c +++ b/APP_Framework/Framework/security/mbedtls/oid.c @@ -50,41 +50,27 @@ */ #define ADD_LEN(s) s, MBEDTLS_OID_SIZE(s) -/* - * Macro to generate mbedtls_oid_descriptor_t - */ -#if !defined(MBEDTLS_X509_REMOVE_INFO) -#define OID_DESCRIPTOR(s, name, description) { ADD_LEN(s), name, description } -#define NULL_OID_DESCRIPTOR { NULL, 0, NULL, NULL } -#else -#define OID_DESCRIPTOR(s, name, description) { ADD_LEN(s) } -#define NULL_OID_DESCRIPTOR { NULL, 0 } -#endif - /* * Macro to generate an internal function for oid_XXX_from_asn1() (used by * the other functions) */ -#define FN_OID_TYPED_FROM_ASN1( TYPE_T, NAME, LIST ) \ - static const TYPE_T * oid_ ## NAME ## _from_asn1( \ - const mbedtls_asn1_buf *oid ) \ - { \ - const TYPE_T *p = (LIST); \ - const mbedtls_oid_descriptor_t *cur = \ - (const mbedtls_oid_descriptor_t *) p; \ - if( p == NULL || oid == NULL ) return( NULL ); \ - while( cur->asn1 != NULL ) { \ - if( cur->asn1_len == oid->len && \ - mbedtls_platform_memequal( cur->asn1, oid->p, oid->len ) == 0 ) { \ - return( p ); \ - } \ - p++; \ - cur = (const mbedtls_oid_descriptor_t *) p; \ - } \ - return( NULL ); \ - } +#define FN_OID_TYPED_FROM_ASN1( TYPE_T, NAME, LIST ) \ +static const TYPE_T * oid_ ## NAME ## _from_asn1( const mbedtls_asn1_buf *oid ) \ +{ \ + const TYPE_T *p = LIST; \ + const mbedtls_oid_descriptor_t *cur = (const mbedtls_oid_descriptor_t *) p; \ + if( p == NULL || oid == NULL ) return( NULL ); \ + while( cur->asn1 != NULL ) { \ + if( cur->asn1_len == oid->len && \ + memcmp( cur->asn1, oid->p, oid->len ) == 0 ) { \ + return( p ); \ + } \ + p++; \ + cur = (const mbedtls_oid_descriptor_t *) p; \ + } \ + return( NULL ); \ +} -#if !defined(MBEDTLS_X509_REMOVE_INFO) /* * Macro to generate a function for retrieving a single attribute from the * descriptor of an mbedtls_oid_descriptor_t wrapper. @@ -97,7 +83,6 @@ int FN_NAME( const mbedtls_asn1_buf *oid, ATTR1_TYPE * ATTR1 ) *ATTR1 = data->descriptor.ATTR1; \ return( 0 ); \ } -#endif /* !MBEDTLS_X509_REMOVE_INFO */ /* * Macro to generate a function for retrieving a single attribute from an @@ -118,13 +103,12 @@ int FN_NAME( const mbedtls_asn1_buf *oid, ATTR1_TYPE * ATTR1 ) */ #define FN_OID_GET_ATTR2(FN_NAME, TYPE_T, TYPE_NAME, ATTR1_TYPE, ATTR1, \ ATTR2_TYPE, ATTR2) \ -int FN_NAME( const mbedtls_asn1_buf *oid, ATTR1_TYPE * ATTR1, \ - ATTR2_TYPE * ATTR2 ) \ +int FN_NAME( const mbedtls_asn1_buf *oid, ATTR1_TYPE * ATTR1, ATTR2_TYPE * ATTR2 ) \ { \ const TYPE_T *data = oid_ ## TYPE_NAME ## _from_asn1( oid ); \ - if( data == NULL ) return( MBEDTLS_ERR_OID_NOT_FOUND ); \ - *(ATTR1) = data->ATTR1; \ - *(ATTR2) = data->ATTR2; \ + if( data == NULL ) return( MBEDTLS_ERR_OID_NOT_FOUND ); \ + *ATTR1 = data->ATTR1; \ + *ATTR2 = data->ATTR2; \ return( 0 ); \ } @@ -135,16 +119,16 @@ int FN_NAME( const mbedtls_asn1_buf *oid, ATTR1_TYPE * ATTR1, \ #define FN_OID_GET_OID_BY_ATTR1(FN_NAME, TYPE_T, LIST, ATTR1_TYPE, ATTR1) \ int FN_NAME( ATTR1_TYPE ATTR1, const char **oid, size_t *olen ) \ { \ - const TYPE_T *cur = (LIST); \ + const TYPE_T *cur = LIST; \ while( cur->descriptor.asn1 != NULL ) { \ - if( cur->ATTR1 == (ATTR1) ) { \ + if( cur->ATTR1 == ATTR1 ) { \ *oid = cur->descriptor.asn1; \ *olen = cur->descriptor.asn1_len; \ return( 0 ); \ } \ cur++; \ } \ - return( MBEDTLS_ERR_OID_NOT_FOUND ); \ + return( MBEDTLS_ERR_OID_NOT_FOUND ); \ } /* @@ -156,9 +140,9 @@ int FN_NAME( ATTR1_TYPE ATTR1, const char **oid, size_t *olen ) \ int FN_NAME( ATTR1_TYPE ATTR1, ATTR2_TYPE ATTR2, const char **oid , \ size_t *olen ) \ { \ - const TYPE_T *cur = (LIST); \ + const TYPE_T *cur = LIST; \ while( cur->descriptor.asn1 != NULL ) { \ - if( cur->ATTR1 == (ATTR1) && cur->ATTR2 == (ATTR2) ) { \ + if( cur->ATTR1 == ATTR1 && cur->ATTR2 == ATTR2 ) { \ *oid = cur->descriptor.asn1; \ *olen = cur->descriptor.asn1_len; \ return( 0 ); \ @@ -180,83 +164,83 @@ typedef struct { static const oid_x520_attr_t oid_x520_attr_type[] = { { - OID_DESCRIPTOR( MBEDTLS_OID_AT_CN, "id-at-commonName", "Common Name" ), + { ADD_LEN( MBEDTLS_OID_AT_CN ), "id-at-commonName", "Common Name" }, "CN", }, { - OID_DESCRIPTOR( MBEDTLS_OID_AT_COUNTRY, "id-at-countryName", "Country" ), + { ADD_LEN( MBEDTLS_OID_AT_COUNTRY ), "id-at-countryName", "Country" }, "C", }, { - OID_DESCRIPTOR( MBEDTLS_OID_AT_LOCALITY, "id-at-locality", "Locality" ), + { ADD_LEN( MBEDTLS_OID_AT_LOCALITY ), "id-at-locality", "Locality" }, "L", }, { - OID_DESCRIPTOR( MBEDTLS_OID_AT_STATE, "id-at-state", "State" ), + { ADD_LEN( MBEDTLS_OID_AT_STATE ), "id-at-state", "State" }, "ST", }, { - OID_DESCRIPTOR( MBEDTLS_OID_AT_ORGANIZATION,"id-at-organizationName", "Organization" ), + { ADD_LEN( MBEDTLS_OID_AT_ORGANIZATION ),"id-at-organizationName", "Organization" }, "O", }, { - OID_DESCRIPTOR( MBEDTLS_OID_AT_ORG_UNIT, "id-at-organizationalUnitName", "Org Unit" ), + { ADD_LEN( MBEDTLS_OID_AT_ORG_UNIT ), "id-at-organizationalUnitName", "Org Unit" }, "OU", }, { - OID_DESCRIPTOR( MBEDTLS_OID_PKCS9_EMAIL, "emailAddress", "E-mail address" ), + { ADD_LEN( MBEDTLS_OID_PKCS9_EMAIL ), "emailAddress", "E-mail address" }, "emailAddress", }, { - OID_DESCRIPTOR( MBEDTLS_OID_AT_SERIAL_NUMBER,"id-at-serialNumber", "Serial number" ), + { ADD_LEN( MBEDTLS_OID_AT_SERIAL_NUMBER ),"id-at-serialNumber", "Serial number" }, "serialNumber", }, { - OID_DESCRIPTOR( MBEDTLS_OID_AT_POSTAL_ADDRESS,"id-at-postalAddress", "Postal address" ), + { ADD_LEN( MBEDTLS_OID_AT_POSTAL_ADDRESS ),"id-at-postalAddress", "Postal address" }, "postalAddress", }, { - OID_DESCRIPTOR( MBEDTLS_OID_AT_POSTAL_CODE, "id-at-postalCode", "Postal code" ), + { ADD_LEN( MBEDTLS_OID_AT_POSTAL_CODE ), "id-at-postalCode", "Postal code" }, "postalCode", }, { - OID_DESCRIPTOR( MBEDTLS_OID_AT_SUR_NAME, "id-at-surName", "Surname" ), + { ADD_LEN( MBEDTLS_OID_AT_SUR_NAME ), "id-at-surName", "Surname" }, "SN", }, { - OID_DESCRIPTOR( MBEDTLS_OID_AT_GIVEN_NAME, "id-at-givenName", "Given name" ), + { ADD_LEN( MBEDTLS_OID_AT_GIVEN_NAME ), "id-at-givenName", "Given name" }, "GN", }, { - OID_DESCRIPTOR( MBEDTLS_OID_AT_INITIALS, "id-at-initials", "Initials" ), + { ADD_LEN( MBEDTLS_OID_AT_INITIALS ), "id-at-initials", "Initials" }, "initials", }, { - OID_DESCRIPTOR( MBEDTLS_OID_AT_GENERATION_QUALIFIER, "id-at-generationQualifier", "Generation qualifier" ), + { ADD_LEN( MBEDTLS_OID_AT_GENERATION_QUALIFIER ), "id-at-generationQualifier", "Generation qualifier" }, "generationQualifier", }, { - OID_DESCRIPTOR( MBEDTLS_OID_AT_TITLE, "id-at-title", "Title" ), + { ADD_LEN( MBEDTLS_OID_AT_TITLE ), "id-at-title", "Title" }, "title", }, { - OID_DESCRIPTOR( MBEDTLS_OID_AT_DN_QUALIFIER,"id-at-dnQualifier", "Distinguished Name qualifier" ), + { ADD_LEN( MBEDTLS_OID_AT_DN_QUALIFIER ),"id-at-dnQualifier", "Distinguished Name qualifier" }, "dnQualifier", }, { - OID_DESCRIPTOR( MBEDTLS_OID_AT_PSEUDONYM, "id-at-pseudonym", "Pseudonym" ), + { ADD_LEN( MBEDTLS_OID_AT_PSEUDONYM ), "id-at-pseudonym", "Pseudonym" }, "pseudonym", }, { - OID_DESCRIPTOR( MBEDTLS_OID_DOMAIN_COMPONENT, "id-domainComponent", "Domain component" ), + { ADD_LEN( MBEDTLS_OID_DOMAIN_COMPONENT ), "id-domainComponent", "Domain component" }, "DC", }, { - OID_DESCRIPTOR( MBEDTLS_OID_AT_UNIQUE_IDENTIFIER, "id-at-uniqueIdentifier", "Unique Identifier" ), + { ADD_LEN( MBEDTLS_OID_AT_UNIQUE_IDENTIFIER ), "id-at-uniqueIdentifier", "Unique Identifier" }, "uniqueIdentifier", }, { - NULL_OID_DESCRIPTOR, + { NULL, 0, NULL, NULL }, NULL, } }; @@ -275,27 +259,27 @@ typedef struct { static const oid_x509_ext_t oid_x509_ext[] = { { - OID_DESCRIPTOR( MBEDTLS_OID_BASIC_CONSTRAINTS, "id-ce-basicConstraints", "Basic Constraints" ), + { ADD_LEN( MBEDTLS_OID_BASIC_CONSTRAINTS ), "id-ce-basicConstraints", "Basic Constraints" }, MBEDTLS_X509_EXT_BASIC_CONSTRAINTS, }, { - OID_DESCRIPTOR( MBEDTLS_OID_KEY_USAGE, "id-ce-keyUsage", "Key Usage" ), + { ADD_LEN( MBEDTLS_OID_KEY_USAGE ), "id-ce-keyUsage", "Key Usage" }, MBEDTLS_X509_EXT_KEY_USAGE, }, { - OID_DESCRIPTOR( MBEDTLS_OID_EXTENDED_KEY_USAGE, "id-ce-extKeyUsage", "Extended Key Usage" ), + { ADD_LEN( MBEDTLS_OID_EXTENDED_KEY_USAGE ), "id-ce-extKeyUsage", "Extended Key Usage" }, MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE, }, { - OID_DESCRIPTOR( MBEDTLS_OID_SUBJECT_ALT_NAME, "id-ce-subjectAltName", "Subject Alt Name" ), + { ADD_LEN( MBEDTLS_OID_SUBJECT_ALT_NAME ), "id-ce-subjectAltName", "Subject Alt Name" }, MBEDTLS_X509_EXT_SUBJECT_ALT_NAME, }, { - OID_DESCRIPTOR( MBEDTLS_OID_NS_CERT_TYPE, "id-netscape-certtype", "Netscape Certificate Type" ), + { ADD_LEN( MBEDTLS_OID_NS_CERT_TYPE ), "id-netscape-certtype", "Netscape Certificate Type" }, MBEDTLS_X509_EXT_NS_CERT_TYPE, }, { - NULL_OID_DESCRIPTOR, + { NULL, 0, NULL, NULL }, 0, }, }; @@ -303,22 +287,19 @@ static const oid_x509_ext_t oid_x509_ext[] = FN_OID_TYPED_FROM_ASN1(oid_x509_ext_t, x509_ext, oid_x509_ext) FN_OID_GET_ATTR1(mbedtls_oid_get_x509_ext_type, oid_x509_ext_t, x509_ext, int, ext_type) -#if !defined(MBEDTLS_X509_REMOVE_INFO) static const mbedtls_oid_descriptor_t oid_ext_key_usage[] = { - OID_DESCRIPTOR( MBEDTLS_OID_SERVER_AUTH, "id-kp-serverAuth", "TLS Web Server Authentication" ), - OID_DESCRIPTOR( MBEDTLS_OID_CLIENT_AUTH, "id-kp-clientAuth", "TLS Web Client Authentication" ), - OID_DESCRIPTOR( MBEDTLS_OID_CODE_SIGNING, "id-kp-codeSigning", "Code Signing" ), - OID_DESCRIPTOR( MBEDTLS_OID_EMAIL_PROTECTION, "id-kp-emailProtection", "E-mail Protection" ), - OID_DESCRIPTOR( MBEDTLS_OID_TIME_STAMPING, "id-kp-timeStamping", "Time Stamping" ), - OID_DESCRIPTOR( MBEDTLS_OID_OCSP_SIGNING, "id-kp-OCSPSigning", "OCSP Signing" ), - NULL_OID_DESCRIPTOR, + { ADD_LEN( MBEDTLS_OID_SERVER_AUTH ), "id-kp-serverAuth", "TLS Web Server Authentication" }, + { ADD_LEN( MBEDTLS_OID_CLIENT_AUTH ), "id-kp-clientAuth", "TLS Web Client Authentication" }, + { ADD_LEN( MBEDTLS_OID_CODE_SIGNING ), "id-kp-codeSigning", "Code Signing" }, + { ADD_LEN( MBEDTLS_OID_EMAIL_PROTECTION ), "id-kp-emailProtection", "E-mail Protection" }, + { ADD_LEN( MBEDTLS_OID_TIME_STAMPING ), "id-kp-timeStamping", "Time Stamping" }, + { ADD_LEN( MBEDTLS_OID_OCSP_SIGNING ), "id-kp-OCSPSigning", "OCSP Signing" }, + { NULL, 0, NULL, NULL }, }; FN_OID_TYPED_FROM_ASN1(mbedtls_oid_descriptor_t, ext_key_usage, oid_ext_key_usage) FN_OID_GET_ATTR1(mbedtls_oid_get_extended_key_usage, mbedtls_oid_descriptor_t, ext_key_usage, const char *, description) -#endif /* !MBEDTLS_X509_REMOVE_INFO */ - #endif /* MBEDTLS_X509_USE_C || MBEDTLS_X509_CREATE_C */ #if defined(MBEDTLS_MD_C) @@ -336,101 +317,97 @@ static const oid_sig_alg_t oid_sig_alg[] = #if defined(MBEDTLS_RSA_C) #if defined(MBEDTLS_MD2_C) { - OID_DESCRIPTOR( MBEDTLS_OID_PKCS1_MD2, "md2WithRSAEncryption", "RSA with MD2" ), + { ADD_LEN( MBEDTLS_OID_PKCS1_MD2 ), "md2WithRSAEncryption", "RSA with MD2" }, MBEDTLS_MD_MD2, MBEDTLS_PK_RSA, }, #endif /* MBEDTLS_MD2_C */ #if defined(MBEDTLS_MD4_C) { - OID_DESCRIPTOR( MBEDTLS_OID_PKCS1_MD4, "md4WithRSAEncryption", "RSA with MD4" ), + { ADD_LEN( MBEDTLS_OID_PKCS1_MD4 ), "md4WithRSAEncryption", "RSA with MD4" }, MBEDTLS_MD_MD4, MBEDTLS_PK_RSA, }, #endif /* MBEDTLS_MD4_C */ #if defined(MBEDTLS_MD5_C) { - OID_DESCRIPTOR( MBEDTLS_OID_PKCS1_MD5, "md5WithRSAEncryption", "RSA with MD5" ), + { ADD_LEN( MBEDTLS_OID_PKCS1_MD5 ), "md5WithRSAEncryption", "RSA with MD5" }, MBEDTLS_MD_MD5, MBEDTLS_PK_RSA, }, #endif /* MBEDTLS_MD5_C */ #if defined(MBEDTLS_SHA1_C) { - OID_DESCRIPTOR( MBEDTLS_OID_PKCS1_SHA1, "sha-1WithRSAEncryption", "RSA with SHA1" ), + { ADD_LEN( MBEDTLS_OID_PKCS1_SHA1 ), "sha-1WithRSAEncryption", "RSA with SHA1" }, MBEDTLS_MD_SHA1, MBEDTLS_PK_RSA, }, #endif /* MBEDTLS_SHA1_C */ #if defined(MBEDTLS_SHA256_C) { - OID_DESCRIPTOR( MBEDTLS_OID_PKCS1_SHA224, "sha224WithRSAEncryption", "RSA with SHA-224" ), + { ADD_LEN( MBEDTLS_OID_PKCS1_SHA224 ), "sha224WithRSAEncryption", "RSA with SHA-224" }, MBEDTLS_MD_SHA224, MBEDTLS_PK_RSA, }, { - OID_DESCRIPTOR( MBEDTLS_OID_PKCS1_SHA256, "sha256WithRSAEncryption", "RSA with SHA-256" ), + { ADD_LEN( MBEDTLS_OID_PKCS1_SHA256 ), "sha256WithRSAEncryption", "RSA with SHA-256" }, MBEDTLS_MD_SHA256, MBEDTLS_PK_RSA, }, #endif /* MBEDTLS_SHA256_C */ #if defined(MBEDTLS_SHA512_C) { - OID_DESCRIPTOR( MBEDTLS_OID_PKCS1_SHA384, "sha384WithRSAEncryption", "RSA with SHA-384" ), + { ADD_LEN( MBEDTLS_OID_PKCS1_SHA384 ), "sha384WithRSAEncryption", "RSA with SHA-384" }, MBEDTLS_MD_SHA384, MBEDTLS_PK_RSA, }, { - OID_DESCRIPTOR( MBEDTLS_OID_PKCS1_SHA512, "sha512WithRSAEncryption", "RSA with SHA-512" ), + { ADD_LEN( MBEDTLS_OID_PKCS1_SHA512 ), "sha512WithRSAEncryption", "RSA with SHA-512" }, MBEDTLS_MD_SHA512, MBEDTLS_PK_RSA, }, #endif /* MBEDTLS_SHA512_C */ #if defined(MBEDTLS_SHA1_C) { - OID_DESCRIPTOR( MBEDTLS_OID_RSA_SHA_OBS, "sha-1WithRSAEncryption", "RSA with SHA1" ), + { ADD_LEN( MBEDTLS_OID_RSA_SHA_OBS ), "sha-1WithRSAEncryption", "RSA with SHA1" }, MBEDTLS_MD_SHA1, MBEDTLS_PK_RSA, }, #endif /* MBEDTLS_SHA1_C */ #endif /* MBEDTLS_RSA_C */ -#if defined(MBEDTLS_ECDSA_C) || defined(MBEDTLS_USE_TINYCRYPT) +#if defined(MBEDTLS_ECDSA_C) #if defined(MBEDTLS_SHA1_C) { - OID_DESCRIPTOR( MBEDTLS_OID_ECDSA_SHA1, "ecdsa-with-SHA1", "ECDSA with SHA1" ), + { ADD_LEN( MBEDTLS_OID_ECDSA_SHA1 ), "ecdsa-with-SHA1", "ECDSA with SHA1" }, MBEDTLS_MD_SHA1, MBEDTLS_PK_ECDSA, }, #endif /* MBEDTLS_SHA1_C */ #if defined(MBEDTLS_SHA256_C) { - OID_DESCRIPTOR( MBEDTLS_OID_ECDSA_SHA224, "ecdsa-with-SHA224", "ECDSA with SHA224" ), + { ADD_LEN( MBEDTLS_OID_ECDSA_SHA224 ), "ecdsa-with-SHA224", "ECDSA with SHA224" }, MBEDTLS_MD_SHA224, MBEDTLS_PK_ECDSA, }, { - OID_DESCRIPTOR( MBEDTLS_OID_ECDSA_SHA256, "ecdsa-with-SHA256", "ECDSA with SHA256" ), + { ADD_LEN( MBEDTLS_OID_ECDSA_SHA256 ), "ecdsa-with-SHA256", "ECDSA with SHA256" }, MBEDTLS_MD_SHA256, MBEDTLS_PK_ECDSA, }, #endif /* MBEDTLS_SHA256_C */ #if defined(MBEDTLS_SHA512_C) { - OID_DESCRIPTOR( MBEDTLS_OID_ECDSA_SHA384, "ecdsa-with-SHA384", "ECDSA with SHA384" ), + { ADD_LEN( MBEDTLS_OID_ECDSA_SHA384 ), "ecdsa-with-SHA384", "ECDSA with SHA384" }, MBEDTLS_MD_SHA384, MBEDTLS_PK_ECDSA, }, { - OID_DESCRIPTOR( MBEDTLS_OID_ECDSA_SHA512, "ecdsa-with-SHA512", "ECDSA with SHA512" ), + { ADD_LEN( MBEDTLS_OID_ECDSA_SHA512 ), "ecdsa-with-SHA512", "ECDSA with SHA512" }, MBEDTLS_MD_SHA512, MBEDTLS_PK_ECDSA, }, #endif /* MBEDTLS_SHA512_C */ -#endif /* MBEDTLS_ECDSA_C || MBEDTLS_USE_TINYCRYPT */ +#endif /* MBEDTLS_ECDSA_C */ #if defined(MBEDTLS_RSA_C) { - OID_DESCRIPTOR( MBEDTLS_OID_RSASSA_PSS, "RSASSA-PSS", "RSASSA-PSS" ), + { ADD_LEN( MBEDTLS_OID_RSASSA_PSS ), "RSASSA-PSS", "RSASSA-PSS" }, MBEDTLS_MD_NONE, MBEDTLS_PK_RSASSA_PSS, }, #endif /* MBEDTLS_RSA_C */ { - NULL_OID_DESCRIPTOR, + { NULL, 0, NULL, NULL }, MBEDTLS_MD_NONE, MBEDTLS_PK_NONE, }, }; FN_OID_TYPED_FROM_ASN1(oid_sig_alg_t, sig_alg, oid_sig_alg) - -#if !defined(MBEDTLS_X509_REMOVE_INFO) FN_OID_GET_DESCRIPTOR_ATTR1(mbedtls_oid_get_sig_alg_desc, oid_sig_alg_t, sig_alg, const char *, description) -#endif - FN_OID_GET_ATTR2(mbedtls_oid_get_sig_alg, oid_sig_alg_t, sig_alg, mbedtls_md_type_t, md_alg, mbedtls_pk_type_t, pk_alg) FN_OID_GET_OID_BY_ATTR2(mbedtls_oid_get_oid_by_sig_alg, oid_sig_alg_t, oid_sig_alg, mbedtls_pk_type_t, pk_alg, mbedtls_md_type_t, md_alg) #endif /* MBEDTLS_MD_C */ @@ -446,19 +423,19 @@ typedef struct { static const oid_pk_alg_t oid_pk_alg[] = { { - OID_DESCRIPTOR( MBEDTLS_OID_PKCS1_RSA, "rsaEncryption", "RSA" ), + { ADD_LEN( MBEDTLS_OID_PKCS1_RSA ), "rsaEncryption", "RSA" }, MBEDTLS_PK_RSA, }, { - OID_DESCRIPTOR( MBEDTLS_OID_EC_ALG_UNRESTRICTED, "id-ecPublicKey", "Generic EC key" ), + { ADD_LEN( MBEDTLS_OID_EC_ALG_UNRESTRICTED ), "id-ecPublicKey", "Generic EC key" }, MBEDTLS_PK_ECKEY, }, { - OID_DESCRIPTOR( MBEDTLS_OID_EC_ALG_ECDH, "id-ecDH", "EC key for ECDH" ), + { ADD_LEN( MBEDTLS_OID_EC_ALG_ECDH ), "id-ecDH", "EC key for ECDH" }, MBEDTLS_PK_ECKEY_DH, }, { - NULL_OID_DESCRIPTOR, + { NULL, 0, NULL, NULL }, MBEDTLS_PK_NONE, }, }; @@ -467,12 +444,6 @@ FN_OID_TYPED_FROM_ASN1(oid_pk_alg_t, pk_alg, oid_pk_alg) FN_OID_GET_ATTR1(mbedtls_oid_get_pk_alg, oid_pk_alg_t, pk_alg, mbedtls_pk_type_t, pk_alg) FN_OID_GET_OID_BY_ATTR1(mbedtls_oid_get_oid_by_pk_alg, oid_pk_alg_t, oid_pk_alg, mbedtls_pk_type_t, pk_alg) -#if defined(MBEDTLS_USE_TINYCRYPT) -typedef struct { - mbedtls_oid_descriptor_t descriptor; - mbedtls_uecc_group_id grp_id; -} oid_ecp_grp_t; -#else #if defined(MBEDTLS_ECP_C) /* * For namedCurve (RFC 5480) @@ -481,96 +452,77 @@ typedef struct { mbedtls_oid_descriptor_t descriptor; mbedtls_ecp_group_id grp_id; } oid_ecp_grp_t; -#endif -#endif -#if defined(MBEDTLS_USE_TINYCRYPT) -static const oid_ecp_grp_t oid_ecp_grp[] = -{ - { - OID_DESCRIPTOR( MBEDTLS_OID_EC_GRP_SECP256R1 , "secp256r1", "secp256r1" ), - MBEDTLS_UECC_DP_SECP256R1, - }, - { - NULL_OID_DESCRIPTOR, - MBEDTLS_UECC_DP_NONE, - }, -}; -FN_OID_TYPED_FROM_ASN1(oid_ecp_grp_t, grp_id, oid_ecp_grp) -FN_OID_GET_ATTR1(mbedtls_oid_get_ec_grp, oid_ecp_grp_t, grp_id, mbedtls_uecc_group_id, grp_id) -FN_OID_GET_OID_BY_ATTR1(mbedtls_oid_get_oid_by_ec_grp, oid_ecp_grp_t, oid_ecp_grp, mbedtls_uecc_group_id, grp_id) -#else -#if defined(MBEDTLS_ECP_C) static const oid_ecp_grp_t oid_ecp_grp[] = { #if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) { - OID_DESCRIPTOR( MBEDTLS_OID_EC_GRP_SECP192R1, "secp192r1", "secp192r1" ), + { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP192R1 ), "secp192r1", "secp192r1" }, MBEDTLS_ECP_DP_SECP192R1, }, #endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */ #if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) { - OID_DESCRIPTOR( MBEDTLS_OID_EC_GRP_SECP224R1, "secp224r1", "secp224r1" ), + { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP224R1 ), "secp224r1", "secp224r1" }, MBEDTLS_ECP_DP_SECP224R1, }, #endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */ #if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) { - OID_DESCRIPTOR( MBEDTLS_OID_EC_GRP_SECP256R1, "secp256r1", "secp256r1" ), + { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP256R1 ), "secp256r1", "secp256r1" }, MBEDTLS_ECP_DP_SECP256R1, }, #endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */ #if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) { - OID_DESCRIPTOR( MBEDTLS_OID_EC_GRP_SECP384R1, "secp384r1", "secp384r1" ), + { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP384R1 ), "secp384r1", "secp384r1" }, MBEDTLS_ECP_DP_SECP384R1, }, #endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */ #if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) { - OID_DESCRIPTOR( MBEDTLS_OID_EC_GRP_SECP521R1, "secp521r1", "secp521r1" ), + { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP521R1 ), "secp521r1", "secp521r1" }, MBEDTLS_ECP_DP_SECP521R1, }, #endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */ #if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) { - OID_DESCRIPTOR( MBEDTLS_OID_EC_GRP_SECP192K1, "secp192k1", "secp192k1" ), + { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP192K1 ), "secp192k1", "secp192k1" }, MBEDTLS_ECP_DP_SECP192K1, }, #endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */ #if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) { - OID_DESCRIPTOR( MBEDTLS_OID_EC_GRP_SECP224K1, "secp224k1", "secp224k1" ), + { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP224K1 ), "secp224k1", "secp224k1" }, MBEDTLS_ECP_DP_SECP224K1, }, #endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */ #if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) { - OID_DESCRIPTOR( MBEDTLS_OID_EC_GRP_SECP256K1, "secp256k1", "secp256k1" ), + { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP256K1 ), "secp256k1", "secp256k1" }, MBEDTLS_ECP_DP_SECP256K1, }, #endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */ #if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) { - OID_DESCRIPTOR( MBEDTLS_OID_EC_GRP_BP256R1, "brainpoolP256r1","brainpool256r1" ), + { ADD_LEN( MBEDTLS_OID_EC_GRP_BP256R1 ), "brainpoolP256r1","brainpool256r1" }, MBEDTLS_ECP_DP_BP256R1, }, #endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */ #if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) { - OID_DESCRIPTOR( MBEDTLS_OID_EC_GRP_BP384R1, "brainpoolP384r1","brainpool384r1" ), + { ADD_LEN( MBEDTLS_OID_EC_GRP_BP384R1 ), "brainpoolP384r1","brainpool384r1" }, MBEDTLS_ECP_DP_BP384R1, }, #endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */ #if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) { - OID_DESCRIPTOR( MBEDTLS_OID_EC_GRP_BP512R1, "brainpoolP512r1","brainpool512r1" ), + { ADD_LEN( MBEDTLS_OID_EC_GRP_BP512R1 ), "brainpoolP512r1","brainpool512r1" }, MBEDTLS_ECP_DP_BP512R1, }, #endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */ { - NULL_OID_DESCRIPTOR, + { NULL, 0, NULL, NULL }, MBEDTLS_ECP_DP_NONE, }, }; @@ -579,7 +531,6 @@ FN_OID_TYPED_FROM_ASN1(oid_ecp_grp_t, grp_id, oid_ecp_grp) FN_OID_GET_ATTR1(mbedtls_oid_get_ec_grp, oid_ecp_grp_t, grp_id, mbedtls_ecp_group_id, grp_id) FN_OID_GET_OID_BY_ATTR1(mbedtls_oid_get_oid_by_ec_grp, oid_ecp_grp_t, oid_ecp_grp, mbedtls_ecp_group_id, grp_id) #endif /* MBEDTLS_ECP_C */ -#endif #if defined(MBEDTLS_CIPHER_C) /* @@ -593,15 +544,15 @@ typedef struct { static const oid_cipher_alg_t oid_cipher_alg[] = { { - OID_DESCRIPTOR( MBEDTLS_OID_DES_CBC, "desCBC", "DES-CBC" ), + { ADD_LEN( MBEDTLS_OID_DES_CBC ), "desCBC", "DES-CBC" }, MBEDTLS_CIPHER_DES_CBC, }, { - OID_DESCRIPTOR( MBEDTLS_OID_DES_EDE3_CBC, "des-ede3-cbc", "DES-EDE3-CBC" ), + { ADD_LEN( MBEDTLS_OID_DES_EDE3_CBC ), "des-ede3-cbc", "DES-EDE3-CBC" }, MBEDTLS_CIPHER_DES_EDE3_CBC, }, { - NULL_OID_DESCRIPTOR, + { NULL, 0, NULL, NULL }, MBEDTLS_CIPHER_NONE, }, }; @@ -623,50 +574,50 @@ static const oid_md_alg_t oid_md_alg[] = { #if defined(MBEDTLS_MD2_C) { - OID_DESCRIPTOR( MBEDTLS_OID_DIGEST_ALG_MD2, "id-md2", "MD2" ), + { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_MD2 ), "id-md2", "MD2" }, MBEDTLS_MD_MD2, }, #endif /* MBEDTLS_MD2_C */ #if defined(MBEDTLS_MD4_C) { - OID_DESCRIPTOR( MBEDTLS_OID_DIGEST_ALG_MD4, "id-md4", "MD4" ), + { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_MD4 ), "id-md4", "MD4" }, MBEDTLS_MD_MD4, }, #endif /* MBEDTLS_MD4_C */ #if defined(MBEDTLS_MD5_C) { - OID_DESCRIPTOR( MBEDTLS_OID_DIGEST_ALG_MD5, "id-md5", "MD5" ), + { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_MD5 ), "id-md5", "MD5" }, MBEDTLS_MD_MD5, }, #endif /* MBEDTLS_MD5_C */ #if defined(MBEDTLS_SHA1_C) { - OID_DESCRIPTOR( MBEDTLS_OID_DIGEST_ALG_SHA1, "id-sha1", "SHA-1" ), + { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA1 ), "id-sha1", "SHA-1" }, MBEDTLS_MD_SHA1, }, #endif /* MBEDTLS_SHA1_C */ #if defined(MBEDTLS_SHA256_C) { - OID_DESCRIPTOR( MBEDTLS_OID_DIGEST_ALG_SHA224, "id-sha224", "SHA-224" ), + { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA224 ), "id-sha224", "SHA-224" }, MBEDTLS_MD_SHA224, }, { - OID_DESCRIPTOR( MBEDTLS_OID_DIGEST_ALG_SHA256, "id-sha256", "SHA-256" ), + { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA256 ), "id-sha256", "SHA-256" }, MBEDTLS_MD_SHA256, }, #endif /* MBEDTLS_SHA256_C */ #if defined(MBEDTLS_SHA512_C) { - OID_DESCRIPTOR( MBEDTLS_OID_DIGEST_ALG_SHA384, "id-sha384", "SHA-384" ), + { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA384 ), "id-sha384", "SHA-384" }, MBEDTLS_MD_SHA384, }, { - OID_DESCRIPTOR( MBEDTLS_OID_DIGEST_ALG_SHA512, "id-sha512", "SHA-512" ), + { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA512 ), "id-sha512", "SHA-512" }, MBEDTLS_MD_SHA512, }, #endif /* MBEDTLS_SHA512_C */ { - NULL_OID_DESCRIPTOR, + { NULL, 0, NULL, NULL }, MBEDTLS_MD_NONE, }, }; @@ -687,32 +638,32 @@ static const oid_md_hmac_t oid_md_hmac[] = { #if defined(MBEDTLS_SHA1_C) { - OID_DESCRIPTOR( MBEDTLS_OID_HMAC_SHA1, "hmacSHA1", "HMAC-SHA-1" ), + { ADD_LEN( MBEDTLS_OID_HMAC_SHA1 ), "hmacSHA1", "HMAC-SHA-1" }, MBEDTLS_MD_SHA1, }, #endif /* MBEDTLS_SHA1_C */ #if defined(MBEDTLS_SHA256_C) { - OID_DESCRIPTOR( MBEDTLS_OID_HMAC_SHA224, "hmacSHA224", "HMAC-SHA-224" ), + { ADD_LEN( MBEDTLS_OID_HMAC_SHA224 ), "hmacSHA224", "HMAC-SHA-224" }, MBEDTLS_MD_SHA224, }, { - OID_DESCRIPTOR( MBEDTLS_OID_HMAC_SHA256, "hmacSHA256", "HMAC-SHA-256" ), + { ADD_LEN( MBEDTLS_OID_HMAC_SHA256 ), "hmacSHA256", "HMAC-SHA-256" }, MBEDTLS_MD_SHA256, }, #endif /* MBEDTLS_SHA256_C */ #if defined(MBEDTLS_SHA512_C) { - OID_DESCRIPTOR( MBEDTLS_OID_HMAC_SHA384, "hmacSHA384", "HMAC-SHA-384" ), + { ADD_LEN( MBEDTLS_OID_HMAC_SHA384 ), "hmacSHA384", "HMAC-SHA-384" }, MBEDTLS_MD_SHA384, }, { - OID_DESCRIPTOR( MBEDTLS_OID_HMAC_SHA512, "hmacSHA512", "HMAC-SHA-512" ), + { ADD_LEN( MBEDTLS_OID_HMAC_SHA512 ), "hmacSHA512", "HMAC-SHA-512" }, MBEDTLS_MD_SHA512, }, #endif /* MBEDTLS_SHA512_C */ { - NULL_OID_DESCRIPTOR, + { NULL, 0, NULL, NULL }, MBEDTLS_MD_NONE, }, }; @@ -734,15 +685,15 @@ typedef struct { static const oid_pkcs12_pbe_alg_t oid_pkcs12_pbe_alg[] = { { - OID_DESCRIPTOR( MBEDTLS_OID_PKCS12_PBE_SHA1_DES3_EDE_CBC, "pbeWithSHAAnd3-KeyTripleDES-CBC", "PBE with SHA1 and 3-Key 3DES" ), + { ADD_LEN( MBEDTLS_OID_PKCS12_PBE_SHA1_DES3_EDE_CBC ), "pbeWithSHAAnd3-KeyTripleDES-CBC", "PBE with SHA1 and 3-Key 3DES" }, MBEDTLS_MD_SHA1, MBEDTLS_CIPHER_DES_EDE3_CBC, }, { - OID_DESCRIPTOR( MBEDTLS_OID_PKCS12_PBE_SHA1_DES2_EDE_CBC, "pbeWithSHAAnd2-KeyTripleDES-CBC", "PBE with SHA1 and 2-Key 3DES" ), + { ADD_LEN( MBEDTLS_OID_PKCS12_PBE_SHA1_DES2_EDE_CBC ), "pbeWithSHAAnd2-KeyTripleDES-CBC", "PBE with SHA1 and 2-Key 3DES" }, MBEDTLS_MD_SHA1, MBEDTLS_CIPHER_DES_EDE_CBC, }, { - NULL_OID_DESCRIPTOR, + { NULL, 0, NULL, NULL }, MBEDTLS_MD_NONE, MBEDTLS_CIPHER_NONE, }, }; diff --git a/APP_Framework/Framework/security/mbedtls/oid.h b/APP_Framework/Framework/security/mbedtls/oid.h index 584c47003..408645ece 100644 --- a/APP_Framework/Framework/security/mbedtls/oid.h +++ b/APP_Framework/Framework/security/mbedtls/oid.h @@ -97,8 +97,6 @@ /* ISO arc for standard certificate and CRL extensions */ #define MBEDTLS_OID_ID_CE MBEDTLS_OID_ISO_CCITT_DS "\x1D" /**< id-ce OBJECT IDENTIFIER ::= {joint-iso-ccitt(2) ds(5) 29} */ -#define MBEDTLS_OID_NIST_ALG MBEDTLS_OID_GOV "\x03\x04" /** { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithm(4) */ - /** * Private Internet Extensions * { iso(1) identified-organization(3) dod(6) internet(1) @@ -221,12 +219,12 @@ #define MBEDTLS_OID_DIGEST_ALG_MD4 MBEDTLS_OID_RSA_COMPANY "\x02\x04" /**< id-mbedtls_md4 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 4 } */ #define MBEDTLS_OID_DIGEST_ALG_MD5 MBEDTLS_OID_RSA_COMPANY "\x02\x05" /**< id-mbedtls_md5 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 5 } */ #define MBEDTLS_OID_DIGEST_ALG_SHA1 MBEDTLS_OID_ISO_IDENTIFIED_ORG MBEDTLS_OID_OIW_SECSIG_SHA1 /**< id-mbedtls_sha1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) oiw(14) secsig(3) algorithms(2) 26 } */ -#define MBEDTLS_OID_DIGEST_ALG_SHA224 MBEDTLS_OID_NIST_ALG "\x02\x04" /**< id-sha224 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 4 } */ -#define MBEDTLS_OID_DIGEST_ALG_SHA256 MBEDTLS_OID_NIST_ALG "\x02\x01" /**< id-mbedtls_sha256 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 1 } */ +#define MBEDTLS_OID_DIGEST_ALG_SHA224 MBEDTLS_OID_GOV "\x03\x04\x02\x04" /**< id-sha224 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 4 } */ +#define MBEDTLS_OID_DIGEST_ALG_SHA256 MBEDTLS_OID_GOV "\x03\x04\x02\x01" /**< id-mbedtls_sha256 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 1 } */ -#define MBEDTLS_OID_DIGEST_ALG_SHA384 MBEDTLS_OID_NIST_ALG "\x02\x02" /**< id-sha384 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 2 } */ +#define MBEDTLS_OID_DIGEST_ALG_SHA384 MBEDTLS_OID_GOV "\x03\x04\x02\x02" /**< id-sha384 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 2 } */ -#define MBEDTLS_OID_DIGEST_ALG_SHA512 MBEDTLS_OID_NIST_ALG "\x02\x03" /**< id-mbedtls_sha512 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 3 } */ +#define MBEDTLS_OID_DIGEST_ALG_SHA512 MBEDTLS_OID_GOV "\x03\x04\x02\x03" /**< id-mbedtls_sha512 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 3 } */ #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 } */ @@ -243,20 +241,7 @@ */ #define MBEDTLS_OID_DES_CBC MBEDTLS_OID_ISO_IDENTIFIED_ORG MBEDTLS_OID_OIW_SECSIG_ALG "\x07" /**< desCBC OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) oiw(14) secsig(3) algorithms(2) 7 } */ #define MBEDTLS_OID_DES_EDE3_CBC MBEDTLS_OID_RSA_COMPANY "\x03\x07" /**< des-ede3-cbc OBJECT IDENTIFIER ::= { iso(1) member-body(2) -- us(840) rsadsi(113549) encryptionAlgorithm(3) 7 } */ -#define MBEDTLS_OID_AES MBEDTLS_OID_NIST_ALG "\x01" /** aes OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithm(4) 1 } */ -/* - * Key Wrapping algorithms - */ -/* - * RFC 5649 - */ -#define MBEDTLS_OID_AES128_KW MBEDTLS_OID_AES "\x05" /** id-aes128-wrap OBJECT IDENTIFIER ::= { aes 5 } */ -#define MBEDTLS_OID_AES128_KWP MBEDTLS_OID_AES "\x08" /** id-aes128-wrap-pad OBJECT IDENTIFIER ::= { aes 8 } */ -#define MBEDTLS_OID_AES192_KW MBEDTLS_OID_AES "\x19" /** id-aes192-wrap OBJECT IDENTIFIER ::= { aes 25 } */ -#define MBEDTLS_OID_AES192_KWP MBEDTLS_OID_AES "\x1c" /** id-aes192-wrap-pad OBJECT IDENTIFIER ::= { aes 28 } */ -#define MBEDTLS_OID_AES256_KW MBEDTLS_OID_AES "\x2d" /** id-aes256-wrap OBJECT IDENTIFIER ::= { aes 45 } */ -#define MBEDTLS_OID_AES256_KWP MBEDTLS_OID_AES "\x30" /** id-aes256-wrap-pad OBJECT IDENTIFIER ::= { aes 48 } */ /* * PKCS#5 OIDs */ @@ -403,14 +388,11 @@ extern "C" { /** * \brief Base OID descriptor structure */ -typedef struct mbedtls_oid_descriptor_t -{ +typedef struct { const char *asn1; /*!< OID ASN.1 representation */ size_t asn1_len; /*!< length of asn1 */ -#if !defined(MBEDTLS_X509_REMOVE_INFO) const char *name; /*!< official name (e.g. from RFC) */ const char *description; /*!< human friendly description */ -#endif } mbedtls_oid_descriptor_t; /** @@ -471,18 +453,6 @@ int mbedtls_oid_get_pk_alg( const mbedtls_asn1_buf *oid, mbedtls_pk_type_t *pk_a int mbedtls_oid_get_oid_by_pk_alg( mbedtls_pk_type_t pk_alg, const char **oid, size_t *olen ); -#if defined(MBEDTLS_USE_TINYCRYPT) -typedef enum -{ - MBEDTLS_UECC_DP_NONE = 0, /*!< Curve not defined. */ - MBEDTLS_UECC_DP_SECP256R1, /*!< Domain parameters for the 256-bit curve defined by FIPS 186-4 and SEC1. */ -} mbedtls_uecc_group_id; - -int mbedtls_oid_get_ec_grp( const mbedtls_asn1_buf *oid, mbedtls_uecc_group_id *grp_id ); - -int mbedtls_oid_get_oid_by_ec_grp( mbedtls_uecc_group_id grp_id, - const char **oid, size_t *olen); -#else #if defined(MBEDTLS_ECP_C) /** * \brief Translate NamedCurve OID into an EC group identifier @@ -506,7 +476,6 @@ int mbedtls_oid_get_ec_grp( const mbedtls_asn1_buf *oid, mbedtls_ecp_group_id *g int mbedtls_oid_get_oid_by_ec_grp( mbedtls_ecp_group_id grp_id, const char **oid, size_t *olen ); #endif /* MBEDTLS_ECP_C */ -#endif #if defined(MBEDTLS_MD_C) /** @@ -565,7 +534,6 @@ int mbedtls_oid_get_md_alg( const mbedtls_asn1_buf *oid, mbedtls_md_type_t *md_a int mbedtls_oid_get_md_hmac( const mbedtls_asn1_buf *oid, mbedtls_md_type_t *md_hmac ); #endif /* MBEDTLS_MD_C */ -#if !defined(MBEDTLS_X509_REMOVE_INFO) /** * \brief Translate Extended Key Usage OID into description * @@ -575,7 +543,6 @@ int mbedtls_oid_get_md_hmac( const mbedtls_asn1_buf *oid, mbedtls_md_type_t *md_ * \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND */ int mbedtls_oid_get_extended_key_usage( const mbedtls_asn1_buf *oid, const char **desc ); -#endif /** * \brief Translate md_type into hash algorithm OID diff --git a/APP_Framework/Framework/security/mbedtls/padlock.c b/APP_Framework/Framework/security/mbedtls/padlock.c new file mode 100644 index 000000000..e065974ee --- /dev/null +++ b/APP_Framework/Framework/security/mbedtls/padlock.c @@ -0,0 +1,170 @@ +/* + * VIA PadLock support functions + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +/* + * This implementation is based on the VIA PadLock Programming Guide: + * + * http://www.via.com.tw/en/downloads/whitepapers/initiatives/padlock/ + * programming_guide.pdf + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_PADLOCK_C) + +#include "padlock.h" + +#include + +#ifndef asm +#define asm __asm +#endif + +#if defined(MBEDTLS_HAVE_X86) + +/* + * PadLock detection routine + */ +int mbedtls_padlock_has_support( int feature ) +{ + static int flags = -1; + int ebx = 0, edx = 0; + + if( flags == -1 ) + { + asm( "movl %%ebx, %0 \n\t" + "movl $0xC0000000, %%eax \n\t" + "cpuid \n\t" + "cmpl $0xC0000001, %%eax \n\t" + "movl $0, %%edx \n\t" + "jb unsupported \n\t" + "movl $0xC0000001, %%eax \n\t" + "cpuid \n\t" + "unsupported: \n\t" + "movl %%edx, %1 \n\t" + "movl %2, %%ebx \n\t" + : "=m" (ebx), "=m" (edx) + : "m" (ebx) + : "eax", "ecx", "edx" ); + + flags = edx; + } + + return( flags & feature ); +} + +/* + * PadLock AES-ECB block en(de)cryption + */ +int mbedtls_padlock_xcryptecb( mbedtls_aes_context *ctx, + int mode, + const unsigned char input[16], + unsigned char output[16] ) +{ + int ebx = 0; + uint32_t *rk; + uint32_t *blk; + uint32_t *ctrl; + unsigned char buf[256]; + + rk = ctx->rk; + blk = MBEDTLS_PADLOCK_ALIGN16( buf ); + memcpy( blk, input, 16 ); + + ctrl = blk + 4; + *ctrl = 0x80 | ctx->nr | ( ( ctx->nr + ( mode^1 ) - 10 ) << 9 ); + + asm( "pushfl \n\t" + "popfl \n\t" + "movl %%ebx, %0 \n\t" + "movl $1, %%ecx \n\t" + "movl %2, %%edx \n\t" + "movl %3, %%ebx \n\t" + "movl %4, %%esi \n\t" + "movl %4, %%edi \n\t" + ".byte 0xf3,0x0f,0xa7,0xc8 \n\t" + "movl %1, %%ebx \n\t" + : "=m" (ebx) + : "m" (ebx), "m" (ctrl), "m" (rk), "m" (blk) + : "memory", "ecx", "edx", "esi", "edi" ); + + memcpy( output, blk, 16 ); + + return( 0 ); +} + +/* + * PadLock AES-CBC buffer en(de)cryption + */ +int mbedtls_padlock_xcryptcbc( mbedtls_aes_context *ctx, + int mode, + size_t length, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ) +{ + int ebx = 0; + size_t count; + uint32_t *rk; + uint32_t *iw; + uint32_t *ctrl; + unsigned char buf[256]; + + if( ( (long) input & 15 ) != 0 || + ( (long) output & 15 ) != 0 ) + return( MBEDTLS_ERR_PADLOCK_DATA_MISALIGNED ); + + rk = ctx->rk; + iw = MBEDTLS_PADLOCK_ALIGN16( buf ); + memcpy( iw, iv, 16 ); + + ctrl = iw + 4; + *ctrl = 0x80 | ctx->nr | ( ( ctx->nr + ( mode ^ 1 ) - 10 ) << 9 ); + + count = ( length + 15 ) >> 4; + + asm( "pushfl \n\t" + "popfl \n\t" + "movl %%ebx, %0 \n\t" + "movl %2, %%ecx \n\t" + "movl %3, %%edx \n\t" + "movl %4, %%ebx \n\t" + "movl %5, %%esi \n\t" + "movl %6, %%edi \n\t" + "movl %7, %%eax \n\t" + ".byte 0xf3,0x0f,0xa7,0xd0 \n\t" + "movl %1, %%ebx \n\t" + : "=m" (ebx) + : "m" (ebx), "m" (count), "m" (ctrl), + "m" (rk), "m" (input), "m" (output), "m" (iw) + : "memory", "eax", "ecx", "edx", "esi", "edi" ); + + memcpy( iv, iw, 16 ); + + return( 0 ); +} + +#endif /* MBEDTLS_HAVE_X86 */ + +#endif /* MBEDTLS_PADLOCK_C */ diff --git a/APP_Framework/Framework/security/mbedtls/padlock.h b/APP_Framework/Framework/security/mbedtls/padlock.h index 721a5d493..918e6195a 100644 --- a/APP_Framework/Framework/security/mbedtls/padlock.h +++ b/APP_Framework/Framework/security/mbedtls/padlock.h @@ -3,9 +3,6 @@ * * \brief VIA PadLock ACE for HW encryption/decryption supported by some * processors - * - * \warning These functions are only for internal use by other library - * functions; you must not call them directly. */ /* * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved @@ -59,17 +56,14 @@ #define MBEDTLS_PADLOCK_PHE 0x0C00 #define MBEDTLS_PADLOCK_PMM 0x3000 -#define MBEDTLS_PADLOCK_ALIGN16(x) (uint32_t *) (16 + ((int32_t) (x) & ~15)) +#define MBEDTLS_PADLOCK_ALIGN16(x) (uint32_t *) (16 + ((int32_t) x & ~15)) #ifdef __cplusplus extern "C" { #endif /** - * \brief Internal PadLock detection routine - * - * \note This function is only for internal use by other library - * functions; you must not call it directly. + * \brief PadLock detection routine * * \param feature The feature to detect * @@ -78,10 +72,7 @@ extern "C" { int mbedtls_padlock_has_support( int feature ); /** - * \brief Internal PadLock AES-ECB block en(de)cryption - * - * \note This function is only for internal use by other library - * functions; you must not call it directly. + * \brief PadLock AES-ECB block en(de)cryption * * \param ctx AES context * \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT @@ -91,15 +82,12 @@ int mbedtls_padlock_has_support( int feature ); * \return 0 if success, 1 if operation failed */ int mbedtls_padlock_xcryptecb( mbedtls_aes_context *ctx, - int mode, - const unsigned char input[16], - unsigned char output[16] ); + int mode, + const unsigned char input[16], + unsigned char output[16] ); /** - * \brief Internal PadLock AES-CBC buffer en(de)cryption - * - * \note This function is only for internal use by other library - * functions; you must not call it directly. + * \brief PadLock AES-CBC buffer en(de)cryption * * \param ctx AES context * \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT @@ -111,11 +99,11 @@ int mbedtls_padlock_xcryptecb( mbedtls_aes_context *ctx, * \return 0 if success, 1 if operation failed */ int mbedtls_padlock_xcryptcbc( mbedtls_aes_context *ctx, - int mode, - size_t length, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output ); + int mode, + size_t length, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ); #ifdef __cplusplus } diff --git a/APP_Framework/Framework/security/mbedtls/pem.c b/APP_Framework/Framework/security/mbedtls/pem.c index ae60aa670..2316ce9b1 100644 --- a/APP_Framework/Framework/security/mbedtls/pem.c +++ b/APP_Framework/Framework/security/mbedtls/pem.c @@ -33,7 +33,6 @@ #include "aes.h" #include "md5.h" #include "cipher.h" -#include "platform_util.h" #include @@ -46,9 +45,14 @@ #endif #if defined(MBEDTLS_PEM_PARSE_C) +/* 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; +} + void mbedtls_pem_init( mbedtls_pem_context *ctx ) { - mbedtls_platform_memset( ctx, 0, sizeof( mbedtls_pem_context ) ); + memset( ctx, 0, sizeof( mbedtls_pem_context ) ); } #if defined(MBEDTLS_MD5_C) && defined(MBEDTLS_CIPHER_MODE_CBC) && \ @@ -61,7 +65,7 @@ static int pem_get_iv( const unsigned char *s, unsigned char *iv, { size_t i, j, k; - mbedtls_platform_memset( iv, 0, iv_len ); + memset( iv, 0, iv_len ); for( i = 0; i < iv_len * 2; i++, s++ ) { @@ -103,11 +107,11 @@ static int pem_pbkdf1( unsigned char *key, size_t keylen, if( keylen <= 16 ) { - mbedtls_platform_memcpy( key, md5sum, keylen ); + memcpy( key, md5sum, keylen ); goto exit; } - mbedtls_platform_memcpy( key, md5sum, 16 ); + memcpy( key, md5sum, 16 ); /* * key[16..23] = MD5(key[ 0..15] || pwd || IV]) @@ -127,11 +131,11 @@ static int pem_pbkdf1( unsigned char *key, size_t keylen, if( keylen < 32 ) use_len = keylen - 16; - mbedtls_platform_memcpy( key + 16, md5sum, use_len ); + memcpy( key + 16, md5sum, use_len ); exit: mbedtls_md5_free( &md5_ctx ); - mbedtls_platform_zeroize( md5sum, 16 ); + mbedtls_zeroize( md5sum, 16 ); return( ret ); } @@ -160,7 +164,7 @@ static int pem_des_decrypt( unsigned char des_iv[8], exit: mbedtls_des_free( &des_ctx ); - mbedtls_platform_zeroize( des_key, 8 ); + mbedtls_zeroize( des_key, 8 ); return( ret ); } @@ -188,7 +192,7 @@ static int pem_des3_decrypt( unsigned char des3_iv[8], exit: mbedtls_des3_free( &des3_ctx ); - mbedtls_platform_zeroize( des3_key, 24 ); + mbedtls_zeroize( des3_key, 24 ); return( ret ); } @@ -218,7 +222,7 @@ static int pem_aes_decrypt( unsigned char aes_iv[16], unsigned int keylen, exit: mbedtls_aes_free( &aes_ctx ); - mbedtls_platform_zeroize( aes_key, keylen ); + mbedtls_zeroize( aes_key, keylen ); return( ret ); } @@ -273,7 +277,7 @@ int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const enc = 0; - if( s2 - s1 >= 22 && mbedtls_platform_memequal( s1, "Proc-Type: 4,ENCRYPTED", 22 ) == 0 ) + if( s2 - s1 >= 22 && memcmp( s1, "Proc-Type: 4,ENCRYPTED", 22 ) == 0 ) { #if defined(MBEDTLS_MD5_C) && defined(MBEDTLS_CIPHER_MODE_CBC) && \ ( defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C) ) @@ -286,7 +290,7 @@ int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const #if defined(MBEDTLS_DES_C) - if( s2 - s1 >= 23 && mbedtls_platform_memequal( s1, "DEK-Info: DES-EDE3-CBC,", 23 ) == 0 ) + if( s2 - s1 >= 23 && memcmp( s1, "DEK-Info: DES-EDE3-CBC,", 23 ) == 0 ) { enc_alg = MBEDTLS_CIPHER_DES_EDE3_CBC; @@ -296,7 +300,7 @@ int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const s1 += 16; } - else if( s2 - s1 >= 18 && mbedtls_platform_memequal( s1, "DEK-Info: DES-CBC,", 18 ) == 0 ) + else if( s2 - s1 >= 18 && memcmp( s1, "DEK-Info: DES-CBC,", 18 ) == 0 ) { enc_alg = MBEDTLS_CIPHER_DES_CBC; @@ -309,15 +313,15 @@ int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const #endif /* MBEDTLS_DES_C */ #if defined(MBEDTLS_AES_C) - if( s2 - s1 >= 14 && mbedtls_platform_memequal( s1, "DEK-Info: AES-", 14 ) == 0 ) + if( s2 - s1 >= 14 && memcmp( s1, "DEK-Info: AES-", 14 ) == 0 ) { if( s2 - s1 < 22 ) return( MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG ); - else if( mbedtls_platform_memequal( s1, "DEK-Info: AES-128-CBC,", 22 ) == 0 ) + else if( memcmp( s1, "DEK-Info: AES-128-CBC,", 22 ) == 0 ) enc_alg = MBEDTLS_CIPHER_AES_128_CBC; - else if( mbedtls_platform_memequal( s1, "DEK-Info: AES-192-CBC,", 22 ) == 0 ) + else if( memcmp( s1, "DEK-Info: AES-192-CBC,", 22 ) == 0 ) enc_alg = MBEDTLS_CIPHER_AES_192_CBC; - else if( mbedtls_platform_memequal( s1, "DEK-Info: AES-256-CBC,", 22 ) == 0 ) + else if( memcmp( s1, "DEK-Info: AES-256-CBC,", 22 ) == 0 ) enc_alg = MBEDTLS_CIPHER_AES_256_CBC; else return( MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG ); @@ -355,7 +359,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 ) { - mbedtls_platform_zeroize( buf, len ); + mbedtls_zeroize( buf, len ); mbedtls_free( buf ); return( MBEDTLS_ERR_PEM_INVALID_DATA + ret ); } @@ -366,7 +370,7 @@ int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const ( defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C) ) if( pwd == NULL ) { - mbedtls_platform_zeroize( buf, len ); + mbedtls_zeroize( buf, len ); mbedtls_free( buf ); return( MBEDTLS_ERR_PEM_PASSWORD_REQUIRED ); } @@ -399,16 +403,16 @@ int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const * 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. * - * Use that as a heuristic to try to detect password mismatches. + * Use that as heurisitic to try detecting password mismatchs. */ if( len <= 2 || buf[0] != 0x30 || buf[1] > 0x83 ) { - mbedtls_platform_zeroize( buf, len ); + mbedtls_zeroize( buf, len ); mbedtls_free( buf ); return( MBEDTLS_ERR_PEM_PASSWORD_MISMATCH ); } #else - mbedtls_platform_zeroize( buf, len ); + mbedtls_zeroize( buf, len ); mbedtls_free( buf ); return( MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE ); #endif /* MBEDTLS_MD5_C && MBEDTLS_CIPHER_MODE_CBC && @@ -423,14 +427,12 @@ int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const void mbedtls_pem_free( mbedtls_pem_context *ctx ) { - if ( ctx->buf != NULL ) - { - mbedtls_platform_zeroize( ctx->buf, ctx->buflen ); - mbedtls_free( ctx->buf ); - } + if( ctx->buf != NULL ) + mbedtls_zeroize( ctx->buf, ctx->buflen ); + mbedtls_free( ctx->buf ); mbedtls_free( ctx->info ); - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_pem_context ) ); + mbedtls_zeroize( ctx, sizeof( mbedtls_pem_context ) ); } #endif /* MBEDTLS_PEM_PARSE_C */ @@ -463,21 +465,21 @@ int mbedtls_pem_write_buffer( const char *header, const char *footer, return( ret ); } - mbedtls_platform_memcpy( p, header, strlen( header ) ); + memcpy( p, header, strlen( header ) ); p += strlen( header ); c = encode_buf; while( use_len ) { len = ( use_len > 64 ) ? 64 : use_len; - mbedtls_platform_memcpy( p, c, len ); + memcpy( p, c, len ); use_len -= len; p += len; c += len; *p++ = '\n'; } - mbedtls_platform_memcpy( p, footer, strlen( footer ) ); + memcpy( p, footer, strlen( footer ) ); p += strlen( footer ); *p++ = '\0'; diff --git a/APP_Framework/Framework/security/mbedtls/pem.h b/APP_Framework/Framework/security/mbedtls/pem.h index a29e9ce30..81918503e 100644 --- a/APP_Framework/Framework/security/mbedtls/pem.h +++ b/APP_Framework/Framework/security/mbedtls/pem.h @@ -57,7 +57,7 @@ extern "C" { /** * \brief PEM context structure */ -typedef struct mbedtls_pem_context +typedef struct { unsigned char *buf; /*!< buffer for decoded data */ size_t buflen; /*!< length of the buffer */ diff --git a/APP_Framework/Framework/security/mbedtls/pk.c b/APP_Framework/Framework/security/mbedtls/pk.c index d992cc245..77640418e 100644 --- a/APP_Framework/Framework/security/mbedtls/pk.c +++ b/APP_Framework/Framework/security/mbedtls/pk.c @@ -29,7 +29,7 @@ #include "pk.h" #include "pk_internal.h" -#if defined(MBEDTLS_RSA_C) || defined(MBEDTLS_PK_RSA_ALT_SUPPORT) +#if defined(MBEDTLS_RSA_C) #include "rsa.h" #endif #if defined(MBEDTLS_ECP_C) @@ -38,1286 +38,25 @@ #if defined(MBEDTLS_ECDSA_C) #include "ecdsa.h" #endif -#if defined(MBEDTLS_USE_TINYCRYPT) -#include "tinycrypt/ecc.h" -#include "tinycrypt/ecc_dsa.h" -#include "asn1.h" -#include "asn1write.h" -#endif /* MBEDTLS_USE_TINYCRYPT */ -#include "platform_util.h" -#include "platform.h" - -#if !defined(MBEDTLS_PLATFORM_C) -#include -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif - -#include #include #include -/* Parameter validation macros based on platform_util.h */ -#define PK_VALIDATE_RET( cond ) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_PK_BAD_INPUT_DATA ) -#define PK_VALIDATE( cond ) \ - MBEDTLS_INTERNAL_VALIDATE( cond ) - -/* - * Internal wrappers around RSA functions - */ -#if defined(MBEDTLS_RSA_C) -static int rsa_can_do( mbedtls_pk_type_t type ) -{ - return( type == MBEDTLS_PK_RSA || - type == MBEDTLS_PK_RSASSA_PSS ); +/* 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; } -static size_t rsa_get_bitlen( const void *ctx ) -{ - 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, - const unsigned char *hash, size_t hash_len, - const unsigned char *sig, size_t sig_len ) -{ - int ret; - mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx; - size_t rsa_len = mbedtls_rsa_get_len( rsa ); - -#if SIZE_MAX > UINT_MAX - if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len ) - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); -#endif /* SIZE_MAX > UINT_MAX */ - - if( sig_len < rsa_len ) - return( MBEDTLS_ERR_RSA_VERIFY_FAILED ); - - if( ( ret = mbedtls_rsa_pkcs1_verify( rsa, NULL, NULL, - MBEDTLS_RSA_PUBLIC, md_alg, - (unsigned int) hash_len, hash, sig ) ) != 0 ) - return( ret ); - - /* The buffer contains a valid signature followed by extra data. - * We have a special error code for that so that so that callers can - * use mbedtls_pk_verify() to check "Does the buffer start with a - * valid signature?" and not just "Does the buffer contain a valid - * signature?". */ - if( sig_len > rsa_len ) - return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH ); - - return( 0 ); -} - -static int rsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t *sig_len, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) -{ - mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx; - -#if SIZE_MAX > UINT_MAX - if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len ) - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); -#endif /* SIZE_MAX > UINT_MAX */ - - *sig_len = mbedtls_rsa_get_len( rsa ); - - return( mbedtls_rsa_pkcs1_sign( rsa, f_rng, p_rng, MBEDTLS_RSA_PRIVATE, - md_alg, (unsigned int) hash_len, hash, sig ) ); -} - -static int rsa_decrypt_wrap( void *ctx, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen, size_t osize, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) -{ - mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx; - - if( ilen != mbedtls_rsa_get_len( rsa ) ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - return( mbedtls_rsa_pkcs1_decrypt( rsa, f_rng, p_rng, - MBEDTLS_RSA_PRIVATE, olen, input, output, osize ) ); -} - -static int rsa_encrypt_wrap( void *ctx, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen, size_t osize, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) -{ - mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx; - *olen = mbedtls_rsa_get_len( rsa ); - - if( *olen > osize ) - return( MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE ); - - return( mbedtls_rsa_pkcs1_encrypt( rsa, f_rng, p_rng, MBEDTLS_RSA_PUBLIC, - ilen, input, output ) ); -} - -static int rsa_check_pair_wrap( const void *pub, const void *prv ) -{ - return( mbedtls_rsa_check_pub_priv( (const mbedtls_rsa_context *) pub, - (const mbedtls_rsa_context *) prv ) ); -} - -static void *rsa_alloc_wrap( void ) -{ - void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_rsa_context ) ); - - if( ctx != NULL ) - mbedtls_rsa_init( (mbedtls_rsa_context *) ctx, 0, 0 ); - - return( ctx ); -} - -static void rsa_free_wrap( void *ctx ) -{ - mbedtls_rsa_free( (mbedtls_rsa_context *) ctx ); - mbedtls_free( ctx ); -} - -static void rsa_debug( const void *ctx, mbedtls_pk_debug_item *items ) -{ - items->type = MBEDTLS_PK_DEBUG_MPI; - items->name = "rsa.N"; - items->value = &( ((mbedtls_rsa_context *) ctx)->N ); - - items++; - - items->type = MBEDTLS_PK_DEBUG_MPI; - items->name = "rsa.E"; - items->value = &( ((mbedtls_rsa_context *) ctx)->E ); -} - -const mbedtls_pk_info_t mbedtls_rsa_info = { - MBEDTLS_PK_RSA, - "RSA", - rsa_get_bitlen, - rsa_can_do, - rsa_verify_wrap, - rsa_sign_wrap, -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - NULL, - NULL, -#endif - rsa_decrypt_wrap, - rsa_encrypt_wrap, - rsa_check_pair_wrap, - rsa_alloc_wrap, - rsa_free_wrap, -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - NULL, - NULL, -#endif - rsa_debug, -}; -#endif /* MBEDTLS_RSA_C */ - -/* - * Internal wrappers around ECC functions - based on ECP module - */ -#if defined(MBEDTLS_ECP_C) -/* - * Generic EC key - */ -static int eckey_can_do( mbedtls_pk_type_t type ) -{ - return( type == MBEDTLS_PK_ECKEY || - type == MBEDTLS_PK_ECKEY_DH || - type == MBEDTLS_PK_ECDSA ); -} - -static size_t eckey_get_bitlen( const void *ctx ) -{ - return( ((mbedtls_ecp_keypair *) ctx)->grp.pbits ); -} - -#if defined(MBEDTLS_ECDSA_C) -/* Forward declarations */ -static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - const unsigned char *sig, size_t sig_len ); - -static int ecdsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t *sig_len, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); - -static int eckey_verify_wrap( void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - const unsigned char *sig, size_t sig_len ) -{ - int ret; - mbedtls_ecdsa_context ecdsa; - - mbedtls_ecdsa_init( &ecdsa ); - - if( ( ret = mbedtls_ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 ) - ret = ecdsa_verify_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len ); - - mbedtls_ecdsa_free( &ecdsa ); - - return( ret ); -} - -static int eckey_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t *sig_len, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) -{ - int ret; - mbedtls_ecdsa_context ecdsa; - - mbedtls_ecdsa_init( &ecdsa ); - - if( ( ret = mbedtls_ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 ) - ret = ecdsa_sign_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len, - f_rng, p_rng ); - - mbedtls_ecdsa_free( &ecdsa ); - - return( ret ); -} - -#if defined(MBEDTLS_ECP_RESTARTABLE) -/* Forward declarations */ -static int ecdsa_verify_rs_wrap( void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - const unsigned char *sig, size_t sig_len, - void *rs_ctx ); - -static int ecdsa_sign_rs_wrap( void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t *sig_len, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, - void *rs_ctx ); - -/* - * Restart context for ECDSA operations with ECKEY context - * - * We need to store an actual ECDSA context, as we need to pass the same to - * the underlying ecdsa function, so we can't create it on the fly every time. - */ -typedef struct -{ - mbedtls_ecdsa_restart_ctx ecdsa_rs; - mbedtls_ecdsa_context ecdsa_ctx; -} eckey_restart_ctx; - -static void *eckey_rs_alloc( void ) -{ - eckey_restart_ctx *rs_ctx; - - void *ctx = mbedtls_calloc( 1, sizeof( eckey_restart_ctx ) ); - - if( ctx != NULL ) - { - rs_ctx = ctx; - mbedtls_ecdsa_restart_init( &rs_ctx->ecdsa_rs ); - mbedtls_ecdsa_init( &rs_ctx->ecdsa_ctx ); - } - - return( ctx ); -} - -static void eckey_rs_free( void *ctx ) -{ - eckey_restart_ctx *rs_ctx; - - if( ctx == NULL) - return; - - rs_ctx = ctx; - mbedtls_ecdsa_restart_free( &rs_ctx->ecdsa_rs ); - mbedtls_ecdsa_free( &rs_ctx->ecdsa_ctx ); - - mbedtls_free( ctx ); -} - -static int eckey_verify_rs_wrap( void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - const unsigned char *sig, size_t sig_len, - void *rs_ctx ) -{ - int ret; - eckey_restart_ctx *rs = rs_ctx; - - /* Should never happen */ - if( rs == NULL ) - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); - - /* set up our own sub-context if needed (that is, on first run) */ - if( rs->ecdsa_ctx.grp.pbits == 0 ) - MBEDTLS_MPI_CHK( mbedtls_ecdsa_from_keypair( &rs->ecdsa_ctx, ctx ) ); - - MBEDTLS_MPI_CHK( ecdsa_verify_rs_wrap( &rs->ecdsa_ctx, - md_alg, hash, hash_len, - sig, sig_len, &rs->ecdsa_rs ) ); - -cleanup: - return( ret ); -} - -static int eckey_sign_rs_wrap( void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t *sig_len, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, - void *rs_ctx ) -{ - int ret; - eckey_restart_ctx *rs = rs_ctx; - - /* Should never happen */ - if( rs == NULL ) - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); - - /* set up our own sub-context if needed (that is, on first run) */ - if( rs->ecdsa_ctx.grp.pbits == 0 ) - MBEDTLS_MPI_CHK( mbedtls_ecdsa_from_keypair( &rs->ecdsa_ctx, ctx ) ); - - MBEDTLS_MPI_CHK( ecdsa_sign_rs_wrap( &rs->ecdsa_ctx, md_alg, - hash, hash_len, sig, sig_len, - f_rng, p_rng, &rs->ecdsa_rs ) ); - -cleanup: - return( ret ); -} -#endif /* MBEDTLS_ECP_RESTARTABLE */ -#endif /* MBEDTLS_ECDSA_C */ - -static int eckey_check_pair( const void *pub, const void *prv ) -{ - return( mbedtls_ecp_check_pub_priv( (const mbedtls_ecp_keypair *) pub, - (const mbedtls_ecp_keypair *) prv ) ); -} - -static void *eckey_alloc_wrap( void ) -{ - void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecp_keypair ) ); - - if( ctx != NULL ) - mbedtls_ecp_keypair_init( ctx ); - - return( ctx ); -} - -static void eckey_free_wrap( void *ctx ) -{ - mbedtls_ecp_keypair_free( (mbedtls_ecp_keypair *) ctx ); - mbedtls_free( ctx ); -} - -static void eckey_debug( const void *ctx, mbedtls_pk_debug_item *items ) -{ - items->type = MBEDTLS_PK_DEBUG_ECP; - items->name = "eckey.Q"; - items->value = &( ((mbedtls_ecp_keypair *) ctx)->Q ); -} - -const mbedtls_pk_info_t mbedtls_eckey_info = { - MBEDTLS_PK_ECKEY, - "EC", - eckey_get_bitlen, - eckey_can_do, -#if defined(MBEDTLS_ECDSA_C) - eckey_verify_wrap, - eckey_sign_wrap, -#if defined(MBEDTLS_ECP_RESTARTABLE) - eckey_verify_rs_wrap, - eckey_sign_rs_wrap, -#endif -#else /* MBEDTLS_ECDSA_C */ - NULL, - NULL, -#endif /* MBEDTLS_ECDSA_C */ - NULL, - NULL, - eckey_check_pair, - eckey_alloc_wrap, - eckey_free_wrap, -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - eckey_rs_alloc, - eckey_rs_free, -#endif - eckey_debug, -}; - -/* - * EC key restricted to ECDH - */ -static int eckeydh_can_do( mbedtls_pk_type_t type ) -{ - return( type == MBEDTLS_PK_ECKEY || - type == MBEDTLS_PK_ECKEY_DH ); -} - -const mbedtls_pk_info_t mbedtls_eckeydh_info = { - MBEDTLS_PK_ECKEY_DH, - "EC_DH", - eckey_get_bitlen, /* Same underlying key structure */ - eckeydh_can_do, - NULL, - NULL, -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - NULL, - NULL, -#endif - NULL, - NULL, - eckey_check_pair, - eckey_alloc_wrap, /* Same underlying key structure */ - eckey_free_wrap, /* Same underlying key structure */ -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - NULL, - NULL, -#endif - eckey_debug, /* Same underlying key structure */ -}; -#endif /* MBEDTLS_ECP_C */ - -/* - * Internal wrappers around ECC functions - based on TinyCrypt - */ -#if defined(MBEDTLS_USE_TINYCRYPT) -/* - * An ASN.1 encoded signature is a sequence of two ASN.1 integers. Parse one of - * those integers and convert it to the fixed-length encoding. - */ -static int extract_ecdsa_sig_int( unsigned char **from, const unsigned char *end, - unsigned char *to, size_t to_len ) -{ - int ret; - size_t unpadded_len, padding_len; - - if( ( ret = mbedtls_asn1_get_tag( from, end, &unpadded_len, - MBEDTLS_ASN1_INTEGER ) ) != 0 ) - { - return( ret ); - } - - while( unpadded_len > 0 && **from == 0x00 ) - { - ( *from )++; - unpadded_len--; - } - - if( unpadded_len > to_len || unpadded_len == 0 ) - return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - padding_len = to_len - unpadded_len; - memset( to, 0x00, padding_len ); - mbedtls_platform_memcpy( to + padding_len, *from, unpadded_len ); - ( *from ) += unpadded_len; - - return( 0 ); -} - -/* - * Convert a signature from an ASN.1 sequence of two integers - * to a raw {r,s} buffer. Note: the provided sig buffer must be at least - * twice as big as int_size. - */ -static int extract_ecdsa_sig( unsigned char **p, const unsigned char *end, - unsigned char *sig, size_t int_size ) -{ - int ret; - size_t tmp_size; - - if( ( ret = mbedtls_asn1_get_tag( p, end, &tmp_size, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - return( ret ); - - /* Extract r */ - if( ( ret = extract_ecdsa_sig_int( p, end, sig, int_size ) ) != 0 ) - return( ret ); - /* Extract s */ - if( ( ret = extract_ecdsa_sig_int( p, end, sig + int_size, int_size ) ) != 0 ) - return( ret ); - - return( 0 ); -} - -static size_t uecc_eckey_get_bitlen( const void *ctx ) -{ - (void) ctx; - return( (size_t) ( NUM_ECC_BYTES * 8 ) ); -} - -/* This function compares public keys of two keypairs */ -static int uecc_eckey_check_pair( const void *pub, const void *prv ) -{ - const mbedtls_uecc_keypair *uecc_pub = - (const mbedtls_uecc_keypair *) pub; - const mbedtls_uecc_keypair *uecc_prv = - (const mbedtls_uecc_keypair *) prv; - - if( mbedtls_platform_memequal( uecc_pub->public_key, - uecc_prv->public_key, - 2 * NUM_ECC_BYTES ) == 0 ) - { - return( 0 ); - } - - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); -} - -static int uecc_eckey_can_do( mbedtls_pk_type_t type ) -{ - return( type == MBEDTLS_PK_ECDSA || - type == MBEDTLS_PK_ECKEY ); -} - -static int uecc_eckey_verify_wrap( void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - const unsigned char *sig, size_t sig_len ) -{ - int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; - volatile int ret_fi = UECC_FAULT_DETECTED; - uint8_t signature[2*NUM_ECC_BYTES]; - unsigned char *p; - const mbedtls_uecc_keypair *keypair = (const mbedtls_uecc_keypair *) ctx; - - ((void) md_alg); - p = (unsigned char*) sig; - - ret = extract_ecdsa_sig( &p, sig + sig_len, signature, NUM_ECC_BYTES ); - if( ret != 0 ) - return( ret ); - - ret_fi = uECC_verify( keypair->public_key, hash, - (unsigned) hash_len, signature ); - - if( ret_fi == UECC_FAULT_DETECTED ) - return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); - - if( ret_fi == UECC_SUCCESS ) - { - mbedtls_platform_random_delay(); - if( ret_fi == UECC_SUCCESS ) - return( 0 ); - else - return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); - } - - return( MBEDTLS_ERR_PK_HW_ACCEL_FAILED ); -} - -/* - * Simultaneously convert and move raw MPI from the beginning of a buffer - * to an ASN.1 MPI at the end of the buffer. - * See also mbedtls_asn1_write_mpi(). - * - * p: pointer to the end of the output buffer - * start: start of the output buffer, and also of the mpi to write at the end - * n_len: length of the mpi to read from start - * - * Warning: - * The total length of the output buffer must be smaller than 128 Bytes. - */ -static int asn1_write_mpibuf( unsigned char **p, unsigned char *start, - size_t n_len ) -{ - size_t len = n_len; - int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; - - if( (size_t)( *p - start ) < len ) - return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); - - *p -= len; - ret = mbedtls_platform_memmove( *p, start, len ); - if( ret != 0 ) - { - return( ret ); - } - - /* ASN.1 DER encoding requires minimal length, so skip leading 0s. - * Neither r nor s should be 0, but as a failsafe measure, still detect - * that rather than overflowing the buffer in case of an error. */ - while( len > 0 && **p == 0x00 ) - { - ++(*p); - --len; - } - - /* this is only reached if the signature was invalid */ - if( len == 0 ) - return( MBEDTLS_ERR_PK_HW_ACCEL_FAILED ); - - /* if the msb is 1, ASN.1 requires that we prepend a 0. - * Neither r nor s can be 0, so we can assume len > 0 at all times. */ - if( **p & 0x80 ) - { - if( *p - start < 1 ) - return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); - - *--(*p) = 0x00; - len += 1; - } - - /* Ensure that there is still space for len and ASN1_INTEGER */ - if( ( *p - start ) < 2 ) - return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); - - /* The ASN.1 length encoding is just a single Byte containing the length, - * as we assume that the total buffer length is smaller than 128 Bytes. */ - *--(*p) = len; - *--(*p) = MBEDTLS_ASN1_INTEGER; - len += 2; - - return( (int) len ); -} - -/* Transcode signature from uECC format to ASN.1 sequence. - * See ecdsa_signature_to_asn1 in ecdsa.c, but with byte buffers instead of - * MPIs, and in-place. - * - * [in/out] sig: the signature pre- and post-transcoding - * [in/out] sig_len: signature length pre- and post-transcoding - * [in] buf_len: the available size the in/out buffer - * - * Warning: buf_len must be smaller than 128 Bytes. - */ -static int pk_ecdsa_sig_asn1_from_uecc( unsigned char *sig, size_t *sig_len, - size_t buf_len ) -{ - int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; - size_t len = 0; - const size_t rs_len = *sig_len / 2; - unsigned char *p = sig + buf_len; - - MBEDTLS_ASN1_CHK_ADD( len, asn1_write_mpibuf( &p, sig + rs_len, rs_len ) ); - MBEDTLS_ASN1_CHK_ADD( len, asn1_write_mpibuf( &p, sig, rs_len ) ); - - if( p - sig < 2 ) - return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); - - /* The ASN.1 length encoding is just a single Byte containing the length, - * as we assume that the total buffer length is smaller than 128 Bytes. */ - *--p = len; - *--p = MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE; - len += 2; - - ret = mbedtls_platform_memmove( sig, p, len ); - if( ret != 0 ) - { - return( ret ); - } - *sig_len = len; - - return( ret ); -} - -static int uecc_eckey_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t *sig_len, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) -{ - const mbedtls_uecc_keypair *keypair = (const mbedtls_uecc_keypair *) ctx; - int ret; - - /* - * RFC-4492 page 20: - * - * Ecdsa-Sig-Value ::= SEQUENCE { - * r INTEGER, - * s INTEGER - * } - * - * Size is at most - * 1 (tag) + 1 (len) + 1 (initial 0) + NUM_ECC_BYTES for each of r and s, - * twice that + 1 (tag) + 2 (len) for the sequence - * - * (The ASN.1 length encodings are all 1-Byte encodings because - * the total size is smaller than 128 Bytes). - */ - #define MAX_SECP256R1_ECDSA_SIG_LEN ( 3 + 2 * ( 3 + NUM_ECC_BYTES ) ) - - ret = uECC_sign( keypair->private_key, hash, hash_len, sig ); - if( ret == UECC_FAULT_DETECTED ) - return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); - if( ret != UECC_SUCCESS ) - return( MBEDTLS_ERR_PK_HW_ACCEL_FAILED ); - - *sig_len = 2 * NUM_ECC_BYTES; - - /* uECC owns its rng function pointer */ - (void) f_rng; - (void) p_rng; - (void) md_alg; - - return( pk_ecdsa_sig_asn1_from_uecc( sig, sig_len, - MAX_SECP256R1_ECDSA_SIG_LEN ) ); - - #undef MAX_SECP256R1_ECDSA_SIG_LEN -} - -#if !defined(MBEDTLS_PK_SINGLE_TYPE) -static void *uecc_eckey_alloc_wrap( void ) -{ - return( mbedtls_calloc( 1, sizeof( mbedtls_uecc_keypair ) ) ); -} - -static void uecc_eckey_free_wrap( void *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_uecc_keypair ) ); - mbedtls_free( ctx ); -} -#endif /* MBEDTLS_PK_SINGLE_TYPE */ - -#if !defined(MBEDTLS_PK_SINGLE_TYPE) -const mbedtls_pk_info_t mbedtls_uecc_eckey_info = - MBEDTLS_PK_INFO( MBEDTLS_PK_INFO_ECKEY ); -#endif -#endif /* MBEDTLS_USE_TINYCRYPT */ - -/* - * Internal wrappers around ECDSA functions - */ -#if defined(MBEDTLS_ECDSA_C) -static int ecdsa_can_do( mbedtls_pk_type_t type ) -{ - return( type == MBEDTLS_PK_ECDSA ); -} - -static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - const unsigned char *sig, size_t sig_len ) -{ - int ret; - ((void) md_alg); - - ret = mbedtls_ecdsa_read_signature( (mbedtls_ecdsa_context *) ctx, - hash, hash_len, sig, sig_len ); - - if( ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH ) - return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH ); - - return( ret ); -} - -static int ecdsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t *sig_len, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) -{ - return( mbedtls_ecdsa_write_signature( (mbedtls_ecdsa_context *) ctx, - md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng ) ); -} - -#if defined(MBEDTLS_ECP_RESTARTABLE) -static int ecdsa_verify_rs_wrap( void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - const unsigned char *sig, size_t sig_len, - void *rs_ctx ) -{ - int ret; - ((void) md_alg); - - ret = mbedtls_ecdsa_read_signature_restartable( - (mbedtls_ecdsa_context *) ctx, - hash, hash_len, sig, sig_len, - (mbedtls_ecdsa_restart_ctx *) rs_ctx ); - - if( ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH ) - return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH ); - - return( ret ); -} - -static int ecdsa_sign_rs_wrap( void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t *sig_len, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, - void *rs_ctx ) -{ - return( mbedtls_ecdsa_write_signature_restartable( - (mbedtls_ecdsa_context *) ctx, - md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng, - (mbedtls_ecdsa_restart_ctx *) rs_ctx ) ); - -} -#endif /* MBEDTLS_ECP_RESTARTABLE */ - -static void *ecdsa_alloc_wrap( void ) -{ - void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecdsa_context ) ); - - if( ctx != NULL ) - mbedtls_ecdsa_init( (mbedtls_ecdsa_context *) ctx ); - - return( ctx ); -} - -static void ecdsa_free_wrap( void *ctx ) -{ - mbedtls_ecdsa_free( (mbedtls_ecdsa_context *) ctx ); - mbedtls_free( ctx ); -} - -#if defined(MBEDTLS_ECP_RESTARTABLE) -static void *ecdsa_rs_alloc( void ) -{ - void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecdsa_restart_ctx ) ); - - if( ctx != NULL ) - mbedtls_ecdsa_restart_init( ctx ); - - return( ctx ); -} - -static void ecdsa_rs_free( void *ctx ) -{ - mbedtls_ecdsa_restart_free( ctx ); - mbedtls_free( ctx ); -} -#endif /* MBEDTLS_ECP_RESTARTABLE */ - -const mbedtls_pk_info_t mbedtls_ecdsa_info = { - MBEDTLS_PK_ECDSA, - "ECDSA", - eckey_get_bitlen, /* Compatible key structures */ - ecdsa_can_do, - ecdsa_verify_wrap, - ecdsa_sign_wrap, -#if defined(MBEDTLS_ECP_RESTARTABLE) - ecdsa_verify_rs_wrap, - ecdsa_sign_rs_wrap, -#endif - NULL, - NULL, - eckey_check_pair, /* Compatible key structures */ - ecdsa_alloc_wrap, - ecdsa_free_wrap, -#if defined(MBEDTLS_ECP_RESTARTABLE) - ecdsa_rs_alloc, - ecdsa_rs_free, -#endif - eckey_debug, /* Compatible key structures */ -}; -#endif /* MBEDTLS_ECDSA_C */ - -/* - * Internal wrappers for RSA-alt support - */ -#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) -static int rsa_alt_can_do( mbedtls_pk_type_t type ) -{ - return( type == MBEDTLS_PK_RSA ); -} - -static size_t rsa_alt_get_bitlen( const void *ctx ) -{ - const mbedtls_rsa_alt_context *rsa_alt = (const mbedtls_rsa_alt_context *) ctx; - - return( 8 * rsa_alt->key_len_func( rsa_alt->key ) ); -} - -static int rsa_alt_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t *sig_len, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) -{ - mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx; - -#if SIZE_MAX > UINT_MAX - if( UINT_MAX < hash_len ) - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); -#endif /* SIZE_MAX > UINT_MAX */ - - *sig_len = rsa_alt->key_len_func( rsa_alt->key ); - - return( rsa_alt->sign_func( rsa_alt->key, f_rng, p_rng, MBEDTLS_RSA_PRIVATE, - md_alg, (unsigned int) hash_len, hash, sig ) ); -} - -static int rsa_alt_decrypt_wrap( void *ctx, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen, size_t osize, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) -{ - mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx; - - ((void) f_rng); - ((void) p_rng); - - if( ilen != rsa_alt->key_len_func( rsa_alt->key ) ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - return( rsa_alt->decrypt_func( rsa_alt->key, - MBEDTLS_RSA_PRIVATE, olen, input, output, osize ) ); -} - -#if defined(MBEDTLS_RSA_C) -static int rsa_alt_check_pair( const void *pub, const void *prv ) -{ - unsigned char sig[MBEDTLS_MPI_MAX_SIZE]; - unsigned char hash[32]; - size_t sig_len = 0; - int ret; - - if( rsa_alt_get_bitlen( prv ) != rsa_get_bitlen( pub ) ) - return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); - - mbedtls_platform_memset( hash, 0x2a, sizeof( hash ) ); - - if( ( ret = rsa_alt_sign_wrap( (void *) prv, MBEDTLS_MD_NONE, - hash, sizeof( hash ), - sig, &sig_len, NULL, NULL ) ) != 0 ) - { - return( ret ); - } - - if( rsa_verify_wrap( (void *) pub, MBEDTLS_MD_NONE, - hash, sizeof( hash ), sig, sig_len ) != 0 ) - { - return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); - } - - return( 0 ); -} -#endif /* MBEDTLS_RSA_C */ - -static void *rsa_alt_alloc_wrap( void ) -{ - void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_rsa_alt_context ) ); - - if( ctx != NULL ) - mbedtls_platform_memset( ctx, 0, sizeof( mbedtls_rsa_alt_context ) ); - - return( ctx ); -} - -static void rsa_alt_free_wrap( void *ctx ) -{ - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_rsa_alt_context ) ); - mbedtls_free( ctx ); -} - -const mbedtls_pk_info_t mbedtls_rsa_alt_info = { - MBEDTLS_PK_RSA_ALT, - "RSA-alt", - rsa_alt_get_bitlen, - rsa_alt_can_do, - NULL, - rsa_alt_sign_wrap, -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - NULL, - NULL, -#endif - rsa_alt_decrypt_wrap, - NULL, -#if defined(MBEDTLS_RSA_C) - rsa_alt_check_pair, -#else - NULL, -#endif - rsa_alt_alloc_wrap, - rsa_alt_free_wrap, -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - NULL, - NULL, -#endif - NULL, -}; -#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */ - -/* - * Access to members of the pk_info structure. When a single PK type is - * hardcoded, these should have zero runtime cost; otherwise, the usual - * dynamic dispatch based on pk_info is used. - * - * For function members, don't make a getter, but a function that directly - * calls the method, so that we can entirely get rid of function pointers - * when hardcoding a single PK - some compilers optimize better that way. - * - * Not implemented for members that are only present in builds with - * MBEDTLS_ECP_RESTARTABLE for now, as the main target for this is builds - * with MBEDTLS_USE_TINYCRYPT, which don't have MBEDTLS_ECP_RESTARTABLE. - */ -#if defined(MBEDTLS_PK_SINGLE_TYPE) - -MBEDTLS_ALWAYS_INLINE static inline mbedtls_pk_type_t pk_info_type( - mbedtls_pk_handle_t info ) -{ - (void) info; - return( MBEDTLS_PK_INFO_TYPE( MBEDTLS_PK_SINGLE_TYPE ) ); -} - -MBEDTLS_ALWAYS_INLINE static inline const char * pk_info_name( - mbedtls_pk_handle_t info ) -{ - (void) info; - return( MBEDTLS_PK_INFO_NAME( MBEDTLS_PK_SINGLE_TYPE ) ); -} - -MBEDTLS_ALWAYS_INLINE static inline size_t pk_info_get_bitlen( - mbedtls_pk_handle_t info, const void *ctx ) -{ - (void) info; - return( MBEDTLS_PK_INFO_GET_BITLEN( MBEDTLS_PK_SINGLE_TYPE )( ctx ) ); -} - -MBEDTLS_ALWAYS_INLINE static inline int pk_info_can_do( - mbedtls_pk_handle_t info, mbedtls_pk_type_t type ) -{ - (void) info; - return( MBEDTLS_PK_INFO_CAN_DO( MBEDTLS_PK_SINGLE_TYPE )( type ) ); -} - -MBEDTLS_ALWAYS_INLINE static inline int pk_info_verify_func( - mbedtls_pk_handle_t info, void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - const unsigned char *sig, size_t sig_len ) -{ - (void) info; -#if MBEDTLS_PK_INFO_VERIFY_OMIT( MBEDTLS_PK_SINGLE_TYPE ) - (void) ctx; - (void) md_alg; - (void) hash; - (void) hash_len; - (void) sig; - (void) sig_len; - return( MBEDTLS_ERR_PK_TYPE_MISMATCH ); -#else - return( MBEDTLS_PK_INFO_VERIFY_FUNC( MBEDTLS_PK_SINGLE_TYPE )( - ctx, md_alg, hash, hash_len, sig, sig_len ) ); -#endif -} - -MBEDTLS_ALWAYS_INLINE static inline int pk_info_sign_func( - mbedtls_pk_handle_t info, void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t *sig_len, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - (void) info; -#if MBEDTLS_PK_INFO_SIGN_OMIT( MBEDTLS_PK_SINGLE_TYPE ) - (void) ctx; - (void) md_alg; - (void) hash; - (void) hash_len; - (void) sig; - (void) sig_len; - (void) f_rng; - (void) p_rng; - return( MBEDTLS_ERR_PK_TYPE_MISMATCH ); -#else - return( MBEDTLS_PK_INFO_SIGN_FUNC( MBEDTLS_PK_SINGLE_TYPE )( - ctx, md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng ) ); -#endif -} - -MBEDTLS_ALWAYS_INLINE static inline int pk_info_decrypt_func( - mbedtls_pk_handle_t info, void *ctx, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen, size_t osize, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - (void) info; -#if MBEDTLS_PK_INFO_DECRYPT_OMIT( MBEDTLS_PK_SINGLE_TYPE ) - (void) ctx; - (void) input; - (void) ilen; - (void) output; - (void) olen; - (void) osize; - (void) f_rng; - (void) p_rng; - return( MBEDTLS_ERR_PK_TYPE_MISMATCH ); -#else - return( MBEDTLS_PK_INFO_DECRYPT_FUNC( MBEDTLS_PK_SINGLE_TYPE )( - ctx, input, ilen, output, olen, osize, f_rng, p_rng ) ); -#endif -} - -MBEDTLS_ALWAYS_INLINE static inline int pk_info_encrypt_func( - mbedtls_pk_handle_t info, void *ctx, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen, size_t osize, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - (void) info; -#if MBEDTLS_PK_INFO_ENCRYPT_OMIT( MBEDTLS_PK_SINGLE_TYPE ) - (void) ctx; - (void) input; - (void) ilen; - (void) output; - (void) olen; - (void) osize; - (void) f_rng; - (void) p_rng; - return( MBEDTLS_ERR_PK_TYPE_MISMATCH ); -#else - return( MBEDTLS_PK_INFO_ENCRYPT_FUNC( MBEDTLS_PK_SINGLE_TYPE )( - ctx, input, ilen, output, olen, osize, f_rng, p_rng ) ); -#endif -} - -MBEDTLS_ALWAYS_INLINE static inline int pk_info_check_pair_func( - mbedtls_pk_handle_t info, const void *pub, const void *prv ) -{ - (void) info; -#if MBEDTLS_PK_INFO_CHECK_PAIR_OMIT( MBEDTLS_PK_SINGLE_TYPE ) - (void) pub; - (void) prv; - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); -#else - return( MBEDTLS_PK_INFO_CHECK_PAIR_FUNC( MBEDTLS_PK_SINGLE_TYPE )( - pub, prv ) ); -#endif -} - -MBEDTLS_ALWAYS_INLINE static inline int pk_info_debug_func( - mbedtls_pk_handle_t info, - const void *ctx, mbedtls_pk_debug_item *items ) -{ - (void) info; -#if MBEDTLS_PK_INFO_DEBUG_OMIT( MBEDTLS_PK_SINGLE_TYPE ) - (void) ctx; - (void) items; - return( MBEDTLS_ERR_PK_TYPE_MISMATCH ); -#else - return( MBEDTLS_PK_INFO_DEBUG_FUNC( MBEDTLS_PK_SINGLE_TYPE )( ctx, items ) ); -#endif -} - -#else /* MBEDTLS_PK_SINGLE_TYPE */ - -MBEDTLS_ALWAYS_INLINE static inline mbedtls_pk_type_t pk_info_type( - mbedtls_pk_handle_t info ) -{ - return( info->type ); -} - -MBEDTLS_ALWAYS_INLINE static inline const char * pk_info_name( - mbedtls_pk_handle_t info ) -{ - return( info->name ); -} - -MBEDTLS_ALWAYS_INLINE static inline size_t pk_info_get_bitlen( - mbedtls_pk_handle_t info, const void *ctx ) -{ - return( info->get_bitlen( ctx ) ); -} - -MBEDTLS_ALWAYS_INLINE static inline int pk_info_can_do( - mbedtls_pk_handle_t info, mbedtls_pk_type_t type ) -{ - return( info->can_do( type ) ); -} - -MBEDTLS_ALWAYS_INLINE static inline int pk_info_verify_func( - mbedtls_pk_handle_t info, void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - const unsigned char *sig, size_t sig_len ) -{ - if( info->verify_func == NULL ) - return( MBEDTLS_ERR_PK_TYPE_MISMATCH ); - - return( info->verify_func( ctx, md_alg, hash, hash_len, sig, sig_len ) ); -} - -MBEDTLS_ALWAYS_INLINE static inline int pk_info_sign_func( - mbedtls_pk_handle_t info, void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t *sig_len, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - if( info->sign_func == NULL ) - return( MBEDTLS_ERR_PK_TYPE_MISMATCH ); - - return( info->sign_func( ctx, md_alg, hash, hash_len, sig, sig_len, - f_rng, p_rng ) ); -} - -MBEDTLS_ALWAYS_INLINE static inline int pk_info_decrypt_func( - mbedtls_pk_handle_t info, void *ctx, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen, size_t osize, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - if( info->decrypt_func == NULL ) - return( MBEDTLS_ERR_PK_TYPE_MISMATCH ); - - return( info->decrypt_func( ctx, input, ilen, output, olen, osize, - f_rng, p_rng ) ); -} - -MBEDTLS_ALWAYS_INLINE static inline int pk_info_encrypt_func( - mbedtls_pk_handle_t info, void *ctx, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen, size_t osize, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - if( info->encrypt_func == NULL ) - return( MBEDTLS_ERR_PK_TYPE_MISMATCH ); - - return( info->encrypt_func( ctx, input, ilen, output, olen, osize, - f_rng, p_rng ) ); -} - -MBEDTLS_ALWAYS_INLINE static inline int pk_info_check_pair_func( - mbedtls_pk_handle_t info, const void *pub, const void *prv ) -{ - if( info->check_pair_func == NULL ) - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); - - return( info->check_pair_func( pub, prv ) ); -} - -MBEDTLS_ALWAYS_INLINE static inline void *pk_info_ctx_alloc_func( - mbedtls_pk_handle_t info ) -{ - return( info->ctx_alloc_func( ) ); -} - -MBEDTLS_ALWAYS_INLINE static inline void pk_info_ctx_free_func( - mbedtls_pk_handle_t info, void *ctx ) -{ - info->ctx_free_func( ctx ); -} - -MBEDTLS_ALWAYS_INLINE static inline int pk_info_debug_func( - mbedtls_pk_handle_t info, - const void *ctx, mbedtls_pk_debug_item *items ) -{ - if( info->debug_func == NULL ) - return( MBEDTLS_ERR_PK_TYPE_MISMATCH ); - - info->debug_func( ctx, items ); - return( 0 ); -} - -#endif /* MBEDTLS_PK_SINGLE_TYPE */ - /* * Initialise a mbedtls_pk_context */ void mbedtls_pk_init( mbedtls_pk_context *ctx ) { - PK_VALIDATE( ctx != NULL ); + if( ctx == NULL ) + return; -#if !defined(MBEDTLS_PK_SINGLE_TYPE) - ctx->pk_info = MBEDTLS_PK_INVALID_HANDLE; + ctx->pk_info = NULL; ctx->pk_ctx = NULL; -#else - memset( ctx, 0, sizeof( mbedtls_pk_context ) ); -#endif } /* @@ -1325,65 +64,27 @@ void mbedtls_pk_init( mbedtls_pk_context *ctx ) */ void mbedtls_pk_free( mbedtls_pk_context *ctx ) { - if( ctx == NULL ) + if( ctx == NULL || ctx->pk_info == NULL ) return; -#if !defined(MBEDTLS_PK_SINGLE_TYPE) - if( MBEDTLS_PK_CTX_IS_VALID( ctx ) ) - pk_info_ctx_free_func( MBEDTLS_PK_CTX_INFO( ctx ), ctx->pk_ctx ); -#endif + ctx->pk_info->ctx_free_func( ctx->pk_ctx ); - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_pk_context ) ); + mbedtls_zeroize( ctx, sizeof( mbedtls_pk_context ) ); } -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) -/* - * Initialize a restart context - */ -void mbedtls_pk_restart_init( mbedtls_pk_restart_ctx *ctx ) -{ - PK_VALIDATE( ctx != NULL ); - ctx->pk_info = NULL; - ctx->rs_ctx = NULL; -} - -/* - * Free the components of a restart context - */ -void mbedtls_pk_restart_free( mbedtls_pk_restart_ctx *ctx ) -{ - if( ctx == NULL || !MBEDTLS_PK_CTX_IS_VALID( ctx ) || - ctx->pk_info->rs_free_func == NULL ) - { - return; - } - - ctx->pk_info->rs_free_func( ctx->rs_ctx ); - - ctx->pk_info = MBEDTLS_PK_INVALID_HANDLE; - ctx->rs_ctx = NULL; -} -#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - /* * Get pk_info structure from type */ -mbedtls_pk_handle_t mbedtls_pk_info_from_type( mbedtls_pk_type_t pk_type ) +const mbedtls_pk_info_t * mbedtls_pk_info_from_type( mbedtls_pk_type_t pk_type ) { -#if defined(MBEDTLS_PK_SINGLE_TYPE) - if( pk_type == MBEDTLS_PK_INFO_TYPE( MBEDTLS_PK_SINGLE_TYPE ) ) - return( MBEDTLS_PK_UNIQUE_VALID_HANDLE ); - - return( MBEDTLS_PK_INVALID_HANDLE ); - -#else /* MBEDTLS_PK_SINGLE_TYPE */ - switch( pk_type ) { #if defined(MBEDTLS_RSA_C) case MBEDTLS_PK_RSA: return( &mbedtls_rsa_info ); #endif #if defined(MBEDTLS_ECP_C) + case MBEDTLS_PK_ECKEY: + return( &mbedtls_eckey_info ); case MBEDTLS_PK_ECKEY_DH: return( &mbedtls_eckeydh_info ); #endif @@ -1391,43 +92,25 @@ mbedtls_pk_handle_t mbedtls_pk_info_from_type( mbedtls_pk_type_t pk_type ) case MBEDTLS_PK_ECDSA: return( &mbedtls_ecdsa_info ); #endif -#if defined(MBEDTLS_USE_TINYCRYPT) - case MBEDTLS_PK_ECKEY: - return( &mbedtls_uecc_eckey_info ); -#else /* MBEDTLS_USE_TINYCRYPT */ -#if defined(MBEDTLS_ECP_C) - case MBEDTLS_PK_ECKEY: - return( &mbedtls_eckey_info ); -#endif -#endif /* MBEDTLS_USE_TINYCRYPT */ /* MBEDTLS_PK_RSA_ALT omitted on purpose */ default: return( NULL ); } -#endif /* MBEDTLS_PK_SINGLE_TYPE */ } /* * Initialise context */ -int mbedtls_pk_setup( mbedtls_pk_context *ctx, mbedtls_pk_handle_t info ) +int mbedtls_pk_setup( mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info ) { - PK_VALIDATE_RET( ctx != NULL ); - if( info == MBEDTLS_PK_INVALID_HANDLE ) + if( ctx == NULL || info == NULL || ctx->pk_info != NULL ) return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); -#if !defined(MBEDTLS_PK_SINGLE_TYPE) - if( ctx->pk_info != NULL ) - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); + if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL ) + return( MBEDTLS_ERR_PK_ALLOC_FAILED ); ctx->pk_info = info; - if( ( ctx->pk_ctx = pk_info_ctx_alloc_func( info ) ) == NULL ) - return( MBEDTLS_ERR_PK_ALLOC_FAILED ); -#else - (void) ctx; -#endif - return( 0 ); } @@ -1441,10 +124,9 @@ int mbedtls_pk_setup_rsa_alt( mbedtls_pk_context *ctx, void * key, mbedtls_pk_rsa_alt_key_len_func key_len_func ) { mbedtls_rsa_alt_context *rsa_alt; - mbedtls_pk_handle_t info = &mbedtls_rsa_alt_info; + const mbedtls_pk_info_t *info = &mbedtls_rsa_alt_info; - PK_VALIDATE_RET( ctx != NULL ); - if( MBEDTLS_PK_CTX_IS_VALID( ctx ) ) + if( ctx == NULL || ctx->pk_info != NULL ) return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL ) @@ -1468,13 +150,11 @@ int mbedtls_pk_setup_rsa_alt( mbedtls_pk_context *ctx, void * key, */ int mbedtls_pk_can_do( const mbedtls_pk_context *ctx, mbedtls_pk_type_t type ) { - /* A context with null pk_info is not set up yet and can't do anything. - * For backward compatibility, also accept NULL instead of a context - * pointer. */ - if( ctx == NULL || !MBEDTLS_PK_CTX_IS_VALID( ctx ) ) + /* null or NONE context can't do anything */ + if( ctx == NULL || ctx->pk_info == NULL ) return( 0 ); - return( pk_info_can_do( MBEDTLS_PK_CTX_INFO( ctx ), type ) ); + return( ctx->pk_info->can_do( type ) ); } /* @@ -1482,106 +162,18 @@ int mbedtls_pk_can_do( const mbedtls_pk_context *ctx, mbedtls_pk_type_t type ) */ static inline int pk_hashlen_helper( mbedtls_md_type_t md_alg, size_t *hash_len ) { - mbedtls_md_handle_t md_info; + const mbedtls_md_info_t *md_info; if( *hash_len != 0 ) return( 0 ); - if( ( md_info = mbedtls_md_info_from_type( md_alg ) ) == - MBEDTLS_MD_INVALID_HANDLE ) - { + if( ( md_info = mbedtls_md_info_from_type( md_alg ) ) == NULL ) return( -1 ); - } *hash_len = mbedtls_md_get_size( md_info ); return( 0 ); } -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) -/* - * Helper to set up a restart context if needed - */ -static int pk_restart_setup( mbedtls_pk_restart_ctx *ctx, - mbedtls_pk_handle_t info ) -{ - /* Don't do anything if already set up or invalid */ - if( ctx == NULL || MBEDTLS_PK_CTX_IS_VALID( ctx ) ) - return( 0 ); - - /* Should never happen when we're called */ - if( info->rs_alloc_func == NULL || info->rs_free_func == NULL ) - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); - - if( ( ctx->rs_ctx = info->rs_alloc_func() ) == NULL ) - return( MBEDTLS_ERR_PK_ALLOC_FAILED ); - - ctx->pk_info = info; - - return( 0 ); -} -#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - -/* - * Verify a signature (restartable) - */ -int mbedtls_pk_verify_restartable( mbedtls_pk_context *ctx, - mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - const unsigned char *sig, size_t sig_len, - mbedtls_pk_restart_ctx *rs_ctx ) -{ - volatile int verify_ret = MBEDTLS_ERR_PK_HW_ACCEL_FAILED; - PK_VALIDATE_RET( ctx != NULL ); - PK_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && hash_len == 0 ) || - hash != NULL ); - PK_VALIDATE_RET( sig != NULL ); - - if( !MBEDTLS_PK_CTX_IS_VALID( ctx ) || - pk_hashlen_helper( md_alg, &hash_len ) != 0 ) - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - /* optimization: use non-restartable version if restart disabled */ - if( rs_ctx != NULL && - mbedtls_ecp_restart_is_enabled() && - ctx->pk_info->verify_rs_func != NULL ) - { - int ret; - - if( ( ret = pk_restart_setup( rs_ctx, ctx->pk_info ) ) != 0 ) - return( ret ); - - ret = ctx->pk_info->verify_rs_func( ctx->pk_ctx, - md_alg, hash, hash_len, sig, sig_len, rs_ctx->rs_ctx ); - - if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS ) - mbedtls_pk_restart_free( rs_ctx ); - - return( ret ); - } -#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - (void) rs_ctx; -#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - - verify_ret = pk_info_verify_func( MBEDTLS_PK_CTX_INFO( ctx ), - ctx->pk_ctx, md_alg, hash, hash_len, sig, sig_len ); - - if( verify_ret == 0 ) - { - mbedtls_platform_random_delay(); - if( verify_ret == 0 ) - { - return( verify_ret ); - } - else - { - verify_ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; - } - } - - return( verify_ret ); -} - /* * Verify a signature */ @@ -1589,8 +181,15 @@ int mbedtls_pk_verify( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, const unsigned char *hash, size_t hash_len, const unsigned char *sig, size_t sig_len ) { - return( mbedtls_pk_verify_restartable( ctx, md_alg, hash, hash_len, - sig, sig_len, NULL ) ); + if( ctx == NULL || ctx->pk_info == NULL || + pk_hashlen_helper( md_alg, &hash_len ) != 0 ) + return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); + + if( ctx->pk_info->verify_func == NULL ) + return( MBEDTLS_ERR_PK_TYPE_MISMATCH ); + + return( ctx->pk_info->verify_func( ctx->pk_ctx, md_alg, hash, hash_len, + sig, sig_len ) ); } /* @@ -1601,12 +200,7 @@ int mbedtls_pk_verify_ext( mbedtls_pk_type_t type, const void *options, const unsigned char *hash, size_t hash_len, const unsigned char *sig, size_t sig_len ) { - PK_VALIDATE_RET( ctx != NULL ); - PK_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && hash_len == 0 ) || - hash != NULL ); - PK_VALIDATE_RET( sig != NULL ); - - if( !MBEDTLS_PK_CTX_IS_VALID( ctx ) ) + if( ctx == NULL || ctx->pk_info == NULL ) return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); if( ! mbedtls_pk_can_do( ctx, type ) ) @@ -1656,52 +250,6 @@ int mbedtls_pk_verify_ext( mbedtls_pk_type_t type, const void *options, return( mbedtls_pk_verify( ctx, md_alg, hash, hash_len, sig, sig_len ) ); } -/* - * Make a signature (restartable) - */ -int mbedtls_pk_sign_restartable( mbedtls_pk_context *ctx, - mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t *sig_len, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, - mbedtls_pk_restart_ctx *rs_ctx ) -{ - PK_VALIDATE_RET( ctx != NULL ); - PK_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && hash_len == 0 ) || - hash != NULL ); - PK_VALIDATE_RET( sig != NULL ); - - if( !MBEDTLS_PK_CTX_IS_VALID( ctx ) || - pk_hashlen_helper( md_alg, &hash_len ) != 0 ) - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - /* optimization: use non-restartable version if restart disabled */ - if( rs_ctx != NULL && - mbedtls_ecp_restart_is_enabled() && - ctx->pk_info->sign_rs_func != NULL ) - { - int ret; - - if( ( ret = pk_restart_setup( rs_ctx, ctx->pk_info ) ) != 0 ) - return( ret ); - - ret = ctx->pk_info->sign_rs_func( ctx->pk_ctx, md_alg, - hash, hash_len, sig, sig_len, f_rng, p_rng, rs_ctx->rs_ctx ); - - if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS ) - mbedtls_pk_restart_free( rs_ctx ); - - return( ret ); - } -#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - (void) rs_ctx; -#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - - return( pk_info_sign_func( MBEDTLS_PK_CTX_INFO( ctx ), ctx->pk_ctx, - md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng ) ); -} - /* * Make a signature */ @@ -1710,8 +258,15 @@ int mbedtls_pk_sign( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, unsigned char *sig, size_t *sig_len, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) { - return( mbedtls_pk_sign_restartable( ctx, md_alg, hash, hash_len, - sig, sig_len, f_rng, p_rng, NULL ) ); + if( ctx == NULL || ctx->pk_info == NULL || + pk_hashlen_helper( md_alg, &hash_len ) != 0 ) + return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); + + if( ctx->pk_info->sign_func == NULL ) + return( MBEDTLS_ERR_PK_TYPE_MISMATCH ); + + return( ctx->pk_info->sign_func( ctx->pk_ctx, md_alg, hash, hash_len, + sig, sig_len, f_rng, p_rng ) ); } /* @@ -1722,16 +277,14 @@ int mbedtls_pk_decrypt( mbedtls_pk_context *ctx, unsigned char *output, size_t *olen, size_t osize, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) { - PK_VALIDATE_RET( ctx != NULL ); - PK_VALIDATE_RET( input != NULL || ilen == 0 ); - PK_VALIDATE_RET( output != NULL || osize == 0 ); - PK_VALIDATE_RET( olen != NULL ); - - if( !MBEDTLS_PK_CTX_IS_VALID( ctx ) ) + if( ctx == NULL || ctx->pk_info == NULL ) return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); - return( pk_info_decrypt_func( MBEDTLS_PK_CTX_INFO( ctx ), ctx->pk_ctx, - input, ilen, output, olen, osize, f_rng, p_rng ) ); + if( ctx->pk_info->decrypt_func == NULL ) + return( MBEDTLS_ERR_PK_TYPE_MISMATCH ); + + return( ctx->pk_info->decrypt_func( ctx->pk_ctx, input, ilen, + output, olen, osize, f_rng, p_rng ) ); } /* @@ -1742,16 +295,14 @@ int mbedtls_pk_encrypt( mbedtls_pk_context *ctx, unsigned char *output, size_t *olen, size_t osize, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) { - PK_VALIDATE_RET( ctx != NULL ); - PK_VALIDATE_RET( input != NULL || ilen == 0 ); - PK_VALIDATE_RET( output != NULL || osize == 0 ); - PK_VALIDATE_RET( olen != NULL ); - - if( !MBEDTLS_PK_CTX_IS_VALID( ctx ) ) + if( ctx == NULL || ctx->pk_info == NULL ) return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); - return( pk_info_encrypt_func( MBEDTLS_PK_CTX_INFO( ctx ), ctx->pk_ctx, - input, ilen, output, olen, osize, f_rng, p_rng ) ); + if( ctx->pk_info->encrypt_func == NULL ) + return( MBEDTLS_ERR_PK_TYPE_MISMATCH ); + + return( ctx->pk_info->encrypt_func( ctx->pk_ctx, input, ilen, + output, olen, osize, f_rng, p_rng ) ); } /* @@ -1759,27 +310,25 @@ int mbedtls_pk_encrypt( mbedtls_pk_context *ctx, */ int mbedtls_pk_check_pair( const mbedtls_pk_context *pub, const mbedtls_pk_context *prv ) { - PK_VALIDATE_RET( pub != NULL ); - PK_VALIDATE_RET( prv != NULL ); - - if( !MBEDTLS_PK_CTX_IS_VALID( pub ) || !MBEDTLS_PK_CTX_IS_VALID( prv ) ) - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); - -#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) - if( pk_info_type( prv->pk_info ) == MBEDTLS_PK_RSA_ALT ) + if( pub == NULL || pub->pk_info == NULL || + prv == NULL || prv->pk_info == NULL || + prv->pk_info->check_pair_func == NULL ) { - if( pk_info_type( pub->pk_info ) != MBEDTLS_PK_RSA ) + return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); + } + + if( prv->pk_info->type == MBEDTLS_PK_RSA_ALT ) + { + if( pub->pk_info->type != MBEDTLS_PK_RSA ) return( MBEDTLS_ERR_PK_TYPE_MISMATCH ); } else -#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */ { - if( MBEDTLS_PK_CTX_INFO( pub ) != MBEDTLS_PK_CTX_INFO( prv ) ) + if( pub->pk_info != prv->pk_info ) return( MBEDTLS_ERR_PK_TYPE_MISMATCH ); } - return( pk_info_check_pair_func( MBEDTLS_PK_CTX_INFO( prv ), - pub->pk_ctx, prv->pk_ctx ) ); + return( prv->pk_info->check_pair_func( pub->pk_ctx, prv->pk_ctx ) ); } /* @@ -1787,12 +336,10 @@ int mbedtls_pk_check_pair( const mbedtls_pk_context *pub, const mbedtls_pk_conte */ size_t mbedtls_pk_get_bitlen( const mbedtls_pk_context *ctx ) { - /* For backward compatibility, accept NULL or a context that - * isn't set up yet, and return a fake value that should be safe. */ - if( ctx == NULL || !MBEDTLS_PK_CTX_IS_VALID( ctx ) ) + if( ctx == NULL || ctx->pk_info == NULL ) return( 0 ); - return( pk_info_get_bitlen( MBEDTLS_PK_CTX_INFO( ctx ), ctx->pk_ctx ) ); + return( ctx->pk_info->get_bitlen( ctx->pk_ctx ) ); } /* @@ -1800,11 +347,14 @@ size_t mbedtls_pk_get_bitlen( const mbedtls_pk_context *ctx ) */ int mbedtls_pk_debug( const mbedtls_pk_context *ctx, mbedtls_pk_debug_item *items ) { - PK_VALIDATE_RET( ctx != NULL ); - if( !MBEDTLS_PK_CTX_IS_VALID( ctx ) ) + if( ctx == NULL || ctx->pk_info == NULL ) return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); - return( pk_info_debug_func( MBEDTLS_PK_CTX_INFO( ctx ), ctx->pk_ctx, items ) ); + if( ctx->pk_info->debug_func == NULL ) + return( MBEDTLS_ERR_PK_TYPE_MISMATCH ); + + ctx->pk_info->debug_func( ctx->pk_ctx, items ); + return( 0 ); } /* @@ -1812,10 +362,10 @@ int mbedtls_pk_debug( const mbedtls_pk_context *ctx, mbedtls_pk_debug_item *item */ const char *mbedtls_pk_get_name( const mbedtls_pk_context *ctx ) { - if( ctx == NULL || !MBEDTLS_PK_CTX_IS_VALID( ctx ) ) + if( ctx == NULL || ctx->pk_info == NULL ) return( "invalid PK" ); - return( pk_info_name( MBEDTLS_PK_CTX_INFO( ctx ) ) ); + return( ctx->pk_info->name ); } /* @@ -1823,10 +373,10 @@ const char *mbedtls_pk_get_name( const mbedtls_pk_context *ctx ) */ mbedtls_pk_type_t mbedtls_pk_get_type( const mbedtls_pk_context *ctx ) { - if( ctx == NULL || !MBEDTLS_PK_CTX_IS_VALID( ctx ) ) + if( ctx == NULL || ctx->pk_info == NULL ) return( MBEDTLS_PK_NONE ); - return( pk_info_type( MBEDTLS_PK_CTX_INFO( ctx ) ) ); + return( ctx->pk_info->type ); } #endif /* MBEDTLS_PK_C */ diff --git a/APP_Framework/Framework/security/mbedtls/pk.h b/APP_Framework/Framework/security/mbedtls/pk.h index 2ed9c07b6..ee06b2fd2 100644 --- a/APP_Framework/Framework/security/mbedtls/pk.h +++ b/APP_Framework/Framework/security/mbedtls/pk.h @@ -45,14 +45,6 @@ #include "ecdsa.h" #endif -#if defined(MBEDTLS_USE_TINYCRYPT) -#include "tinycrypt/ecc.h" -#endif - -#if defined(MBEDTLS_PK_SINGLE_TYPE) -#include "pk_internal.h" -#endif - #if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ !defined(inline) && !defined(__cplusplus) #define inline __inline @@ -72,8 +64,6 @@ #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_SIG_LEN_MISMATCH -0x3900 /**< The buffer contains a valid signature followed by more data. */ - -/* MBEDTLS_ERR_PK_HW_ACCEL_FAILED is deprecated and should not be used. */ #define MBEDTLS_ERR_PK_HW_ACCEL_FAILED -0x3880 /**< PK hardware accelerator failed. */ #ifdef __cplusplus @@ -97,7 +87,7 @@ typedef enum { * \brief Options for RSASSA-PSS signature verification. * See \c mbedtls_rsa_rsassa_pss_verify_ext() */ -typedef struct mbedtls_pk_rsassa_pss_options +typedef struct { mbedtls_md_type_t mgf1_hash_id; int expected_salt_len; @@ -117,7 +107,7 @@ typedef enum /** * \brief Item to send to the debug module */ -typedef struct mbedtls_pk_debug_item +typedef struct { mbedtls_pk_debug_type type; const char *name; @@ -130,54 +120,16 @@ typedef struct mbedtls_pk_debug_item /** * \brief Public key information and operations */ -#if defined(MBEDTLS_PK_SINGLE_TYPE) -typedef enum { - MBEDTLS_PK_INVALID_HANDLE, - MBEDTLS_PK_UNIQUE_VALID_HANDLE, -} mbedtls_pk_handle_t; -#else /* MBEDTLS_PK_SINGLE_TYPE */ typedef struct mbedtls_pk_info_t mbedtls_pk_info_t; -typedef const mbedtls_pk_info_t *mbedtls_pk_handle_t; -#define MBEDTLS_PK_INVALID_HANDLE ( (mbedtls_pk_handle_t) NULL ) -#endif /* MBEDTLS_PK_SINGLE_TYPE */ - -#if defined(MBEDTLS_USE_TINYCRYPT) -typedef struct -{ - uint8_t private_key[NUM_ECC_BYTES]; - uint8_t public_key[2*NUM_ECC_BYTES]; -} mbedtls_uecc_keypair; -#endif /** * \brief Public key container */ -typedef struct mbedtls_pk_context -{ -#if defined(MBEDTLS_PK_SINGLE_TYPE) - /* This is an array to make access to it more uniform with the case where - * it's a pointer to void - either way it needs casting before use. */ - unsigned char pk_ctx[sizeof( - MBEDTLS_PK_INFO_CONTEXT( MBEDTLS_PK_SINGLE_TYPE ) )]; -#else - mbedtls_pk_handle_t pk_info; /**< Public key information */ - void * pk_ctx; /**< Underlying public key context */ -#endif -} mbedtls_pk_context; - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) -/** - * \brief Context for resuming operations - */ typedef struct { - mbedtls_pk_handle_t pk_info; /**< Public key information */ - void * rs_ctx; /**< Underlying restart context */ -} mbedtls_pk_restart_ctx; -#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ -/* Now we can declare functions that take a pointer to that */ -typedef void mbedtls_pk_restart_ctx; -#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ + const mbedtls_pk_info_t * pk_info; /**< Public key informations */ + void * pk_ctx; /**< Underlying public key context */ +} mbedtls_pk_context; #if defined(MBEDTLS_RSA_C) /** @@ -192,20 +144,6 @@ static inline mbedtls_rsa_context *mbedtls_pk_rsa( const mbedtls_pk_context pk ) } #endif /* MBEDTLS_RSA_C */ -#if defined(MBEDTLS_USE_TINYCRYPT) -#if !defined(MBEDTLS_PK_SINGLE_TYPE) -static inline mbedtls_uecc_keypair *mbedtls_pk_uecc( const mbedtls_pk_context pk ) -{ - return( (mbedtls_uecc_keypair *) (pk).pk_ctx ); -} -#else -/* Go with a macro in order to avoid making a copy of the struct (the argument - * is not a pointer so it's passed by value) and then returning an address - * inside that copy, which would be undefined behaviour. */ -#define mbedtls_pk_uecc( pk ) ( (mbedtls_uecc_keypair *) (pk).pk_ctx ) -#endif -#endif /* MBEDTLS_USE_TINYCRYPT */ - #if defined(MBEDTLS_ECP_C) /** * Quick access to an EC context inside a PK context. @@ -240,48 +178,23 @@ typedef size_t (*mbedtls_pk_rsa_alt_key_len_func)( void *ctx ); * * \return The PK info associated with the type or NULL if not found. */ -mbedtls_pk_handle_t mbedtls_pk_info_from_type( mbedtls_pk_type_t pk_type ); +const mbedtls_pk_info_t *mbedtls_pk_info_from_type( mbedtls_pk_type_t pk_type ); /** - * \brief Initialize a #mbedtls_pk_context (as NONE). - * - * \param ctx The context to initialize. - * This must not be \c NULL. + * \brief Initialize a mbedtls_pk_context (as NONE) */ void mbedtls_pk_init( mbedtls_pk_context *ctx ); /** - * \brief Free the components of a #mbedtls_pk_context. - * - * \param ctx The context to clear. It must have been initialized. - * If this is \c NULL, this function does nothing. + * \brief Free a mbedtls_pk_context */ void mbedtls_pk_free( mbedtls_pk_context *ctx ); -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) -/** - * \brief Initialize a restart context - * - * \param ctx The context to initialize. - * This must not be \c NULL. - */ -void mbedtls_pk_restart_init( mbedtls_pk_restart_ctx *ctx ); - -/** - * \brief Free the components of a restart context - * - * \param ctx The context to clear. It must have been initialized. - * If this is \c NULL, this function does nothing. - */ -void mbedtls_pk_restart_free( mbedtls_pk_restart_ctx *ctx ); -#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - /** * \brief Initialize a PK context with the information given * and allocates the type-specific PK subcontext. * - * \param ctx Context to initialize. It must not have been set - * up yet (type #MBEDTLS_PK_NONE). + * \param ctx Context to initialize. Must be empty (type NONE). * \param info Information to use * * \return 0 on success, @@ -291,14 +204,13 @@ void mbedtls_pk_restart_free( mbedtls_pk_restart_ctx *ctx ); * \note For contexts holding an RSA-alt key, use * \c mbedtls_pk_setup_rsa_alt() instead. */ -int mbedtls_pk_setup( mbedtls_pk_context *ctx, mbedtls_pk_handle_t info ); +int mbedtls_pk_setup( mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info ); #if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) /** * \brief Initialize an RSA-alt context * - * \param ctx Context to initialize. It must not have been set - * up yet (type #MBEDTLS_PK_NONE). + * \param ctx Context to initialize. Must be empty (type NONE). * \param key RSA key pointer * \param decrypt_func Decryption function * \param sign_func Signing function @@ -318,7 +230,7 @@ int mbedtls_pk_setup_rsa_alt( mbedtls_pk_context *ctx, void * key, /** * \brief Get the size in bits of the underlying key * - * \param ctx The context to query. It must have been initialized. + * \param ctx Context to use * * \return Key size in bits, or 0 on error */ @@ -326,8 +238,7 @@ size_t mbedtls_pk_get_bitlen( const mbedtls_pk_context *ctx ); /** * \brief Get the length in bytes of the underlying key - * - * \param ctx The context to query. It must have been initialized. + * \param ctx Context to use * * \return Key length in bytes, or 0 on error */ @@ -339,21 +250,18 @@ static inline size_t mbedtls_pk_get_len( const mbedtls_pk_context *ctx ) /** * \brief Tell if a context can do the operation given by type * - * \param ctx The context to query. It must have been initialized. - * \param type The desired type. + * \param ctx Context to test + * \param type Target type * - * \return 1 if the context can do operations on the given type. - * \return 0 if the context cannot do the operations on the given - * type. This is always the case for a context that has - * been initialized but not set up, or that has been - * cleared with mbedtls_pk_free(). + * \return 0 if context can't do the operations, + * 1 otherwise. */ int mbedtls_pk_can_do( const mbedtls_pk_context *ctx, mbedtls_pk_type_t type ); /** * \brief Verify signature (including padding if relevant). * - * \param ctx The PK context to use. It must have been set up. + * \param ctx PK context to use * \param md_alg Hash algorithm used (see notes) * \param hash Hash of the message to sign * \param hash_len Hash length or 0 (see notes) @@ -378,39 +286,13 @@ int mbedtls_pk_verify( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, const unsigned char *hash, size_t hash_len, const unsigned char *sig, size_t sig_len ); -/** - * \brief Restartable version of \c mbedtls_pk_verify() - * - * \note Performs the same job as \c mbedtls_pk_verify(), but can - * return early and restart according to the limit set with - * \c mbedtls_ecp_set_max_ops() to reduce blocking for ECC - * operations. For RSA, same as \c mbedtls_pk_verify(). - * - * \param ctx The PK context to use. It must have been set up. - * \param md_alg Hash algorithm used (see notes) - * \param hash Hash of the message to sign - * \param hash_len Hash length or 0 (see notes) - * \param sig Signature to verify - * \param sig_len Signature length - * \param rs_ctx Restart context (NULL to disable restart) - * - * \return See \c mbedtls_pk_verify(), or - * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of - * operations was reached: see \c mbedtls_ecp_set_max_ops(). - */ -int mbedtls_pk_verify_restartable( mbedtls_pk_context *ctx, - mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - const unsigned char *sig, size_t sig_len, - mbedtls_pk_restart_ctx *rs_ctx ); - /** * \brief Verify signature, with options. * (Includes verification of the padding depending on type.) * * \param type Signature type (inc. possible padding type) to verify * \param options Pointer to type-specific options, or NULL - * \param ctx The PK context to use. It must have been set up. + * \param ctx PK context to use * \param md_alg Hash algorithm used (see notes) * \param hash Hash of the message to sign * \param hash_len Hash length or 0 (see notes) @@ -441,8 +323,7 @@ int mbedtls_pk_verify_ext( mbedtls_pk_type_t type, const void *options, /** * \brief Make signature, including padding if relevant. * - * \param ctx The PK context to use. It must have been set up - * with a private key. + * \param ctx PK context to use - must hold a private key * \param md_alg Hash algorithm used (see notes) * \param hash Hash of the message to sign * \param hash_len Hash length or 0 (see notes) @@ -462,55 +343,16 @@ int mbedtls_pk_verify_ext( mbedtls_pk_type_t type, const void *options, * * \note For RSA, md_alg may be MBEDTLS_MD_NONE if hash_len != 0. * For ECDSA, md_alg may never be MBEDTLS_MD_NONE. - * - * \note In order to ensure enough space for the signature, the - * \p sig buffer size must be of at least - * `max(MBEDTLS_ECDSA_MAX_LEN, MBEDTLS_MPI_MAX_SIZE)` bytes. */ int mbedtls_pk_sign( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, const unsigned char *hash, size_t hash_len, unsigned char *sig, size_t *sig_len, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); -/** - * \brief Restartable version of \c mbedtls_pk_sign() - * - * \note Performs the same job as \c mbedtls_pk_sign(), but can - * return early and restart according to the limit set with - * \c mbedtls_ecp_set_max_ops() to reduce blocking for ECC - * operations. For RSA, same as \c mbedtls_pk_sign(). - * - * \note In order to ensure enough space for the signature, the - * \p sig buffer size must be of at least - * `max(MBEDTLS_ECDSA_MAX_LEN, MBEDTLS_MPI_MAX_SIZE)` bytes. - * - * \param ctx The PK context to use. It must have been set up - * with a private key. - * \param md_alg Hash algorithm used (see notes) - * \param hash Hash of the message to sign - * \param hash_len Hash length or 0 (see notes) - * \param sig Place to write the signature - * \param sig_len Number of bytes written - * \param f_rng RNG function - * \param p_rng RNG parameter - * \param rs_ctx Restart context (NULL to disable restart) - * - * \return See \c mbedtls_pk_sign(), or - * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of - * operations was reached: see \c mbedtls_ecp_set_max_ops(). - */ -int mbedtls_pk_sign_restartable( mbedtls_pk_context *ctx, - mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t *sig_len, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, - mbedtls_pk_restart_ctx *rs_ctx ); - /** * \brief Decrypt message (including padding if relevant). * - * \param ctx The PK context to use. It must have been set up - * with a private key. + * \param ctx PK context to use - must hold a private key * \param input Input to decrypt * \param ilen Input size * \param output Decrypted output @@ -531,7 +373,7 @@ int mbedtls_pk_decrypt( mbedtls_pk_context *ctx, /** * \brief Encrypt message (including padding if relevant). * - * \param ctx The PK context to use. It must have been set up. + * \param ctx PK context to use * \param input Message to encrypt * \param ilen Message size * \param output Encrypted output @@ -562,7 +404,7 @@ int mbedtls_pk_check_pair( const mbedtls_pk_context *pub, const mbedtls_pk_conte /** * \brief Export debug information * - * \param ctx The PK context to use. It must have been initialized. + * \param ctx Context to use * \param items Place to write debug items * * \return 0 on success or MBEDTLS_ERR_PK_BAD_INPUT_DATA @@ -572,7 +414,7 @@ int mbedtls_pk_debug( const mbedtls_pk_context *ctx, mbedtls_pk_debug_item *item /** * \brief Access the type name * - * \param ctx The PK context to use. It must have been initialized. + * \param ctx Context to use * * \return Type name on success, or "invalid PK" */ @@ -581,10 +423,9 @@ const char * mbedtls_pk_get_name( const mbedtls_pk_context *ctx ); /** * \brief Get the key type * - * \param ctx The PK context to use. It must have been initialized. + * \param ctx Context to use * - * \return Type on success. - * \return #MBEDTLS_PK_NONE for a context that has not been set up. + * \return Type on success, or MBEDTLS_PK_NONE */ mbedtls_pk_type_t mbedtls_pk_get_type( const mbedtls_pk_context *ctx ); @@ -593,22 +434,12 @@ mbedtls_pk_type_t mbedtls_pk_get_type( const mbedtls_pk_context *ctx ); /** * \brief Parse a private key in PEM or DER format * - * \param ctx The PK context to fill. It must have been initialized - * but not set up. - * \param key Input buffer to parse. - * The buffer must contain the input exactly, with no - * extra trailing material. For PEM, the buffer must - * contain a null-terminated string. - * \param keylen Size of \b key in bytes. - * For PEM data, this includes the terminating null byte, - * so \p keylen must be equal to `strlen(key) + 1`. - * \param pwd Optional password for decryption. - * Pass \c NULL if expecting a non-encrypted key. - * Pass a string of \p pwdlen bytes if expecting an encrypted - * key; a non-encrypted key will also be accepted. - * The empty password is not supported. - * \param pwdlen Size of the password in bytes. - * Ignored if \p pwd is \c NULL. + * \param ctx key to be initialized + * \param key input buffer + * \param keylen size of the buffer + * (including the terminating null byte for PEM data) + * \param pwd password for decryption (optional) + * \param pwdlen size of the password * * \note On entry, ctx must be empty, either freshly initialised * with mbedtls_pk_init() or reset with mbedtls_pk_free(). If you need a @@ -626,15 +457,10 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *ctx, /** * \brief Parse a public key in PEM or DER format * - * \param ctx The PK context to fill. It must have been initialized - * but not set up. - * \param key Input buffer to parse. - * The buffer must contain the input exactly, with no - * extra trailing material. For PEM, the buffer must - * contain a null-terminated string. - * \param keylen Size of \b key in bytes. - * For PEM data, this includes the terminating null byte, - * so \p keylen must be equal to `strlen(key) + 1`. + * \param ctx key to be initialized + * \param key input buffer + * \param keylen size of the buffer + * (including the terminating null byte for PEM data) * * \note On entry, ctx must be empty, either freshly initialised * with mbedtls_pk_init() or reset with mbedtls_pk_free(). If you need a @@ -652,14 +478,9 @@ int mbedtls_pk_parse_public_key( mbedtls_pk_context *ctx, /** * \brief Load and parse a private key * - * \param ctx The PK context to fill. It must have been initialized - * but not set up. + * \param ctx key to be initialized * \param path filename to read the private key from - * \param password Optional password to decrypt the file. - * Pass \c NULL if expecting a non-encrypted key. - * Pass a null-terminated string if expecting an encrypted - * key; a non-encrypted key will also be accepted. - * The empty password is not supported. + * \param password password to decrypt the file (can be NULL) * * \note On entry, ctx must be empty, either freshly initialised * with mbedtls_pk_init() or reset with mbedtls_pk_free(). If you need a @@ -676,8 +497,7 @@ int mbedtls_pk_parse_keyfile( mbedtls_pk_context *ctx, /** * \brief Load and parse a public key * - * \param ctx The PK context to fill. It must have been initialized - * but not set up. + * \param ctx key to be initialized * \param path filename to read the public key from * * \note On entry, ctx must be empty, either freshly initialised @@ -700,7 +520,7 @@ int mbedtls_pk_parse_public_keyfile( mbedtls_pk_context *ctx, const char *path ) * return value to determine where you should start * using the buffer * - * \param ctx PK context which must contain a valid private key. + * \param ctx private to write away * \param buf buffer to write to * \param size size of the buffer * @@ -715,7 +535,7 @@ int mbedtls_pk_write_key_der( mbedtls_pk_context *ctx, unsigned char *buf, size_ * return value to determine where you should start * using the buffer * - * \param ctx PK context which must contain a valid public or private key. + * \param ctx public key to write away * \param buf buffer to write to * \param size size of the buffer * @@ -728,10 +548,9 @@ int mbedtls_pk_write_pubkey_der( mbedtls_pk_context *ctx, unsigned char *buf, si /** * \brief Write a public key to a PEM string * - * \param ctx PK context which must contain a valid public or private key. - * \param buf Buffer to write to. The output includes a - * terminating null byte. - * \param size Size of the buffer in bytes. + * \param ctx public key to write away + * \param buf buffer to write to + * \param size size of the buffer * * \return 0 if successful, or a specific error code */ @@ -740,10 +559,9 @@ int mbedtls_pk_write_pubkey_pem( mbedtls_pk_context *ctx, unsigned char *buf, si /** * \brief Write a private key to a PKCS#1 or SEC1 PEM string * - * \param ctx PK context which must contain a valid private key. - * \param buf Buffer to write to. The output includes a - * terminating null byte. - * \param size Size of the buffer in bytes. + * \param ctx private to write away + * \param buf buffer to write to + * \param size size of the buffer * * \return 0 if successful, or a specific error code */ @@ -762,8 +580,7 @@ int mbedtls_pk_write_key_pem( mbedtls_pk_context *ctx, unsigned char *buf, size_ * * \param p the position in the ASN.1 data * \param end end of the buffer - * \param pk The PK context to fill. It must have been initialized - * but not set up. + * \param pk the key to fill * * \return 0 if successful, or a specific PK error code */ @@ -778,7 +595,7 @@ int mbedtls_pk_parse_subpubkey( unsigned char **p, const unsigned char *end, * * \param p reference to current position pointer * \param start start of the buffer (for bounds-checking) - * \param key PK context which must contain a valid public or private key. + * \param key public key to write away * * \return the length written or a negative error code */ diff --git a/APP_Framework/Framework/security/mbedtls/pk_internal.h b/APP_Framework/Framework/security/mbedtls/pk_internal.h index 2c7d0f98f..3dae0fc5b 100644 --- a/APP_Framework/Framework/security/mbedtls/pk_internal.h +++ b/APP_Framework/Framework/security/mbedtls/pk_internal.h @@ -33,90 +33,6 @@ #include "pk.h" -/* - * PK information macro definitions - */ - -/* - * Each PK type that can be used with MBEDTLS_PK_SINGLE_TYPE needs to have - * the following MBEDTLS_PK_INFO_{FIELD} definitions, plus a dummy one for the - * base name. For now, only ECKEY with MBEDTLS_USE_TINYCRYPT is defined. - * - * For optional functions that are omitted, we need both the _FUNC field - * defined to NULL, and an extra macro _OMIT defined to 1. - */ - -#if defined(MBEDTLS_USE_TINYCRYPT) -/* Dummy definition to keep check-names.sh happy - don't uncomment */ -//#define MBEDTLS_PK_INFO_ECKEY - -#define MBEDTLS_PK_INFO_ECKEY_CONTEXT mbedtls_uecc_keypair -#define MBEDTLS_PK_INFO_ECKEY_TYPE MBEDTLS_PK_ECKEY -#define MBEDTLS_PK_INFO_ECKEY_NAME "EC" -#define MBEDTLS_PK_INFO_ECKEY_GET_BITLEN uecc_eckey_get_bitlen -#define MBEDTLS_PK_INFO_ECKEY_CAN_DO uecc_eckey_can_do -#define MBEDTLS_PK_INFO_ECKEY_VERIFY_FUNC uecc_eckey_verify_wrap -#define MBEDTLS_PK_INFO_ECKEY_SIGN_FUNC uecc_eckey_sign_wrap -#define MBEDTLS_PK_INFO_ECKEY_DECRYPT_FUNC NULL -#define MBEDTLS_PK_INFO_ECKEY_DECRYPT_OMIT 1 -#define MBEDTLS_PK_INFO_ECKEY_ENCRYPT_FUNC NULL -#define MBEDTLS_PK_INFO_ECKEY_ENCRYPT_OMIT 1 -#define MBEDTLS_PK_INFO_ECKEY_CHECK_PAIR_FUNC uecc_eckey_check_pair -#define MBEDTLS_PK_INFO_ECKEY_CTX_ALLOC_FUNC uecc_eckey_alloc_wrap -#define MBEDTLS_PK_INFO_ECKEY_CTX_FREE_FUNC uecc_eckey_free_wrap -#define MBEDTLS_PK_INFO_ECKEY_DEBUG_FUNC NULL -#define MBEDTLS_PK_INFO_ECKEY_DEBUG_OMIT 1 -#endif /* MBEDTLS_USE_TINYCRYPT */ - -/* - * Helper macros to extract fields from PK types - */ -#define MBEDTLS_PK_INFO_CONTEXT_T( PK ) PK ## _CONTEXT -#define MBEDTLS_PK_INFO_TYPE_T( PK ) PK ## _TYPE -#define MBEDTLS_PK_INFO_NAME_T( PK ) PK ## _NAME -#define MBEDTLS_PK_INFO_GET_BITLEN_T( PK ) PK ## _GET_BITLEN -#define MBEDTLS_PK_INFO_CAN_DO_T( PK ) PK ## _CAN_DO -#define MBEDTLS_PK_INFO_VERIFY_FUNC_T( PK ) PK ## _VERIFY_FUNC -#define MBEDTLS_PK_INFO_VERIFY_OMIT_T( PK ) PK ## _VERIFY_OMIT -#define MBEDTLS_PK_INFO_SIGN_FUNC_T( PK ) PK ## _SIGN_FUNC -#define MBEDTLS_PK_INFO_SIGN_OMIT_T( PK ) PK ## _SIGN_OMIT -#define MBEDTLS_PK_INFO_DECRYPT_FUNC_T( PK ) PK ## _DECRYPT_FUNC -#define MBEDTLS_PK_INFO_DECRYPT_OMIT_T( PK ) PK ## _DECRYPT_OMIT -#define MBEDTLS_PK_INFO_ENCRYPT_FUNC_T( PK ) PK ## _ENCRYPT_FUNC -#define MBEDTLS_PK_INFO_ENCRYPT_OMIT_T( PK ) PK ## _ENCRYPT_OMIT -#define MBEDTLS_PK_INFO_CHECK_PAIR_FUNC_T( PK ) PK ## _CHECK_PAIR_FUNC -#define MBEDTLS_PK_INFO_CHECK_PAIR_OMIT_T( PK ) PK ## _CHECK_PAIR_OMIT -#define MBEDTLS_PK_INFO_CTX_ALLOC_FUNC_T( PK ) PK ## _CTX_ALLOC_FUNC -#define MBEDTLS_PK_INFO_CTX_FREE_FUNC_T( PK ) PK ## _CTX_FREE_FUNC -#define MBEDTLS_PK_INFO_DEBUG_FUNC_T( PK ) PK ## _DEBUG_FUNC -#define MBEDTLS_PK_INFO_DEBUG_OMIT_T( PK ) PK ## _DEBUG_OMIT - -/* Wrappers around MBEDTLS_PK_INFO_{FIELD}_T() which makes sure that - * the argument is macro-expanded before concatenated with the - * field name. This allows to call these macros as - * MBEDTLS_PK_INFO_{FIELD}( MBEDTLS_PK_SINGLE_TYPE ). - * where MBEDTLS_PK_SINGLE_TYPE expands to MBEDTLS_PK_INFO_{TYPE}. */ -#define MBEDTLS_PK_INFO_CONTEXT( PK ) MBEDTLS_PK_INFO_CONTEXT_T( PK ) -#define MBEDTLS_PK_INFO_TYPE( PK ) MBEDTLS_PK_INFO_TYPE_T( PK ) -#define MBEDTLS_PK_INFO_NAME( PK ) MBEDTLS_PK_INFO_NAME_T( PK ) -#define MBEDTLS_PK_INFO_GET_BITLEN( PK ) MBEDTLS_PK_INFO_GET_BITLEN_T( PK ) -#define MBEDTLS_PK_INFO_CAN_DO( PK ) MBEDTLS_PK_INFO_CAN_DO_T( PK ) -#define MBEDTLS_PK_INFO_VERIFY_FUNC( PK ) MBEDTLS_PK_INFO_VERIFY_FUNC_T( PK ) -#define MBEDTLS_PK_INFO_VERIFY_OMIT( PK ) MBEDTLS_PK_INFO_VERIFY_OMIT_T( PK ) -#define MBEDTLS_PK_INFO_SIGN_FUNC( PK ) MBEDTLS_PK_INFO_SIGN_FUNC_T( PK ) -#define MBEDTLS_PK_INFO_SIGN_OMIT( PK ) MBEDTLS_PK_INFO_SIGN_OMIT_T( PK ) -#define MBEDTLS_PK_INFO_DECRYPT_FUNC( PK ) MBEDTLS_PK_INFO_DECRYPT_FUNC_T( PK ) -#define MBEDTLS_PK_INFO_DECRYPT_OMIT( PK ) MBEDTLS_PK_INFO_DECRYPT_OMIT_T( PK ) -#define MBEDTLS_PK_INFO_ENCRYPT_FUNC( PK ) MBEDTLS_PK_INFO_ENCRYPT_FUNC_T( PK ) -#define MBEDTLS_PK_INFO_ENCRYPT_OMIT( PK ) MBEDTLS_PK_INFO_ENCRYPT_OMIT_T( PK ) -#define MBEDTLS_PK_INFO_CHECK_PAIR_FUNC( PK ) MBEDTLS_PK_INFO_CHECK_PAIR_FUNC_T( PK ) -#define MBEDTLS_PK_INFO_CHECK_PAIR_OMIT( PK ) MBEDTLS_PK_INFO_CHECK_PAIR_OMIT_T( PK ) -#define MBEDTLS_PK_INFO_CTX_ALLOC_FUNC( PK ) MBEDTLS_PK_INFO_CTX_ALLOC_FUNC_T( PK ) -#define MBEDTLS_PK_INFO_CTX_FREE_FUNC( PK ) MBEDTLS_PK_INFO_CTX_FREE_FUNC_T( PK ) -#define MBEDTLS_PK_INFO_DEBUG_FUNC( PK ) MBEDTLS_PK_INFO_DEBUG_FUNC_T( PK ) -#define MBEDTLS_PK_INFO_DEBUG_OMIT( PK ) MBEDTLS_PK_INFO_DEBUG_OMIT_T( PK ) - -#if !defined(MBEDTLS_PK_SINGLE_TYPE) struct mbedtls_pk_info_t { /** Public key type */ @@ -125,128 +41,49 @@ struct mbedtls_pk_info_t /** Type name */ const char *name; - /** Get key size in bits (must be valid)*/ + /** Get key size in bits */ size_t (*get_bitlen)( const void * ); - /** Tell if the context implements this type (e.g. ECKEY can do ECDSA) - * (must be valid) */ + /** Tell if the context implements this type (e.g. ECKEY can do ECDSA) */ int (*can_do)( mbedtls_pk_type_t type ); - /** Verify signature (may be NULL) */ + /** Verify signature */ int (*verify_func)( void *ctx, mbedtls_md_type_t md_alg, const unsigned char *hash, size_t hash_len, const unsigned char *sig, size_t sig_len ); - /** Make signature (may be NULL)*/ + /** Make signature */ int (*sign_func)( void *ctx, mbedtls_md_type_t md_alg, const unsigned char *hash, size_t hash_len, unsigned char *sig, size_t *sig_len, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - /** Verify signature (restartable) (may be NULL) */ - int (*verify_rs_func)( void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - const unsigned char *sig, size_t sig_len, - void *rs_ctx ); - - /** Make signature (restartable) (may be NULL) */ - int (*sign_rs_func)( void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t *sig_len, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, void *rs_ctx ); -#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - - /** Decrypt message (may be NULL) */ + /** Decrypt message */ int (*decrypt_func)( void *ctx, const unsigned char *input, size_t ilen, unsigned char *output, size_t *olen, size_t osize, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); - /** Encrypt message (may be NULL ) */ + /** Encrypt message */ int (*encrypt_func)( void *ctx, const unsigned char *input, size_t ilen, unsigned char *output, size_t *olen, size_t osize, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); - /** Check public-private key pair (may be NULL) */ + /** Check public-private key pair */ int (*check_pair_func)( const void *pub, const void *prv ); - /** Allocate a new context (must be valid) */ + /** Allocate a new context */ void * (*ctx_alloc_func)( void ); - /** Free the given context (must be valid) */ + /** Free the given context */ void (*ctx_free_func)( void *ctx ); -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - /** Allocate the restart context (may be NULL)*/ - void * (*rs_alloc_func)( void ); - - /** Free the restart context (may be NULL) */ - void (*rs_free_func)( void *rs_ctx ); -#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - - /** Interface with the debug module (may be NULL) */ + /** Interface with the debug module */ void (*debug_func)( const void *ctx, mbedtls_pk_debug_item *items ); }; - -/** - * \brief This macro builds an instance of ::mbedtls_pk_info_t - * from an \c MBEDTLS_PK_INFO_{TYPE} identifier. - */ -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) -#define MBEDTLS_PK_INFO( PK ) \ -{ \ - MBEDTLS_PK_INFO_TYPE( PK ), \ - MBEDTLS_PK_INFO_NAME( PK ), \ - MBEDTLS_PK_INFO_GET_BITLEN( PK ), \ - MBEDTLS_PK_INFO_CAN_DO( PK ), \ - MBEDTLS_PK_INFO_VERIFY_FUNC( PK ), \ - MBEDTLS_PK_INFO_SIGN_FUNC( PK ), \ - NULL, \ - NULL, \ - MBEDTLS_PK_INFO_DECRYPT_FUNC( PK ), \ - MBEDTLS_PK_INFO_ENCRYPT_FUNC( PK ), \ - MBEDTLS_PK_INFO_CHECK_PAIR_FUNC( PK ), \ - MBEDTLS_PK_INFO_CTX_ALLOC_FUNC( PK ), \ - MBEDTLS_PK_INFO_CTX_FREE_FUNC( PK ), \ - NULL, \ - NULL, \ - MBEDTLS_PK_INFO_DEBUG_FUNC( PK ), \ -} -#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ -#define MBEDTLS_PK_INFO( PK ) \ -{ \ - MBEDTLS_PK_INFO_TYPE( PK ), \ - MBEDTLS_PK_INFO_NAME( PK ), \ - MBEDTLS_PK_INFO_GET_BITLEN( PK ), \ - MBEDTLS_PK_INFO_CAN_DO( PK ), \ - MBEDTLS_PK_INFO_VERIFY_FUNC( PK ), \ - MBEDTLS_PK_INFO_SIGN_FUNC( PK ), \ - MBEDTLS_PK_INFO_DECRYPT_FUNC( PK ), \ - MBEDTLS_PK_INFO_ENCRYPT_FUNC( PK ), \ - MBEDTLS_PK_INFO_CHECK_PAIR_FUNC( PK ), \ - MBEDTLS_PK_INFO_CTX_ALLOC_FUNC( PK ), \ - MBEDTLS_PK_INFO_CTX_FREE_FUNC( PK ), \ - MBEDTLS_PK_INFO_DEBUG_FUNC( PK ), \ -} -#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ -#endif /* MBEDTLS_PK_SINGLE_TYPE */ - -/* - * Macros to access pk_info - */ -#if defined(MBEDTLS_PK_SINGLE_TYPE) -#define MBEDTLS_PK_CTX_INFO( ctx ) MBEDTLS_PK_UNIQUE_VALID_HANDLE -#else -#define MBEDTLS_PK_CTX_INFO( ctx ) ( (ctx)->pk_info ) -#endif -#define MBEDTLS_PK_CTX_IS_VALID( ctx ) \ - ( MBEDTLS_PK_CTX_INFO( (ctx) ) != MBEDTLS_PK_INVALID_HANDLE ) - #if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) /* Container for RSA-alt */ typedef struct @@ -258,7 +95,6 @@ typedef struct } mbedtls_rsa_alt_context; #endif -#if !defined(MBEDTLS_PK_SINGLE_TYPE) #if defined(MBEDTLS_RSA_C) extern const mbedtls_pk_info_t mbedtls_rsa_info; #endif @@ -272,13 +108,8 @@ extern const mbedtls_pk_info_t mbedtls_eckeydh_info; extern const mbedtls_pk_info_t mbedtls_ecdsa_info; #endif -#if defined(MBEDTLS_USE_TINYCRYPT) -extern const mbedtls_pk_info_t mbedtls_uecc_eckey_info; -#endif - #if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) extern const mbedtls_pk_info_t mbedtls_rsa_alt_info; #endif -#endif /* MBEDTLS_PK_SINGLE_TYPE */ #endif /* MBEDTLS_PK_WRAP_H */ diff --git a/APP_Framework/Framework/security/mbedtls/pk_wrap.c b/APP_Framework/Framework/security/mbedtls/pk_wrap.c new file mode 100644 index 000000000..b94e8d099 --- /dev/null +++ b/APP_Framework/Framework/security/mbedtls/pk_wrap.c @@ -0,0 +1,526 @@ +/* + * Public Key abstraction layer: wrapper functions + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_PK_C) +#include "pk_internal.h" + +/* Even if RSA not activated, for the sake of RSA-alt */ +#include "rsa.h" + +#include + +#if defined(MBEDTLS_ECP_C) +#include "ecp.h" +#endif + +#if defined(MBEDTLS_ECDSA_C) +#include "ecdsa.h" +#endif + +#if defined(MBEDTLS_PLATFORM_C) +#include "platform.h" +#else +#include +#define mbedtls_calloc calloc +#define mbedtls_free free +#endif + +#include +#include + +#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) +/* 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; +} +#endif + +#if defined(MBEDTLS_RSA_C) +static int rsa_can_do( mbedtls_pk_type_t type ) +{ + return( type == MBEDTLS_PK_RSA || + type == MBEDTLS_PK_RSASSA_PSS ); +} + +static size_t rsa_get_bitlen( const void *ctx ) +{ + 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, + const unsigned char *hash, size_t hash_len, + const unsigned char *sig, size_t sig_len ) +{ + int ret; + mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx; + size_t rsa_len = mbedtls_rsa_get_len( rsa ); + +#if SIZE_MAX > UINT_MAX + if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len ) + return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); +#endif /* SIZE_MAX > UINT_MAX */ + + if( sig_len < rsa_len ) + return( MBEDTLS_ERR_RSA_VERIFY_FAILED ); + + if( ( ret = mbedtls_rsa_pkcs1_verify( rsa, NULL, NULL, + MBEDTLS_RSA_PUBLIC, md_alg, + (unsigned int) hash_len, hash, sig ) ) != 0 ) + return( ret ); + + /* The buffer contains a valid signature followed by extra data. + * We have a special error code for that so that so that callers can + * use mbedtls_pk_verify() to check "Does the buffer start with a + * valid signature?" and not just "Does the buffer contain a valid + * signature?". */ + if( sig_len > rsa_len ) + return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH ); + + return( 0 ); +} + +static int rsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + unsigned char *sig, size_t *sig_len, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx; + +#if SIZE_MAX > UINT_MAX + if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len ) + return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); +#endif /* SIZE_MAX > UINT_MAX */ + + *sig_len = mbedtls_rsa_get_len( rsa ); + + return( mbedtls_rsa_pkcs1_sign( rsa, f_rng, p_rng, MBEDTLS_RSA_PRIVATE, + md_alg, (unsigned int) hash_len, hash, sig ) ); +} + +static int rsa_decrypt_wrap( void *ctx, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen, size_t osize, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx; + + if( ilen != mbedtls_rsa_get_len( rsa ) ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + + return( mbedtls_rsa_pkcs1_decrypt( rsa, f_rng, p_rng, + MBEDTLS_RSA_PRIVATE, olen, input, output, osize ) ); +} + +static int rsa_encrypt_wrap( void *ctx, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen, size_t osize, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx; + *olen = mbedtls_rsa_get_len( rsa ); + + if( *olen > osize ) + return( MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE ); + + return( mbedtls_rsa_pkcs1_encrypt( rsa, f_rng, p_rng, MBEDTLS_RSA_PUBLIC, + ilen, input, output ) ); +} + +static int rsa_check_pair_wrap( const void *pub, const void *prv ) +{ + return( mbedtls_rsa_check_pub_priv( (const mbedtls_rsa_context *) pub, + (const mbedtls_rsa_context *) prv ) ); +} + +static void *rsa_alloc_wrap( void ) +{ + void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_rsa_context ) ); + + if( ctx != NULL ) + mbedtls_rsa_init( (mbedtls_rsa_context *) ctx, 0, 0 ); + + return( ctx ); +} + +static void rsa_free_wrap( void *ctx ) +{ + mbedtls_rsa_free( (mbedtls_rsa_context *) ctx ); + mbedtls_free( ctx ); +} + +static void rsa_debug( const void *ctx, mbedtls_pk_debug_item *items ) +{ + items->type = MBEDTLS_PK_DEBUG_MPI; + items->name = "rsa.N"; + items->value = &( ((mbedtls_rsa_context *) ctx)->N ); + + items++; + + items->type = MBEDTLS_PK_DEBUG_MPI; + items->name = "rsa.E"; + items->value = &( ((mbedtls_rsa_context *) ctx)->E ); +} + +const mbedtls_pk_info_t mbedtls_rsa_info = { + MBEDTLS_PK_RSA, + "RSA", + rsa_get_bitlen, + rsa_can_do, + rsa_verify_wrap, + rsa_sign_wrap, + rsa_decrypt_wrap, + rsa_encrypt_wrap, + rsa_check_pair_wrap, + rsa_alloc_wrap, + rsa_free_wrap, + rsa_debug, +}; +#endif /* MBEDTLS_RSA_C */ + +#if defined(MBEDTLS_ECP_C) +/* + * Generic EC key + */ +static int eckey_can_do( mbedtls_pk_type_t type ) +{ + return( type == MBEDTLS_PK_ECKEY || + type == MBEDTLS_PK_ECKEY_DH || + type == MBEDTLS_PK_ECDSA ); +} + +static size_t eckey_get_bitlen( const void *ctx ) +{ + return( ((mbedtls_ecp_keypair *) ctx)->grp.pbits ); +} + +#if defined(MBEDTLS_ECDSA_C) +/* Forward declarations */ +static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + const unsigned char *sig, size_t sig_len ); + +static int ecdsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + unsigned char *sig, size_t *sig_len, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); + +static int eckey_verify_wrap( void *ctx, mbedtls_md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + const unsigned char *sig, size_t sig_len ) +{ + int ret; + mbedtls_ecdsa_context ecdsa; + + mbedtls_ecdsa_init( &ecdsa ); + + if( ( ret = mbedtls_ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 ) + ret = ecdsa_verify_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len ); + + mbedtls_ecdsa_free( &ecdsa ); + + return( ret ); +} + +static int eckey_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + unsigned char *sig, size_t *sig_len, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + int ret; + mbedtls_ecdsa_context ecdsa; + + mbedtls_ecdsa_init( &ecdsa ); + + if( ( ret = mbedtls_ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 ) + ret = ecdsa_sign_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len, + f_rng, p_rng ); + + mbedtls_ecdsa_free( &ecdsa ); + + return( ret ); +} + +#endif /* MBEDTLS_ECDSA_C */ + +static int eckey_check_pair( const void *pub, const void *prv ) +{ + return( mbedtls_ecp_check_pub_priv( (const mbedtls_ecp_keypair *) pub, + (const mbedtls_ecp_keypair *) prv ) ); +} + +static void *eckey_alloc_wrap( void ) +{ + void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecp_keypair ) ); + + if( ctx != NULL ) + mbedtls_ecp_keypair_init( ctx ); + + return( ctx ); +} + +static void eckey_free_wrap( void *ctx ) +{ + mbedtls_ecp_keypair_free( (mbedtls_ecp_keypair *) ctx ); + mbedtls_free( ctx ); +} + +static void eckey_debug( const void *ctx, mbedtls_pk_debug_item *items ) +{ + items->type = MBEDTLS_PK_DEBUG_ECP; + items->name = "eckey.Q"; + items->value = &( ((mbedtls_ecp_keypair *) ctx)->Q ); +} + +const mbedtls_pk_info_t mbedtls_eckey_info = { + MBEDTLS_PK_ECKEY, + "EC", + eckey_get_bitlen, + eckey_can_do, +#if defined(MBEDTLS_ECDSA_C) + eckey_verify_wrap, + eckey_sign_wrap, +#else + NULL, + NULL, +#endif + NULL, + NULL, + eckey_check_pair, + eckey_alloc_wrap, + eckey_free_wrap, + eckey_debug, +}; + +/* + * EC key restricted to ECDH + */ +static int eckeydh_can_do( mbedtls_pk_type_t type ) +{ + return( type == MBEDTLS_PK_ECKEY || + type == MBEDTLS_PK_ECKEY_DH ); +} + +const mbedtls_pk_info_t mbedtls_eckeydh_info = { + MBEDTLS_PK_ECKEY_DH, + "EC_DH", + eckey_get_bitlen, /* Same underlying key structure */ + eckeydh_can_do, + NULL, + NULL, + NULL, + NULL, + eckey_check_pair, + eckey_alloc_wrap, /* Same underlying key structure */ + eckey_free_wrap, /* Same underlying key structure */ + eckey_debug, /* Same underlying key structure */ +}; +#endif /* MBEDTLS_ECP_C */ + +#if defined(MBEDTLS_ECDSA_C) +static int ecdsa_can_do( mbedtls_pk_type_t type ) +{ + return( type == MBEDTLS_PK_ECDSA ); +} + +static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + const unsigned char *sig, size_t sig_len ) +{ + int ret; + ((void) md_alg); + + ret = mbedtls_ecdsa_read_signature( (mbedtls_ecdsa_context *) ctx, + hash, hash_len, sig, sig_len ); + + if( ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH ) + return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH ); + + return( ret ); +} + +static int ecdsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + unsigned char *sig, size_t *sig_len, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + return( mbedtls_ecdsa_write_signature( (mbedtls_ecdsa_context *) ctx, + md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng ) ); +} + +static void *ecdsa_alloc_wrap( void ) +{ + void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecdsa_context ) ); + + if( ctx != NULL ) + mbedtls_ecdsa_init( (mbedtls_ecdsa_context *) ctx ); + + return( ctx ); +} + +static void ecdsa_free_wrap( void *ctx ) +{ + mbedtls_ecdsa_free( (mbedtls_ecdsa_context *) ctx ); + mbedtls_free( ctx ); +} + +const mbedtls_pk_info_t mbedtls_ecdsa_info = { + MBEDTLS_PK_ECDSA, + "ECDSA", + eckey_get_bitlen, /* Compatible key structures */ + ecdsa_can_do, + ecdsa_verify_wrap, + ecdsa_sign_wrap, + NULL, + NULL, + eckey_check_pair, /* Compatible key structures */ + ecdsa_alloc_wrap, + ecdsa_free_wrap, + eckey_debug, /* Compatible key structures */ +}; +#endif /* MBEDTLS_ECDSA_C */ + +#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) +/* + * Support for alternative RSA-private implementations + */ + +static int rsa_alt_can_do( mbedtls_pk_type_t type ) +{ + return( type == MBEDTLS_PK_RSA ); +} + +static size_t rsa_alt_get_bitlen( const void *ctx ) +{ + const mbedtls_rsa_alt_context *rsa_alt = (const mbedtls_rsa_alt_context *) ctx; + + return( 8 * rsa_alt->key_len_func( rsa_alt->key ) ); +} + +static int rsa_alt_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + unsigned char *sig, size_t *sig_len, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx; + +#if SIZE_MAX > UINT_MAX + if( UINT_MAX < hash_len ) + return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); +#endif /* SIZE_MAX > UINT_MAX */ + + *sig_len = rsa_alt->key_len_func( rsa_alt->key ); + + return( rsa_alt->sign_func( rsa_alt->key, f_rng, p_rng, MBEDTLS_RSA_PRIVATE, + md_alg, (unsigned int) hash_len, hash, sig ) ); +} + +static int rsa_alt_decrypt_wrap( void *ctx, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen, size_t osize, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx; + + ((void) f_rng); + ((void) p_rng); + + if( ilen != rsa_alt->key_len_func( rsa_alt->key ) ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + + return( rsa_alt->decrypt_func( rsa_alt->key, + MBEDTLS_RSA_PRIVATE, olen, input, output, osize ) ); +} + +#if defined(MBEDTLS_RSA_C) +static int rsa_alt_check_pair( const void *pub, const void *prv ) +{ + unsigned char sig[MBEDTLS_MPI_MAX_SIZE]; + unsigned char hash[32]; + size_t sig_len = 0; + int ret; + + if( rsa_alt_get_bitlen( prv ) != rsa_get_bitlen( pub ) ) + return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); + + memset( hash, 0x2a, sizeof( hash ) ); + + if( ( ret = rsa_alt_sign_wrap( (void *) prv, MBEDTLS_MD_NONE, + hash, sizeof( hash ), + sig, &sig_len, NULL, NULL ) ) != 0 ) + { + return( ret ); + } + + if( rsa_verify_wrap( (void *) pub, MBEDTLS_MD_NONE, + hash, sizeof( hash ), sig, sig_len ) != 0 ) + { + return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); + } + + return( 0 ); +} +#endif /* MBEDTLS_RSA_C */ + +static void *rsa_alt_alloc_wrap( void ) +{ + void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_rsa_alt_context ) ); + + if( ctx != NULL ) + memset( ctx, 0, sizeof( mbedtls_rsa_alt_context ) ); + + return( ctx ); +} + +static void rsa_alt_free_wrap( void *ctx ) +{ + mbedtls_zeroize( ctx, sizeof( mbedtls_rsa_alt_context ) ); + mbedtls_free( ctx ); +} + +const mbedtls_pk_info_t mbedtls_rsa_alt_info = { + MBEDTLS_PK_RSA_ALT, + "RSA-alt", + rsa_alt_get_bitlen, + rsa_alt_can_do, + NULL, + rsa_alt_sign_wrap, + rsa_alt_decrypt_wrap, + NULL, +#if defined(MBEDTLS_RSA_C) + rsa_alt_check_pair, +#else + NULL, +#endif + rsa_alt_alloc_wrap, + rsa_alt_free_wrap, + NULL, +}; + +#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */ + +#endif /* MBEDTLS_PK_C */ diff --git a/APP_Framework/Framework/security/mbedtls/pkcs11.c b/APP_Framework/Framework/security/mbedtls/pkcs11.c new file mode 100644 index 000000000..b173e2d21 --- /dev/null +++ b/APP_Framework/Framework/security/mbedtls/pkcs11.c @@ -0,0 +1,240 @@ +/** + * \file pkcs11.c + * + * \brief Wrapper for PKCS#11 library libpkcs11-helper + * + * \author Adriaan de Jong + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#include "pkcs11.h" + +#if defined(MBEDTLS_PKCS11_C) + +#include "md.h" +#include "oid.h" +#include "x509_crt.h" + +#if defined(MBEDTLS_PLATFORM_C) +#include "platform.h" +#else +#include +#define mbedtls_calloc calloc +#define mbedtls_free free +#endif + +#include + +void mbedtls_pkcs11_init( mbedtls_pkcs11_context *ctx ) +{ + memset( ctx, 0, sizeof( mbedtls_pkcs11_context ) ); +} + +int mbedtls_pkcs11_x509_cert_bind( mbedtls_x509_crt *cert, pkcs11h_certificate_t pkcs11_cert ) +{ + int ret = 1; + unsigned char *cert_blob = NULL; + size_t cert_blob_size = 0; + + if( cert == NULL ) + { + ret = 2; + goto cleanup; + } + + if( pkcs11h_certificate_getCertificateBlob( pkcs11_cert, NULL, + &cert_blob_size ) != CKR_OK ) + { + ret = 3; + goto cleanup; + } + + cert_blob = mbedtls_calloc( 1, cert_blob_size ); + if( NULL == cert_blob ) + { + ret = 4; + goto cleanup; + } + + if( pkcs11h_certificate_getCertificateBlob( pkcs11_cert, cert_blob, + &cert_blob_size ) != CKR_OK ) + { + ret = 5; + goto cleanup; + } + + if( 0 != mbedtls_x509_crt_parse( cert, cert_blob, cert_blob_size ) ) + { + ret = 6; + goto cleanup; + } + + ret = 0; + +cleanup: + if( NULL != cert_blob ) + mbedtls_free( cert_blob ); + + return( ret ); +} + + +int mbedtls_pkcs11_priv_key_bind( mbedtls_pkcs11_context *priv_key, + pkcs11h_certificate_t pkcs11_cert ) +{ + int ret = 1; + mbedtls_x509_crt cert; + + mbedtls_x509_crt_init( &cert ); + + if( priv_key == NULL ) + goto cleanup; + + if( 0 != mbedtls_pkcs11_x509_cert_bind( &cert, pkcs11_cert ) ) + goto cleanup; + + priv_key->len = mbedtls_pk_get_len( &cert.pk ); + priv_key->pkcs11h_cert = pkcs11_cert; + + ret = 0; + +cleanup: + mbedtls_x509_crt_free( &cert ); + + return( ret ); +} + +void mbedtls_pkcs11_priv_key_free( mbedtls_pkcs11_context *priv_key ) +{ + if( NULL != priv_key ) + pkcs11h_certificate_freeCertificate( priv_key->pkcs11h_cert ); +} + +int mbedtls_pkcs11_decrypt( mbedtls_pkcs11_context *ctx, + int mode, size_t *olen, + const unsigned char *input, + unsigned char *output, + size_t output_max_len ) +{ + size_t input_len, output_len; + + if( NULL == ctx ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + + if( MBEDTLS_RSA_PRIVATE != mode ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + + output_len = input_len = ctx->len; + + if( input_len < 16 || input_len > output_max_len ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + + /* Determine size of output buffer */ + if( pkcs11h_certificate_decryptAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, input, + input_len, NULL, &output_len ) != CKR_OK ) + { + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + } + + if( output_len > output_max_len ) + return( MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE ); + + if( pkcs11h_certificate_decryptAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, input, + input_len, output, &output_len ) != CKR_OK ) + { + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + } + *olen = output_len; + return( 0 ); +} + +int mbedtls_pkcs11_sign( mbedtls_pkcs11_context *ctx, + int mode, + mbedtls_md_type_t md_alg, + unsigned int hashlen, + const unsigned char *hash, + unsigned char *sig ) +{ + size_t sig_len = 0, asn_len = 0, oid_size = 0; + unsigned char *p = sig; + const char *oid; + + if( NULL == ctx ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + + if( MBEDTLS_RSA_PRIVATE != mode ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + + if( md_alg != MBEDTLS_MD_NONE ) + { + const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg ); + if( md_info == NULL ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + + if( mbedtls_oid_get_oid_by_md( md_alg, &oid, &oid_size ) != 0 ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + + hashlen = mbedtls_md_get_size( md_info ); + asn_len = 10 + oid_size; + } + + sig_len = ctx->len; + if( hashlen > sig_len || asn_len > sig_len || + hashlen + asn_len > sig_len ) + { + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + } + + if( md_alg != MBEDTLS_MD_NONE ) + { + /* + * DigestInfo ::= SEQUENCE { + * digestAlgorithm DigestAlgorithmIdentifier, + * digest Digest } + * + * DigestAlgorithmIdentifier ::= AlgorithmIdentifier + * + * Digest ::= OCTET STRING + */ + *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED; + *p++ = (unsigned char) ( 0x08 + oid_size + hashlen ); + *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED; + *p++ = (unsigned char) ( 0x04 + oid_size ); + *p++ = MBEDTLS_ASN1_OID; + *p++ = oid_size & 0xFF; + memcpy( p, oid, oid_size ); + p += oid_size; + *p++ = MBEDTLS_ASN1_NULL; + *p++ = 0x00; + *p++ = MBEDTLS_ASN1_OCTET_STRING; + *p++ = hashlen; + } + + memcpy( p, hash, hashlen ); + + if( pkcs11h_certificate_signAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, sig, + asn_len + hashlen, sig, &sig_len ) != CKR_OK ) + { + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + } + + return( 0 ); +} + +#endif /* defined(MBEDTLS_PKCS11_C) */ diff --git a/APP_Framework/Framework/security/mbedtls/pkcs11.h b/APP_Framework/Framework/security/mbedtls/pkcs11.h index 02427ddc1..bf65c55a7 100644 --- a/APP_Framework/Framework/security/mbedtls/pkcs11.h +++ b/APP_Framework/Framework/security/mbedtls/pkcs11.h @@ -50,8 +50,7 @@ extern "C" { /** * Context for PKCS #11 private keys. */ -typedef struct mbedtls_pkcs11_context -{ +typedef struct { pkcs11h_certificate_t pkcs11h_cert; int len; } mbedtls_pkcs11_context; diff --git a/APP_Framework/Framework/security/mbedtls/pkcs12.c b/APP_Framework/Framework/security/mbedtls/pkcs12.c index 97785745d..11c0cea20 100644 --- a/APP_Framework/Framework/security/mbedtls/pkcs12.c +++ b/APP_Framework/Framework/security/mbedtls/pkcs12.c @@ -36,7 +36,6 @@ #include "pkcs12.h" #include "asn1.h" #include "cipher.h" -#include "platform_util.h" #include @@ -48,6 +47,11 @@ #include "des.h" #endif +/* 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; +} + #if defined(MBEDTLS_ASN1_PARSE_C) static int pkcs12_parse_pbe_params( mbedtls_asn1_buf *params, @@ -99,8 +103,8 @@ static int pkcs12_pbe_derive_key_iv( mbedtls_asn1_buf *pbe_params, mbedtls_md_ty if( pwdlen > PKCS12_MAX_PWDLEN ) return( MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA ); - mbedtls_platform_memset( &salt, 0, sizeof(mbedtls_asn1_buf) ); - mbedtls_platform_memset( &unipwd, 0, sizeof(unipwd) ); + memset( &salt, 0, sizeof(mbedtls_asn1_buf) ); + memset( &unipwd, 0, sizeof(unipwd) ); if( ( ret = pkcs12_parse_pbe_params( pbe_params, &salt, &iterations ) ) != 0 ) @@ -164,7 +168,7 @@ int mbedtls_pkcs12_pbe_sha1_rc4_128( mbedtls_asn1_buf *pbe_params, int mode, goto exit; exit: - mbedtls_platform_zeroize( key, sizeof( key ) ); + mbedtls_zeroize( key, sizeof( key ) ); mbedtls_arc4_free( &ctx ); return( ret ); @@ -221,8 +225,8 @@ int mbedtls_pkcs12_pbe( mbedtls_asn1_buf *pbe_params, int mode, ret = MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH; exit: - mbedtls_platform_zeroize( key, sizeof( key ) ); - mbedtls_platform_zeroize( iv, sizeof( iv ) ); + mbedtls_zeroize( key, sizeof( key ) ); + mbedtls_zeroize( iv, sizeof( iv ) ); mbedtls_cipher_free( &cipher_ctx ); return( ret ); @@ -239,7 +243,7 @@ static void pkcs12_fill_buffer( unsigned char *data, size_t data_len, while( data_len > 0 ) { use_len = ( data_len > fill_len ) ? fill_len : data_len; - mbedtls_platform_memcpy( p, filler, use_len ); + memcpy( p, filler, use_len ); p += use_len; data_len -= use_len; } @@ -261,7 +265,7 @@ int mbedtls_pkcs12_derivation( unsigned char *data, size_t datalen, size_t hlen, use_len, v, i; - mbedtls_md_handle_t md_info; + const mbedtls_md_info_t *md_info; mbedtls_md_context_t md_ctx; // This version only allows max of 64 bytes of password or salt @@ -269,7 +273,7 @@ int mbedtls_pkcs12_derivation( unsigned char *data, size_t datalen, return( MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA ); md_info = mbedtls_md_info_from_type( md_type ); - if( md_info == MBEDTLS_MD_INVALID_HANDLE ) + if( md_info == NULL ) return( MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE ); mbedtls_md_init( &md_ctx ); @@ -283,7 +287,7 @@ int mbedtls_pkcs12_derivation( unsigned char *data, size_t datalen, else v = 128; - mbedtls_platform_memset( diversifier, (unsigned char) id, v ); + memset( diversifier, (unsigned char) id, v ); pkcs12_fill_buffer( salt_block, v, salt, saltlen ); pkcs12_fill_buffer( pwd_block, v, pwd, pwdlen ); @@ -315,7 +319,7 @@ int mbedtls_pkcs12_derivation( unsigned char *data, size_t datalen, } use_len = ( datalen > hlen ) ? hlen : datalen; - mbedtls_platform_memcpy( p, hash_output, use_len ); + memcpy( p, hash_output, use_len ); datalen -= use_len; p += use_len; @@ -352,10 +356,10 @@ int mbedtls_pkcs12_derivation( unsigned char *data, size_t datalen, ret = 0; exit: - mbedtls_platform_zeroize( salt_block, sizeof( salt_block ) ); - mbedtls_platform_zeroize( pwd_block, sizeof( pwd_block ) ); - mbedtls_platform_zeroize( hash_block, sizeof( hash_block ) ); - mbedtls_platform_zeroize( hash_output, sizeof( hash_output ) ); + mbedtls_zeroize( salt_block, sizeof( salt_block ) ); + mbedtls_zeroize( pwd_block, sizeof( pwd_block ) ); + mbedtls_zeroize( hash_block, sizeof( hash_block ) ); + mbedtls_zeroize( hash_output, sizeof( hash_output ) ); mbedtls_md_free( &md_ctx ); diff --git a/APP_Framework/Framework/security/mbedtls/pkcs5.c b/APP_Framework/Framework/security/mbedtls/pkcs5.c index 417d50a0e..ddde62f76 100644 --- a/APP_Framework/Framework/security/mbedtls/pkcs5.c +++ b/APP_Framework/Framework/security/mbedtls/pkcs5.c @@ -46,7 +46,6 @@ #endif /* MBEDTLS_ASN1_PARSE_C */ #include -#include "platform_util.h" #if defined(MBEDTLS_PLATFORM_C) #include "platform.h" @@ -123,7 +122,7 @@ int mbedtls_pkcs5_pbes2( const mbedtls_asn1_buf *pbe_params, int mode, mbedtls_md_type_t md_type = MBEDTLS_MD_SHA1; unsigned char key[32], iv[32]; size_t olen = 0; - mbedtls_md_handle_t md_info; + const mbedtls_md_info_t *md_info; const mbedtls_cipher_info_t *cipher_info; mbedtls_md_context_t md_ctx; mbedtls_cipher_type_t cipher_alg; @@ -158,7 +157,7 @@ int mbedtls_pkcs5_pbes2( const mbedtls_asn1_buf *pbe_params, int mode, } md_info = mbedtls_md_info_from_type( md_type ); - if( md_info == MBEDTLS_MD_INVALID_HANDLE ) + if( md_info == NULL ) return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE ); if( ( ret = mbedtls_asn1_get_alg( &p, end, &enc_scheme_oid, @@ -189,7 +188,7 @@ int mbedtls_pkcs5_pbes2( const mbedtls_asn1_buf *pbe_params, int mode, mbedtls_md_init( &md_ctx ); mbedtls_cipher_init( &cipher_ctx ); - mbedtls_platform_memcpy( iv, enc_scheme_params.p, enc_scheme_params.len ); + memcpy( iv, enc_scheme_params.p, enc_scheme_params.len ); if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 1 ) ) != 0 ) goto exit; @@ -227,12 +226,12 @@ int mbedtls_pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx, const unsigned char *p unsigned int i; unsigned char md1[MBEDTLS_MD_MAX_SIZE]; unsigned char work[MBEDTLS_MD_MAX_SIZE]; - unsigned char md_size = mbedtls_md_get_size( mbedtls_md_get_handle( ctx ) ); + unsigned char md_size = mbedtls_md_get_size( ctx->md_info ); size_t use_len; unsigned char *out_p = output; unsigned char counter[4]; - mbedtls_platform_memset( counter, 0, 4 ); + memset( counter, 0, 4 ); counter[3] = 1; #if UINT_MAX > 0xFFFFFFFF @@ -256,7 +255,7 @@ int mbedtls_pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx, const unsigned char *p if( ( ret = mbedtls_md_hmac_finish( ctx, work ) ) != 0 ) return( ret ); - mbedtls_platform_memcpy( md1, work, md_size ); + memcpy( md1, work, md_size ); for( i = 1; i < iteration_count; i++ ) { @@ -278,7 +277,7 @@ int mbedtls_pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx, const unsigned char *p } use_len = ( key_length < md_size ) ? key_length : md_size; - mbedtls_platform_memcpy( out_p, work, use_len ); + memcpy( out_p, work, use_len ); key_length -= (uint32_t) use_len; out_p += use_len; @@ -357,14 +356,14 @@ static const unsigned char result_key[MAX_TESTS][32] = int mbedtls_pkcs5_self_test( int verbose ) { mbedtls_md_context_t sha1_ctx; - mbedtls_md_handle_t info_sha1; + const mbedtls_md_info_t *info_sha1; int ret, i; unsigned char key[64]; mbedtls_md_init( &sha1_ctx ); info_sha1 = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 ); - if( info_sha1 == MBEDTLS_MD_INVALID_HANDLE ) + if( info_sha1 == NULL ) { ret = 1; goto exit; @@ -384,7 +383,7 @@ int mbedtls_pkcs5_self_test( int verbose ) ret = mbedtls_pkcs5_pbkdf2_hmac( &sha1_ctx, password[i], plen[i], salt[i], slen[i], it_cnt[i], key_len[i], key ); if( ret != 0 || - memcmp( result_key[i], key, key_len[i] ) != 0 ) + memcmp( result_key[i], key, key_len[i] ) != 0 ) { if( verbose != 0 ) mbedtls_printf( "failed\n" ); diff --git a/APP_Framework/Framework/security/mbedtls/pkcs5.h b/APP_Framework/Framework/security/mbedtls/pkcs5.h index c92185f7a..f20125004 100644 --- a/APP_Framework/Framework/security/mbedtls/pkcs5.h +++ b/APP_Framework/Framework/security/mbedtls/pkcs5.h @@ -91,8 +91,6 @@ int mbedtls_pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx, const unsigned char *p unsigned int iteration_count, uint32_t key_length, unsigned char *output ); -#if defined(MBEDTLS_SELF_TEST) - /** * \brief Checkup routine * @@ -100,8 +98,6 @@ int mbedtls_pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx, const unsigned char *p */ int mbedtls_pkcs5_self_test( int verbose ); -#endif /* MBEDTLS_SELF_TEST */ - #ifdef __cplusplus } #endif diff --git a/APP_Framework/Framework/security/mbedtls/pkparse.c b/APP_Framework/Framework/security/mbedtls/pkparse.c index 684086e36..829f9f76a 100644 --- a/APP_Framework/Framework/security/mbedtls/pkparse.c +++ b/APP_Framework/Framework/security/mbedtls/pkparse.c @@ -30,7 +30,6 @@ #include "pk.h" #include "asn1.h" #include "oid.h" -#include "platform_util.h" #include @@ -52,9 +51,6 @@ #if defined(MBEDTLS_PKCS12_C) #include "pkcs12.h" #endif -#if defined(MBEDTLS_USE_TINYCRYPT) -#include "tinycrypt/ecc.h" -#endif #if defined(MBEDTLS_PLATFORM_C) #include "platform.h" @@ -64,11 +60,13 @@ #define mbedtls_free free #endif -/* Parameter validation macros based on platform_util.h */ -#define PK_VALIDATE_RET( cond ) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_PK_BAD_INPUT_DATA ) -#define PK_VALIDATE( cond ) \ - MBEDTLS_INTERNAL_VALIDATE( cond ) +#if defined(MBEDTLS_FS_IO) || \ + defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C) +/* 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; +} +#endif #if defined(MBEDTLS_FS_IO) /* @@ -83,10 +81,6 @@ int mbedtls_pk_load_file( const char *path, unsigned char **buf, size_t *n ) FILE *f; long size; - PK_VALIDATE_RET( path != NULL ); - PK_VALIDATE_RET( buf != NULL ); - PK_VALIDATE_RET( n != NULL ); - if( ( f = fopen( path, "rb" ) ) == NULL ) return( MBEDTLS_ERR_PK_FILE_IO_ERROR ); @@ -111,7 +105,7 @@ int mbedtls_pk_load_file( const char *path, unsigned char **buf, size_t *n ) { fclose( f ); - mbedtls_platform_zeroize( *buf, *n ); + mbedtls_zeroize( *buf, *n ); mbedtls_free( *buf ); return( MBEDTLS_ERR_PK_FILE_IO_ERROR ); @@ -137,9 +131,6 @@ int mbedtls_pk_parse_keyfile( mbedtls_pk_context *ctx, size_t n; unsigned char *buf; - PK_VALIDATE_RET( ctx != NULL ); - PK_VALIDATE_RET( path != NULL ); - if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 ) return( ret ); @@ -149,7 +140,7 @@ int mbedtls_pk_parse_keyfile( mbedtls_pk_context *ctx, ret = mbedtls_pk_parse_key( ctx, buf, n, (const unsigned char *) pwd, strlen( pwd ) ); - mbedtls_platform_zeroize( buf, n ); + mbedtls_zeroize( buf, n ); mbedtls_free( buf ); return( ret ); @@ -164,43 +155,19 @@ int mbedtls_pk_parse_public_keyfile( mbedtls_pk_context *ctx, const char *path ) size_t n; unsigned char *buf; - PK_VALIDATE_RET( ctx != NULL ); - PK_VALIDATE_RET( path != NULL ); - if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 ) return( ret ); ret = mbedtls_pk_parse_public_key( ctx, buf, n ); - mbedtls_platform_zeroize( buf, n ); + mbedtls_zeroize( buf, n ); mbedtls_free( buf ); return( ret ); } #endif /* MBEDTLS_FS_IO */ -#if defined(MBEDTLS_USE_TINYCRYPT) -static int pk_use_ecparams( const mbedtls_asn1_buf *params ) -{ - mbedtls_uecc_group_id grp_id; - - if( params->tag == MBEDTLS_ASN1_OID ) - { - if( mbedtls_oid_get_ec_grp( params, &grp_id ) != 0 ) - return( MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE ); - } - else - { - // Only P-256 is supported - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); - } - - return( 0 ); -} -#endif /* MBEDTLS_USE_TINYCRYPT */ - -#if defined(MBEDTLS_ECP_C) || \ - defined(MBEDTLS_USE_TINYCRYPT) +#if defined(MBEDTLS_ECP_C) /* Minimally parse an ECParameters buffer to and mbedtls_asn1_buf * * ECParameters ::= CHOICE { @@ -244,11 +211,7 @@ static int pk_get_ecparams( unsigned char **p, const unsigned char *end, return( 0 ); } -#endif /* MBEDTLS_ECP_C || MBEDTLS_USE_TINYCRYPT */ -#if !defined(MBEDTLS_USE_TINYCRYPT) - -#if defined(MBEDTLS_ECP_C) #if defined(MBEDTLS_PK_PARSE_EC_EXTENDED) /* * Parse a SpecifiedECDomain (SEC 1 C.2) and (mostly) fill the group with it. @@ -309,7 +272,7 @@ static int pk_group_from_specified( const mbedtls_asn1_buf *params, mbedtls_ecp_ return( ret ); if( len != MBEDTLS_OID_SIZE( MBEDTLS_OID_ANSI_X9_62_PRIME_FIELD ) || - mbedtls_platform_memequal( p, MBEDTLS_OID_ANSI_X9_62_PRIME_FIELD, len ) != 0 ) + memcmp( p, MBEDTLS_OID_ANSI_X9_62_PRIME_FIELD, len ) != 0 ) { return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE ); } @@ -544,52 +507,6 @@ static int pk_get_ecpubkey( unsigned char **p, const unsigned char *end, return( ret ); } #endif /* MBEDTLS_ECP_C */ -#endif /* !MBEDTLS_USE_TINYCRYPT */ - -#if defined(MBEDTLS_USE_TINYCRYPT) -/* - * Import a point from unsigned binary data (SEC1 2.3.4) - */ -static int uecc_public_key_read_binary( mbedtls_uecc_keypair *uecc_keypair, - const unsigned char *buf, size_t ilen ) -{ - if( ilen != 2 * NUM_ECC_BYTES + 1 ) - return( MBEDTLS_ERR_PK_INVALID_PUBKEY ); - - /* We are not handling the point at infinity. */ - - if( buf[0] != 0x04 ) - return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE ); - - if( mbedtls_platform_memcpy( uecc_keypair->public_key, buf + 1, 2 * NUM_ECC_BYTES ) == - uecc_keypair->public_key ) - { - return( 0 ); - } - - return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); -} - -static int pk_get_ueccpubkey( unsigned char **p, - const unsigned char *end, - uint8_t *pk_context) -{ - mbedtls_uecc_keypair *uecc_keypair = (mbedtls_uecc_keypair *) pk_context; - int ret; - - if( ( ret = uecc_public_key_read_binary( uecc_keypair, - (const unsigned char *) *p, end - *p ) ) - != 0 ) - return ret; - - /* - * We know uecc_public_key_read_binary consumed all bytes or failed - */ - *p = (unsigned char *) end; - - return( ret ); -} -#endif /* MBEDTLS_USE_TINYCRYPT */ #if defined(MBEDTLS_RSA_C) /* @@ -660,7 +577,7 @@ static int pk_get_pk_alg( unsigned char **p, int ret; mbedtls_asn1_buf alg_oid; - mbedtls_platform_memset( params, 0, sizeof(mbedtls_asn1_buf) ); + memset( params, 0, sizeof(mbedtls_asn1_buf) ); if( ( ret = mbedtls_asn1_get_alg( p, end, &alg_oid, params ) ) != 0 ) return( MBEDTLS_ERR_PK_INVALID_ALG + ret ); @@ -693,12 +610,7 @@ int mbedtls_pk_parse_subpubkey( unsigned char **p, const unsigned char *end, size_t len; mbedtls_asn1_buf alg_params; mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE; - mbedtls_pk_handle_t pk_info; - - PK_VALIDATE_RET( p != NULL ); - PK_VALIDATE_RET( *p != NULL ); - PK_VALIDATE_RET( end != NULL ); - PK_VALIDATE_RET( pk != NULL ); + const mbedtls_pk_info_t *pk_info; if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) @@ -718,7 +630,7 @@ int mbedtls_pk_parse_subpubkey( unsigned char **p, const unsigned char *end, return( MBEDTLS_ERR_PK_INVALID_PUBKEY + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - if( ( pk_info = mbedtls_pk_info_from_type( pk_alg ) ) == MBEDTLS_PK_INVALID_HANDLE ) + if( ( pk_info = mbedtls_pk_info_from_type( pk_alg ) ) == NULL ) return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG ); if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 ) @@ -730,12 +642,6 @@ int mbedtls_pk_parse_subpubkey( unsigned char **p, const unsigned char *end, ret = pk_get_rsapubkey( p, end, mbedtls_pk_rsa( *pk ) ); } else #endif /* MBEDTLS_RSA_C */ -#if defined(MBEDTLS_USE_TINYCRYPT) - if( pk_alg == MBEDTLS_PK_ECKEY ) - { - ret = pk_get_ueccpubkey( p, end, (uint8_t*) pk->pk_ctx ); - } else -#else /* MBEDTLS_USE_TINYCRYPT */ #if defined(MBEDTLS_ECP_C) if( pk_alg == MBEDTLS_PK_ECKEY_DH || pk_alg == MBEDTLS_PK_ECKEY ) { @@ -744,7 +650,6 @@ int mbedtls_pk_parse_subpubkey( unsigned char **p, const unsigned char *end, ret = pk_get_ecpubkey( p, end, mbedtls_pk_ec( *pk ) ); } else #endif /* MBEDTLS_ECP_C */ -#endif /* MBEDTLS_USE_TINYCRYPT */ ret = MBEDTLS_ERR_PK_UNKNOWN_PK_ALG; if( ret == 0 && *p != end ) @@ -758,32 +663,6 @@ int mbedtls_pk_parse_subpubkey( unsigned char **p, const unsigned char *end, } #if defined(MBEDTLS_RSA_C) -/* - * Wrapper around mbedtls_asn1_get_mpi() that rejects zero. - * - * The value zero is: - * - never a valid value for an RSA parameter - * - interpreted as "omitted, please reconstruct" by mbedtls_rsa_complete(). - * - * Since values can't be omitted in PKCS#1, passing a zero value to - * rsa_complete() would be incorrect, so reject zero values early. - */ -static int asn1_get_nonzero_mpi( unsigned char **p, - const unsigned char *end, - mbedtls_mpi *X ) -{ - int ret; - - ret = mbedtls_asn1_get_mpi( p, end, X ); - if( ret != 0 ) - return( ret ); - - if( mbedtls_mpi_cmp_int( X, 0 ) == 0 ) - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); - - return( 0 ); -} - /* * Parse a PKCS#1 encoded private RSA key */ @@ -836,84 +715,54 @@ static int pk_parse_key_pkcs1_der( mbedtls_rsa_context *rsa, } /* Import N */ - if( ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 || - ( ret = mbedtls_rsa_import( rsa, &T, NULL, NULL, - NULL, NULL ) ) != 0 ) + if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, + MBEDTLS_ASN1_INTEGER ) ) != 0 || + ( ret = mbedtls_rsa_import_raw( rsa, p, len, NULL, 0, NULL, 0, + NULL, 0, NULL, 0 ) ) != 0 ) goto cleanup; + p += len; /* Import E */ - if( ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 || - ( ret = mbedtls_rsa_import( rsa, NULL, NULL, NULL, - NULL, &T ) ) != 0 ) + 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 = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 || - ( ret = mbedtls_rsa_import( rsa, NULL, NULL, NULL, - &T, NULL ) ) != 0 ) + 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 = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 || - ( ret = mbedtls_rsa_import( rsa, NULL, &T, NULL, - NULL, NULL ) ) != 0 ) + 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 = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 || - ( ret = mbedtls_rsa_import( rsa, NULL, NULL, &T, - NULL, NULL ) ) != 0 ) + 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; -#if !defined(MBEDTLS_RSA_NO_CRT) && !defined(MBEDTLS_RSA_ALT) - /* - * The RSA CRT parameters DP, DQ and QP are nominally redundant, in - * that they can be easily recomputed from D, P and Q. However by - * parsing them from the PKCS1 structure it is possible to avoid - * recalculating them which both reduces the overhead of loading - * RSA private keys into memory and also avoids side channels which - * can arise when computing those values, since all of D, P, and Q - * are secret. See https://eprint.iacr.org/2020/055 for a - * description of one such attack. - */ - - /* Import DP */ - if( ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 || - ( ret = mbedtls_mpi_copy( &rsa->DP, &T ) ) != 0 ) - goto cleanup; - - /* Import DQ */ - if( ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 || - ( ret = mbedtls_mpi_copy( &rsa->DQ, &T ) ) != 0 ) - goto cleanup; - - /* Import QP */ - if( ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 || - ( ret = mbedtls_mpi_copy( &rsa->QP, &T ) ) != 0 ) - goto cleanup; - -#else - /* Verify existance of the CRT params */ - if( ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 || - ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 || - ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 ) - goto cleanup; -#endif - - /* rsa_complete() doesn't complete anything with the default - * implementation but is still called: - * - for the benefit of alternative implementation that may want to - * pre-compute stuff beyond what's provided (eg Montgomery factors) - * - as is also sanity-checks the key - * - * Furthermore, we also check the public part for consistency with - * mbedtls_pk_parse_pubkey(), as it includes size minima for example. - */ - if( ( ret = mbedtls_rsa_complete( rsa ) ) != 0 || - ( ret = mbedtls_rsa_check_pubkey( rsa ) ) != 0 ) - { + /* 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 ) { @@ -940,129 +789,6 @@ cleanup: } #endif /* MBEDTLS_RSA_C */ -#if defined(MBEDTLS_USE_TINYCRYPT) -static int pk_parse_key_sec1_der( mbedtls_uecc_keypair *keypair, - const unsigned char *key, - size_t keylen) -{ - int ret; - int version, pubkey_done; - size_t len; - mbedtls_asn1_buf params; - unsigned char *p = (unsigned char *) key; - unsigned char *end = p + keylen; - unsigned char *end2; - - /* - * RFC 5915, or SEC1 Appendix C.4 - * - * ECPrivateKey ::= SEQUENCE { - * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), - * privateKey OCTET STRING, - * parameters [0] ECParameters {{ NamedCurve }} OPTIONAL, - * publicKey [1] BIT STRING OPTIONAL - * } - */ - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - { - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); - } - - end = p + len; - - if( ( ret = mbedtls_asn1_get_int( &p, end, &version ) ) != 0 ) - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); - - if( version != 1 ) - return( MBEDTLS_ERR_PK_KEY_INVALID_VERSION ); - - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ) - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); - - if( mbedtls_platform_memcpy( keypair->private_key, p, len ) != - keypair->private_key ) - { - return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); - } - - p += len; - - pubkey_done = 0; - if( p != end ) - { - /* - * Is 'parameters' present? - */ - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0 ) ) == 0 ) - { - if( ( ret = pk_get_ecparams( &p, p + len, ¶ms) ) != 0 || - ( ret = pk_use_ecparams( ¶ms ) ) != 0 ) - { - return( ret ); - } - } - else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) - { - 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 compressed), create it from the private key. - */ - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 1 ) ) == 0 ) - { - end2 = p + len; - - if( ( ret = mbedtls_asn1_get_bitstring_null( &p, end2, &len ) ) != 0 ) - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); - - if( p + len != end2 ) - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - if( ( ret = uecc_public_key_read_binary( keypair, - (const unsigned char *) p, end2 - p ) ) == 0 ) - { - pubkey_done = 1; - } - else - { - /* - * The only acceptable failure mode of - * uecc_public_key_read_binary() above - * is if the point format is not recognized. - */ - if( ret != MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE ) - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); - } - } - else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) - { - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); - } - } - - if( !pubkey_done ) - { - ret = uECC_compute_public_key( keypair->private_key, - keypair->public_key ); - if( ret == UECC_FAULT_DETECTED ) - return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); - if( ret != UECC_SUCCESS ) - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); - } - - return( 0 ); -} -#else /* MBEDTLS_USE_TINYCRYPT */ - #if defined(MBEDTLS_ECP_C) /* * Parse a SEC1 encoded private EC key @@ -1072,7 +798,7 @@ static int pk_parse_key_sec1_der( mbedtls_ecp_keypair *eck, size_t keylen ) { int ret; - int version, pubkey_done = 0; + int version, pubkey_done; size_t len; mbedtls_asn1_buf params; unsigned char *p = (unsigned char *) key; @@ -1114,6 +840,7 @@ static int pk_parse_key_sec1_der( mbedtls_ecp_keypair *eck, p += len; + pubkey_done = 0; if( p != end ) { /* @@ -1190,7 +917,6 @@ static int pk_parse_key_sec1_der( mbedtls_ecp_keypair *eck, return( 0 ); } #endif /* MBEDTLS_ECP_C */ -#endif /* MBEDTLS_USE_TINYCRYPT */ /* * Parse an unencrypted PKCS#8 encoded private key @@ -1216,7 +942,7 @@ static int pk_parse_key_pkcs8_unencrypted_der( unsigned char *p = (unsigned char *) key; unsigned char *end = p + keylen; mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE; - mbedtls_pk_handle_t pk_info; + const mbedtls_pk_info_t *pk_info; /* * This function parses the PrivateKeyInfo object (PKCS#8 v1.2 = RFC 5208) @@ -1258,7 +984,7 @@ static int pk_parse_key_pkcs8_unencrypted_der( return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + MBEDTLS_ERR_ASN1_OUT_OF_DATA ); - if( ( pk_info = mbedtls_pk_info_from_type( pk_alg ) ) == MBEDTLS_PK_INVALID_HANDLE ) + if( ( pk_info = mbedtls_pk_info_from_type( pk_alg ) ) == NULL ) return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG ); if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 ) @@ -1274,16 +1000,6 @@ static int pk_parse_key_pkcs8_unencrypted_der( } } else #endif /* MBEDTLS_RSA_C */ -#if defined(MBEDTLS_USE_TINYCRYPT) - if( pk_alg == MBEDTLS_PK_ECKEY ) - { - if( ( ret = pk_use_ecparams( ¶ms ) ) != 0 || - ( ret = pk_parse_key_sec1_der( mbedtls_pk_uecc( *pk ), p, len ) ) != 0) - { - return( ret ); - } - } else -#else /* MBEDTLS_USE_TINYCRYPT */ #if defined(MBEDTLS_ECP_C) if( pk_alg == MBEDTLS_PK_ECKEY || pk_alg == MBEDTLS_PK_ECKEY_DH ) { @@ -1295,7 +1011,6 @@ static int pk_parse_key_pkcs8_unencrypted_der( } } else #endif /* MBEDTLS_ECP_C */ -#endif /* MBEDTLS_USE_TINYCRYPT */ return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG ); return( 0 ); @@ -1435,28 +1150,18 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk, const unsigned char *key, size_t keylen, const unsigned char *pwd, size_t pwdlen ) { -#if defined(MBEDTLS_PKCS12_C) || \ - defined(MBEDTLS_PKCS5_C) || \ - defined(MBEDTLS_PEM_PARSE_C) int ret; -#endif - mbedtls_pk_handle_t pk_info; + const mbedtls_pk_info_t *pk_info; + #if defined(MBEDTLS_PEM_PARSE_C) size_t len; mbedtls_pem_context pem; -#endif - PK_VALIDATE_RET( pk != NULL ); - if( keylen == 0 ) - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); - PK_VALIDATE_RET( key != NULL ); - -#if defined(MBEDTLS_PEM_PARSE_C) - mbedtls_pem_init( &pem ); + mbedtls_pem_init( &pem ); #if defined(MBEDTLS_RSA_C) /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ - if( key[keylen - 1] != '\0' ) + if( keylen == 0 || key[keylen - 1] != '\0' ) ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; else ret = mbedtls_pem_read_buffer( &pem, @@ -1485,9 +1190,9 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk, return( ret ); #endif /* MBEDTLS_RSA_C */ -#if defined(MBEDTLS_ECP_C) || defined(MBEDTLS_USE_TINYCRYPT) +#if defined(MBEDTLS_ECP_C) /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ - if( key[keylen - 1] != '\0' ) + if( keylen == 0 || key[keylen - 1] != '\0' ) ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; else ret = mbedtls_pem_read_buffer( &pem, @@ -1498,15 +1203,9 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk, { pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_ECKEY ); -#if defined(MBEDTLS_USE_TINYCRYPT) - if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 || - ( ret = pk_parse_key_sec1_der( mbedtls_pk_uecc( *pk ), - pem.buf, pem.buflen ) ) != 0 ) -#else /* MBEDTLS_USE_TINYCRYPT */ if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 || ( ret = pk_parse_key_sec1_der( mbedtls_pk_ec( *pk ), pem.buf, pem.buflen ) ) != 0 ) -#endif /* MBEDTLS_USE_TINYCRYPT */ { mbedtls_pk_free( pk ); } @@ -1520,10 +1219,10 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk, return( MBEDTLS_ERR_PK_PASSWORD_REQUIRED ); else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) return( ret ); -#endif /* MBEDTLS_ECP_C || MBEDTLS_USE_TINYCRYPT */ +#endif /* MBEDTLS_ECP_C */ /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ - if( key[keylen - 1] != '\0' ) + if( keylen == 0 || key[keylen - 1] != '\0' ) ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; else ret = mbedtls_pem_read_buffer( &pem, @@ -1546,7 +1245,7 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk, #if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C) /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ - if( key[keylen - 1] != '\0' ) + if( keylen == 0 || key[keylen - 1] != '\0' ) ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; else ret = mbedtls_pem_read_buffer( &pem, @@ -1584,15 +1283,18 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk, { 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 ); - mbedtls_platform_memcpy( key_copy, key, keylen ); + memcpy( key_copy, key, keylen ); ret = pk_parse_key_pkcs8_encrypted_der( pk, key_copy, keylen, pwd, pwdlen ); - mbedtls_platform_zeroize( key_copy, keylen ); + mbedtls_zeroize( key_copy, keylen ); mbedtls_free( key_copy ); } @@ -1608,7 +1310,7 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk, } #endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */ - if( pk_parse_key_pkcs8_unencrypted_der( pk, key, keylen ) == 0 ) + if( ( ret = pk_parse_key_pkcs8_unencrypted_der( pk, key, keylen ) ) == 0 ) return( 0 ); mbedtls_pk_free( pk ); @@ -1627,15 +1329,6 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk, mbedtls_pk_init( pk ); #endif /* MBEDTLS_RSA_C */ -#if defined(MBEDTLS_USE_TINYCRYPT) - pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_ECKEY ); - if( mbedtls_pk_setup( pk, pk_info ) == 0 && - pk_parse_key_sec1_der( mbedtls_pk_uecc( *pk), - key, keylen) == 0) - { - return( 0 ); - } -#else /* MBEDTLS_USE_TINYCRYPT */ #if defined(MBEDTLS_ECP_C) pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_ECKEY ); if( mbedtls_pk_setup( pk, pk_info ) == 0 && @@ -1646,7 +1339,6 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk, } mbedtls_pk_free( pk ); #endif /* MBEDTLS_ECP_C */ -#endif /* MBEDTLS_USE_TINYCRYPT */ /* If MBEDTLS_RSA_C is defined but MBEDTLS_ECP_C isn't, * it is ok to leave the PK context initialized but not @@ -1669,55 +1361,14 @@ int mbedtls_pk_parse_public_key( mbedtls_pk_context *ctx, { int ret; unsigned char *p; -#if defined(MBEDTLS_RSA_C) - mbedtls_pk_handle_t pk_info; -#endif #if defined(MBEDTLS_PEM_PARSE_C) size_t len; mbedtls_pem_context pem; -#endif - PK_VALIDATE_RET( ctx != NULL ); - if( keylen == 0 ) - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); - PK_VALIDATE_RET( key != NULL || keylen == 0 ); - -#if defined(MBEDTLS_PEM_PARSE_C) mbedtls_pem_init( &pem ); -#if defined(MBEDTLS_RSA_C) - /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ - if( key[keylen - 1] != '\0' ) - ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; - else - ret = mbedtls_pem_read_buffer( &pem, - "-----BEGIN RSA PUBLIC KEY-----", - "-----END RSA PUBLIC KEY-----", - key, NULL, 0, &len ); - - if( ret == 0 ) - { - p = pem.buf; - if( ( pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ) ) == MBEDTLS_PK_INVALID_HANDLE ) - return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG ); - - if( ( ret = mbedtls_pk_setup( ctx, pk_info ) ) != 0 ) - return( ret ); - - if ( ( ret = pk_get_rsapubkey( &p, p + pem.buflen, mbedtls_pk_rsa( *ctx ) ) ) != 0 ) - mbedtls_pk_free( ctx ); - - mbedtls_pem_free( &pem ); - return( ret ); - } - else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) - { - mbedtls_pem_free( &pem ); - return( ret ); - } -#endif /* MBEDTLS_RSA_C */ /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ - if( key[keylen - 1] != '\0' ) + if( keylen == 0 || key[keylen - 1] != '\0' ) ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; else ret = mbedtls_pem_read_buffer( &pem, @@ -1730,43 +1381,23 @@ int mbedtls_pk_parse_public_key( mbedtls_pk_context *ctx, /* * Was PEM encoded */ - p = pem.buf; - - ret = mbedtls_pk_parse_subpubkey( &p, p + pem.buflen, ctx ); - mbedtls_pem_free( &pem ); - return( ret ); + key = pem.buf; + keylen = pem.buflen; } else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) { mbedtls_pem_free( &pem ); return( ret ); } - mbedtls_pem_free( &pem ); #endif /* MBEDTLS_PEM_PARSE_C */ - -#if defined(MBEDTLS_RSA_C) - if( ( pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ) ) == MBEDTLS_PK_INVALID_HANDLE ) - return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG ); - - if( ( ret = mbedtls_pk_setup( ctx, pk_info ) ) != 0 ) - return( ret ); - - p = (unsigned char *)key; - ret = pk_get_rsapubkey( &p, p + keylen, mbedtls_pk_rsa( *ctx ) ); - if( ret == 0 ) - { - return( ret ); - } - mbedtls_pk_free( ctx ); - if( ret != ( MBEDTLS_ERR_PK_INVALID_PUBKEY + MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) ) - { - return( ret ); - } -#endif /* MBEDTLS_RSA_C */ p = (unsigned char *) key; ret = mbedtls_pk_parse_subpubkey( &p, p + keylen, ctx ); +#if defined(MBEDTLS_PEM_PARSE_C) + mbedtls_pem_free( &pem ); +#endif + return( ret ); } diff --git a/APP_Framework/Framework/security/mbedtls/pkwrite.c b/APP_Framework/Framework/security/mbedtls/pkwrite.c new file mode 100644 index 000000000..ae88c0837 --- /dev/null +++ b/APP_Framework/Framework/security/mbedtls/pkwrite.c @@ -0,0 +1,515 @@ +/* + * Public Key layer for writing key files and structures + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_PK_WRITE_C) + +#include "pk.h" +#include "asn1write.h" +#include "oid.h" + +#include + +#if defined(MBEDTLS_RSA_C) +#include "rsa.h" +#endif +#if defined(MBEDTLS_ECP_C) +#include "ecp.h" +#endif +#if defined(MBEDTLS_ECDSA_C) +#include "ecdsa.h" +#endif +#if defined(MBEDTLS_PEM_WRITE_C) +#include "pem.h" +#endif + +#if defined(MBEDTLS_PLATFORM_C) +#include "platform.h" +#else +#include +#define mbedtls_calloc calloc +#define mbedtls_free free +#endif + +#if defined(MBEDTLS_RSA_C) +/* + * RSAPublicKey ::= SEQUENCE { + * modulus INTEGER, -- n + * publicExponent INTEGER -- e + * } + */ +static int pk_write_rsa_pubkey( unsigned char **p, unsigned char *start, + mbedtls_rsa_context *rsa ) +{ + int ret; + size_t len = 0; + mbedtls_mpi T; + + mbedtls_mpi_init( &T ); + + /* 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_tag( p, start, MBEDTLS_ASN1_CONSTRUCTED | + MBEDTLS_ASN1_SEQUENCE ) ); + + return( (int) len ); +} +#endif /* MBEDTLS_RSA_C */ + +#if defined(MBEDTLS_ECP_C) +/* + * EC public key is an EC point + */ +static int pk_write_ec_pubkey( unsigned char **p, unsigned char *start, + mbedtls_ecp_keypair *ec ) +{ + int ret; + size_t len = 0; + unsigned char buf[MBEDTLS_ECP_MAX_PT_LEN]; + + if( ( ret = mbedtls_ecp_point_write_binary( &ec->grp, &ec->Q, + MBEDTLS_ECP_PF_UNCOMPRESSED, + &len, buf, sizeof( buf ) ) ) != 0 ) + { + return( ret ); + } + + if( *p < start || (size_t)( *p - start ) < len ) + return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); + + *p -= len; + memcpy( *p, buf, len ); + + return( (int) len ); +} + +/* + * ECParameters ::= CHOICE { + * namedCurve OBJECT IDENTIFIER + * } + */ +static int pk_write_ec_param( unsigned char **p, unsigned char *start, + mbedtls_ecp_keypair *ec ) +{ + int ret; + size_t len = 0; + const char *oid; + size_t oid_len; + + if( ( ret = mbedtls_oid_get_oid_by_ec_grp( ec->grp.id, &oid, &oid_len ) ) != 0 ) + return( ret ); + + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_oid( p, start, oid, oid_len ) ); + + return( (int) len ); +} +#endif /* MBEDTLS_ECP_C */ + +int mbedtls_pk_write_pubkey( unsigned char **p, unsigned char *start, + const mbedtls_pk_context *key ) +{ + int ret; + size_t len = 0; + +#if defined(MBEDTLS_RSA_C) + if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_RSA ) + MBEDTLS_ASN1_CHK_ADD( len, pk_write_rsa_pubkey( p, start, mbedtls_pk_rsa( *key ) ) ); + else +#endif +#if defined(MBEDTLS_ECP_C) + if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY ) + MBEDTLS_ASN1_CHK_ADD( len, pk_write_ec_pubkey( p, start, mbedtls_pk_ec( *key ) ) ); + else +#endif + return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE ); + + return( (int) len ); +} + +int mbedtls_pk_write_pubkey_der( mbedtls_pk_context *key, unsigned char *buf, size_t size ) +{ + int ret; + unsigned char *c; + size_t len = 0, par_len = 0, oid_len; + const char *oid; + + c = buf + size; + + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_pk_write_pubkey( &c, buf, key ) ); + + if( c - buf < 1 ) + return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); + + /* + * SubjectPublicKeyInfo ::= SEQUENCE { + * algorithm AlgorithmIdentifier, + * subjectPublicKey BIT STRING } + */ + *--c = 0; + len += 1; + + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_BIT_STRING ) ); + + if( ( ret = mbedtls_oid_get_oid_by_pk_alg( mbedtls_pk_get_type( key ), + &oid, &oid_len ) ) != 0 ) + { + return( ret ); + } + +#if defined(MBEDTLS_ECP_C) + if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY ) + { + MBEDTLS_ASN1_CHK_ADD( par_len, pk_write_ec_param( &c, buf, mbedtls_pk_ec( *key ) ) ); + } +#endif + + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_algorithm_identifier( &c, buf, oid, oid_len, + par_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_SEQUENCE ) ); + + return( (int) len ); +} + +int mbedtls_pk_write_key_der( mbedtls_pk_context *key, unsigned char *buf, size_t size ) +{ + int ret; + unsigned char *c = buf + size; + size_t len = 0; + +#if defined(MBEDTLS_RSA_C) + 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 ); + + /* + * Export the parameters one after another to avoid simultaneous copies. + */ + + 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_tag( &c, + buf, MBEDTLS_ASN1_CONSTRUCTED | + MBEDTLS_ASN1_SEQUENCE ) ); + } + else +#endif /* MBEDTLS_RSA_C */ +#if defined(MBEDTLS_ECP_C) + if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY ) + { + mbedtls_ecp_keypair *ec = mbedtls_pk_ec( *key ); + size_t pub_len = 0, par_len = 0; + + /* + * RFC 5915, or SEC1 Appendix C.4 + * + * ECPrivateKey ::= SEQUENCE { + * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), + * privateKey OCTET STRING, + * parameters [0] ECParameters {{ NamedCurve }} OPTIONAL, + * publicKey [1] BIT STRING OPTIONAL + * } + */ + + /* publicKey */ + MBEDTLS_ASN1_CHK_ADD( pub_len, pk_write_ec_pubkey( &c, buf, ec ) ); + + if( c - buf < 1 ) + return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); + *--c = 0; + pub_len += 1; + + MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_asn1_write_len( &c, buf, pub_len ) ); + MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_BIT_STRING ) ); + + MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_asn1_write_len( &c, buf, pub_len ) ); + MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_asn1_write_tag( &c, buf, + MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 1 ) ); + len += pub_len; + + /* parameters */ + MBEDTLS_ASN1_CHK_ADD( par_len, pk_write_ec_param( &c, buf, ec ) ); + + MBEDTLS_ASN1_CHK_ADD( par_len, mbedtls_asn1_write_len( &c, buf, par_len ) ); + MBEDTLS_ASN1_CHK_ADD( par_len, mbedtls_asn1_write_tag( &c, buf, + MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0 ) ); + len += par_len; + + /* privateKey: write as MPI then fix tag */ + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &ec->d ) ); + *c = MBEDTLS_ASN1_OCTET_STRING; + + /* version */ + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, buf, 1 ) ); + + 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_SEQUENCE ) ); + } + else +#endif /* MBEDTLS_ECP_C */ + return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE ); + + return( (int) len ); +} + +#if defined(MBEDTLS_PEM_WRITE_C) + +#define PEM_BEGIN_PUBLIC_KEY "-----BEGIN PUBLIC KEY-----\n" +#define PEM_END_PUBLIC_KEY "-----END PUBLIC KEY-----\n" + +#define PEM_BEGIN_PRIVATE_KEY_RSA "-----BEGIN RSA PRIVATE KEY-----\n" +#define PEM_END_PRIVATE_KEY_RSA "-----END RSA PRIVATE KEY-----\n" +#define PEM_BEGIN_PRIVATE_KEY_EC "-----BEGIN EC PRIVATE KEY-----\n" +#define PEM_END_PRIVATE_KEY_EC "-----END EC PRIVATE KEY-----\n" + +/* + * Max sizes of key per types. Shown as tag + len (+ content). + */ + +#if defined(MBEDTLS_RSA_C) +/* + * RSA public keys: + * SubjectPublicKeyInfo ::= SEQUENCE { 1 + 3 + * algorithm AlgorithmIdentifier, 1 + 1 (sequence) + * + 1 + 1 + 9 (rsa oid) + * + 1 + 1 (params null) + * subjectPublicKey BIT STRING } 1 + 3 + (1 + below) + * RSAPublicKey ::= SEQUENCE { 1 + 3 + * modulus INTEGER, -- n 1 + 3 + MPI_MAX + 1 + * publicExponent INTEGER -- e 1 + 3 + MPI_MAX + 1 + * } + */ +#define RSA_PUB_DER_MAX_BYTES 38 + 2 * MBEDTLS_MPI_MAX_SIZE + +/* + * RSA private keys: + * RSAPrivateKey ::= SEQUENCE { 1 + 3 + * version Version, 1 + 1 + 1 + * modulus INTEGER, 1 + 3 + MPI_MAX + 1 + * publicExponent INTEGER, 1 + 3 + MPI_MAX + 1 + * privateExponent INTEGER, 1 + 3 + MPI_MAX + 1 + * prime1 INTEGER, 1 + 3 + MPI_MAX / 2 + 1 + * prime2 INTEGER, 1 + 3 + MPI_MAX / 2 + 1 + * exponent1 INTEGER, 1 + 3 + MPI_MAX / 2 + 1 + * exponent2 INTEGER, 1 + 3 + MPI_MAX / 2 + 1 + * coefficient INTEGER, 1 + 3 + MPI_MAX / 2 + 1 + * otherPrimeInfos OtherPrimeInfos OPTIONAL 0 (not supported) + * } + */ +#define MPI_MAX_SIZE_2 MBEDTLS_MPI_MAX_SIZE / 2 + \ + MBEDTLS_MPI_MAX_SIZE % 2 +#define RSA_PRV_DER_MAX_BYTES 47 + 3 * MBEDTLS_MPI_MAX_SIZE \ + + 5 * MPI_MAX_SIZE_2 + +#else /* MBEDTLS_RSA_C */ + +#define RSA_PUB_DER_MAX_BYTES 0 +#define RSA_PRV_DER_MAX_BYTES 0 + +#endif /* MBEDTLS_RSA_C */ + +#if defined(MBEDTLS_ECP_C) +/* + * EC public keys: + * SubjectPublicKeyInfo ::= SEQUENCE { 1 + 2 + * algorithm AlgorithmIdentifier, 1 + 1 (sequence) + * + 1 + 1 + 7 (ec oid) + * + 1 + 1 + 9 (namedCurve oid) + * subjectPublicKey BIT STRING 1 + 2 + 1 [1] + * + 1 (point format) [1] + * + 2 * ECP_MAX (coords) [1] + * } + */ +#define ECP_PUB_DER_MAX_BYTES 30 + 2 * MBEDTLS_ECP_MAX_BYTES + +/* + * EC private keys: + * ECPrivateKey ::= SEQUENCE { 1 + 2 + * version INTEGER , 1 + 1 + 1 + * privateKey OCTET STRING, 1 + 1 + ECP_MAX + * parameters [0] ECParameters OPTIONAL, 1 + 1 + (1 + 1 + 9) + * publicKey [1] BIT STRING OPTIONAL 1 + 2 + [1] above + * } + */ +#define ECP_PRV_DER_MAX_BYTES 29 + 3 * MBEDTLS_ECP_MAX_BYTES + +#else /* MBEDTLS_ECP_C */ + +#define ECP_PUB_DER_MAX_BYTES 0 +#define ECP_PRV_DER_MAX_BYTES 0 + +#endif /* MBEDTLS_ECP_C */ + +#define PUB_DER_MAX_BYTES RSA_PUB_DER_MAX_BYTES > ECP_PUB_DER_MAX_BYTES ? \ + RSA_PUB_DER_MAX_BYTES : ECP_PUB_DER_MAX_BYTES +#define PRV_DER_MAX_BYTES RSA_PRV_DER_MAX_BYTES > ECP_PRV_DER_MAX_BYTES ? \ + RSA_PRV_DER_MAX_BYTES : ECP_PRV_DER_MAX_BYTES + +int mbedtls_pk_write_pubkey_pem( mbedtls_pk_context *key, unsigned char *buf, size_t size ) +{ + int ret; + unsigned char output_buf[PUB_DER_MAX_BYTES]; + size_t olen = 0; + + if( ( ret = mbedtls_pk_write_pubkey_der( key, output_buf, + sizeof(output_buf) ) ) < 0 ) + { + return( ret ); + } + + if( ( ret = mbedtls_pem_write_buffer( PEM_BEGIN_PUBLIC_KEY, PEM_END_PUBLIC_KEY, + output_buf + sizeof(output_buf) - ret, + ret, buf, size, &olen ) ) != 0 ) + { + return( ret ); + } + + return( 0 ); +} + +int mbedtls_pk_write_key_pem( mbedtls_pk_context *key, unsigned char *buf, size_t size ) +{ + int ret; + unsigned char output_buf[PRV_DER_MAX_BYTES]; + const char *begin, *end; + size_t olen = 0; + + if( ( ret = mbedtls_pk_write_key_der( key, output_buf, sizeof(output_buf) ) ) < 0 ) + return( ret ); + +#if defined(MBEDTLS_RSA_C) + if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_RSA ) + { + begin = PEM_BEGIN_PRIVATE_KEY_RSA; + end = PEM_END_PRIVATE_KEY_RSA; + } + else +#endif +#if defined(MBEDTLS_ECP_C) + if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY ) + { + begin = PEM_BEGIN_PRIVATE_KEY_EC; + end = PEM_END_PRIVATE_KEY_EC; + } + else +#endif + return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE ); + + if( ( ret = mbedtls_pem_write_buffer( begin, end, + output_buf + sizeof(output_buf) - ret, + ret, buf, size, &olen ) ) != 0 ) + { + return( ret ); + } + + return( 0 ); +} +#endif /* MBEDTLS_PEM_WRITE_C */ + +#endif /* MBEDTLS_PK_WRITE_C */ diff --git a/APP_Framework/Framework/security/mbedtls/platform.c b/APP_Framework/Framework/security/mbedtls/platform.c new file mode 100644 index 000000000..c1f587931 --- /dev/null +++ b/APP_Framework/Framework/security/mbedtls/platform.c @@ -0,0 +1,345 @@ +/* + * Platform abstraction layer + * + * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_PLATFORM_C) + +#include "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 + +/* The compile time configuration of memory allocation via the macros + * MBEDTLS_PLATFORM_{FREE/CALLOC}_MACRO takes precedence over the runtime + * configuration via mbedtls_platform_set_calloc_free(). So, omit everything + * related to the latter if MBEDTLS_PLATFORM_{FREE/CALLOC}_MACRO are defined. */ +#if defined(MBEDTLS_PLATFORM_MEMORY) && \ + !( defined(MBEDTLS_PLATFORM_CALLOC_MACRO) && \ + defined(MBEDTLS_PLATFORM_FREE_MACRO) ) + +#if !defined(MBEDTLS_PLATFORM_STD_CALLOC) +static void *platform_calloc_uninit( size_t n, size_t size ) +{ + ((void) n); + ((void) size); + return( NULL ); +} + +#define MBEDTLS_PLATFORM_STD_CALLOC platform_calloc_uninit +#endif /* !MBEDTLS_PLATFORM_STD_CALLOC */ + +#if !defined(MBEDTLS_PLATFORM_STD_FREE) +static void platform_free_uninit( void *ptr ) +{ + ((void) ptr); +} + +#define MBEDTLS_PLATFORM_STD_FREE platform_free_uninit +#endif /* !MBEDTLS_PLATFORM_STD_FREE */ + +void * (*mbedtls_calloc)( size_t, size_t ) = MBEDTLS_PLATFORM_STD_CALLOC; +void (*mbedtls_free)( void * ) = MBEDTLS_PLATFORM_STD_FREE; + +int mbedtls_platform_set_calloc_free( void * (*calloc_func)( size_t, size_t ), + void (*free_func)( void * ) ) +{ + mbedtls_calloc = calloc_func; + mbedtls_free = free_func; + return( 0 ); +} +#endif /* MBEDTLS_PLATFORM_MEMORY && + !( defined(MBEDTLS_PLATFORM_CALLOC_MACRO) && + defined(MBEDTLS_PLATFORM_FREE_MACRO) ) */ + +#if defined(_WIN32) +#include +int mbedtls_platform_win32_snprintf( char *s, size_t n, const char *fmt, ... ) +{ + int ret; + va_list argp; + + /* Avoid calling the invalid parameter handler by checking ourselves */ + if( s == NULL || n == 0 || fmt == NULL ) + return( -1 ); + + va_start( argp, fmt ); +#if defined(_TRUNCATE) && !defined(__MINGW32__) + ret = _vsnprintf_s( s, n, _TRUNCATE, fmt, argp ); +#else + ret = _vsnprintf( s, n, fmt, argp ); + if( ret < 0 || (size_t) ret == n ) + { + s[n-1] = '\0'; + ret = -1; + } +#endif + va_end( argp ); + + return( ret ); +} +#endif + +#if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) +#if !defined(MBEDTLS_PLATFORM_STD_SNPRINTF) +/* + * Make dummy function to prevent NULL pointer dereferences + */ +static int platform_snprintf_uninit( char * s, size_t n, + const char * format, ... ) +{ + ((void) s); + ((void) n); + ((void) format); + return( 0 ); +} + +#define MBEDTLS_PLATFORM_STD_SNPRINTF platform_snprintf_uninit +#endif /* !MBEDTLS_PLATFORM_STD_SNPRINTF */ + +int (*mbedtls_snprintf)( char * s, size_t n, + const char * format, + ... ) = MBEDTLS_PLATFORM_STD_SNPRINTF; + +int mbedtls_platform_set_snprintf( int (*snprintf_func)( char * s, size_t n, + const char * format, + ... ) ) +{ + mbedtls_snprintf = snprintf_func; + return( 0 ); +} +#endif /* MBEDTLS_PLATFORM_SNPRINTF_ALT */ + +#if defined(MBEDTLS_PLATFORM_PRINTF_ALT) +#if !defined(MBEDTLS_PLATFORM_STD_PRINTF) +/* + * Make dummy function to prevent NULL pointer dereferences + */ +static int platform_printf_uninit( const char *format, ... ) +{ + ((void) format); + return( 0 ); +} + +#define MBEDTLS_PLATFORM_STD_PRINTF platform_printf_uninit +#endif /* !MBEDTLS_PLATFORM_STD_PRINTF */ + +int (*mbedtls_printf)( const char *, ... ) = MBEDTLS_PLATFORM_STD_PRINTF; + +int mbedtls_platform_set_printf( int (*printf_func)( const char *, ... ) ) +{ + mbedtls_printf = printf_func; + return( 0 ); +} +#endif /* MBEDTLS_PLATFORM_PRINTF_ALT */ + +#if defined(MBEDTLS_PLATFORM_FPRINTF_ALT) +#if !defined(MBEDTLS_PLATFORM_STD_FPRINTF) +/* + * Make dummy function to prevent NULL pointer dereferences + */ +static int platform_fprintf_uninit( FILE *stream, const char *format, ... ) +{ + ((void) stream); + ((void) format); + return( 0 ); +} + +#define MBEDTLS_PLATFORM_STD_FPRINTF platform_fprintf_uninit +#endif /* !MBEDTLS_PLATFORM_STD_FPRINTF */ + +int (*mbedtls_fprintf)( FILE *, const char *, ... ) = + MBEDTLS_PLATFORM_STD_FPRINTF; + +int mbedtls_platform_set_fprintf( int (*fprintf_func)( FILE *, const char *, ... ) ) +{ + mbedtls_fprintf = fprintf_func; + return( 0 ); +} +#endif /* MBEDTLS_PLATFORM_FPRINTF_ALT */ + +#if defined(MBEDTLS_PLATFORM_EXIT_ALT) +#if !defined(MBEDTLS_PLATFORM_STD_EXIT) +/* + * Make dummy function to prevent NULL pointer dereferences + */ +static void platform_exit_uninit( int status ) +{ + ((void) status); +} + +#define MBEDTLS_PLATFORM_STD_EXIT platform_exit_uninit +#endif /* !MBEDTLS_PLATFORM_STD_EXIT */ + +void (*mbedtls_exit)( int status ) = MBEDTLS_PLATFORM_STD_EXIT; + +int mbedtls_platform_set_exit( void (*exit_func)( int status ) ) +{ + mbedtls_exit = exit_func; + return( 0 ); +} +#endif /* MBEDTLS_PLATFORM_EXIT_ALT */ + +#if defined(MBEDTLS_HAVE_TIME) + +#if defined(MBEDTLS_PLATFORM_TIME_ALT) +#if !defined(MBEDTLS_PLATFORM_STD_TIME) +/* + * Make dummy function to prevent NULL pointer dereferences + */ +static mbedtls_time_t platform_time_uninit( mbedtls_time_t* timer ) +{ + ((void) timer); + return( 0 ); +} + +#define MBEDTLS_PLATFORM_STD_TIME platform_time_uninit +#endif /* !MBEDTLS_PLATFORM_STD_TIME */ + +mbedtls_time_t (*mbedtls_time)( mbedtls_time_t* timer ) = MBEDTLS_PLATFORM_STD_TIME; + +int mbedtls_platform_set_time( mbedtls_time_t (*time_func)( mbedtls_time_t* timer ) ) +{ + mbedtls_time = time_func; + return( 0 ); +} +#endif /* MBEDTLS_PLATFORM_TIME_ALT */ + +#endif /* MBEDTLS_HAVE_TIME */ + +#if defined(MBEDTLS_ENTROPY_NV_SEED) +#if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) && defined(MBEDTLS_FS_IO) +/* Default implementations for the platform independent seed functions use + * standard libc file functions to read from and write to a pre-defined filename + */ +int mbedtls_platform_std_nv_seed_read( unsigned char *buf, size_t buf_len ) +{ + FILE *file; + size_t n; + + if( ( file = fopen( MBEDTLS_PLATFORM_STD_NV_SEED_FILE, "rb" ) ) == NULL ) + return( -1 ); + + if( ( n = fread( buf, 1, buf_len, file ) ) != buf_len ) + { + fclose( file ); + mbedtls_zeroize( buf, buf_len ); + return( -1 ); + } + + fclose( file ); + return( (int)n ); +} + +int mbedtls_platform_std_nv_seed_write( unsigned char *buf, size_t buf_len ) +{ + FILE *file; + size_t n; + + if( ( file = fopen( MBEDTLS_PLATFORM_STD_NV_SEED_FILE, "w" ) ) == NULL ) + return -1; + + if( ( n = fwrite( buf, 1, buf_len, file ) ) != buf_len ) + { + fclose( file ); + return -1; + } + + fclose( file ); + return( (int)n ); +} +#endif /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */ + +#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT) +#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ) +/* + * Make dummy function to prevent NULL pointer dereferences + */ +static int platform_nv_seed_read_uninit( unsigned char *buf, size_t buf_len ) +{ + ((void) buf); + ((void) buf_len); + return( -1 ); +} + +#define MBEDTLS_PLATFORM_STD_NV_SEED_READ platform_nv_seed_read_uninit +#endif /* !MBEDTLS_PLATFORM_STD_NV_SEED_READ */ + +#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE) +/* + * Make dummy function to prevent NULL pointer dereferences + */ +static int platform_nv_seed_write_uninit( unsigned char *buf, size_t buf_len ) +{ + ((void) buf); + ((void) buf_len); + return( -1 ); +} + +#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE platform_nv_seed_write_uninit +#endif /* !MBEDTLS_PLATFORM_STD_NV_SEED_WRITE */ + +int (*mbedtls_nv_seed_read)( unsigned char *buf, size_t buf_len ) = + MBEDTLS_PLATFORM_STD_NV_SEED_READ; +int (*mbedtls_nv_seed_write)( unsigned char *buf, size_t buf_len ) = + MBEDTLS_PLATFORM_STD_NV_SEED_WRITE; + +int mbedtls_platform_set_nv_seed( + int (*nv_seed_read_func)( unsigned char *buf, size_t buf_len ), + int (*nv_seed_write_func)( unsigned char *buf, size_t buf_len ) ) +{ + mbedtls_nv_seed_read = nv_seed_read_func; + mbedtls_nv_seed_write = nv_seed_write_func; + return( 0 ); +} +#endif /* MBEDTLS_PLATFORM_NV_SEED_ALT */ +#endif /* MBEDTLS_ENTROPY_NV_SEED */ + +#if !defined(MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT) +/* + * Placeholder platform setup that does nothing by default + */ +int mbedtls_platform_setup( mbedtls_platform_context *ctx ) +{ + (void)ctx; + + return( 0 ); +} + +/* + * Placeholder platform teardown that does nothing by default + */ +void mbedtls_platform_teardown( mbedtls_platform_context *ctx ) +{ + (void)ctx; +} +#endif /* MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT */ + +#endif /* MBEDTLS_PLATFORM_C */ diff --git a/APP_Framework/Framework/security/mbedtls/platform.h b/APP_Framework/Framework/security/mbedtls/platform.h index 8a88ce712..7c2835b30 100644 --- a/APP_Framework/Framework/security/mbedtls/platform.h +++ b/APP_Framework/Framework/security/mbedtls/platform.h @@ -1,16 +1,7 @@ /** * \file platform.h * - * \brief This file contains the definitions and functions of the - * Mbed TLS platform abstraction layer. - * - * The platform abstraction layer removes the need for the library - * to directly link to standard C library functions or operating - * system services, making the library easier to port and embed. - * Application developers and users of the library can provide their own - * implementations of these functions, or implementations specific to - * their platform, which can be statically linked to the library or - * dynamically configured at runtime. + * \brief The Mbed TLS platform abstraction layer. */ /* * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved @@ -39,13 +30,6 @@ #include MBEDTLS_CONFIG_FILE #endif -#define MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED -0x0070 /**< Hardware accelerator failed */ -#define MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED -0x0072 /**< The requested feature is not supported by the platform */ -#define MBEDTLS_ERR_PLATFORM_FAULT_DETECTED -0x0071 /**< A hardware fault was detected in a critical path. As a security precaution this should be treated as a potential physical attack */ -#define MBEDTLS_ERR_PLATFORM_ALLOC_FAILED -0x0076 /**< Memory allocation failed */ - -#if defined(MBEDTLS_PLATFORM_C) - #if defined(MBEDTLS_HAVE_TIME) #include "platform_time.h" #endif @@ -118,7 +102,7 @@ extern "C" { /* \} name SECTION: Module settings */ /* - * The function pointers for calloc and free. + * The function pointers for calloc and free */ #if defined(MBEDTLS_PLATFORM_MEMORY) #if defined(MBEDTLS_PLATFORM_FREE_MACRO) && \ @@ -128,12 +112,11 @@ extern "C" { #else /* For size_t */ #include -extern void *mbedtls_calloc( size_t n, size_t size ); -extern void mbedtls_free( void *ptr ); +extern void * (*mbedtls_calloc)( size_t n, size_t size ); +extern void (*mbedtls_free)( void *ptr ); /** - * \brief This function dynamically sets the memory-management - * functions used by the library, during runtime. + * \brief This function allows configuring custom memory-management functions. * * \param calloc_func The \c calloc function implementation. * \param free_func The \c free function implementation. @@ -157,9 +140,7 @@ int mbedtls_platform_set_calloc_free( void * (*calloc_func)( size_t, size_t ), extern int (*mbedtls_fprintf)( FILE *stream, const char *format, ... ); /** - * \brief This function dynamically configures the fprintf - * function that is called when the - * mbedtls_fprintf() function is invoked by the library. + * \brief This function allows configuring a custom \p fprintf function pointer. * * \param fprintf_func The \c fprintf function implementation. * @@ -182,9 +163,8 @@ int mbedtls_platform_set_fprintf( int (*fprintf_func)( FILE *stream, const char extern int (*mbedtls_printf)( const char *format, ... ); /** - * \brief This function dynamically configures the snprintf - * function that is called when the mbedtls_snprintf() - * function is invoked by the library. + * \brief This function allows configuring a custom \c printf function + * pointer. * * \param printf_func The \c printf function implementation. * @@ -217,12 +197,12 @@ int mbedtls_platform_win32_snprintf( char *s, size_t n, const char *fmt, ... ); extern int (*mbedtls_snprintf)( char * s, size_t n, const char * format, ... ); /** - * \brief This function allows configuring a custom - * \c snprintf function pointer. + * \brief This function allows configuring a custom \c snprintf function + * pointer. * * \param snprintf_func The \c snprintf function implementation. * - * \return \c 0 on success. + * \return \c 0 on success. */ int mbedtls_platform_set_snprintf( int (*snprintf_func)( char * s, size_t n, const char * format, ... ) ); @@ -241,13 +221,12 @@ int mbedtls_platform_set_snprintf( int (*snprintf_func)( char * s, size_t n, extern void (*mbedtls_exit)( int status ); /** - * \brief This function dynamically configures the exit - * function that is called when the mbedtls_exit() - * function is invoked by the library. + * \brief This function allows configuring a custom \c exit function + * pointer. * * \param exit_func The \c exit function implementation. * - * \return \c 0 on success. + * \return \c 0 on success. */ int mbedtls_platform_set_exit( void (*exit_func)( int status ) ); #else @@ -322,9 +301,8 @@ int mbedtls_platform_set_nv_seed( * \note This structure may be used to assist platform-specific * setup or teardown operations. */ -typedef struct mbedtls_platform_context -{ - char dummy; /**< A placeholder member, as empty structs are not portable. */ +typedef struct { + char dummy; /**< Placeholder member, as empty structs are not portable. */ } mbedtls_platform_context; @@ -333,34 +311,33 @@ mbedtls_platform_context; #endif /* !MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT */ /** - * \brief This function performs any platform-specific initialization - * operations. + * \brief This function performs any platform initialization operations. * - * \note This function should be called before any other library functions. - * - * Its implementation is platform-specific, and unless - * platform-specific code is provided, it does nothing. - * - * \note The usage and necessity of this function is dependent on the platform. - * - * \param ctx The platform context. + * \param ctx The Mbed TLS context. * * \return \c 0 on success. + * + * \note This function is intended to allow platform-specific initialization, + * and should be called before any other library functions. Its + * implementation is platform-specific, and unless + * platform-specific code is provided, it does nothing. + * + * Its use and whether it is necessary to call it is dependent on the + * platform. */ int mbedtls_platform_setup( mbedtls_platform_context *ctx ); /** * \brief This function performs any platform teardown operations. * + * \param ctx The Mbed TLS context. + * * \note This function should be called after every other Mbed TLS module * has been correctly freed using the appropriate free function. - * * Its implementation is platform-specific, and unless * platform-specific code is provided, it does nothing. * - * \note The usage and necessity of this function is dependent on the platform. - * - * \param ctx The platform context. - * + * Its use and whether it is necessary to call it is dependent on the + * platform. */ void mbedtls_platform_teardown( mbedtls_platform_context *ctx ); @@ -368,6 +345,4 @@ void mbedtls_platform_teardown( mbedtls_platform_context *ctx ); } #endif -#endif /* MBEDTLS_PLATFORM_C */ - #endif /* platform.h */ diff --git a/APP_Framework/Framework/security/mbedtls/platform_time.h b/APP_Framework/Framework/security/mbedtls/platform_time.h index 2ed36f56c..4d0630bbe 100644 --- a/APP_Framework/Framework/security/mbedtls/platform_time.h +++ b/APP_Framework/Framework/security/mbedtls/platform_time.h @@ -49,7 +49,7 @@ extern "C" { typedef MBEDTLS_PLATFORM_TIME_TYPE_MACRO mbedtls_time_t; #else /* For time_t */ -#include +#include typedef time_t mbedtls_time_t; #endif /* MBEDTLS_PLATFORM_TIME_TYPE_MACRO */ diff --git a/APP_Framework/Framework/security/mbedtls/platform_util.h b/APP_Framework/Framework/security/mbedtls/platform_util.h deleted file mode 100644 index 4999500ce..000000000 --- a/APP_Framework/Framework/security/mbedtls/platform_util.h +++ /dev/null @@ -1,435 +0,0 @@ -/** - * \file platform_util.h - * - * \brief Common and shared functions used by multiple modules in the Mbed TLS - * library. - */ -/* - * Copyright (C) 2018, Arm Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * This file is part of Mbed TLS (https://tls.mbed.org) - */ -#ifndef MBEDTLS_PLATFORM_UTIL_H -#define MBEDTLS_PLATFORM_UTIL_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif -#include -#include -#if defined(MBEDTLS_HAVE_TIME_DATE) -#include "platform_time.h" -#include -#endif /* MBEDTLS_HAVE_TIME_DATE */ - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(MBEDTLS_CHECK_PARAMS) - -#if defined(MBEDTLS_CHECK_PARAMS_ASSERT) -/* Allow the user to define MBEDTLS_PARAM_FAILED to something like assert - * (which is what our config.h suggests). */ -#include -#endif /* MBEDTLS_CHECK_PARAMS_ASSERT */ - -#if defined(MBEDTLS_PARAM_FAILED) -/** An alternative definition of MBEDTLS_PARAM_FAILED has been set in config.h. - * - * This flag can be used to check whether it is safe to assume that - * MBEDTLS_PARAM_FAILED() will expand to a call to mbedtls_param_failed(). - */ -#define MBEDTLS_PARAM_FAILED_ALT - -#elif defined(MBEDTLS_CHECK_PARAMS_ASSERT) -#define MBEDTLS_PARAM_FAILED( cond ) assert( cond ) -#define MBEDTLS_PARAM_FAILED_ALT - -#else /* MBEDTLS_PARAM_FAILED */ -#define MBEDTLS_PARAM_FAILED( cond ) \ - mbedtls_param_failed( #cond, __FILE__, __LINE__ ) - -/** - * \brief User supplied callback function for parameter validation failure. - * See #MBEDTLS_CHECK_PARAMS for context. - * - * This function will be called unless an alternative treatement - * is defined through the #MBEDTLS_PARAM_FAILED macro. - * - * This function can return, and the operation will be aborted, or - * alternatively, through use of setjmp()/longjmp() can resume - * execution in the application code. - * - * \param failure_condition The assertion that didn't hold. - * \param file The file where the assertion failed. - * \param line The line in the file where the assertion failed. - */ -void mbedtls_param_failed( const char *failure_condition, - const char *file, - int line ); -#endif /* MBEDTLS_PARAM_FAILED */ - -/* Internal macro meant to be called only from within the library. */ -#define MBEDTLS_INTERNAL_VALIDATE_RET( cond, ret ) \ - do { \ - if( !(cond) ) \ - { \ - MBEDTLS_PARAM_FAILED( cond ); \ - return( ret ); \ - } \ - } while( 0 ) - -/* Internal macro meant to be called only from within the library. */ -#define MBEDTLS_INTERNAL_VALIDATE( cond ) \ - do { \ - if( !(cond) ) \ - { \ - MBEDTLS_PARAM_FAILED( cond ); \ - return; \ - } \ - } while( 0 ) - -#else /* MBEDTLS_CHECK_PARAMS */ - -/* Internal macros meant to be called only from within the library. */ -#define MBEDTLS_INTERNAL_VALIDATE_RET( cond, ret ) do { } while( 0 ) -#define MBEDTLS_INTERNAL_VALIDATE( cond ) do { } while( 0 ) - -#endif /* MBEDTLS_CHECK_PARAMS */ - -#if defined(__GNUC__) || defined(__arm__) -#define MBEDTLS_ALWAYS_INLINE __attribute__((always_inline)) -#else -#define MBEDTLS_ALWAYS_INLINE -#endif - -/* Internal helper macros for deprecating API constants. */ -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -#if defined(MBEDTLS_DEPRECATED_WARNING) -/* Deliberately don't (yet) export MBEDTLS_DEPRECATED here - * to avoid conflict with other headers which define and use - * it, too. We might want to move all these definitions here at - * some point for uniformity. */ -#define MBEDTLS_DEPRECATED __attribute__((deprecated)) -MBEDTLS_DEPRECATED typedef char const * mbedtls_deprecated_string_constant_t; -#define MBEDTLS_DEPRECATED_STRING_CONSTANT( VAL ) \ - ( (mbedtls_deprecated_string_constant_t) ( VAL ) ) -MBEDTLS_DEPRECATED typedef int mbedtls_deprecated_numeric_constant_t; -#define MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( VAL ) \ - ( (mbedtls_deprecated_numeric_constant_t) ( VAL ) ) -#undef MBEDTLS_DEPRECATED -#else /* MBEDTLS_DEPRECATED_WARNING */ -#define MBEDTLS_DEPRECATED_STRING_CONSTANT( VAL ) VAL -#define MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( VAL ) VAL -#endif /* MBEDTLS_DEPRECATED_WARNING */ -#endif /* MBEDTLS_DEPRECATED_REMOVED */ - -/** - * \brief Securely zeroize a buffer - * - * The function is meant to wipe the data contained in a buffer so - * that it can no longer be recovered even if the program memory - * is later compromised. Call this function on sensitive data - * stored on the stack before returning from a function, and on - * sensitive data stored on the heap before freeing the heap - * object. - * - * It is extremely difficult to guarantee that calls to - * mbedtls_platform_zeroize() are not removed by aggressive - * compiler optimizations in a portable way. For this reason, Mbed - * TLS provides the configuration option - * MBEDTLS_PLATFORM_ZEROIZE_ALT, which allows users to configure - * mbedtls_platform_zeroize() to use a suitable implementation for - * their platform and needs - * - * \param buf Buffer to be zeroized - * \param len Length of the buffer in bytes - * - * \return The value of \p buf if the operation was successful. - * \return NULL if a potential FI attack was detected or input parameters - * are not valid. - */ -void *mbedtls_platform_zeroize( void *buf, size_t len ); - -/** - * \brief Secure memset - * - * This is a constant-time version of memset(). The buffer is - * initialised with random data and the order is also randomised - * using the RNG in order to further harden against side-channel - * attacks. - * - * \param ptr Buffer to be set. - * \param value Value to be used when setting the buffer. - * \param num The length of the buffer in bytes. - * - * \return The value of \p ptr if the operation was successful. - * \return NULL if a potential FI attack was detected. - */ -void *mbedtls_platform_memset( void *ptr, int value, size_t num ); - -/** - * \brief Secure memcpy - * - * This is a constant-time version of memcpy(). The buffer is - * initialised with random data and the order is also randomised - * using the RNG in order to further harden against side-channel - * attacks. - * - * \param dst Destination buffer where the data is being copied to. - * \param src Source buffer where the data is being copied from. - * \param num The length of the buffers in bytes. - * - * \return The value of \p dst. - * \return NULL if a potential FI attack was detected. - */ -void *mbedtls_platform_memcpy( void *dst, const void *src, size_t num ); - -/** - * \brief Secure memmove - * - * This is a constant-time version of memmove(). It is based on - * the double use of the mbedtls_platform_memcpy() function secured - * against side-channel attacks. - * - * \param dst Destination buffer where the data is being moved to. - * \param src Source buffer where the data is being moved from. - * \param num The length of the buffers in bytes. - * - * \return 0 if the operation was successful - * \return #MBEDTLS_ERR_PLATFORM_ALLOC_FAILED if a memory allocation failed - */ -int mbedtls_platform_memmove( void *dst, const void *src, size_t num ); - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -#if defined(MBEDTLS_DEPRECATED_WARNING) -#define MBEDTLS_DEPRECATED __attribute__((deprecated)) -#else -#define MBEDTLS_DEPRECATED -#endif - -/** - * \brief Secure memcmp - * - * This is a constant-time version of memcmp(), but without checking - * if the bytes are greater or lower. The order is also randomised - * using the RNG in order to further harden against side-channel attacks. - * - * \param buf1 First buffer to compare. - * \param buf2 Second buffer to compare against. - * \param num The length of the buffers in bytes. - * - * \deprecated Superseded by mbedtls_platform_memequal(), and is only an alias to it. - * - * \return 0 if the buffers were equal or an unspecified non-zero value - * otherwise. - */ -int mbedtls_platform_memcmp( const void *buf1, const void *buf2, size_t num ); - -#endif -/** - * \brief Secure check if the buffers have the same data. - * - * This is a constant-time version of memcmp(), but without checking - * if the bytes are greater or lower. The order is also randomised - * using the RNG in order to further harden against side-channel attacks. - * - * \param buf1 First buffer to compare. - * \param buf2 Second buffer to compare against. - * \param num The length of the buffers in bytes. - * - * \return 0 if the buffers were equal or an unspecified non-zero value - * otherwise. - */ -int mbedtls_platform_memequal( const void *buf1, const void *buf2, size_t num ); - -/** - * \brief RNG-function for getting a random 32-bit integer. - * - * \return The generated random number. - */ -uint32_t mbedtls_platform_random_uint32( void ); - -/** - * \brief RNG-function for getting a random in given range. - * - * This function is meant to provide a global RNG to be used - * throughout Mbed TLS for hardening the library. It is used - * for generating a random delay, random data or random offset - * for utility functions. It is not meant to be a - * cryptographically secure RNG, but provide an RNG for utility - * functions. - * - * \param num Max-value for the generated random number, exclusive. - * Must be greater than zero, otherwise an undefined behavior - * will occur on "num % 0". - * The generated number will be on range [0, num). - * - * \return The generated random number. - */ -uint32_t mbedtls_platform_random_in_range( uint32_t num ); - -/** - * \brief Random delay function. - * - * Function implements a random delay by incrementing a local - * variable randomized number of times (busy-looping). - * - * Duration of the delay is random as number of variable increments - * is randomized. - * - * \note This function works only if the MBEDTLS_FI_COUNTERMEASURES flag - * is defined in the configuration. Otherwise, the function does - * nothing. - */ -void mbedtls_platform_random_delay( void ); - -/** - * \brief RNG-function for getting a random buffer. - * - * \param buf Buffer for random data - * \param len Length of the buffer in bytes - * - */ -void mbedtls_platform_random_buf( uint8_t *buf, size_t len); - -#if defined(MBEDTLS_HAVE_TIME_DATE) -/** - * \brief Platform-specific implementation of gmtime_r() - * - * The function is a thread-safe abstraction that behaves - * similarly to the gmtime_r() function from Unix/POSIX. - * - * Mbed TLS will try to identify the underlying platform and - * make use of an appropriate underlying implementation (e.g. - * gmtime_r() for POSIX and gmtime_s() for Windows). If this is - * not possible, then gmtime() will be used. In this case, calls - * from the library to gmtime() will be guarded by the mutex - * mbedtls_threading_gmtime_mutex if MBEDTLS_THREADING_C is - * enabled. It is recommended that calls from outside the library - * are also guarded by this mutex. - * - * If MBEDTLS_PLATFORM_GMTIME_R_ALT is defined, then Mbed TLS will - * unconditionally use the alternative implementation for - * mbedtls_platform_gmtime_r() supplied by the user at compile time. - * - * \param tt Pointer to an object containing time (in seconds) since the - * epoch to be converted - * \param tm_buf Pointer to an object where the results will be stored - * - * \return Pointer to an object of type struct tm on success, otherwise - * NULL - */ -struct tm *mbedtls_platform_gmtime_r( const mbedtls_time_t *tt, - struct tm *tm_buf ); -#endif /* MBEDTLS_HAVE_TIME_DATE */ - -#if defined(MBEDTLS_VALIDATE_AES_KEYS_INTEGRITY) || defined(MBEDTLS_VALIDATE_SSL_KEYS_INTEGRITY) -/** - * \brief Calculate a hash from the given data. - * - * \param data Data from which the hash is calculated. - * \param data_len_bytes Length of the data in bytes. - * - * \return A hash calculated from the provided data. - */ -uint32_t mbedtls_hash( const void *data, size_t data_len_bytes ); -#endif - -/** - * \brief Convert a 32-bit number to the big endian format and write it to - * the given buffer. - * - * \param buf Address where the converted number is written. - * \param num A number that needs to be converted to the big endian format. - * - * \return Address to the end of buffer where the converted number is - * written. - */ -unsigned char* mbedtls_platform_put_uint32_be( unsigned char *buf, - size_t num ); - -/** - * \brief Convert a 24-bit number to the big endian format and write it to - * the given buffer. - * - * \param buf Address where the converted number is written. - * \param num A number that needs to be converted to the big endian format. - * - * \return Address to the end of buffer where the converted number is - * written. - */ -unsigned char* mbedtls_platform_put_uint24_be( unsigned char *buf, - size_t num ); - -/** - * \brief Convert a 16-bit number to the big endian format and write it to - * the given buffer. - * - * - * \param buf Address where the converted number is written. - * \param num A number that needs to be converted to the big endian format. - * - * \return Address to the end of buffer where the converted number is - * written. - */ -unsigned char* mbedtls_platform_put_uint16_be( unsigned char *buf, - size_t num ); - -/** - * \brief Convert a 32-bit number from the big endian format. - * - * The function reads a 32-bit number from the given buffer in the - * big endian format and returns it to the caller. - * - * \param buf Buffer where the 32-bit number locates. - * - * \return Converted number. - */ -size_t mbedtls_platform_get_uint32_be( const unsigned char *buf ); - -/** - * \brief Convert a 24-bit number from the big endian format. - * - * The function reads a 14-bit number from the given buffer in the - * big endian format and returns it to the caller. - * - * \param buf Buffer where the 24-bit number locates. - * - * \return Converted number. - */ -size_t mbedtls_platform_get_uint24_be( const unsigned char *buf ); - -/** - * \brief Convert a 16-bit number from the big endian format. - * - * The function reads a 16-bit number from the given buffer in the - * big endian format and returns it to the caller. - * - * \param buf Buffer where the 16-bit number locates. - * - * \return Converted number. - */ -size_t mbedtls_platform_get_uint16_be( const unsigned char *buf ); - -#ifdef __cplusplus -} -#endif - -#endif /* MBEDTLS_PLATFORM_UTIL_H */ diff --git a/APP_Framework/Framework/security/mbedtls/poly1305.h b/APP_Framework/Framework/security/mbedtls/poly1305.h deleted file mode 100644 index f0ec44c96..000000000 --- a/APP_Framework/Framework/security/mbedtls/poly1305.h +++ /dev/null @@ -1,192 +0,0 @@ -/** - * \file poly1305.h - * - * \brief This file contains Poly1305 definitions and functions. - * - * Poly1305 is a one-time message authenticator that can be used to - * authenticate messages. Poly1305-AES was created by Daniel - * Bernstein https://cr.yp.to/mac/poly1305-20050329.pdf The generic - * Poly1305 algorithm (not tied to AES) was also standardized in RFC - * 7539. - * - * \author Daniel King - */ - -/* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * This file is part of Mbed TLS (https://tls.mbed.org) - */ - -#ifndef MBEDTLS_POLY1305_H -#define MBEDTLS_POLY1305_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include -#include - -#define MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA -0x0057 /**< Invalid input parameter(s). */ - -/* MBEDTLS_ERR_POLY1305_FEATURE_UNAVAILABLE is deprecated and should not be - * used. */ -#define MBEDTLS_ERR_POLY1305_FEATURE_UNAVAILABLE -0x0059 /**< Feature not available. For example, s part of the API is not implemented. */ - -/* MBEDTLS_ERR_POLY1305_HW_ACCEL_FAILED is deprecated and should not be used. - */ -#define MBEDTLS_ERR_POLY1305_HW_ACCEL_FAILED -0x005B /**< Poly1305 hardware accelerator failed. */ - -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined(MBEDTLS_POLY1305_ALT) - -typedef struct mbedtls_poly1305_context -{ - uint32_t r[4]; /** The value for 'r' (low 128 bits of the key). */ - uint32_t s[4]; /** The value for 's' (high 128 bits of the key). */ - uint32_t acc[5]; /** The accumulator number. */ - uint8_t queue[16]; /** The current partial block of data. */ - size_t queue_len; /** The number of bytes stored in 'queue'. */ -} -mbedtls_poly1305_context; - -#else /* MBEDTLS_POLY1305_ALT */ -#include "poly1305_alt.h" -#endif /* MBEDTLS_POLY1305_ALT */ - -/** - * \brief This function initializes the specified Poly1305 context. - * - * It must be the first API called before using - * the context. - * - * It is usually followed by a call to - * \c mbedtls_poly1305_starts(), then one or more calls to - * \c mbedtls_poly1305_update(), then one call to - * \c mbedtls_poly1305_finish(), then finally - * \c mbedtls_poly1305_free(). - * - * \param ctx The Poly1305 context to initialize. This must - * not be \c NULL. - */ -void mbedtls_poly1305_init( mbedtls_poly1305_context *ctx ); - -/** - * \brief This function releases and clears the specified - * Poly1305 context. - * - * \param ctx The Poly1305 context to clear. This may be \c NULL, in which - * case this function is a no-op. If it is not \c NULL, it must - * point to an initialized Poly1305 context. - */ -void mbedtls_poly1305_free( mbedtls_poly1305_context *ctx ); - -/** - * \brief This function sets the one-time authentication key. - * - * \warning The key must be unique and unpredictable for each - * invocation of Poly1305. - * - * \param ctx The Poly1305 context to which the key should be bound. - * This must be initialized. - * \param key The buffer containing the \c 32 Byte (\c 256 Bit) key. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_poly1305_starts( mbedtls_poly1305_context *ctx, - const unsigned char key[32] ); - -/** - * \brief This functions feeds an input buffer into an ongoing - * Poly1305 computation. - * - * It is called between \c mbedtls_cipher_poly1305_starts() and - * \c mbedtls_cipher_poly1305_finish(). - * It can be called repeatedly to process a stream of data. - * - * \param ctx The Poly1305 context to use for the Poly1305 operation. - * This must be initialized and bound to a key. - * \param ilen The length of the input data in Bytes. - * Any value is accepted. - * \param input The buffer holding the input data. - * This pointer can be \c NULL if `ilen == 0`. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_poly1305_update( mbedtls_poly1305_context *ctx, - const unsigned char *input, - size_t ilen ); - -/** - * \brief This function generates the Poly1305 Message - * Authentication Code (MAC). - * - * \param ctx The Poly1305 context to use for the Poly1305 operation. - * This must be initialized and bound to a key. - * \param mac The buffer to where the MAC is written. This must - * be a writable buffer of length \c 16 Bytes. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_poly1305_finish( mbedtls_poly1305_context *ctx, - unsigned char mac[16] ); - -/** - * \brief This function calculates the Poly1305 MAC of the input - * buffer with the provided key. - * - * \warning The key must be unique and unpredictable for each - * invocation of Poly1305. - * - * \param key The buffer containing the \c 32 Byte (\c 256 Bit) key. - * \param ilen The length of the input data in Bytes. - * Any value is accepted. - * \param input The buffer holding the input data. - * This pointer can be \c NULL if `ilen == 0`. - * \param mac The buffer to where the MAC is written. This must be - * a writable buffer of length \c 16 Bytes. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_poly1305_mac( const unsigned char key[32], - const unsigned char *input, - size_t ilen, - unsigned char mac[16] ); - -#if defined(MBEDTLS_SELF_TEST) -/** - * \brief The Poly1305 checkup routine. - * - * \return \c 0 on success. - * \return \c 1 on failure. - */ -int mbedtls_poly1305_self_test( int verbose ); -#endif /* MBEDTLS_SELF_TEST */ - -#ifdef __cplusplus -} -#endif - -#endif /* MBEDTLS_POLY1305_H */ diff --git a/APP_Framework/Framework/security/mbedtls/ripemd160.c b/APP_Framework/Framework/security/mbedtls/ripemd160.c new file mode 100644 index 000000000..52723b002 --- /dev/null +++ b/APP_Framework/Framework/security/mbedtls/ripemd160.c @@ -0,0 +1,556 @@ +/* + * RIPE MD-160 implementation + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +/* + * The RIPEMD-160 algorithm was designed by RIPE in 1996 + * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html + * http://ehash.iaik.tugraz.at/wiki/RIPEMD-160 + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_RIPEMD160_C) + +#include "ripemd160.h" + +#include + +#if defined(MBEDTLS_SELF_TEST) +#if defined(MBEDTLS_PLATFORM_C) +#include "platform.h" +#else +#include +#define mbedtls_printf printf +#endif /* MBEDTLS_PLATFORM_C */ +#endif /* MBEDTLS_SELF_TEST */ + +#if !defined(MBEDTLS_RIPEMD160_ALT) + +/* + * 32-bit integer manipulation macros (little endian) + */ +#ifndef GET_UINT32_LE +#define GET_UINT32_LE(n,b,i) \ +{ \ + (n) = ( (uint32_t) (b)[(i) ] ) \ + | ( (uint32_t) (b)[(i) + 1] << 8 ) \ + | ( (uint32_t) (b)[(i) + 2] << 16 ) \ + | ( (uint32_t) (b)[(i) + 3] << 24 ); \ +} +#endif + +#ifndef PUT_UINT32_LE +#define PUT_UINT32_LE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \ + (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \ + (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \ + (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \ +} +#endif + +/* 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; +} + +void mbedtls_ripemd160_init( mbedtls_ripemd160_context *ctx ) +{ + memset( ctx, 0, sizeof( mbedtls_ripemd160_context ) ); +} + +void mbedtls_ripemd160_free( mbedtls_ripemd160_context *ctx ) +{ + if( ctx == NULL ) + return; + + mbedtls_zeroize( ctx, sizeof( mbedtls_ripemd160_context ) ); +} + +void mbedtls_ripemd160_clone( mbedtls_ripemd160_context *dst, + const mbedtls_ripemd160_context *src ) +{ + *dst = *src; +} + +/* + * RIPEMD-160 context setup + */ +int mbedtls_ripemd160_starts_ret( mbedtls_ripemd160_context *ctx ) +{ + ctx->total[0] = 0; + ctx->total[1] = 0; + + ctx->state[0] = 0x67452301; + ctx->state[1] = 0xEFCDAB89; + ctx->state[2] = 0x98BADCFE; + ctx->state[3] = 0x10325476; + 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) +/* + * Process one block + */ +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]; + + GET_UINT32_LE( X[ 0], data, 0 ); + GET_UINT32_LE( X[ 1], data, 4 ); + GET_UINT32_LE( X[ 2], data, 8 ); + GET_UINT32_LE( X[ 3], data, 12 ); + GET_UINT32_LE( X[ 4], data, 16 ); + GET_UINT32_LE( X[ 5], data, 20 ); + GET_UINT32_LE( X[ 6], data, 24 ); + GET_UINT32_LE( X[ 7], data, 28 ); + GET_UINT32_LE( X[ 8], data, 32 ); + GET_UINT32_LE( X[ 9], data, 36 ); + GET_UINT32_LE( X[10], data, 40 ); + GET_UINT32_LE( X[11], data, 44 ); + GET_UINT32_LE( X[12], data, 48 ); + GET_UINT32_LE( X[13], data, 52 ); + GET_UINT32_LE( X[14], data, 56 ); + GET_UINT32_LE( X[15], data, 60 ); + + A = Ap = ctx->state[0]; + B = Bp = ctx->state[1]; + C = Cp = ctx->state[2]; + D = Dp = ctx->state[3]; + E = Ep = ctx->state[4]; + +#define F1( x, y, z ) ( x ^ y ^ z ) +#define F2( x, y, z ) ( ( x & y ) | ( ~x & z ) ) +#define F3( x, y, z ) ( ( x | ~y ) ^ z ) +#define F4( x, y, z ) ( ( x & z ) | ( y & ~z ) ) +#define F5( x, y, z ) ( x ^ ( y | ~z ) ) + +#define S( x, n ) ( ( x << n ) | ( x >> (32 - n) ) ) + +#define P( a, b, c, d, e, r, s, f, k ) \ + a += f( b, c, d ) + X[r] + k; \ + a = S( a, s ) + e; \ + c = S( c, 10 ); + +#define P2( a, b, c, d, e, r, s, rp, sp ) \ + P( a, b, c, d, e, r, s, F, K ); \ + P( a ## p, b ## p, c ## p, d ## p, e ## p, rp, sp, Fp, Kp ); + +#define F F1 +#define K 0x00000000 +#define Fp F5 +#define Kp 0x50A28BE6 + P2( A, B, C, D, E, 0, 11, 5, 8 ); + P2( E, A, B, C, D, 1, 14, 14, 9 ); + P2( D, E, A, B, C, 2, 15, 7, 9 ); + P2( C, D, E, A, B, 3, 12, 0, 11 ); + P2( B, C, D, E, A, 4, 5, 9, 13 ); + P2( A, B, C, D, E, 5, 8, 2, 15 ); + P2( E, A, B, C, D, 6, 7, 11, 15 ); + P2( D, E, A, B, C, 7, 9, 4, 5 ); + P2( C, D, E, A, B, 8, 11, 13, 7 ); + P2( B, C, D, E, A, 9, 13, 6, 7 ); + P2( A, B, C, D, E, 10, 14, 15, 8 ); + P2( E, A, B, C, D, 11, 15, 8, 11 ); + P2( D, E, A, B, C, 12, 6, 1, 14 ); + P2( C, D, E, A, B, 13, 7, 10, 14 ); + P2( B, C, D, E, A, 14, 9, 3, 12 ); + P2( A, B, C, D, E, 15, 8, 12, 6 ); +#undef F +#undef K +#undef Fp +#undef Kp + +#define F F2 +#define K 0x5A827999 +#define Fp F4 +#define Kp 0x5C4DD124 + P2( E, A, B, C, D, 7, 7, 6, 9 ); + P2( D, E, A, B, C, 4, 6, 11, 13 ); + P2( C, D, E, A, B, 13, 8, 3, 15 ); + P2( B, C, D, E, A, 1, 13, 7, 7 ); + P2( A, B, C, D, E, 10, 11, 0, 12 ); + P2( E, A, B, C, D, 6, 9, 13, 8 ); + P2( D, E, A, B, C, 15, 7, 5, 9 ); + P2( C, D, E, A, B, 3, 15, 10, 11 ); + P2( B, C, D, E, A, 12, 7, 14, 7 ); + P2( A, B, C, D, E, 0, 12, 15, 7 ); + P2( E, A, B, C, D, 9, 15, 8, 12 ); + P2( D, E, A, B, C, 5, 9, 12, 7 ); + P2( C, D, E, A, B, 2, 11, 4, 6 ); + P2( B, C, D, E, A, 14, 7, 9, 15 ); + P2( A, B, C, D, E, 11, 13, 1, 13 ); + P2( E, A, B, C, D, 8, 12, 2, 11 ); +#undef F +#undef K +#undef Fp +#undef Kp + +#define F F3 +#define K 0x6ED9EBA1 +#define Fp F3 +#define Kp 0x6D703EF3 + P2( D, E, A, B, C, 3, 11, 15, 9 ); + P2( C, D, E, A, B, 10, 13, 5, 7 ); + P2( B, C, D, E, A, 14, 6, 1, 15 ); + P2( A, B, C, D, E, 4, 7, 3, 11 ); + P2( E, A, B, C, D, 9, 14, 7, 8 ); + P2( D, E, A, B, C, 15, 9, 14, 6 ); + P2( C, D, E, A, B, 8, 13, 6, 6 ); + P2( B, C, D, E, A, 1, 15, 9, 14 ); + P2( A, B, C, D, E, 2, 14, 11, 12 ); + P2( E, A, B, C, D, 7, 8, 8, 13 ); + P2( D, E, A, B, C, 0, 13, 12, 5 ); + P2( C, D, E, A, B, 6, 6, 2, 14 ); + P2( B, C, D, E, A, 13, 5, 10, 13 ); + P2( A, B, C, D, E, 11, 12, 0, 13 ); + P2( E, A, B, C, D, 5, 7, 4, 7 ); + P2( D, E, A, B, C, 12, 5, 13, 5 ); +#undef F +#undef K +#undef Fp +#undef Kp + +#define F F4 +#define K 0x8F1BBCDC +#define Fp F2 +#define Kp 0x7A6D76E9 + P2( C, D, E, A, B, 1, 11, 8, 15 ); + P2( B, C, D, E, A, 9, 12, 6, 5 ); + P2( A, B, C, D, E, 11, 14, 4, 8 ); + P2( E, A, B, C, D, 10, 15, 1, 11 ); + P2( D, E, A, B, C, 0, 14, 3, 14 ); + P2( C, D, E, A, B, 8, 15, 11, 14 ); + P2( B, C, D, E, A, 12, 9, 15, 6 ); + P2( A, B, C, D, E, 4, 8, 0, 14 ); + P2( E, A, B, C, D, 13, 9, 5, 6 ); + P2( D, E, A, B, C, 3, 14, 12, 9 ); + P2( C, D, E, A, B, 7, 5, 2, 12 ); + P2( B, C, D, E, A, 15, 6, 13, 9 ); + P2( A, B, C, D, E, 14, 8, 9, 12 ); + P2( E, A, B, C, D, 5, 6, 7, 5 ); + P2( D, E, A, B, C, 6, 5, 10, 15 ); + P2( C, D, E, A, B, 2, 12, 14, 8 ); +#undef F +#undef K +#undef Fp +#undef Kp + +#define F F5 +#define K 0xA953FD4E +#define Fp F1 +#define Kp 0x00000000 + P2( B, C, D, E, A, 4, 9, 12, 8 ); + P2( A, B, C, D, E, 0, 15, 15, 5 ); + P2( E, A, B, C, D, 5, 5, 10, 12 ); + P2( D, E, A, B, C, 9, 11, 4, 9 ); + P2( C, D, E, A, B, 7, 6, 1, 12 ); + P2( B, C, D, E, A, 12, 8, 5, 5 ); + P2( A, B, C, D, E, 2, 13, 8, 14 ); + P2( E, A, B, C, D, 10, 12, 7, 6 ); + P2( D, E, A, B, C, 14, 5, 6, 8 ); + P2( C, D, E, A, B, 1, 12, 2, 13 ); + P2( B, C, D, E, A, 3, 13, 13, 6 ); + P2( A, B, C, D, E, 8, 14, 14, 5 ); + P2( E, A, B, C, D, 11, 11, 0, 15 ); + P2( D, E, A, B, C, 6, 8, 3, 13 ); + P2( C, D, E, A, B, 15, 5, 9, 11 ); + P2( B, C, D, E, A, 13, 6, 11, 11 ); +#undef F +#undef K +#undef Fp +#undef Kp + + C = ctx->state[1] + C + Dp; + ctx->state[1] = ctx->state[2] + D + Ep; + ctx->state[2] = ctx->state[3] + E + Ap; + ctx->state[3] = ctx->state[4] + A + Bp; + ctx->state[4] = ctx->state[0] + B + Cp; + 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 */ + +/* + * RIPEMD-160 process buffer + */ +int mbedtls_ripemd160_update_ret( mbedtls_ripemd160_context *ctx, + const unsigned char *input, + size_t ilen ) +{ + int ret; + size_t fill; + uint32_t left; + + if( ilen == 0 ) + return( 0 ); + + left = ctx->total[0] & 0x3F; + fill = 64 - left; + + ctx->total[0] += (uint32_t) ilen; + ctx->total[0] &= 0xFFFFFFFF; + + if( ctx->total[0] < (uint32_t) ilen ) + ctx->total[1]++; + + if( left && ilen >= fill ) + { + memcpy( (void *) (ctx->buffer + left), input, fill ); + + if( ( ret = mbedtls_internal_ripemd160_process( ctx, ctx->buffer ) ) != 0 ) + return( ret ); + + input += fill; + ilen -= fill; + left = 0; + } + + while( ilen >= 64 ) + { + if( ( ret = mbedtls_internal_ripemd160_process( ctx, input ) ) != 0 ) + return( ret ); + + input += 64; + ilen -= 64; + } + + if( ilen > 0 ) + { + 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] = +{ + 0x80, 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 +}; + +/* + * RIPEMD-160 final digest + */ +int mbedtls_ripemd160_finish_ret( mbedtls_ripemd160_context *ctx, + unsigned char output[20] ) +{ + int ret; + uint32_t last, padn; + uint32_t high, low; + unsigned char msglen[8]; + + high = ( ctx->total[0] >> 29 ) + | ( ctx->total[1] << 3 ); + low = ( ctx->total[0] << 3 ); + + PUT_UINT32_LE( low, msglen, 0 ); + PUT_UINT32_LE( high, msglen, 4 ); + + last = ctx->total[0] & 0x3F; + padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); + + ret = mbedtls_ripemd160_update_ret( ctx, ripemd160_padding, padn ); + 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[1], output, 4 ); + PUT_UINT32_LE( ctx->state[2], output, 8 ); + PUT_UINT32_LE( ctx->state[3], output, 12 ); + PUT_UINT32_LE( ctx->state[4], output, 16 ); + + 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 ) + */ +int mbedtls_ripemd160_ret( const unsigned char *input, + size_t ilen, + unsigned char output[20] ) +{ + int ret; + mbedtls_ripemd160_context ctx; + + mbedtls_ripemd160_init( &ctx ); + + if( ( ret = mbedtls_ripemd160_starts_ret( &ctx ) ) != 0 ) + 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 ); + + 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) +/* + * Test vectors from the RIPEMD-160 paper and + * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html#HMAC + */ +#define TESTS 8 +static const unsigned char ripemd160_test_str[TESTS][81] = +{ + { "" }, + { "a" }, + { "abc" }, + { "message digest" }, + { "abcdefghijklmnopqrstuvwxyz" }, + { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" }, + { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" }, + { "12345678901234567890123456789012345678901234567890123456789012" + "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] = +{ + { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28, + 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 }, + { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae, + 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe }, + { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04, + 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc }, + { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8, + 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 }, + { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb, + 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc }, + { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05, + 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b }, + { 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed, + 0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 }, + { 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb, + 0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb }, +}; + +/* + * Checkup routine + */ +int mbedtls_ripemd160_self_test( int verbose ) +{ + int i, ret = 0; + unsigned char output[20]; + + memset( output, 0, sizeof output ); + + for( i = 0; i < TESTS; i++ ) + { + if( verbose != 0 ) + mbedtls_printf( " RIPEMD-160 test #%d: ", i + 1 ); + + ret = mbedtls_ripemd160_ret( ripemd160_test_str[i], + ripemd160_test_strlen[i], output ); + if( ret != 0 ) + goto fail; + + if( memcmp( output, ripemd160_test_md[i], 20 ) != 0 ) + { + ret = 1; + goto fail; + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + } + + if( verbose != 0 ) + mbedtls_printf( "\n" ); + + return( 0 ); + +fail: + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + return( ret ); +} + +#endif /* MBEDTLS_SELF_TEST */ + +#endif /* MBEDTLS_RIPEMD160_C */ diff --git a/APP_Framework/Framework/security/mbedtls/ripemd160.h b/APP_Framework/Framework/security/mbedtls/ripemd160.h index b42f6d2a9..3a8b50a62 100644 --- a/APP_Framework/Framework/security/mbedtls/ripemd160.h +++ b/APP_Framework/Framework/security/mbedtls/ripemd160.h @@ -33,22 +33,20 @@ #include #include -/* MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED is deprecated and should not be used. - */ #define MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED -0x0031 /**< RIPEMD160 hardware accelerator failed */ -#ifdef __cplusplus -extern "C" { -#endif - #if !defined(MBEDTLS_RIPEMD160_ALT) // Regular implementation // +#ifdef __cplusplus +extern "C" { +#endif + /** * \brief RIPEMD-160 context structure */ -typedef struct mbedtls_ripemd160_context +typedef struct { uint32_t total[2]; /*!< number of bytes processed */ uint32_t state[5]; /*!< intermediate digest state */ @@ -56,10 +54,6 @@ typedef struct mbedtls_ripemd160_context } mbedtls_ripemd160_context; -#else /* MBEDTLS_RIPEMD160_ALT */ -#include "ripemd160.h" -#endif /* MBEDTLS_RIPEMD160_ALT */ - /** * \brief Initialize RIPEMD-160 context * @@ -184,6 +178,18 @@ MBEDTLS_DEPRECATED void mbedtls_ripemd160_process( #undef MBEDTLS_DEPRECATED #endif /* !MBEDTLS_DEPRECATED_REMOVED */ +#ifdef __cplusplus +} +#endif + +#else /* MBEDTLS_RIPEMD160_ALT */ +#include "ripemd160_alt.h" +#endif /* MBEDTLS_RIPEMD160_ALT */ + +#ifdef __cplusplus +extern "C" { +#endif + /** * \brief Output = RIPEMD-160( input buffer ) * @@ -219,8 +225,6 @@ MBEDTLS_DEPRECATED void mbedtls_ripemd160( const unsigned char *input, #undef MBEDTLS_DEPRECATED #endif /* !MBEDTLS_DEPRECATED_REMOVED */ -#if defined(MBEDTLS_SELF_TEST) - /** * \brief Checkup routine * @@ -228,8 +232,6 @@ MBEDTLS_DEPRECATED void mbedtls_ripemd160( const unsigned char *input, */ int mbedtls_ripemd160_self_test( int verbose ); -#endif /* MBEDTLS_SELF_TEST */ - #ifdef __cplusplus } #endif diff --git a/APP_Framework/Framework/security/mbedtls/rsa.c b/APP_Framework/Framework/security/mbedtls/rsa.c index 7adbf782f..6e90e0e5f 100644 --- a/APP_Framework/Framework/security/mbedtls/rsa.c +++ b/APP_Framework/Framework/security/mbedtls/rsa.c @@ -48,7 +48,6 @@ #include "rsa.h" #include "rsa_internal.h" #include "oid.h" -#include "platform_util.h" #include @@ -60,9 +59,9 @@ #include #endif +#if defined(MBEDTLS_PLATFORM_C) #include "platform.h" - -#if !defined(MBEDTLS_PLATFORM_C) +#else #include #define mbedtls_printf printf #define mbedtls_calloc calloc @@ -71,11 +70,10 @@ #if !defined(MBEDTLS_RSA_ALT) -/* Parameter validation macros */ -#define RSA_VALIDATE_RET( cond ) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_RSA_BAD_INPUT_DATA ) -#define RSA_VALIDATE( cond ) \ - MBEDTLS_INTERNAL_VALIDATE( cond ) +/* 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; +} #if defined(MBEDTLS_PKCS1_V15) /* constant-time buffer comparison */ @@ -99,7 +97,6 @@ int mbedtls_rsa_import( mbedtls_rsa_context *ctx, const mbedtls_mpi *D, const mbedtls_mpi *E ) { int ret; - RSA_VALIDATE_RET( ctx != NULL ); if( ( N != NULL && ( ret = mbedtls_mpi_copy( &ctx->N, N ) ) != 0 ) || ( P != NULL && ( ret = mbedtls_mpi_copy( &ctx->P, P ) ) != 0 ) || @@ -124,7 +121,6 @@ int mbedtls_rsa_import_raw( mbedtls_rsa_context *ctx, unsigned char const *E, size_t E_len ) { int ret = 0; - RSA_VALIDATE_RET( ctx != NULL ); if( N != NULL ) { @@ -248,25 +244,12 @@ static int rsa_check_context( mbedtls_rsa_context const *ctx, int is_priv, int mbedtls_rsa_complete( mbedtls_rsa_context *ctx ) { int ret = 0; - int have_N, have_P, have_Q, have_D, have_E; -#if !defined(MBEDTLS_RSA_NO_CRT) - int have_DP, have_DQ, have_QP; -#endif - int n_missing, pq_missing, d_missing, is_pub, is_priv; - RSA_VALIDATE_RET( ctx != NULL ); - - have_N = ( mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 ); - have_P = ( mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 ); - have_Q = ( mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 ); - have_D = ( mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 ); - have_E = ( mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0 ); - -#if !defined(MBEDTLS_RSA_NO_CRT) - have_DP = ( mbedtls_mpi_cmp_int( &ctx->DP, 0 ) != 0 ); - have_DQ = ( mbedtls_mpi_cmp_int( &ctx->DQ, 0 ) != 0 ); - have_QP = ( mbedtls_mpi_cmp_int( &ctx->QP, 0 ) != 0 ); -#endif + const int have_N = ( mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 ); + const int have_P = ( mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 ); + const int have_Q = ( mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 ); + const int have_D = ( mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 ); + const int have_E = ( mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0 ); /* * Check whether provided parameters are enough @@ -278,13 +261,13 @@ int mbedtls_rsa_complete( mbedtls_rsa_context *ctx ) * */ - n_missing = have_P && have_Q && have_D && have_E; - pq_missing = have_N && !have_P && !have_Q && have_D && have_E; - d_missing = have_P && have_Q && !have_D && have_E; - is_pub = have_N && !have_P && !have_Q && !have_D && have_E; + const int n_missing = have_P && have_Q && have_D && have_E; + const int pq_missing = have_N && !have_P && !have_Q && have_D && have_E; + const int d_missing = have_P && have_Q && !have_D && have_E; + const int is_pub = have_N && !have_P && !have_Q && !have_D && have_E; /* These three alternatives are mutually exclusive */ - is_priv = n_missing || pq_missing || d_missing; + const int is_priv = n_missing || pq_missing || d_missing; if( !is_priv && !is_pub ) return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); @@ -333,7 +316,7 @@ int mbedtls_rsa_complete( mbedtls_rsa_context *ctx ) */ #if !defined(MBEDTLS_RSA_NO_CRT) - if( is_priv && ! ( have_DP && have_DQ && have_QP ) ) + if( is_priv ) { ret = mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D, &ctx->DP, &ctx->DQ, &ctx->QP ); @@ -357,11 +340,9 @@ int mbedtls_rsa_export_raw( const mbedtls_rsa_context *ctx, unsigned char *E, size_t E_len ) { int ret = 0; - int is_priv; - RSA_VALIDATE_RET( ctx != NULL ); /* Check if key is private or public */ - is_priv = + const int is_priv = mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 && mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 && mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 && @@ -402,11 +383,9 @@ int mbedtls_rsa_export( const mbedtls_rsa_context *ctx, mbedtls_mpi *D, mbedtls_mpi *E ) { int ret; - int is_priv; - RSA_VALIDATE_RET( ctx != NULL ); /* Check if key is private or public */ - is_priv = + int is_priv = mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 && mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 && mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 && @@ -446,11 +425,9 @@ int mbedtls_rsa_export_crt( const mbedtls_rsa_context *ctx, mbedtls_mpi *DP, mbedtls_mpi *DQ, mbedtls_mpi *QP ) { int ret; - int is_priv; - RSA_VALIDATE_RET( ctx != NULL ); /* Check if key is private or public */ - is_priv = + int is_priv = mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 && mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 && mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 && @@ -486,11 +463,7 @@ void mbedtls_rsa_init( mbedtls_rsa_context *ctx, int padding, int hash_id ) { - RSA_VALIDATE( ctx != NULL ); - RSA_VALIDATE( padding == MBEDTLS_RSA_PKCS_V15 || - padding == MBEDTLS_RSA_PKCS_V21 ); - - mbedtls_platform_memset( ctx, 0, sizeof( mbedtls_rsa_context ) ); + memset( ctx, 0, sizeof( mbedtls_rsa_context ) ); mbedtls_rsa_set_padding( ctx, padding, hash_id ); @@ -502,13 +475,8 @@ void mbedtls_rsa_init( mbedtls_rsa_context *ctx, /* * Set padding for an existing RSA context */ -void mbedtls_rsa_set_padding( mbedtls_rsa_context *ctx, int padding, - int hash_id ) +void mbedtls_rsa_set_padding( mbedtls_rsa_context *ctx, int padding, int hash_id ) { - RSA_VALIDATE( ctx != NULL ); - RSA_VALIDATE( padding == MBEDTLS_RSA_PKCS_V15 || - padding == MBEDTLS_RSA_PKCS_V21 ); - ctx->padding = padding; ctx->hash_id = hash_id; } @@ -527,9 +495,6 @@ size_t mbedtls_rsa_get_len( const mbedtls_rsa_context *ctx ) /* * Generate an RSA keypair - * - * This generation method follows the RSA key pair generation procedure of - * FIPS 186-4 if 2^16 < exponent < 2^256 and nbits = 2048 or nbits = 3072. */ int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx, int (*f_rng)(void *, unsigned char *, size_t), @@ -537,87 +502,65 @@ int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx, unsigned int nbits, int exponent ) { int ret; - mbedtls_mpi H, G, L; - int prime_quality = 0; - RSA_VALIDATE_RET( ctx != NULL ); - RSA_VALIDATE_RET( f_rng != NULL ); + mbedtls_mpi H, G; - if( nbits < 128 || exponent < 3 || nbits % 2 != 0 ) + if( f_rng == NULL || nbits < 128 || exponent < 3 ) return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - /* - * If the modulus is 1024 bit long or shorter, then the security strength of - * the RSA algorithm is less than or equal to 80 bits and therefore an error - * rate of 2^-80 is sufficient. - */ - if( nbits > 1024 ) - prime_quality = MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR; + if( nbits % 2 ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); mbedtls_mpi_init( &H ); mbedtls_mpi_init( &G ); - mbedtls_mpi_init( &L ); /* * find primes P and Q with Q < P so that: - * 1. |P-Q| > 2^( nbits / 2 - 100 ) - * 2. GCD( E, (P-1)*(Q-1) ) == 1 - * 3. E^-1 mod LCM(P-1, Q-1) > 2^( nbits / 2 ) + * GCD( E, (P-1)*(Q-1) ) == 1 */ MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->E, exponent ) ); do { - MBEDTLS_MPI_CHK( mbedtls_mpi_gen_prime( &ctx->P, nbits >> 1, - prime_quality, f_rng, p_rng ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_gen_prime( &ctx->P, nbits >> 1, 0, + f_rng, p_rng ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_gen_prime( &ctx->Q, nbits >> 1, - prime_quality, f_rng, p_rng ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_gen_prime( &ctx->Q, nbits >> 1, 0, + f_rng, p_rng ) ); - /* make sure the difference between p and q is not too small (FIPS 186-4 §B.3.3 step 5.4) */ - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &H, &ctx->P, &ctx->Q ) ); - if( mbedtls_mpi_bitlen( &H ) <= ( ( nbits >= 200 ) ? ( ( nbits >> 1 ) - 99 ) : 0 ) ) + if( mbedtls_mpi_cmp_mpi( &ctx->P, &ctx->Q ) == 0 ) continue; - /* not required by any standards, but some users rely on the fact that P > Q */ - if( H.s < 0 ) + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->N, &ctx->P, &ctx->Q ) ); + if( mbedtls_mpi_bitlen( &ctx->N ) != nbits ) + continue; + + if( mbedtls_mpi_cmp_mpi( &ctx->P, &ctx->Q ) < 0 ) mbedtls_mpi_swap( &ctx->P, &ctx->Q ); /* Temporarily replace P,Q by P-1, Q-1 */ MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &ctx->P, &ctx->P, 1 ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &ctx->Q, &ctx->Q, 1 ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &H, &ctx->P, &ctx->Q ) ); - - /* check GCD( E, (P-1)*(Q-1) ) == 1 (FIPS 186-4 §B.3.1 criterion 2(a)) */ MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G, &ctx->E, &H ) ); - if( mbedtls_mpi_cmp_int( &G, 1 ) != 0 ) - continue; - - /* compute smallest possible D = E^-1 mod LCM(P-1, Q-1) (FIPS 186-4 §B.3.1 criterion 3(b)) */ - MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G, &ctx->P, &ctx->Q ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( &L, NULL, &H, &G ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->D, &ctx->E, &L ) ); - - if( mbedtls_mpi_bitlen( &ctx->D ) <= ( ( nbits + 1 ) / 2 ) ) // (FIPS 186-4 §B.3.1 criterion 3(a)) - continue; - - break; } - while( 1 ); + while( mbedtls_mpi_cmp_int( &G, 1 ) != 0 ); /* Restore P,Q */ MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &ctx->P, &ctx->P, 1 ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &ctx->Q, &ctx->Q, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->N, &ctx->P, &ctx->Q ) ); - ctx->len = mbedtls_mpi_size( &ctx->N ); -#if !defined(MBEDTLS_RSA_NO_CRT) /* + * D = E^-1 mod ((P-1)*(Q-1)) * DP = D mod (P - 1) * DQ = D mod (Q - 1) * QP = Q^-1 mod P */ + + MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->D, &ctx->E, &H ) ); + +#if !defined(MBEDTLS_RSA_NO_CRT) MBEDTLS_MPI_CHK( mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D, &ctx->DP, &ctx->DQ, &ctx->QP ) ); #endif /* MBEDTLS_RSA_NO_CRT */ @@ -629,7 +572,6 @@ cleanup: mbedtls_mpi_free( &H ); mbedtls_mpi_free( &G ); - mbedtls_mpi_free( &L ); if( ret != 0 ) { @@ -647,8 +589,6 @@ cleanup: */ int mbedtls_rsa_check_pubkey( const mbedtls_rsa_context *ctx ) { - RSA_VALIDATE_RET( ctx != NULL ); - if( rsa_check_context( ctx, 0 /* public */, 0 /* no blinding */ ) != 0 ) return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); @@ -672,8 +612,6 @@ int mbedtls_rsa_check_pubkey( const mbedtls_rsa_context *ctx ) */ int mbedtls_rsa_check_privkey( const mbedtls_rsa_context *ctx ) { - RSA_VALIDATE_RET( ctx != NULL ); - if( mbedtls_rsa_check_pubkey( ctx ) != 0 || rsa_check_context( ctx, 1 /* private */, 1 /* blinding */ ) != 0 ) { @@ -703,9 +641,6 @@ int mbedtls_rsa_check_privkey( const mbedtls_rsa_context *ctx ) int mbedtls_rsa_check_pub_priv( const mbedtls_rsa_context *pub, const mbedtls_rsa_context *prv ) { - RSA_VALIDATE_RET( pub != NULL ); - RSA_VALIDATE_RET( prv != NULL ); - if( mbedtls_rsa_check_pubkey( pub ) != 0 || mbedtls_rsa_check_privkey( prv ) != 0 ) { @@ -731,9 +666,6 @@ int mbedtls_rsa_public( mbedtls_rsa_context *ctx, int ret; size_t olen; mbedtls_mpi T; - RSA_VALIDATE_RET( ctx != NULL ); - RSA_VALIDATE_RET( input != NULL ); - RSA_VALIDATE_RET( output != NULL ); if( rsa_check_context( ctx, 0 /* public */, 0 /* no blinding */ ) ) return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); @@ -876,10 +808,6 @@ int mbedtls_rsa_private( mbedtls_rsa_context *ctx, * checked result; should be the same in the end. */ mbedtls_mpi I, C; - RSA_VALIDATE_RET( ctx != NULL ); - RSA_VALIDATE_RET( input != NULL ); - RSA_VALIDATE_RET( output != NULL ); - if( rsa_check_context( ctx, 1 /* private key checks */, f_rng != NULL /* blinding y/n */ ) != 0 ) { @@ -1082,10 +1010,10 @@ static int mgf_mask( unsigned char *dst, size_t dlen, unsigned char *src, size_t i, use_len; int ret = 0; - mbedtls_platform_memset( mask, 0, MBEDTLS_MD_MAX_SIZE ); - mbedtls_platform_memset( counter, 0, 4 ); + memset( mask, 0, MBEDTLS_MD_MAX_SIZE ); + memset( counter, 0, 4 ); - hlen = mbedtls_md_get_size( mbedtls_md_get_handle( md_ctx ) ); + hlen = mbedtls_md_get_size( md_ctx->md_info ); /* Generate and apply dbMask */ p = dst; @@ -1114,7 +1042,7 @@ static int mgf_mask( unsigned char *dst, size_t dlen, unsigned char *src, } exit: - mbedtls_platform_zeroize( mask, sizeof( mask ) ); + mbedtls_zeroize( mask, sizeof( mask ) ); return( ret ); } @@ -1137,16 +1065,9 @@ int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx, int ret; unsigned char *p = output; unsigned int hlen; - mbedtls_md_handle_t md_info; + const mbedtls_md_info_t *md_info; mbedtls_md_context_t md_ctx; - RSA_VALIDATE_RET( ctx != NULL ); - RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE || - mode == MBEDTLS_RSA_PUBLIC ); - RSA_VALIDATE_RET( output != NULL ); - RSA_VALIDATE_RET( input != NULL ); - RSA_VALIDATE_RET( label_len == 0 || label != NULL ); - if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 ) return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); @@ -1154,7 +1075,7 @@ int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx, return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id ); - if( md_info == MBEDTLS_MD_INVALID_HANDLE ) + if( md_info == NULL ) return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); olen = ctx->len; @@ -1164,7 +1085,7 @@ int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx, if( ilen + 2 * hlen + 2 < ilen || olen < ilen + 2 * hlen + 2 ) return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - mbedtls_platform_memset( output, 0, olen ); + memset( output, 0, olen ); *p++ = 0; @@ -1180,7 +1101,7 @@ int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx, p += hlen; p += olen - 2 * hlen - 2 - ilen; *p++ = 1; - mbedtls_platform_memcpy( p, input, ilen ); + memcpy( p, input, ilen ); mbedtls_md_init( &md_ctx ); if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 ) @@ -1223,15 +1144,13 @@ int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx, int ret; unsigned char *p = output; - RSA_VALIDATE_RET( ctx != NULL ); - RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE || - mode == MBEDTLS_RSA_PUBLIC ); - RSA_VALIDATE_RET( output != NULL ); - RSA_VALIDATE_RET( input != NULL ); - if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 ) return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + // We don't check p_rng because it won't be dereferenced here + if( f_rng == NULL || input == NULL || output == NULL ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + olen = ctx->len; /* first comparison checks for overflow */ @@ -1243,9 +1162,6 @@ int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx, *p++ = 0; if( mode == MBEDTLS_RSA_PUBLIC ) { - if( f_rng == NULL ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - *p++ = MBEDTLS_RSA_CRYPT; while( nb_pad-- > 0 ) @@ -1272,7 +1188,7 @@ int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx, } *p++ = 0; - mbedtls_platform_memcpy( p, input, ilen ); + memcpy( p, input, ilen ); return( ( mode == MBEDTLS_RSA_PUBLIC ) ? mbedtls_rsa_public( ctx, output, output ) @@ -1290,12 +1206,6 @@ int mbedtls_rsa_pkcs1_encrypt( mbedtls_rsa_context *ctx, const unsigned char *input, unsigned char *output ) { - RSA_VALIDATE_RET( ctx != NULL ); - RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE || - mode == MBEDTLS_RSA_PUBLIC ); - RSA_VALIDATE_RET( output != NULL ); - RSA_VALIDATE_RET( input != NULL ); - switch( ctx->padding ) { #if defined(MBEDTLS_PKCS1_V15) @@ -1335,17 +1245,9 @@ int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx, unsigned char buf[MBEDTLS_MPI_MAX_SIZE]; unsigned char lhash[MBEDTLS_MD_MAX_SIZE]; unsigned int hlen; - mbedtls_md_handle_t md_info; + const mbedtls_md_info_t *md_info; mbedtls_md_context_t md_ctx; - RSA_VALIDATE_RET( ctx != NULL ); - RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE || - mode == MBEDTLS_RSA_PUBLIC ); - RSA_VALIDATE_RET( output_max_len == 0 || output != NULL ); - RSA_VALIDATE_RET( label_len == 0 || label != NULL ); - RSA_VALIDATE_RET( input != NULL ); - RSA_VALIDATE_RET( olen != NULL ); - /* * Parameters sanity checks */ @@ -1358,7 +1260,7 @@ int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx, return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id ); - if( md_info == MBEDTLS_MD_INVALID_HANDLE ) + if( md_info == NULL ) return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); hlen = mbedtls_md_get_size( md_info ); @@ -1450,12 +1352,12 @@ int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx, } *olen = ilen - (p - buf); - mbedtls_platform_memcpy( output, p, *olen ); + memcpy( output, p, *olen ); ret = 0; cleanup: - mbedtls_platform_zeroize( buf, sizeof( buf ) ); - mbedtls_platform_zeroize( lhash, sizeof( lhash ) ); + mbedtls_zeroize( buf, sizeof( buf ) ); + mbedtls_zeroize( lhash, sizeof( lhash ) ); return( ret ); } @@ -1519,7 +1421,7 @@ static unsigned if_int( unsigned cond, unsigned if1, unsigned if0 ) * `mem_move_to_left(start, total, offset)` is functionally equivalent to * ``` * memmove(start, start + offset, total - offset); - * mbedtls_platform_memset(start + offset, 0, total - offset); + * memset(start + offset, 0, total - offset); * ``` * but it strives to use a memory access pattern (and thus total timing) * that does not depend on \p offset. This timing independence comes at @@ -1565,7 +1467,11 @@ int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx, size_t output_max_len ) { int ret; - size_t ilen, i, plaintext_max_size; + size_t ilen = ctx->len; + size_t i; + size_t plaintext_max_size = ( output_max_len > ilen - 11 ? + ilen - 11 : + output_max_len ); unsigned char buf[MBEDTLS_MPI_MAX_SIZE]; /* The following variables take sensitive values: their value must * not leak into the observable behavior of the function other than @@ -1583,18 +1489,6 @@ int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx, size_t plaintext_size = 0; unsigned output_too_large; - RSA_VALIDATE_RET( ctx != NULL ); - RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE || - mode == MBEDTLS_RSA_PUBLIC ); - RSA_VALIDATE_RET( output_max_len == 0 || output != NULL ); - RSA_VALIDATE_RET( input != NULL ); - RSA_VALIDATE_RET( olen != NULL ); - - ilen = ctx->len; - plaintext_max_size = ( output_max_len > ilen - 11 ? - ilen - 11 : - output_max_len ); - if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 ) return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); @@ -1704,7 +1598,7 @@ int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx, /* Finally copy the decrypted plaintext plus trailing zeros * into the output buffer. */ - mbedtls_platform_memcpy( output, buf + ilen - plaintext_max_size, plaintext_max_size ); + memcpy( output, buf + ilen - plaintext_max_size, plaintext_max_size ); /* Report the amount of data we copied to the output buffer. In case * of errors (bad padding or output too large), the value of *olen @@ -1713,7 +1607,7 @@ int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx, *olen = plaintext_size; cleanup: - mbedtls_platform_zeroize( buf, sizeof( buf ) ); + mbedtls_zeroize( buf, sizeof( buf ) ); return( ret ); } @@ -1730,13 +1624,6 @@ int mbedtls_rsa_pkcs1_decrypt( mbedtls_rsa_context *ctx, unsigned char *output, size_t output_max_len) { - RSA_VALIDATE_RET( ctx != NULL ); - RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE || - mode == MBEDTLS_RSA_PUBLIC ); - RSA_VALIDATE_RET( output_max_len == 0 || output != NULL ); - RSA_VALIDATE_RET( input != NULL ); - RSA_VALIDATE_RET( olen != NULL ); - switch( ctx->padding ) { #if defined(MBEDTLS_PKCS1_V15) @@ -1773,18 +1660,11 @@ int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx, size_t olen; unsigned char *p = sig; unsigned char salt[MBEDTLS_MD_MAX_SIZE]; - size_t slen, min_slen, hlen, offset = 0; + unsigned int slen, hlen, offset = 0; int ret; size_t msb; - mbedtls_md_handle_t md_info; + const mbedtls_md_info_t *md_info; mbedtls_md_context_t md_ctx; - RSA_VALIDATE_RET( ctx != NULL ); - RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE || - mode == MBEDTLS_RSA_PUBLIC ); - RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && - hashlen == 0 ) || - hash != NULL ); - RSA_VALIDATE_RET( sig != NULL ); if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 ) return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); @@ -1798,33 +1678,23 @@ int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx, { /* Gather length of hash to sign */ md_info = mbedtls_md_info_from_type( md_alg ); - if( md_info == MBEDTLS_MD_INVALID_HANDLE ) + if( md_info == NULL ) return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); hashlen = mbedtls_md_get_size( md_info ); } md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id ); - if( md_info == MBEDTLS_MD_INVALID_HANDLE ) + if( md_info == NULL ) return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); hlen = mbedtls_md_get_size( md_info ); + slen = hlen; - /* Calculate the largest possible salt length. Normally this is the hash - * length, which is the maximum length the salt can have. If there is not - * enough room, use the maximum salt length that fits. The constraint is - * that the hash length plus the salt length plus 2 bytes must be at most - * the key length. This complies with FIPS 186-4 §5.5 (e) and RFC 8017 - * (PKCS#1 v2.2) §9.1.1 step 3. */ - min_slen = hlen - 2; - if( olen < hlen + min_slen + 2 ) + if( olen < hlen + slen + 2 ) return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - else if( olen >= hlen + hlen + 2 ) - slen = hlen; - else - slen = olen - hlen - 2; - mbedtls_platform_memset( sig, 0, olen ); + memset( sig, 0, olen ); /* Generate salt of length slen */ if( ( ret = f_rng( p_rng, salt, slen ) ) != 0 ) @@ -1832,9 +1702,9 @@ int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx, /* Note: EMSA-PSS encoding is over the length of N - 1 bits */ msb = mbedtls_mpi_bitlen( &ctx->N ) - 1; - p += olen - hlen - slen - 2; + p += olen - hlen * 2 - 2; *p++ = 0x01; - mbedtls_platform_memcpy( p, salt, slen ); + memcpy( p, salt, slen ); p += slen; mbedtls_md_init( &md_ctx ); @@ -1868,7 +1738,7 @@ int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx, p += hlen; *p++ = 0xBC; - mbedtls_platform_zeroize( salt, sizeof( salt ) ); + mbedtls_zeroize( salt, sizeof( salt ) ); exit: mbedtls_md_free( &md_ctx ); @@ -1919,8 +1789,8 @@ static int rsa_rsassa_pkcs1_v15_encode( mbedtls_md_type_t md_alg, /* Are we signing hashed or raw data? */ if( md_alg != MBEDTLS_MD_NONE ) { - mbedtls_md_handle_t md_info = mbedtls_md_info_from_type( md_alg ); - if( md_info == MBEDTLS_MD_INVALID_HANDLE ) + const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg ); + if( md_info == NULL ) return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); if( mbedtls_oid_get_oid_by_md( md_alg, &oid, &oid_size ) != 0 ) @@ -1967,18 +1837,15 @@ static int rsa_rsassa_pkcs1_v15_encode( mbedtls_md_type_t md_alg, /* Write signature header and padding */ *p++ = 0; *p++ = MBEDTLS_RSA_SIGN; - mbedtls_platform_memset( p, 0xFF, nb_pad ); + memset( p, 0xFF, nb_pad ); p += nb_pad; *p++ = 0; /* Are we signing raw data? */ if( md_alg == MBEDTLS_MD_NONE ) { - if( mbedtls_platform_memcpy( p, hash, hashlen ) == p ) - { - return( 0 ); - } - return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); + memcpy( p, hash, hashlen ); + return( 0 ); } /* Signing hashed data, add corresponding ASN.1 structure @@ -2000,23 +1867,20 @@ static int rsa_rsassa_pkcs1_v15_encode( mbedtls_md_type_t md_alg, *p++ = (unsigned char)( 0x04 + oid_size ); *p++ = MBEDTLS_ASN1_OID; *p++ = (unsigned char) oid_size; - mbedtls_platform_memcpy( p, oid, oid_size ); + memcpy( p, oid, oid_size ); p += oid_size; *p++ = MBEDTLS_ASN1_NULL; *p++ = 0x00; *p++ = MBEDTLS_ASN1_OCTET_STRING; *p++ = (unsigned char) hashlen; - if( mbedtls_platform_memcpy( p, hash, hashlen ) != p ) - { - return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); - } + memcpy( p, hash, hashlen ); p += hashlen; /* Just a sanity-check, should be automatic * after the initial bounds check. */ if( p != dst + dst_len ) { - mbedtls_platform_zeroize( dst, dst_len ); + mbedtls_zeroize( dst, dst_len ); return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); } @@ -2035,17 +1899,9 @@ int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx, const unsigned char *hash, unsigned char *sig ) { - int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; + int ret; unsigned char *sig_try = NULL, *verif = NULL; - RSA_VALIDATE_RET( ctx != NULL ); - RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE || - mode == MBEDTLS_RSA_PUBLIC ); - RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && - hashlen == 0 ) || - hash != NULL ); - RSA_VALIDATE_RET( sig != NULL ); - if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 ) return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); @@ -2093,10 +1949,7 @@ int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx, goto cleanup; } - if( mbedtls_platform_memcpy( sig, sig_try, ctx->len ) != sig ) - { - ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; - } + memcpy( sig, sig_try, ctx->len ); cleanup: mbedtls_free( sig_try ); @@ -2118,14 +1971,6 @@ int mbedtls_rsa_pkcs1_sign( mbedtls_rsa_context *ctx, const unsigned char *hash, unsigned char *sig ) { - RSA_VALIDATE_RET( ctx != NULL ); - RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE || - mode == MBEDTLS_RSA_PUBLIC ); - RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && - hashlen == 0 ) || - hash != NULL ); - RSA_VALIDATE_RET( sig != NULL ); - switch( ctx->padding ) { #if defined(MBEDTLS_PKCS1_V15) @@ -2168,18 +2013,10 @@ int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx, unsigned char zeros[8]; unsigned int hlen; size_t observed_salt_len, msb; - mbedtls_md_handle_t md_info; + const mbedtls_md_info_t *md_info; mbedtls_md_context_t md_ctx; unsigned char buf[MBEDTLS_MPI_MAX_SIZE]; - RSA_VALIDATE_RET( ctx != NULL ); - RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE || - mode == MBEDTLS_RSA_PUBLIC ); - RSA_VALIDATE_RET( sig != NULL ); - RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && - hashlen == 0 ) || - hash != NULL ); - if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 ) return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); @@ -2204,19 +2041,19 @@ int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx, { /* Gather length of hash to sign */ md_info = mbedtls_md_info_from_type( md_alg ); - if( md_info == MBEDTLS_MD_INVALID_HANDLE ) + if( md_info == NULL ) return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); hashlen = mbedtls_md_get_size( md_info ); } md_info = mbedtls_md_info_from_type( mgf1_hash_id ); - if( md_info == MBEDTLS_MD_INVALID_HANDLE ) + if( md_info == NULL ) return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); hlen = mbedtls_md_get_size( md_info ); - mbedtls_platform_memset( zeros, 0, 8 ); + memset( zeros, 0, 8 ); /* * Note: EMSA-PSS verification is over the length of N - 1 bits @@ -2284,7 +2121,7 @@ int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx, if ( ret != 0 ) goto exit; - if( mbedtls_platform_memequal( hash_start, result, hlen ) != 0 ) + if( memcmp( hash_start, result, hlen ) != 0 ) { ret = MBEDTLS_ERR_RSA_VERIFY_FAILED; goto exit; @@ -2308,16 +2145,7 @@ int mbedtls_rsa_rsassa_pss_verify( mbedtls_rsa_context *ctx, const unsigned char *hash, const unsigned char *sig ) { - mbedtls_md_type_t mgf1_hash_id; - RSA_VALIDATE_RET( ctx != NULL ); - RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE || - mode == MBEDTLS_RSA_PUBLIC ); - RSA_VALIDATE_RET( sig != NULL ); - RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && - hashlen == 0 ) || - hash != NULL ); - - mgf1_hash_id = ( ctx->hash_id != MBEDTLS_MD_NONE ) + mbedtls_md_type_t mgf1_hash_id = ( ctx->hash_id != MBEDTLS_MD_NONE ) ? (mbedtls_md_type_t) ctx->hash_id : md_alg; @@ -2343,19 +2171,9 @@ int mbedtls_rsa_rsassa_pkcs1_v15_verify( mbedtls_rsa_context *ctx, const unsigned char *sig ) { int ret = 0; - size_t sig_len; + const size_t sig_len = ctx->len; unsigned char *encoded = NULL, *encoded_expected = NULL; - RSA_VALIDATE_RET( ctx != NULL ); - RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE || - mode == MBEDTLS_RSA_PUBLIC ); - RSA_VALIDATE_RET( sig != NULL ); - RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && - hashlen == 0 ) || - hash != NULL ); - - sig_len = ctx->len; - if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 ) return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); @@ -2399,13 +2217,13 @@ cleanup: if( encoded != NULL ) { - mbedtls_platform_zeroize( encoded, sig_len ); + mbedtls_zeroize( encoded, sig_len ); mbedtls_free( encoded ); } if( encoded_expected != NULL ) { - mbedtls_platform_zeroize( encoded_expected, sig_len ); + mbedtls_zeroize( encoded_expected, sig_len ); mbedtls_free( encoded_expected ); } @@ -2425,14 +2243,6 @@ int mbedtls_rsa_pkcs1_verify( mbedtls_rsa_context *ctx, const unsigned char *hash, const unsigned char *sig ) { - RSA_VALIDATE_RET( ctx != NULL ); - RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE || - mode == MBEDTLS_RSA_PUBLIC ); - RSA_VALIDATE_RET( sig != NULL ); - RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && - hashlen == 0 ) || - hash != NULL ); - switch( ctx->padding ) { #if defined(MBEDTLS_PKCS1_V15) @@ -2458,8 +2268,6 @@ int mbedtls_rsa_pkcs1_verify( mbedtls_rsa_context *ctx, int mbedtls_rsa_copy( mbedtls_rsa_context *dst, const mbedtls_rsa_context *src ) { int ret; - RSA_VALIDATE_RET( dst != NULL ); - RSA_VALIDATE_RET( src != NULL ); dst->ver = src->ver; dst->len = src->len; @@ -2499,23 +2307,14 @@ cleanup: */ void mbedtls_rsa_free( mbedtls_rsa_context *ctx ) { - if( ctx == NULL ) - return; - - mbedtls_mpi_free( &ctx->Vi ); - mbedtls_mpi_free( &ctx->Vf ); - mbedtls_mpi_free( &ctx->RN ); - mbedtls_mpi_free( &ctx->D ); - mbedtls_mpi_free( &ctx->Q ); - mbedtls_mpi_free( &ctx->P ); - mbedtls_mpi_free( &ctx->E ); - mbedtls_mpi_free( &ctx->N ); + mbedtls_mpi_free( &ctx->Vi ); mbedtls_mpi_free( &ctx->Vf ); + mbedtls_mpi_free( &ctx->RN ); mbedtls_mpi_free( &ctx->D ); + mbedtls_mpi_free( &ctx->Q ); mbedtls_mpi_free( &ctx->P ); + mbedtls_mpi_free( &ctx->E ); mbedtls_mpi_free( &ctx->N ); #if !defined(MBEDTLS_RSA_NO_CRT) - mbedtls_mpi_free( &ctx->RQ ); - mbedtls_mpi_free( &ctx->RP ); - mbedtls_mpi_free( &ctx->QP ); - mbedtls_mpi_free( &ctx->DQ ); + mbedtls_mpi_free( &ctx->RQ ); mbedtls_mpi_free( &ctx->RP ); + mbedtls_mpi_free( &ctx->QP ); mbedtls_mpi_free( &ctx->DQ ); mbedtls_mpi_free( &ctx->DP ); #endif /* MBEDTLS_RSA_NO_CRT */ diff --git a/APP_Framework/Framework/security/mbedtls/rsa.h b/APP_Framework/Framework/security/mbedtls/rsa.h index 35bacd876..5548f3c12 100644 --- a/APP_Framework/Framework/security/mbedtls/rsa.h +++ b/APP_Framework/Framework/security/mbedtls/rsa.h @@ -1,12 +1,11 @@ /** * \file rsa.h * - * \brief This file provides an API for the RSA public-key cryptosystem. + * \brief The RSA public-key cryptosystem. * - * The RSA public-key cryptosystem is defined in Public-Key - * Cryptography Standards (PKCS) #1 v1.5: RSA Encryption - * and Public-Key Cryptography Standards (PKCS) #1 v2.1: - * RSA Cryptography Specifications. + * For more information, see Public-Key Cryptography Standards (PKCS) + * #1 v1.5: RSA Encryption and Public-Key Cryptography Standards + * (PKCS) #1 v2.1: RSA Cryptography Specifications. * */ /* @@ -55,12 +54,7 @@ #define MBEDTLS_ERR_RSA_VERIFY_FAILED -0x4380 /**< The PKCS#1 verification failed. */ #define MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE -0x4400 /**< The output buffer for decryption is not large enough. */ #define MBEDTLS_ERR_RSA_RNG_FAILED -0x4480 /**< The random generator failed to generate non-zeros. */ - -/* MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION is deprecated and should not be used. - */ #define MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION -0x4500 /**< The implementation does not offer the requested operation, for example, because of security violations or lack of functionality. */ - -/* MBEDTLS_ERR_RSA_HW_ACCEL_FAILED is deprecated and should not be used. */ #define MBEDTLS_ERR_RSA_HW_ACCEL_FAILED -0x4580 /**< RSA hardware accelerator failed. */ /* @@ -69,8 +63,8 @@ #define MBEDTLS_RSA_PUBLIC 0 /**< Request private key operation. */ #define MBEDTLS_RSA_PRIVATE 1 /**< Request public key operation. */ -#define MBEDTLS_RSA_PKCS_V15 0 /**< Use PKCS#1 v1.5 encoding. */ -#define MBEDTLS_RSA_PKCS_V21 1 /**< Use PKCS#1 v2.1 encoding. */ +#define MBEDTLS_RSA_PKCS_V15 0 /**< Use PKCS-1 v1.5 encoding. */ +#define MBEDTLS_RSA_PKCS_V21 1 /**< Use PKCS-1 v2.1 encoding. */ #define MBEDTLS_RSA_SIGN 1 /**< Identifier for RSA signature operations. */ #define MBEDTLS_RSA_CRYPT 2 /**< Identifier for RSA encryption and decryption operations. */ @@ -82,14 +76,14 @@ * eg for alternative (PKCS#11) RSA implemenations in the PK layers. */ -#ifdef __cplusplus -extern "C" { -#endif - #if !defined(MBEDTLS_RSA_ALT) // Regular implementation // +#ifdef __cplusplus +extern "C" { +#endif + /** * \brief The RSA context structure. * @@ -97,29 +91,29 @@ extern "C" { * is deprecated. All manipulation should instead be done through * the public interface functions. */ -typedef struct mbedtls_rsa_context +typedef struct { int ver; /*!< Always 0.*/ size_t len; /*!< The size of \p N in Bytes. */ - mbedtls_mpi N; /*!< The public modulus. */ - mbedtls_mpi E; /*!< The public exponent. */ + mbedtls_mpi N; /*!< The public modulus. */ + mbedtls_mpi E; /*!< The public exponent. */ - mbedtls_mpi D; /*!< The private exponent. */ - mbedtls_mpi P; /*!< The first prime factor. */ - mbedtls_mpi Q; /*!< The second prime factor. */ + mbedtls_mpi D; /*!< The private exponent. */ + mbedtls_mpi P; /*!< The first prime factor. */ + mbedtls_mpi Q; /*!< The second prime factor. */ - mbedtls_mpi DP; /*!< D % (P - 1). */ - mbedtls_mpi DQ; /*!< D % (Q - 1). */ - mbedtls_mpi QP; /*!< 1 / (Q % P). */ + mbedtls_mpi DP; /*!< \p D % (P - 1) */ + mbedtls_mpi DQ; /*!< \p D % (Q - 1) */ + mbedtls_mpi QP; /*!< 1 / (Q % P) */ - mbedtls_mpi RN; /*!< cached R^2 mod N. */ + mbedtls_mpi RN; /*!< cached R^2 mod \p N */ - mbedtls_mpi RP; /*!< cached R^2 mod P. */ - mbedtls_mpi RQ; /*!< cached R^2 mod Q. */ + mbedtls_mpi RP; /*!< cached R^2 mod \p P */ + mbedtls_mpi RQ; /*!< cached R^2 mod \p Q */ - mbedtls_mpi Vi; /*!< The cached blinding value. */ - mbedtls_mpi Vf; /*!< The cached un-blinding value. */ + mbedtls_mpi Vi; /*!< The cached blinding value. */ + mbedtls_mpi Vf; /*!< The cached un-blinding value. */ int padding; /*!< Selects padding mode: #MBEDTLS_RSA_PKCS_V15 for 1.5 padding and @@ -134,45 +128,47 @@ typedef struct mbedtls_rsa_context } mbedtls_rsa_context; -#else /* MBEDTLS_RSA_ALT */ -#include "rsa_alt.h" -#endif /* MBEDTLS_RSA_ALT */ - /** * \brief This function initializes an RSA context. * * \note Set padding to #MBEDTLS_RSA_PKCS_V21 for the RSAES-OAEP * encryption scheme and the RSASSA-PSS signature scheme. * + * \param ctx The RSA context to initialize. + * \param padding Selects padding mode: #MBEDTLS_RSA_PKCS_V15 or + * #MBEDTLS_RSA_PKCS_V21. + * \param hash_id The hash identifier of #mbedtls_md_type_t type, if + * \p padding is #MBEDTLS_RSA_PKCS_V21. + * * \note The \p hash_id parameter is ignored when using * #MBEDTLS_RSA_PKCS_V15 padding. * * \note The choice of padding mode is strictly enforced for private key * operations, since there might be security concerns in * mixing padding modes. For public key operations it is - * a default value, which can be overridden by calling specific + * a default value, which can be overriden by calling specific * \c rsa_rsaes_xxx or \c rsa_rsassa_xxx functions. * * \note The hash selected in \p hash_id is always used for OEAP * encryption. For PSS signatures, it is always used for - * making signatures, but can be overridden for verifying them. - * If set to #MBEDTLS_MD_NONE, it is always overridden. - * - * \param ctx The RSA context to initialize. This must not be \c NULL. - * \param padding The padding mode to use. This must be either - * #MBEDTLS_RSA_PKCS_V15 or #MBEDTLS_RSA_PKCS_V21. - * \param hash_id The hash identifier of ::mbedtls_md_type_t type, if - * \p padding is #MBEDTLS_RSA_PKCS_V21. It is unused - * otherwise. + * making signatures, but can be overriden for verifying them. + * If set to #MBEDTLS_MD_NONE, it is always overriden. */ void mbedtls_rsa_init( mbedtls_rsa_context *ctx, int padding, - int hash_id ); + int hash_id); /** * \brief This function imports a set of core parameters into an * RSA context. * + * \param ctx The initialized RSA context to store the parameters in. + * \param N The RSA modulus, or NULL. + * \param P The first prime factor of \p N, or NULL. + * \param Q The second prime factor of \p N, or NULL. + * \param D The private exponent, or NULL. + * \param E The public exponent, or NULL. + * * \note This function can be called multiple times for successive * imports, if the parameters are not simultaneously present. * @@ -188,15 +184,7 @@ void mbedtls_rsa_init( mbedtls_rsa_context *ctx, * \note The imported parameters are copied and need not be preserved * for the lifetime of the RSA context being set up. * - * \param ctx The initialized RSA context to store the parameters in. - * \param N The RSA modulus. This may be \c NULL. - * \param P The first prime factor of \p N. This may be \c NULL. - * \param Q The second prime factor of \p N. This may be \c NULL. - * \param D The private exponent. This may be \c NULL. - * \param E The public exponent. This may be \c NULL. - * - * \return \c 0 on success. - * \return A non-zero error code on failure. + * \return \c 0 on success, or a non-zero error code on failure. */ int mbedtls_rsa_import( mbedtls_rsa_context *ctx, const mbedtls_mpi *N, @@ -207,6 +195,18 @@ int mbedtls_rsa_import( mbedtls_rsa_context *ctx, * \brief This function imports core RSA parameters, in raw big-endian * binary format, into an RSA context. * + * \param ctx The initialized RSA context to store the parameters in. + * \param N The RSA modulus, or NULL. + * \param N_len The Byte length of \p N, ignored if \p N == NULL. + * \param P The first prime factor of \p N, or NULL. + * \param P_len The Byte length of \p P, ignored if \p P == NULL. + * \param Q The second prime factor of \p N, or NULL. + * \param Q_len The Byte length of \p Q, ignored if \p Q == NULL. + * \param D The private exponent, or NULL. + * \param D_len The Byte length of \p D, ignored if \p D == NULL. + * \param E The public exponent, or NULL. + * \param E_len The Byte length of \p E, ignored if \p E == NULL. + * * \note This function can be called multiple times for successive * imports, if the parameters are not simultaneously present. * @@ -222,20 +222,7 @@ int mbedtls_rsa_import( mbedtls_rsa_context *ctx, * \note The imported parameters are copied and need not be preserved * for the lifetime of the RSA context being set up. * - * \param ctx The initialized RSA context to store the parameters in. - * \param N The RSA modulus. This may be \c NULL. - * \param N_len The Byte length of \p N; it is ignored if \p N == NULL. - * \param P The first prime factor of \p N. This may be \c NULL. - * \param P_len The Byte length of \p P; it ns ignored if \p P == NULL. - * \param Q The second prime factor of \p N. This may be \c NULL. - * \param Q_len The Byte length of \p Q; it is ignored if \p Q == NULL. - * \param D The private exponent. This may be \c NULL. - * \param D_len The Byte length of \p D; it is ignored if \p D == NULL. - * \param E The public exponent. This may be \c NULL. - * \param E_len The Byte length of \p E; it is ignored if \p E == NULL. - * - * \return \c 0 on success. - * \return A non-zero error code on failure. + * \return \c 0 on success, or a non-zero error code on failure. */ int mbedtls_rsa_import_raw( mbedtls_rsa_context *ctx, unsigned char const *N, size_t N_len, @@ -263,18 +250,17 @@ int mbedtls_rsa_import_raw( mbedtls_rsa_context *ctx, * the RSA context can be used for RSA operations without * the risk of failure or crash. * + * \param ctx The initialized RSA context holding imported parameters. + * + * \return \c 0 on success, or #MBEDTLS_ERR_RSA_BAD_INPUT_DATA if the + * attempted derivations failed. + * * \warning This function need not perform consistency checks * for the imported parameters. In particular, parameters that * are not needed by the implementation might be silently * discarded and left unchecked. To check the consistency * of the key material, see mbedtls_rsa_check_privkey(). * - * \param ctx The initialized RSA context holding imported parameters. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_RSA_BAD_INPUT_DATA if the attempted derivations - * failed. - * */ int mbedtls_rsa_complete( mbedtls_rsa_context *ctx ); @@ -287,7 +273,7 @@ int mbedtls_rsa_complete( mbedtls_rsa_context *ctx ); * zero Bytes. * * Possible reasons for returning - * #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED:
      + * #MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION:
        *
      • An alternative RSA implementation is in use, which * stores the key externally, and either cannot or should * not export it into RAM.
      • @@ -300,22 +286,17 @@ int mbedtls_rsa_complete( mbedtls_rsa_context *ctx ); * the RSA context stays intact and remains usable. * * \param ctx The initialized RSA context. - * \param N The MPI to hold the RSA modulus. - * This may be \c NULL if this field need not be exported. - * \param P The MPI to hold the first prime factor of \p N. - * This may be \c NULL if this field need not be exported. - * \param Q The MPI to hold the second prime factor of \p N. - * This may be \c NULL if this field need not be exported. - * \param D The MPI to hold the private exponent. - * This may be \c NULL if this field need not be exported. - * \param E The MPI to hold the public exponent. - * This may be \c NULL if this field need not be exported. + * \param N The MPI to hold the RSA modulus, or NULL. + * \param P The MPI to hold the first prime factor of \p N, or NULL. + * \param Q The MPI to hold the second prime factor of \p N, or NULL. + * \param D The MPI to hold the private exponent, or NULL. + * \param E The MPI to hold the public exponent, or NULL. * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED if exporting the + * \return \c 0 on success, + * #MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION if exporting the * requested parameters cannot be done due to missing - * functionality or because of security policies. - * \return A non-zero return code on any other failure. + * functionality or because of security policies, + * or a non-zero return code on any other failure. * */ int mbedtls_rsa_export( const mbedtls_rsa_context *ctx, @@ -332,7 +313,7 @@ int mbedtls_rsa_export( const mbedtls_rsa_context *ctx, * zero Bytes. * * Possible reasons for returning - * #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED:
          + * #MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION:
            *
          • An alternative RSA implementation is in use, which * stores the key externally, and either cannot or should * not export it into RAM.
          • @@ -343,31 +324,28 @@ int mbedtls_rsa_export( const mbedtls_rsa_context *ctx, * If the function fails due to an unsupported operation, * the RSA context stays intact and remains usable. * - * \note The length parameters are ignored if the corresponding - * buffer pointers are NULL. - * * \param ctx The initialized RSA context. - * \param N The Byte array to store the RSA modulus, - * or \c NULL if this field need not be exported. + * \param N The Byte array to store the RSA modulus, or NULL. * \param N_len The size of the buffer for the modulus. - * \param P The Byte array to hold the first prime factor of \p N, - * or \c NULL if this field need not be exported. + * \param P The Byte array to hold the first prime factor of \p N, or + * NULL. * \param P_len The size of the buffer for the first prime factor. - * \param Q The Byte array to hold the second prime factor of \p N, - * or \c NULL if this field need not be exported. + * \param Q The Byte array to hold the second prime factor of \p N, or + NULL. * \param Q_len The size of the buffer for the second prime factor. - * \param D The Byte array to hold the private exponent, - * or \c NULL if this field need not be exported. + * \param D The Byte array to hold the private exponent, or NULL. * \param D_len The size of the buffer for the private exponent. - * \param E The Byte array to hold the public exponent, - * or \c NULL if this field need not be exported. + * \param E The Byte array to hold the public exponent, or NULL. * \param E_len The size of the buffer for the public exponent. * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED if exporting the + * \note The length fields are ignored if the corresponding + * buffer pointers are NULL. + * + * \return \c 0 on success, + * #MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION if exporting the * requested parameters cannot be done due to missing - * functionality or because of security policies. - * \return A non-zero return code on any other failure. + * functionality or because of security policies, + * or a non-zero return code on any other failure. */ int mbedtls_rsa_export_raw( const mbedtls_rsa_context *ctx, unsigned char *N, size_t N_len, @@ -379,21 +357,17 @@ int mbedtls_rsa_export_raw( const mbedtls_rsa_context *ctx, /** * \brief This function exports CRT parameters of a private RSA key. * + * \param ctx The initialized RSA context. + * \param DP The MPI to hold D modulo P-1, or NULL. + * \param DQ The MPI to hold D modulo Q-1, or NULL. + * \param QP The MPI to hold modular inverse of Q modulo P, or NULL. + * + * \return \c 0 on success, non-zero error code otherwise. + * * \note Alternative RSA implementations not using CRT-parameters * internally can implement this function based on * mbedtls_rsa_deduce_opt(). * - * \param ctx The initialized RSA context. - * \param DP The MPI to hold \c D modulo `P-1`, - * or \c NULL if it need not be exported. - * \param DQ The MPI to hold \c D modulo `Q-1`, - * or \c NULL if it need not be exported. - * \param QP The MPI to hold modular inverse of \c Q modulo \c P, - * or \c NULL if it need not be exported. - * - * \return \c 0 on success. - * \return A non-zero error code on failure. - * */ int mbedtls_rsa_export_crt( const mbedtls_rsa_context *ctx, mbedtls_mpi *DP, mbedtls_mpi *DQ, mbedtls_mpi *QP ); @@ -402,13 +376,13 @@ int mbedtls_rsa_export_crt( const mbedtls_rsa_context *ctx, * \brief This function sets padding for an already initialized RSA * context. See mbedtls_rsa_init() for details. * - * \param ctx The initialized RSA context to be configured. - * \param padding The padding mode to use. This must be either - * #MBEDTLS_RSA_PKCS_V15 or #MBEDTLS_RSA_PKCS_V21. + * \param ctx The RSA context to be set. + * \param padding Selects padding mode: #MBEDTLS_RSA_PKCS_V15 or + * #MBEDTLS_RSA_PKCS_V21. * \param hash_id The #MBEDTLS_RSA_PKCS_V21 hash identifier. */ void mbedtls_rsa_set_padding( mbedtls_rsa_context *ctx, int padding, - int hash_id ); + int hash_id); /** * \brief This function retrieves the length of RSA modulus in Bytes. @@ -423,20 +397,17 @@ size_t mbedtls_rsa_get_len( const mbedtls_rsa_context *ctx ); /** * \brief This function generates an RSA keypair. * + * \param ctx The RSA context used to hold the key. + * \param f_rng The RNG function. + * \param p_rng The RNG parameter. + * \param nbits The size of the public key in bits. + * \param exponent The public exponent. For example, 65537. + * * \note mbedtls_rsa_init() must be called before this function, * to set up the RSA context. * - * \param ctx The initialized RSA context used to hold the key. - * \param f_rng The RNG function to be used for key generation. - * This must not be \c NULL. - * \param p_rng The RNG context to be passed to \p f_rng. - * This may be \c NULL if \p f_rng doesn't need a context. - * \param nbits The size of the public key in bits. - * \param exponent The public exponent to use. For example, \c 65537. - * This must be odd and greater than \c 1. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + * \return \c 0 on success, or an \c MBEDTLS_ERR_RSA_XXX error code + on failure. */ int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx, int (*f_rng)(void *, unsigned char *, size_t), @@ -451,10 +422,10 @@ int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx, * enough information is present to perform an RSA public key * operation using mbedtls_rsa_public(). * - * \param ctx The initialized RSA context to check. + * \param ctx The RSA context to check. * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + * \return \c 0 on success, or an \c MBEDTLS_ERR_RSA_XXX error code + * on failure. * */ int mbedtls_rsa_check_pubkey( const mbedtls_rsa_context *ctx ); @@ -463,6 +434,11 @@ int mbedtls_rsa_check_pubkey( const mbedtls_rsa_context *ctx ); * \brief This function checks if a context contains an RSA private key * and perform basic consistency checks. * + * \param ctx The RSA context to check. + * + * \return \c 0 on success, or an \c MBEDTLS_ERR_RSA_XXX error code on + * failure. + * * \note The consistency checks performed by this function not only * ensure that mbedtls_rsa_private() can be called successfully * on the given context, but that the various parameters are @@ -489,11 +465,6 @@ int mbedtls_rsa_check_pubkey( const mbedtls_rsa_context *ctx ); * user to ensure the trustworthiness of the source of his RSA * parameters, which goes beyond what is effectively checkable * by the library.
          - * - * \param ctx The initialized RSA context to check. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. */ int mbedtls_rsa_check_privkey( const mbedtls_rsa_context *ctx ); @@ -502,11 +473,11 @@ int mbedtls_rsa_check_privkey( const mbedtls_rsa_context *ctx ); * * It checks each of the contexts, and makes sure they match. * - * \param pub The initialized RSA context holding the public key. - * \param prv The initialized RSA context holding the private key. + * \param pub The RSA context holding the public key. + * \param prv The RSA context holding the private key. * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + * \return \c 0 on success, or an \c MBEDTLS_ERR_RSA_XXX error code + * on failure. */ int mbedtls_rsa_check_pub_priv( const mbedtls_rsa_context *pub, const mbedtls_rsa_context *prv ); @@ -514,21 +485,20 @@ int mbedtls_rsa_check_pub_priv( const mbedtls_rsa_context *pub, /** * \brief This function performs an RSA public key operation. * - * \param ctx The initialized RSA context to use. - * \param input The input buffer. This must be a readable buffer - * of length \c ctx->len Bytes. For example, \c 256 Bytes - * for an 2048-bit RSA modulus. - * \param output The output buffer. This must be a writable buffer - * of length \c ctx->len Bytes. For example, \c 256 Bytes - * for an 2048-bit RSA modulus. + * \param ctx The RSA context. + * \param input The input buffer. + * \param output The output buffer. + * + * \return \c 0 on success, or an \c MBEDTLS_ERR_RSA_XXX error code + * on failure. * * \note This function does not handle message padding. * * \note Make sure to set \p input[0] = 0 or ensure that * input is smaller than \p N. * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + * \note The input and output buffers must be large + * enough. For example, 128 Bytes if RSA-1024 is used. */ int mbedtls_rsa_public( mbedtls_rsa_context *ctx, const unsigned char *input, @@ -537,6 +507,18 @@ int mbedtls_rsa_public( mbedtls_rsa_context *ctx, /** * \brief This function performs an RSA private key operation. * + * \param ctx The RSA context. + * \param f_rng The RNG function. Needed for blinding. + * \param p_rng The RNG parameter. + * \param input The input buffer. + * \param output The output buffer. + * + * \return \c 0 on success, or an \c MBEDTLS_ERR_RSA_XXX error code + * on failure. + * + * \note The input and output buffers must be large + * enough. For example, 128 Bytes if RSA-1024 is used. + * * \note Blinding is used if and only if a PRNG is provided. * * \note If blinding is used, both the base of exponentation @@ -548,22 +530,6 @@ int mbedtls_rsa_public( mbedtls_rsa_context *ctx, * Future versions of the library may enforce the presence * of a PRNG. * - * \param ctx The initialized RSA context to use. - * \param f_rng The RNG function, used for blinding. It is discouraged - * and deprecated to pass \c NULL here, in which case - * blinding will be omitted. - * \param p_rng The RNG context to pass to \p f_rng. This may be \c NULL - * if \p f_rng is \c NULL or if \p f_rng doesn't need a context. - * \param input The input buffer. This must be a readable buffer - * of length \c ctx->len Bytes. For example, \c 256 Bytes - * for an 2048-bit RSA modulus. - * \param output The output buffer. This must be a writable buffer - * of length \c ctx->len Bytes. For example, \c 256 Bytes - * for an 2048-bit RSA modulus. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. - * */ int mbedtls_rsa_private( mbedtls_rsa_context *ctx, int (*f_rng)(void *, unsigned char *, size_t), @@ -578,6 +544,16 @@ int mbedtls_rsa_private( mbedtls_rsa_context *ctx, * It is the generic wrapper for performing a PKCS#1 encryption * operation using the \p mode from the context. * + * + * \param ctx The RSA context. + * \param f_rng The RNG function. Needed for padding, PKCS#1 v2.1 + * encoding, and #MBEDTLS_RSA_PRIVATE. + * \param p_rng The RNG parameter. + * \param mode #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE. + * \param ilen The length of the plaintext. + * \param input The buffer holding the data to encrypt. + * \param output The buffer used to hold the ciphertext. + * * \deprecated It is deprecated and discouraged to call this function * in #MBEDTLS_RSA_PRIVATE mode. Future versions of the library * are likely to remove the \p mode argument and have it @@ -585,29 +561,13 @@ int mbedtls_rsa_private( mbedtls_rsa_context *ctx, * * \note Alternative implementations of RSA need not support * mode being set to #MBEDTLS_RSA_PRIVATE and might instead - * return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED. + * return #MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION. * - * \param ctx The initialized RSA context to use. - * \param f_rng The RNG to use. It is mandatory for PKCS#1 v2.1 padding - * encoding, and for PKCS#1 v1.5 padding encoding when used - * with \p mode set to #MBEDTLS_RSA_PUBLIC. For PKCS#1 v1.5 - * padding encoding and \p mode set to #MBEDTLS_RSA_PRIVATE, - * it is used for blinding and should be provided in this - * case; see mbedtls_rsa_private() for more. - * \param p_rng The RNG context to be passed to \p f_rng. May be - * \c NULL if \p f_rng is \c NULL or if \p f_rng doesn't - * need a context argument. - * \param mode The mode of operation. This must be either - * #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE (deprecated). - * \param ilen The length of the plaintext in Bytes. - * \param input The input data to encrypt. This must be a readable - * buffer of size \p ilen Bytes. This must not be \c NULL. - * \param output The output buffer. This must be a writable buffer - * of length \c ctx->len Bytes. For example, \c 256 Bytes - * for an 2048-bit RSA modulus. + * \return \c 0 on success, or an \c MBEDTLS_ERR_RSA_XXX error code + * on failure. * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + * \note The input and output buffers must be as large as the size + * of \p ctx->N. For example, 128 Bytes if RSA-1024 is used. */ int mbedtls_rsa_pkcs1_encrypt( mbedtls_rsa_context *ctx, int (*f_rng)(void *, unsigned char *, size_t), @@ -620,6 +580,15 @@ int mbedtls_rsa_pkcs1_encrypt( mbedtls_rsa_context *ctx, * \brief This function performs a PKCS#1 v1.5 encryption operation * (RSAES-PKCS1-v1_5-ENCRYPT). * + * \param ctx The RSA context. + * \param f_rng The RNG function. Needed for padding and + * #MBEDTLS_RSA_PRIVATE. + * \param p_rng The RNG parameter. + * \param mode #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE. + * \param ilen The length of the plaintext. + * \param input The buffer holding the data to encrypt. + * \param output The buffer used to hold the ciphertext. + * * \deprecated It is deprecated and discouraged to call this function * in #MBEDTLS_RSA_PRIVATE mode. Future versions of the library * are likely to remove the \p mode argument and have it @@ -627,27 +596,13 @@ int mbedtls_rsa_pkcs1_encrypt( mbedtls_rsa_context *ctx, * * \note Alternative implementations of RSA need not support * mode being set to #MBEDTLS_RSA_PRIVATE and might instead - * return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED. + * return #MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION. * - * \param ctx The initialized RSA context to use. - * \param f_rng The RNG function to use. It is needed for padding generation - * if \p mode is #MBEDTLS_RSA_PUBLIC. If \p mode is - * #MBEDTLS_RSA_PRIVATE (discouraged), it is used for - * blinding and should be provided; see mbedtls_rsa_private(). - * \param p_rng The RNG context to be passed to \p f_rng. This may - * be \c NULL if \p f_rng is \c NULL or if \p f_rng - * doesn't need a context argument. - * \param mode The mode of operation. This must be either - * #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE (deprecated). - * \param ilen The length of the plaintext in Bytes. - * \param input The input data to encrypt. This must be a readable - * buffer of size \p ilen Bytes. This must not be \c NULL. - * \param output The output buffer. This must be a writable buffer - * of length \c ctx->len Bytes. For example, \c 256 Bytes - * for an 2048-bit RSA modulus. + * \return \c 0 on success, or an \c MBEDTLS_ERR_RSA_XXX error code + * on failure. * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + * \note The output buffer must be as large as the size + * of \p ctx->N. For example, 128 Bytes if RSA-1024 is used. */ int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx, int (*f_rng)(void *, unsigned char *, size_t), @@ -660,38 +615,31 @@ int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx, * \brief This function performs a PKCS#1 v2.1 OAEP encryption * operation (RSAES-OAEP-ENCRYPT). * - * \note The output buffer must be as large as the size - * of ctx->N. For example, 128 Bytes if RSA-1024 is used. - * - * \deprecated It is deprecated and discouraged to call this function - * in #MBEDTLS_RSA_PRIVATE mode. Future versions of the library - * are likely to remove the \p mode argument and have it - * implicitly set to #MBEDTLS_RSA_PUBLIC. - * - * \note Alternative implementations of RSA need not support - * mode being set to #MBEDTLS_RSA_PRIVATE and might instead - * return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED. - * - * \param ctx The initnialized RSA context to use. - * \param f_rng The RNG function to use. This is needed for padding - * generation and must be provided. - * \param p_rng The RNG context to be passed to \p f_rng. This may - * be \c NULL if \p f_rng doesn't need a context argument. - * \param mode The mode of operation. This must be either - * #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE (deprecated). + * \param ctx The RSA context. + * \param f_rng The RNG function. Needed for padding and PKCS#1 v2.1 + * encoding and #MBEDTLS_RSA_PRIVATE. + * \param p_rng The RNG parameter. + * \param mode #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE. * \param label The buffer holding the custom label to use. - * This must be a readable buffer of length \p label_len - * Bytes. It may be \c NULL if \p label_len is \c 0. - * \param label_len The length of the label in Bytes. - * \param ilen The length of the plaintext buffer \p input in Bytes. - * \param input The input data to encrypt. This must be a readable - * buffer of size \p ilen Bytes. This must not be \c NULL. - * \param output The output buffer. This must be a writable buffer - * of length \c ctx->len Bytes. For example, \c 256 Bytes - * for an 2048-bit RSA modulus. + * \param label_len The length of the label. + * \param ilen The length of the plaintext. + * \param input The buffer holding the data to encrypt. + * \param output The buffer used to hold the ciphertext. * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + * \deprecated It is deprecated and discouraged to call this function + * in #MBEDTLS_RSA_PRIVATE mode. Future versions of the library + * are likely to remove the \p mode argument and have it + * implicitly set to #MBEDTLS_RSA_PUBLIC. + * + * \note Alternative implementations of RSA need not support + * mode being set to #MBEDTLS_RSA_PRIVATE and might instead + * return #MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION. + * + * \return \c 0 on success, or an \c MBEDTLS_ERR_RSA_XXX error code + * on failure. + * + * \note The output buffer must be as large as the size + * of ctx->N. For example, 128 Bytes if RSA-1024 is used. */ int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx, int (*f_rng)(void *, unsigned char *, size_t), @@ -709,12 +657,14 @@ int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx, * It is the generic wrapper for performing a PKCS#1 decryption * operation using the \p mode from the context. * - * \note The output buffer length \c output_max_len should be - * as large as the size \p ctx->len of \p ctx->N (for example, - * 128 Bytes if RSA-1024 is used) to be able to hold an - * arbitrary decrypted message. If it is not large enough to - * hold the decryption of the particular ciphertext provided, - * the function returns \c MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE. + * \param ctx The RSA context. + * \param f_rng The RNG function. Only needed for #MBEDTLS_RSA_PRIVATE. + * \param p_rng The RNG parameter. + * \param mode #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE. + * \param olen The length of the plaintext. + * \param input The buffer holding the encrypted data. + * \param output The buffer used to hold the plaintext. + * \param output_max_len The maximum length of the output buffer. * * \deprecated It is deprecated and discouraged to call this function * in #MBEDTLS_RSA_PUBLIC mode. Future versions of the library @@ -723,28 +673,20 @@ int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx, * * \note Alternative implementations of RSA need not support * mode being set to #MBEDTLS_RSA_PUBLIC and might instead - * return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED. + * return #MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION. * - * \param ctx The initialized RSA context to use. - * \param f_rng The RNG function. If \p mode is #MBEDTLS_RSA_PRIVATE, - * this is used for blinding and should be provided; see - * mbedtls_rsa_private() for more. If \p mode is - * #MBEDTLS_RSA_PUBLIC, it is ignored. - * \param p_rng The RNG context to be passed to \p f_rng. This may be - * \c NULL if \p f_rng is \c NULL or doesn't need a context. - * \param mode The mode of operation. This must be either - * #MBEDTLS_RSA_PRIVATE or #MBEDTLS_RSA_PUBLIC (deprecated). - * \param olen The address at which to store the length of - * the plaintext. This must not be \c NULL. - * \param input The ciphertext buffer. This must be a readable buffer - * of length \c ctx->len Bytes. For example, \c 256 Bytes - * for an 2048-bit RSA modulus. - * \param output The buffer used to hold the plaintext. This must - * be a writable buffer of length \p output_max_len Bytes. - * \param output_max_len The length in Bytes of the output buffer \p output. + * \return \c 0 on success, or an \c MBEDTLS_ERR_RSA_XXX error code + * on failure. * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + * \note The output buffer length \c output_max_len should be + * as large as the size \p ctx->len of \p ctx->N (for example, + * 128 Bytes if RSA-1024 is used) to be able to hold an + * arbitrary decrypted message. If it is not large enough to + * hold the decryption of the particular ciphertext provided, + * the function returns \c MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE. + * + * \note The input buffer must be as large as the size + * of \p ctx->N. For example, 128 Bytes if RSA-1024 is used. */ int mbedtls_rsa_pkcs1_decrypt( mbedtls_rsa_context *ctx, int (*f_rng)(void *, unsigned char *, size_t), @@ -758,12 +700,14 @@ int mbedtls_rsa_pkcs1_decrypt( mbedtls_rsa_context *ctx, * \brief This function performs a PKCS#1 v1.5 decryption * operation (RSAES-PKCS1-v1_5-DECRYPT). * - * \note The output buffer length \c output_max_len should be - * as large as the size \p ctx->len of \p ctx->N, for example, - * 128 Bytes if RSA-1024 is used, to be able to hold an - * arbitrary decrypted message. If it is not large enough to - * hold the decryption of the particular ciphertext provided, - * the function returns #MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE. + * \param ctx The RSA context. + * \param f_rng The RNG function. Only needed for #MBEDTLS_RSA_PRIVATE. + * \param p_rng The RNG parameter. + * \param mode #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE. + * \param olen The length of the plaintext. + * \param input The buffer holding the encrypted data. + * \param output The buffer to hold the plaintext. + * \param output_max_len The maximum length of the output buffer. * * \deprecated It is deprecated and discouraged to call this function * in #MBEDTLS_RSA_PUBLIC mode. Future versions of the library @@ -772,29 +716,20 @@ int mbedtls_rsa_pkcs1_decrypt( mbedtls_rsa_context *ctx, * * \note Alternative implementations of RSA need not support * mode being set to #MBEDTLS_RSA_PUBLIC and might instead - * return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED. + * return #MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION. * - * \param ctx The initialized RSA context to use. - * \param f_rng The RNG function. If \p mode is #MBEDTLS_RSA_PRIVATE, - * this is used for blinding and should be provided; see - * mbedtls_rsa_private() for more. If \p mode is - * #MBEDTLS_RSA_PUBLIC, it is ignored. - * \param p_rng The RNG context to be passed to \p f_rng. This may be - * \c NULL if \p f_rng is \c NULL or doesn't need a context. - * \param mode The mode of operation. This must be either - * #MBEDTLS_RSA_PRIVATE or #MBEDTLS_RSA_PUBLIC (deprecated). - * \param olen The address at which to store the length of - * the plaintext. This must not be \c NULL. - * \param input The ciphertext buffer. This must be a readable buffer - * of length \c ctx->len Bytes. For example, \c 256 Bytes - * for an 2048-bit RSA modulus. - * \param output The buffer used to hold the plaintext. This must - * be a writable buffer of length \p output_max_len Bytes. - * \param output_max_len The length in Bytes of the output buffer \p output. + * \return \c 0 on success, or an \c MBEDTLS_ERR_RSA_XXX error code + * on failure. * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + * \note The output buffer length \c output_max_len should be + * as large as the size \p ctx->len of \p ctx->N, for example, + * 128 Bytes if RSA-1024 is used, to be able to hold an + * arbitrary decrypted message. If it is not large enough to + * hold the decryption of the particular ciphertext provided, + * the function returns #MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE. * + * \note The input buffer must be as large as the size + * of \p ctx->N. For example, 128 Bytes if RSA-1024 is used. */ int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx, int (*f_rng)(void *, unsigned char *, size_t), @@ -805,50 +740,42 @@ int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx, size_t output_max_len ); /** - * \brief This function performs a PKCS#1 v2.1 OAEP decryption - * operation (RSAES-OAEP-DECRYPT). + * \brief This function performs a PKCS#1 v2.1 OAEP decryption + * operation (RSAES-OAEP-DECRYPT). * - * \note The output buffer length \c output_max_len should be - * as large as the size \p ctx->len of \p ctx->N, for - * example, 128 Bytes if RSA-1024 is used, to be able to - * hold an arbitrary decrypted message. If it is not - * large enough to hold the decryption of the particular - * ciphertext provided, the function returns - * #MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE. - * - * \deprecated It is deprecated and discouraged to call this function - * in #MBEDTLS_RSA_PUBLIC mode. Future versions of the library - * are likely to remove the \p mode argument and have it - * implicitly set to #MBEDTLS_RSA_PRIVATE. - * - * \note Alternative implementations of RSA need not support - * mode being set to #MBEDTLS_RSA_PUBLIC and might instead - * return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED. - * - * \param ctx The initialized RSA context to use. - * \param f_rng The RNG function. If \p mode is #MBEDTLS_RSA_PRIVATE, - * this is used for blinding and should be provided; see - * mbedtls_rsa_private() for more. If \p mode is - * #MBEDTLS_RSA_PUBLIC, it is ignored. - * \param p_rng The RNG context to be passed to \p f_rng. This may be - * \c NULL if \p f_rng is \c NULL or doesn't need a context. - * \param mode The mode of operation. This must be either - * #MBEDTLS_RSA_PRIVATE or #MBEDTLS_RSA_PUBLIC (deprecated). + * \param ctx The RSA context. + * \param f_rng The RNG function. Only needed for #MBEDTLS_RSA_PRIVATE. + * \param p_rng The RNG parameter. + * \param mode #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE. * \param label The buffer holding the custom label to use. - * This must be a readable buffer of length \p label_len - * Bytes. It may be \c NULL if \p label_len is \c 0. - * \param label_len The length of the label in Bytes. - * \param olen The address at which to store the length of - * the plaintext. This must not be \c NULL. - * \param input The ciphertext buffer. This must be a readable buffer - * of length \c ctx->len Bytes. For example, \c 256 Bytes - * for an 2048-bit RSA modulus. - * \param output The buffer used to hold the plaintext. This must - * be a writable buffer of length \p output_max_len Bytes. - * \param output_max_len The length in Bytes of the output buffer \p output. + * \param label_len The length of the label. + * \param olen The length of the plaintext. + * \param input The buffer holding the encrypted data. + * \param output The buffer to hold the plaintext. + * \param output_max_len The maximum length of the output buffer. * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + * \deprecated It is deprecated and discouraged to call this function + * in #MBEDTLS_RSA_PUBLIC mode. Future versions of the library + * are likely to remove the \p mode argument and have it + * implicitly set to #MBEDTLS_RSA_PRIVATE. + * + * \note Alternative implementations of RSA need not support + * mode being set to #MBEDTLS_RSA_PUBLIC and might instead + * return #MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION. + * + * \return \c 0 on success, or an \c MBEDTLS_ERR_RSA_XXX error code + * on failure. + * + * \note The output buffer length \c output_max_len should be + * as large as the size \p ctx->len of \p ctx->N, for + * example, 128 Bytes if RSA-1024 is used, to be able to + * hold an arbitrary decrypted message. If it is not + * large enough to hold the decryption of the particular + * ciphertext provided, the function returns + * #MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE. + * + * \note The input buffer must be as large as the size + * of \p ctx->N. For example, 128 Bytes if RSA-1024 is used. */ int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx, int (*f_rng)(void *, unsigned char *, size_t), @@ -867,12 +794,16 @@ int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx, * It is the generic wrapper for performing a PKCS#1 * signature using the \p mode from the context. * - * \note The \p sig buffer must be as large as the size - * of \p ctx->N. For example, 128 Bytes if RSA-1024 is used. - * - * \note For PKCS#1 v2.1 encoding, see comments on - * mbedtls_rsa_rsassa_pss_sign() for details on - * \p md_alg and \p hash_id. + * \param ctx The RSA context. + * \param f_rng The RNG function. Needed for PKCS#1 v2.1 encoding and for + * #MBEDTLS_RSA_PRIVATE. + * \param p_rng The RNG parameter. + * \param mode #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE. + * \param md_alg The message-digest algorithm used to hash the original data. + * Use #MBEDTLS_MD_NONE for signing raw data. + * \param hashlen The length of the message digest. Only used if \p md_alg is #MBEDTLS_MD_NONE. + * \param hash The buffer holding the message digest. + * \param sig The buffer to hold the ciphertext. * * \deprecated It is deprecated and discouraged to call this function * in #MBEDTLS_RSA_PUBLIC mode. Future versions of the library @@ -881,34 +812,17 @@ int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx, * * \note Alternative implementations of RSA need not support * mode being set to #MBEDTLS_RSA_PUBLIC and might instead - * return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED. + * return #MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION. * - * \param ctx The initialized RSA context to use. - * \param f_rng The RNG function to use. If the padding mode is PKCS#1 v2.1, - * this must be provided. If the padding mode is PKCS#1 v1.5 and - * \p mode is #MBEDTLS_RSA_PRIVATE, it is used for blinding - * and should be provided; see mbedtls_rsa_private() for more - * more. It is ignored otherwise. - * \param p_rng The RNG context to be passed to \p f_rng. This may be \c NULL - * if \p f_rng is \c NULL or doesn't need a context argument. - * \param mode The mode of operation. This must be either - * #MBEDTLS_RSA_PRIVATE or #MBEDTLS_RSA_PUBLIC (deprecated). - * \param md_alg The message-digest algorithm used to hash the original data. - * Use #MBEDTLS_MD_NONE for signing raw data. - * \param hashlen The length of the message digest. - * Ths is only used if \p md_alg is #MBEDTLS_MD_NONE. - * \param hash The buffer holding the message digest or raw data. - * If \p md_alg is #MBEDTLS_MD_NONE, this must be a readable - * buffer of length \p hashlen Bytes. If \p md_alg is not - * #MBEDTLS_MD_NONE, it must be a readable buffer of length - * the size of the hash corresponding to \p md_alg. - * \param sig The buffer to hold the signature. This must be a writable - * buffer of length \c ctx->len Bytes. For example, \c 256 Bytes - * for an 2048-bit RSA modulus. A buffer length of - * #MBEDTLS_MPI_MAX_SIZE is always safe. + * \return \c 0 if the signing operation was successful, + * or an \c MBEDTLS_ERR_RSA_XXX error code on failure. * - * \return \c 0 if the signing operation was successful. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + * \note The \p sig buffer must be as large as the size + * of \p ctx->N. For example, 128 Bytes if RSA-1024 is used. + * + * \note For PKCS#1 v2.1 encoding, see comments on + * mbedtls_rsa_rsassa_pss_sign() for details on + * \p md_alg and \p hash_id. */ int mbedtls_rsa_pkcs1_sign( mbedtls_rsa_context *ctx, int (*f_rng)(void *, unsigned char *, size_t), @@ -923,6 +837,16 @@ int mbedtls_rsa_pkcs1_sign( mbedtls_rsa_context *ctx, * \brief This function performs a PKCS#1 v1.5 signature * operation (RSASSA-PKCS1-v1_5-SIGN). * + * \param ctx The RSA context. + * \param f_rng The RNG function. Only needed for #MBEDTLS_RSA_PRIVATE. + * \param p_rng The RNG parameter. + * \param mode #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE. + * \param md_alg The message-digest algorithm used to hash the original data. + * Use #MBEDTLS_MD_NONE for signing raw data. + * \param hashlen The length of the message digest. Only used if \p md_alg is #MBEDTLS_MD_NONE. + * \param hash The buffer holding the message digest. + * \param sig The buffer to hold the ciphertext. + * * \deprecated It is deprecated and discouraged to call this function * in #MBEDTLS_RSA_PUBLIC mode. Future versions of the library * are likely to remove the \p mode argument and have it @@ -930,33 +854,14 @@ int mbedtls_rsa_pkcs1_sign( mbedtls_rsa_context *ctx, * * \note Alternative implementations of RSA need not support * mode being set to #MBEDTLS_RSA_PUBLIC and might instead - * return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED. + * return #MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION. * - * \param ctx The initialized RSA context to use. - * \param f_rng The RNG function. If \p mode is #MBEDTLS_RSA_PRIVATE, - * this is used for blinding and should be provided; see - * mbedtls_rsa_private() for more. If \p mode is - * #MBEDTLS_RSA_PUBLIC, it is ignored. - * \param p_rng The RNG context to be passed to \p f_rng. This may be \c NULL - * if \p f_rng is \c NULL or doesn't need a context argument. - * \param mode The mode of operation. This must be either - * #MBEDTLS_RSA_PRIVATE or #MBEDTLS_RSA_PUBLIC (deprecated). - * \param md_alg The message-digest algorithm used to hash the original data. - * Use #MBEDTLS_MD_NONE for signing raw data. - * \param hashlen The length of the message digest. - * Ths is only used if \p md_alg is #MBEDTLS_MD_NONE. - * \param hash The buffer holding the message digest or raw data. - * If \p md_alg is #MBEDTLS_MD_NONE, this must be a readable - * buffer of length \p hashlen Bytes. If \p md_alg is not - * #MBEDTLS_MD_NONE, it must be a readable buffer of length - * the size of the hash corresponding to \p md_alg. - * \param sig The buffer to hold the signature. This must be a writable - * buffer of length \c ctx->len Bytes. For example, \c 256 Bytes - * for an 2048-bit RSA modulus. A buffer length of - * #MBEDTLS_MPI_MAX_SIZE is always safe. + * \return \c 0 if the signing operation was successful, + * or an \c MBEDTLS_ERR_RSA_XXX error code + * on failure. * - * \return \c 0 if the signing operation was successful. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + * \note The \p sig buffer must be as large as the size + * of \p ctx->N. For example, 128 Bytes if RSA-1024 is used. */ int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx, int (*f_rng)(void *, unsigned char *, size_t), @@ -971,22 +876,16 @@ int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx, * \brief This function performs a PKCS#1 v2.1 PSS signature * operation (RSASSA-PSS-SIGN). * - * \note The \p hash_id in the RSA context is the one used for the - * encoding. \p md_alg in the function call is the type of hash - * that is encoded. According to RFC-3447: Public-Key - * Cryptography Standards (PKCS) #1 v2.1: RSA Cryptography - * Specifications it is advised to keep both hashes the - * same. - * - * \note This function always uses the maximum possible salt size, - * up to the length of the payload hash. This choice of salt - * size complies with FIPS 186-4 §5.5 (e) and RFC 8017 (PKCS#1 - * v2.2) §9.1.1 step 3. Furthermore this function enforces a - * minimum salt size which is the hash size minus 2 bytes. If - * this minimum size is too large given the key size (the salt - * size, plus the hash size, plus 2 bytes must be no more than - * the key size in bytes), this function returns - * #MBEDTLS_ERR_RSA_BAD_INPUT_DATA. + * \param ctx The RSA context. + * \param f_rng The RNG function. Needed for PKCS#1 v2.1 encoding and for + * #MBEDTLS_RSA_PRIVATE. + * \param p_rng The RNG parameter. + * \param mode #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE. + * \param md_alg The message-digest algorithm used to hash the original data. + * Use #MBEDTLS_MD_NONE for signing raw data. + * \param hashlen The length of the message digest. Only used if \p md_alg is #MBEDTLS_MD_NONE. + * \param hash The buffer holding the message digest. + * \param sig The buffer to hold the ciphertext. * * \deprecated It is deprecated and discouraged to call this function * in #MBEDTLS_RSA_PUBLIC mode. Future versions of the library @@ -995,30 +894,21 @@ int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx, * * \note Alternative implementations of RSA need not support * mode being set to #MBEDTLS_RSA_PUBLIC and might instead - * return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED. + * return #MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION. * - * \param ctx The initialized RSA context to use. - * \param f_rng The RNG function. It must not be \c NULL. - * \param p_rng The RNG context to be passed to \p f_rng. This may be \c NULL - * if \p f_rng doesn't need a context argument. - * \param mode The mode of operation. This must be either - * #MBEDTLS_RSA_PRIVATE or #MBEDTLS_RSA_PUBLIC (deprecated). - * \param md_alg The message-digest algorithm used to hash the original data. - * Use #MBEDTLS_MD_NONE for signing raw data. - * \param hashlen The length of the message digest. - * Ths is only used if \p md_alg is #MBEDTLS_MD_NONE. - * \param hash The buffer holding the message digest or raw data. - * If \p md_alg is #MBEDTLS_MD_NONE, this must be a readable - * buffer of length \p hashlen Bytes. If \p md_alg is not - * #MBEDTLS_MD_NONE, it must be a readable buffer of length - * the size of the hash corresponding to \p md_alg. - * \param sig The buffer to hold the signature. This must be a writable - * buffer of length \c ctx->len Bytes. For example, \c 256 Bytes - * for an 2048-bit RSA modulus. A buffer length of - * #MBEDTLS_MPI_MAX_SIZE is always safe. + * \return \c 0 if the signing operation was successful, + * or an \c MBEDTLS_ERR_RSA_XXX error code + * on failure. * - * \return \c 0 if the signing operation was successful. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + * \note The \p sig buffer must be as large as the size + * of \p ctx->N. For example, 128 Bytes if RSA-1024 is used. + * + * \note The \p hash_id in the RSA context is the one used for the + * encoding. \p md_alg in the function call is the type of hash + * that is encoded. According to RFC-3447: Public-Key + * Cryptography Standards (PKCS) #1 v2.1: RSA Cryptography + * Specifications it is advised to keep both hashes the + * same. */ int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx, int (*f_rng)(void *, unsigned char *, size_t), @@ -1036,9 +926,15 @@ int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx, * This is the generic wrapper for performing a PKCS#1 * verification using the mode from the context. * - * \note For PKCS#1 v2.1 encoding, see comments on - * mbedtls_rsa_rsassa_pss_verify() about \p md_alg and - * \p hash_id. + * \param ctx The RSA public key context. + * \param f_rng The RNG function. Only needed for #MBEDTLS_RSA_PRIVATE. + * \param p_rng The RNG parameter. + * \param mode #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE. + * \param md_alg The message-digest algorithm used to hash the original data. + * Use #MBEDTLS_MD_NONE for signing raw data. + * \param hashlen The length of the message digest. Only used if \p md_alg is #MBEDTLS_MD_NONE. + * \param hash The buffer holding the message digest. + * \param sig The buffer holding the ciphertext. * * \deprecated It is deprecated and discouraged to call this function * in #MBEDTLS_RSA_PRIVATE mode. Future versions of the library @@ -1047,31 +943,18 @@ int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx, * * \note Alternative implementations of RSA need not support * mode being set to #MBEDTLS_RSA_PRIVATE and might instead - * return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED. + * return #MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION. * - * \param ctx The initialized RSA public key context to use. - * \param f_rng The RNG function to use. If \p mode is #MBEDTLS_RSA_PRIVATE, - * this is used for blinding and should be provided; see - * mbedtls_rsa_private() for more. Otherwise, it is ignored. - * \param p_rng The RNG context to be passed to \p f_rng. This may be - * \c NULL if \p f_rng is \c NULL or doesn't need a context. - * \param mode The mode of operation. This must be either - * #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE (deprecated). - * \param md_alg The message-digest algorithm used to hash the original data. - * Use #MBEDTLS_MD_NONE for signing raw data. - * \param hashlen The length of the message digest. - * This is only used if \p md_alg is #MBEDTLS_MD_NONE. - * \param hash The buffer holding the message digest or raw data. - * If \p md_alg is #MBEDTLS_MD_NONE, this must be a readable - * buffer of length \p hashlen Bytes. If \p md_alg is not - * #MBEDTLS_MD_NONE, it must be a readable buffer of length - * the size of the hash corresponding to \p md_alg. - * \param sig The buffer holding the signature. This must be a readable - * buffer of length \c ctx->len Bytes. For example, \c 256 Bytes - * for an 2048-bit RSA modulus. + * \return \c 0 if the verify operation was successful, + * or an \c MBEDTLS_ERR_RSA_XXX error code + * on failure. * - * \return \c 0 if the verify operation was successful. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + * \note The \p sig buffer must be as large as the size + * of \p ctx->N. For example, 128 Bytes if RSA-1024 is used. + * + * \note For PKCS#1 v2.1 encoding, see comments on + * mbedtls_rsa_rsassa_pss_verify() about \p md_alg and + * \p hash_id. */ int mbedtls_rsa_pkcs1_verify( mbedtls_rsa_context *ctx, int (*f_rng)(void *, unsigned char *, size_t), @@ -1086,6 +969,16 @@ int mbedtls_rsa_pkcs1_verify( mbedtls_rsa_context *ctx, * \brief This function performs a PKCS#1 v1.5 verification * operation (RSASSA-PKCS1-v1_5-VERIFY). * + * \param ctx The RSA public key context. + * \param f_rng The RNG function. Only needed for #MBEDTLS_RSA_PRIVATE. + * \param p_rng The RNG parameter. + * \param mode #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE. + * \param md_alg The message-digest algorithm used to hash the original data. + * Use #MBEDTLS_MD_NONE for signing raw data. + * \param hashlen The length of the message digest. Only used if \p md_alg is #MBEDTLS_MD_NONE. + * \param hash The buffer holding the message digest. + * \param sig The buffer holding the ciphertext. + * * \deprecated It is deprecated and discouraged to call this function * in #MBEDTLS_RSA_PRIVATE mode. Future versions of the library * are likely to remove the \p mode argument and have it @@ -1093,31 +986,14 @@ int mbedtls_rsa_pkcs1_verify( mbedtls_rsa_context *ctx, * * \note Alternative implementations of RSA need not support * mode being set to #MBEDTLS_RSA_PRIVATE and might instead - * return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED. + * return #MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION. * - * \param ctx The initialized RSA public key context to use. - * \param f_rng The RNG function to use. If \p mode is #MBEDTLS_RSA_PRIVATE, - * this is used for blinding and should be provided; see - * mbedtls_rsa_private() for more. Otherwise, it is ignored. - * \param p_rng The RNG context to be passed to \p f_rng. This may be - * \c NULL if \p f_rng is \c NULL or doesn't need a context. - * \param mode The mode of operation. This must be either - * #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE (deprecated). - * \param md_alg The message-digest algorithm used to hash the original data. - * Use #MBEDTLS_MD_NONE for signing raw data. - * \param hashlen The length of the message digest. - * This is only used if \p md_alg is #MBEDTLS_MD_NONE. - * \param hash The buffer holding the message digest or raw data. - * If \p md_alg is #MBEDTLS_MD_NONE, this must be a readable - * buffer of length \p hashlen Bytes. If \p md_alg is not - * #MBEDTLS_MD_NONE, it must be a readable buffer of length - * the size of the hash corresponding to \p md_alg. - * \param sig The buffer holding the signature. This must be a readable - * buffer of length \c ctx->len Bytes. For example, \c 256 Bytes - * for an 2048-bit RSA modulus. + * \return \c 0 if the verify operation was successful, + * or an \c MBEDTLS_ERR_RSA_XXX error code + * on failure. * - * \return \c 0 if the verify operation was successful. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + * \note The \p sig buffer must be as large as the size + * of \p ctx->N. For example, 128 Bytes if RSA-1024 is used. */ int mbedtls_rsa_rsassa_pkcs1_v15_verify( mbedtls_rsa_context *ctx, int (*f_rng)(void *, unsigned char *, size_t), @@ -1135,13 +1011,15 @@ int mbedtls_rsa_rsassa_pkcs1_v15_verify( mbedtls_rsa_context *ctx, * The hash function for the MGF mask generating function * is that specified in the RSA context. * - * \note The \p hash_id in the RSA context is the one used for the - * verification. \p md_alg in the function call is the type of - * hash that is verified. According to RFC-3447: Public-Key - * Cryptography Standards (PKCS) #1 v2.1: RSA Cryptography - * Specifications it is advised to keep both hashes the - * same. If \p hash_id in the RSA context is unset, - * the \p md_alg from the function call is used. + * \param ctx The RSA public key context. + * \param f_rng The RNG function. Only needed for #MBEDTLS_RSA_PRIVATE. + * \param p_rng The RNG parameter. + * \param mode #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE. + * \param md_alg The message-digest algorithm used to hash the original data. + * Use #MBEDTLS_MD_NONE for signing raw data. + * \param hashlen The length of the message digest. Only used if \p md_alg is #MBEDTLS_MD_NONE. + * \param hash The buffer holding the message digest. + * \param sig The buffer holding the ciphertext. * * \deprecated It is deprecated and discouraged to call this function * in #MBEDTLS_RSA_PRIVATE mode. Future versions of the library @@ -1150,31 +1028,22 @@ int mbedtls_rsa_rsassa_pkcs1_v15_verify( mbedtls_rsa_context *ctx, * * \note Alternative implementations of RSA need not support * mode being set to #MBEDTLS_RSA_PRIVATE and might instead - * return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED. + * return #MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION. * - * \param ctx The initialized RSA public key context to use. - * \param f_rng The RNG function to use. If \p mode is #MBEDTLS_RSA_PRIVATE, - * this is used for blinding and should be provided; see - * mbedtls_rsa_private() for more. Otherwise, it is ignored. - * \param p_rng The RNG context to be passed to \p f_rng. This may be - * \c NULL if \p f_rng is \c NULL or doesn't need a context. - * \param mode The mode of operation. This must be either - * #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE (deprecated). - * \param md_alg The message-digest algorithm used to hash the original data. - * Use #MBEDTLS_MD_NONE for signing raw data. - * \param hashlen The length of the message digest. - * This is only used if \p md_alg is #MBEDTLS_MD_NONE. - * \param hash The buffer holding the message digest or raw data. - * If \p md_alg is #MBEDTLS_MD_NONE, this must be a readable - * buffer of length \p hashlen Bytes. If \p md_alg is not - * #MBEDTLS_MD_NONE, it must be a readable buffer of length - * the size of the hash corresponding to \p md_alg. - * \param sig The buffer holding the signature. This must be a readable - * buffer of length \c ctx->len Bytes. For example, \c 256 Bytes - * for an 2048-bit RSA modulus. + * \return \c 0 if the verify operation was successful, + * or an \c MBEDTLS_ERR_RSA_XXX error code + * on failure. * - * \return \c 0 if the verify operation was successful. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + * \note The \p sig buffer must be as large as the size + * of \p ctx->N. For example, 128 Bytes if RSA-1024 is used. + * + * \note The \p hash_id in the RSA context is the one used for the + * verification. \p md_alg in the function call is the type of + * hash that is verified. According to RFC-3447: Public-Key + * Cryptography Standards (PKCS) #1 v2.1: RSA Cryptography + * Specifications it is advised to keep both hashes the + * same. If \p hash_id in the RSA context is unset, + * the \p md_alg from the function call is used. */ int mbedtls_rsa_rsassa_pss_verify( mbedtls_rsa_context *ctx, int (*f_rng)(void *, unsigned char *, size_t), @@ -1192,37 +1061,27 @@ int mbedtls_rsa_rsassa_pss_verify( mbedtls_rsa_context *ctx, * The hash function for the MGF mask generating function * is that specified in \p mgf1_hash_id. * + * \param ctx The RSA public key context. + * \param f_rng The RNG function. Only needed for #MBEDTLS_RSA_PRIVATE. + * \param p_rng The RNG parameter. + * \param mode #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE. + * \param md_alg The message-digest algorithm used to hash the original data. + * Use #MBEDTLS_MD_NONE for signing raw data. + * \param hashlen The length of the message digest. Only used if \p md_alg is #MBEDTLS_MD_NONE. + * \param hash The buffer holding the message digest. + * \param mgf1_hash_id The message digest used for mask generation. + * \param expected_salt_len The length of the salt used in padding. Use + * #MBEDTLS_RSA_SALT_LEN_ANY to accept any salt length. + * \param sig The buffer holding the ciphertext. + * + * \return \c 0 if the verify operation was successful, + * or an \c MBEDTLS_ERR_RSA_XXX error code + * on failure. + * * \note The \p sig buffer must be as large as the size * of \p ctx->N. For example, 128 Bytes if RSA-1024 is used. * * \note The \p hash_id in the RSA context is ignored. - * - * \param ctx The initialized RSA public key context to use. - * \param f_rng The RNG function to use. If \p mode is #MBEDTLS_RSA_PRIVATE, - * this is used for blinding and should be provided; see - * mbedtls_rsa_private() for more. Otherwise, it is ignored. - * \param p_rng The RNG context to be passed to \p f_rng. This may be - * \c NULL if \p f_rng is \c NULL or doesn't need a context. - * \param mode The mode of operation. This must be either - * #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE. - * \param md_alg The message-digest algorithm used to hash the original data. - * Use #MBEDTLS_MD_NONE for signing raw data. - * \param hashlen The length of the message digest. - * This is only used if \p md_alg is #MBEDTLS_MD_NONE. - * \param hash The buffer holding the message digest or raw data. - * If \p md_alg is #MBEDTLS_MD_NONE, this must be a readable - * buffer of length \p hashlen Bytes. If \p md_alg is not - * #MBEDTLS_MD_NONE, it must be a readable buffer of length - * the size of the hash corresponding to \p md_alg. - * \param mgf1_hash_id The message digest used for mask generation. - * \param expected_salt_len The length of the salt used in padding. Use - * #MBEDTLS_RSA_SALT_LEN_ANY to accept any salt length. - * \param sig The buffer holding the signature. This must be a readable - * buffer of length \c ctx->len Bytes. For example, \c 256 Bytes - * for an 2048-bit RSA modulus. - * - * \return \c 0 if the verify operation was successful. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. */ int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx, int (*f_rng)(void *, unsigned char *, size_t), @@ -1238,35 +1097,40 @@ int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx, /** * \brief This function copies the components of an RSA context. * - * \param dst The destination context. This must be initialized. - * \param src The source context. This must be initialized. + * \param dst The destination context. + * \param src The source context. * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory allocation failure. + * \return \c 0 on success, + * #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory allocation failure. */ int mbedtls_rsa_copy( mbedtls_rsa_context *dst, const mbedtls_rsa_context *src ); /** * \brief This function frees the components of an RSA key. * - * \param ctx The RSA context to free. May be \c NULL, in which case - * this function is a no-op. If it is not \c NULL, it must - * point to an initialized RSA context. + * \param ctx The RSA Context to free. */ void mbedtls_rsa_free( mbedtls_rsa_context *ctx ); -#if defined(MBEDTLS_SELF_TEST) +#ifdef __cplusplus +} +#endif + +#else /* MBEDTLS_RSA_ALT */ +#include "rsa_alt.h" +#endif /* MBEDTLS_RSA_ALT */ + +#ifdef __cplusplus +extern "C" { +#endif /** * \brief The RSA checkup routine. * - * \return \c 0 on success. - * \return \c 1 on failure. + * \return \c 0 on success, or \c 1 on failure. */ int mbedtls_rsa_self_test( int verbose ); -#endif /* MBEDTLS_SELF_TEST */ - #ifdef __cplusplus } #endif diff --git a/APP_Framework/Framework/security/mbedtls/rsa_internal.c b/APP_Framework/Framework/security/mbedtls/rsa_internal.c index 86797f78f..4dd46672e 100644 --- a/APP_Framework/Framework/security/mbedtls/rsa_internal.c +++ b/APP_Framework/Framework/security/mbedtls/rsa_internal.c @@ -351,20 +351,15 @@ int mbedtls_rsa_validate_params( const mbedtls_mpi *N, const mbedtls_mpi *P, */ #if defined(MBEDTLS_GENPRIME) - /* - * When generating keys, the strongest security we support aims for an error - * rate of at most 2^-100 and we are aiming for the same certainty here as - * well. - */ if( f_rng != NULL && P != NULL && - ( ret = mbedtls_mpi_is_prime_ext( P, 50, f_rng, p_rng ) ) != 0 ) + ( 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_ext( Q, 50, f_rng, p_rng ) ) != 0 ) + ( ret = mbedtls_mpi_is_prime( Q, f_rng, p_rng ) ) != 0 ) { ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; goto cleanup; diff --git a/APP_Framework/Framework/security/mbedtls/sha1.c b/APP_Framework/Framework/security/mbedtls/sha1.c index 95ef6f9b7..26c9d33dc 100644 --- a/APP_Framework/Framework/security/mbedtls/sha1.c +++ b/APP_Framework/Framework/security/mbedtls/sha1.c @@ -33,7 +33,6 @@ #if defined(MBEDTLS_SHA1_C) #include "sha1.h" -#include "platform_util.h" #include @@ -46,13 +45,13 @@ #endif /* MBEDTLS_PLATFORM_C */ #endif /* MBEDTLS_SELF_TEST */ -#define SHA1_VALIDATE_RET(cond) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA1_BAD_INPUT_DATA ) - -#define SHA1_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE( cond ) - #if !defined(MBEDTLS_SHA1_ALT) +/* 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; +} + /* * 32-bit integer manipulation macros (big endian) */ @@ -78,9 +77,7 @@ void mbedtls_sha1_init( mbedtls_sha1_context *ctx ) { - SHA1_VALIDATE( ctx != NULL ); - - mbedtls_platform_memset( ctx, 0, sizeof( mbedtls_sha1_context ) ); + memset( ctx, 0, sizeof( mbedtls_sha1_context ) ); } void mbedtls_sha1_free( mbedtls_sha1_context *ctx ) @@ -88,15 +85,12 @@ void mbedtls_sha1_free( mbedtls_sha1_context *ctx ) if( ctx == NULL ) return; - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha1_context ) ); + mbedtls_zeroize( ctx, sizeof( mbedtls_sha1_context ) ); } void mbedtls_sha1_clone( mbedtls_sha1_context *dst, const mbedtls_sha1_context *src ) { - SHA1_VALIDATE( dst != NULL ); - SHA1_VALIDATE( src != NULL ); - *dst = *src; } @@ -105,8 +99,6 @@ void mbedtls_sha1_clone( mbedtls_sha1_context *dst, */ int mbedtls_sha1_starts_ret( mbedtls_sha1_context *ctx ) { - SHA1_VALIDATE_RET( ctx != NULL ); - ctx->total[0] = 0; ctx->total[1] = 0; @@ -132,9 +124,6 @@ int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx, { uint32_t temp, W[16], A, B, C, D, E; - SHA1_VALIDATE_RET( ctx != NULL ); - SHA1_VALIDATE_RET( (const unsigned char *)data != NULL ); - GET_UINT32_BE( W[ 0], data, 0 ); GET_UINT32_BE( W[ 1], data, 4 ); GET_UINT32_BE( W[ 2], data, 8 ); @@ -152,21 +141,19 @@ int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx, GET_UINT32_BE( W[14], data, 56 ); GET_UINT32_BE( W[15], data, 60 ); -#define S(x,n) (((x) << (n)) | (((x) & 0xFFFFFFFF) >> (32 - (n)))) +#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) -#define R(t) \ - ( \ - temp = W[( (t) - 3 ) & 0x0F] ^ W[( (t) - 8 ) & 0x0F] ^ \ - W[( (t) - 14 ) & 0x0F] ^ W[ (t) & 0x0F], \ - ( W[(t) & 0x0F] = S(temp,1) ) \ - ) +#define R(t) \ +( \ + temp = W[( t - 3 ) & 0x0F] ^ W[( t - 8 ) & 0x0F] ^ \ + W[( t - 14 ) & 0x0F] ^ W[ t & 0x0F], \ + ( W[t & 0x0F] = S(temp,1) ) \ +) -#define P(a,b,c,d,e,x) \ - do \ - { \ - (e) += S((a),5) + F((b),(c),(d)) + K + (x); \ - (b) = S((b),30); \ - } while( 0 ) +#define P(a,b,c,d,e,x) \ +{ \ + e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \ +} A = ctx->state[0]; B = ctx->state[1]; @@ -174,7 +161,7 @@ int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx, D = ctx->state[3]; E = ctx->state[4]; -#define F(x,y,z) ((z) ^ ((x) & ((y) ^ (z)))) +#define F(x,y,z) (z ^ (x & (y ^ z))) #define K 0x5A827999 P( A, B, C, D, E, W[0] ); @@ -201,7 +188,7 @@ int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx, #undef K #undef F -#define F(x,y,z) ((x) ^ (y) ^ (z)) +#define F(x,y,z) (x ^ y ^ z) #define K 0x6ED9EBA1 P( A, B, C, D, E, R(20) ); @@ -228,7 +215,7 @@ int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx, #undef K #undef F -#define F(x,y,z) (((x) & (y)) | ((z) & ((x) | (y)))) +#define F(x,y,z) ((x & y) | (z & (x | y))) #define K 0x8F1BBCDC P( A, B, C, D, E, R(40) ); @@ -255,7 +242,7 @@ int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx, #undef K #undef F -#define F(x,y,z) ((x) ^ (y) ^ (z)) +#define F(x,y,z) (x ^ y ^ z) #define K 0xCA62C1D6 P( A, B, C, D, E, R(60) ); @@ -311,9 +298,6 @@ int mbedtls_sha1_update_ret( mbedtls_sha1_context *ctx, size_t fill; uint32_t left; - SHA1_VALIDATE_RET( ctx != NULL ); - SHA1_VALIDATE_RET( ilen == 0 || input != NULL ); - if( ilen == 0 ) return( 0 ); @@ -328,7 +312,7 @@ int mbedtls_sha1_update_ret( mbedtls_sha1_context *ctx, if( left && ilen >= fill ) { - mbedtls_platform_memcpy( (void *) (ctx->buffer + left), input, fill ); + memcpy( (void *) (ctx->buffer + left), input, fill ); if( ( ret = mbedtls_internal_sha1_process( ctx, ctx->buffer ) ) != 0 ) return( ret ); @@ -348,7 +332,7 @@ int mbedtls_sha1_update_ret( mbedtls_sha1_context *ctx, } if( ilen > 0 ) - mbedtls_platform_memcpy( (void *) (ctx->buffer + left), input, ilen ); + memcpy( (void *) (ctx->buffer + left), input, ilen ); return( 0 ); } @@ -372,9 +356,6 @@ int mbedtls_sha1_finish_ret( mbedtls_sha1_context *ctx, uint32_t used; uint32_t high, low; - SHA1_VALIDATE_RET( ctx != NULL ); - SHA1_VALIDATE_RET( (unsigned char *)output != NULL ); - /* * Add padding: 0x80 then 0x00 until 8 bytes remain for the length */ @@ -385,17 +366,17 @@ int mbedtls_sha1_finish_ret( mbedtls_sha1_context *ctx, if( used <= 56 ) { /* Enough room for padding + length in current block */ - mbedtls_platform_memset( ctx->buffer + used, 0, 56 - used ); + memset( ctx->buffer + used, 0, 56 - used ); } else { /* We'll need an extra block */ - mbedtls_platform_memset( ctx->buffer + used, 0, 64 - used ); + memset( ctx->buffer + used, 0, 64 - used ); if( ( ret = mbedtls_internal_sha1_process( ctx, ctx->buffer ) ) != 0 ) return( ret ); - mbedtls_platform_memset( ctx->buffer, 0, 56 ); + memset( ctx->buffer, 0, 56 ); } /* @@ -443,9 +424,6 @@ int mbedtls_sha1_ret( const unsigned char *input, int ret; mbedtls_sha1_context ctx; - SHA1_VALIDATE_RET( ilen == 0 || input != NULL ); - SHA1_VALIDATE_RET( (unsigned char *)output != NULL ); - mbedtls_sha1_init( &ctx ); if( ( ret = mbedtls_sha1_starts_ret( &ctx ) ) != 0 ) diff --git a/APP_Framework/Framework/security/mbedtls/sha1.h b/APP_Framework/Framework/security/mbedtls/sha1.h index bb6ecf05a..05540cde1 100644 --- a/APP_Framework/Framework/security/mbedtls/sha1.h +++ b/APP_Framework/Framework/security/mbedtls/sha1.h @@ -1,10 +1,7 @@ /** * \file sha1.h * - * \brief This file contains SHA-1 definitions and functions. - * - * The Secure Hash Algorithm 1 (SHA-1) cryptographic hash function is defined in - * FIPS 180-4: Secure Hash Standard (SHS). + * \brief The SHA-1 cryptographic hash function. * * \warning SHA-1 is considered a weak message digest and its use constitutes * a security risk. We recommend considering stronger message @@ -40,18 +37,16 @@ #include #include -/* MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED is deprecated and should not be used. */ #define MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED -0x0035 /**< SHA-1 hardware accelerator failed */ -#define MBEDTLS_ERR_SHA1_BAD_INPUT_DATA -0x0073 /**< SHA-1 input data was malformed. */ - -#ifdef __cplusplus -extern "C" { -#endif #if !defined(MBEDTLS_SHA1_ALT) // Regular implementation // +#ifdef __cplusplus +extern "C" { +#endif + /** * \brief The SHA-1 context structure. * @@ -60,7 +55,7 @@ extern "C" { * stronger message digests instead. * */ -typedef struct mbedtls_sha1_context +typedef struct { uint32_t total[2]; /*!< The number of Bytes processed. */ uint32_t state[5]; /*!< The intermediate digest state. */ @@ -68,48 +63,40 @@ typedef struct mbedtls_sha1_context } mbedtls_sha1_context; -#else /* MBEDTLS_SHA1_ALT */ -#include "sha1_alt.h" -#endif /* MBEDTLS_SHA1_ALT */ - /** * \brief This function initializes a SHA-1 context. * + * \param ctx The SHA-1 context to initialize. + * * \warning SHA-1 is considered a weak message digest and its use * constitutes a security risk. We recommend considering * stronger message digests instead. * - * \param ctx The SHA-1 context to initialize. - * This must not be \c NULL. - * */ void mbedtls_sha1_init( mbedtls_sha1_context *ctx ); /** * \brief This function clears a SHA-1 context. * + * \param ctx The SHA-1 context to clear. + * * \warning SHA-1 is considered a weak message digest and its use * constitutes a security risk. We recommend considering * stronger message digests instead. * - * \param ctx The SHA-1 context to clear. This may be \c NULL, - * in which case this function does nothing. If it is - * not \c NULL, it must point to an initialized - * SHA-1 context. - * */ void mbedtls_sha1_free( mbedtls_sha1_context *ctx ); /** * \brief This function clones the state of a SHA-1 context. * + * \param dst The destination context. + * \param src The context to clone. + * * \warning SHA-1 is considered a weak message digest and its use * constitutes a security risk. We recommend considering * stronger message digests instead. * - * \param dst The SHA-1 context to clone to. This must be initialized. - * \param src The SHA-1 context to clone from. This must be initialized. - * */ void mbedtls_sha1_clone( mbedtls_sha1_context *dst, const mbedtls_sha1_context *src ); @@ -117,15 +104,14 @@ void mbedtls_sha1_clone( mbedtls_sha1_context *dst, /** * \brief This function starts a SHA-1 checksum calculation. * + * \param ctx The context to initialize. + * + * \return \c 0 if successful + * * \warning SHA-1 is considered a weak message digest and its use * constitutes a security risk. We recommend considering * stronger message digests instead. * - * \param ctx The SHA-1 context to initialize. This must be initialized. - * - * \return \c 0 on success. - * \return A negative error code on failure. - * */ int mbedtls_sha1_starts_ret( mbedtls_sha1_context *ctx ); @@ -133,18 +119,16 @@ int mbedtls_sha1_starts_ret( mbedtls_sha1_context *ctx ); * \brief This function feeds an input buffer into an ongoing SHA-1 * checksum calculation. * + * \param ctx The SHA-1 context. + * \param input The buffer holding the input data. + * \param ilen The length of the input data. + * + * \return \c 0 if successful + * * \warning SHA-1 is considered a weak message digest and its use * constitutes a security risk. We recommend considering * stronger message digests instead. * - * \param ctx The SHA-1 context. This must be initialized - * and have a hash operation started. - * \param input The buffer holding the input data. - * This must be a readable buffer of length \p ilen Bytes. - * \param ilen The length of the input data \p input in Bytes. - * - * \return \c 0 on success. - * \return A negative error code on failure. */ int mbedtls_sha1_update_ret( mbedtls_sha1_context *ctx, const unsigned char *input, @@ -154,35 +138,31 @@ int mbedtls_sha1_update_ret( mbedtls_sha1_context *ctx, * \brief This function finishes the SHA-1 operation, and writes * the result to the output buffer. * + * \param ctx The SHA-1 context. + * \param output The SHA-1 checksum result. + * + * \return \c 0 if successful + * * \warning SHA-1 is considered a weak message digest and its use * constitutes a security risk. We recommend considering * stronger message digests instead. * - * \param ctx The SHA-1 context to use. This must be initialized and - * have a hash operation started. - * \param output The SHA-1 checksum result. This must be a writable - * buffer of length \c 20 Bytes. - * - * \return \c 0 on success. - * \return A negative error code on failure. */ int mbedtls_sha1_finish_ret( mbedtls_sha1_context *ctx, unsigned char output[20] ); /** - * \brief SHA-1 process data block (internal use only). + * \brief SHA-1 process data block (internal use only) + * + * \param ctx SHA-1 context + * \param data The data block being processed. + * + * \return \c 0 if successful * * \warning SHA-1 is considered a weak message digest and its use * constitutes a security risk. We recommend considering * stronger message digests instead. * - * \param ctx The SHA-1 context to use. This must be initialized. - * \param data The data block being processed. This must be a - * readable buffer of length \c 64 Bytes. - * - * \return \c 0 on success. - * \return A negative error code on failure. - * */ int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx, const unsigned char data[64] ); @@ -194,71 +174,65 @@ int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx, #define MBEDTLS_DEPRECATED #endif /** - * \brief This function starts a SHA-1 checksum calculation. + * \brief SHA-1 context setup + * + * \deprecated Superseded by mbedtls_sha1_starts_ret() in 2.7.0 + * + * \param ctx The SHA-1 context to be initialized. * * \warning SHA-1 is considered a weak message digest and its use * constitutes a security risk. We recommend considering * stronger message digests instead. * - * \deprecated Superseded by mbedtls_sha1_starts_ret() in 2.7.0. - * - * \param ctx The SHA-1 context to initialize. This must be initialized. - * */ MBEDTLS_DEPRECATED void mbedtls_sha1_starts( mbedtls_sha1_context *ctx ); /** - * \brief This function feeds an input buffer into an ongoing SHA-1 - * checksum calculation. + * \brief SHA-1 process buffer + * + * \deprecated Superseded by mbedtls_sha1_update_ret() in 2.7.0 + * + * \param ctx The SHA-1 context. + * \param input The buffer holding the input data. + * \param ilen The length of the input data. * * \warning SHA-1 is considered a weak message digest and its use * constitutes a security risk. We recommend considering * stronger message digests instead. * - * \deprecated Superseded by mbedtls_sha1_update_ret() in 2.7.0. - * - * \param ctx The SHA-1 context. This must be initialized and - * have a hash operation started. - * \param input The buffer holding the input data. - * This must be a readable buffer of length \p ilen Bytes. - * \param ilen The length of the input data \p input in Bytes. - * */ MBEDTLS_DEPRECATED void mbedtls_sha1_update( mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen ); /** - * \brief This function finishes the SHA-1 operation, and writes - * the result to the output buffer. + * \brief SHA-1 final digest + * + * \deprecated Superseded by mbedtls_sha1_finish_ret() in 2.7.0 + * + * \param ctx The SHA-1 context. + * \param output The SHA-1 checksum result. * * \warning SHA-1 is considered a weak message digest and its use * constitutes a security risk. We recommend considering * stronger message digests instead. * - * \deprecated Superseded by mbedtls_sha1_finish_ret() in 2.7.0. - * - * \param ctx The SHA-1 context. This must be initialized and - * have a hash operation started. - * \param output The SHA-1 checksum result. - * This must be a writable buffer of length \c 20 Bytes. */ MBEDTLS_DEPRECATED void mbedtls_sha1_finish( mbedtls_sha1_context *ctx, unsigned char output[20] ); /** - * \brief SHA-1 process data block (internal use only). + * \brief SHA-1 process data block (internal use only) + * + * \deprecated Superseded by mbedtls_internal_sha1_process() in 2.7.0 + * + * \param ctx The SHA-1 context. + * \param data The data block being processed. * * \warning SHA-1 is considered a weak message digest and its use * constitutes a security risk. We recommend considering * stronger message digests instead. * - * \deprecated Superseded by mbedtls_internal_sha1_process() in 2.7.0. - * - * \param ctx The SHA-1 context. This must be initialized. - * \param data The data block being processed. - * This must be a readable buffer of length \c 64 bytes. - * */ MBEDTLS_DEPRECATED void mbedtls_sha1_process( mbedtls_sha1_context *ctx, const unsigned char data[64] ); @@ -266,6 +240,18 @@ MBEDTLS_DEPRECATED void mbedtls_sha1_process( mbedtls_sha1_context *ctx, #undef MBEDTLS_DEPRECATED #endif /* !MBEDTLS_DEPRECATED_REMOVED */ +#ifdef __cplusplus +} +#endif + +#else /* MBEDTLS_SHA1_ALT */ +#include "sha1_alt.h" +#endif /* MBEDTLS_SHA1_ALT */ + +#ifdef __cplusplus +extern "C" { +#endif + /** * \brief This function calculates the SHA-1 checksum of a buffer. * @@ -275,19 +261,16 @@ MBEDTLS_DEPRECATED void mbedtls_sha1_process( mbedtls_sha1_context *ctx, * The SHA-1 result is calculated as * output = SHA-1(input buffer). * + * \param input The buffer holding the input data. + * \param ilen The length of the input data. + * \param output The SHA-1 checksum result. + * + * \return \c 0 if successful + * * \warning SHA-1 is considered a weak message digest and its use * constitutes a security risk. We recommend considering * stronger message digests instead. * - * \param input The buffer holding the input data. - * This must be a readable buffer of length \p ilen Bytes. - * \param ilen The length of the input data \p input in Bytes. - * \param output The SHA-1 checksum result. - * This must be a writable buffer of length \c 20 Bytes. - * - * \return \c 0 on success. - * \return A negative error code on failure. - * */ int mbedtls_sha1_ret( const unsigned char *input, size_t ilen, @@ -300,25 +283,17 @@ int mbedtls_sha1_ret( const unsigned char *input, #define MBEDTLS_DEPRECATED #endif /** - * \brief This function calculates the SHA-1 checksum of a buffer. - * - * The function allocates the context, performs the - * calculation, and frees the context. - * - * The SHA-1 result is calculated as - * output = SHA-1(input buffer). - * - * \warning SHA-1 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. + * \brief Output = SHA-1( input buffer ) * * \deprecated Superseded by mbedtls_sha1_ret() in 2.7.0 * * \param input The buffer holding the input data. - * This must be a readable buffer of length \p ilen Bytes. - * \param ilen The length of the input data \p input in Bytes. - * \param output The SHA-1 checksum result. This must be a writable - * buffer of size \c 20 Bytes. + * \param ilen The length of the input data. + * \param output The SHA-1 checksum result. + * + * \warning SHA-1 is considered a weak message digest and its use + * constitutes a security risk. We recommend considering + * stronger message digests instead. * */ MBEDTLS_DEPRECATED void mbedtls_sha1( const unsigned char *input, @@ -328,23 +303,18 @@ MBEDTLS_DEPRECATED void mbedtls_sha1( const unsigned char *input, #undef MBEDTLS_DEPRECATED #endif /* !MBEDTLS_DEPRECATED_REMOVED */ -#if defined(MBEDTLS_SELF_TEST) - /** * \brief The SHA-1 checkup routine. * + * \return \c 0 on success, or \c 1 on failure. + * * \warning SHA-1 is considered a weak message digest and its use * constitutes a security risk. We recommend considering * stronger message digests instead. * - * \return \c 0 on success. - * \return \c 1 on failure. - * */ int mbedtls_sha1_self_test( int verbose ); -#endif /* MBEDTLS_SELF_TEST */ - #ifdef __cplusplus } #endif diff --git a/APP_Framework/Framework/security/mbedtls/sha256.c b/APP_Framework/Framework/security/mbedtls/sha256.c index eae98e335..403b00510 100644 --- a/APP_Framework/Framework/security/mbedtls/sha256.c +++ b/APP_Framework/Framework/security/mbedtls/sha256.c @@ -33,9 +33,6 @@ #if defined(MBEDTLS_SHA256_C) #include "sha256.h" -#include "platform_util.h" -#include "platform.h" -#include #include @@ -51,16 +48,38 @@ #endif /* MBEDTLS_PLATFORM_C */ #endif /* MBEDTLS_SELF_TEST */ -#define SHA256_VALIDATE_RET(cond) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA256_BAD_INPUT_DATA ) -#define SHA256_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE( cond ) - #if !defined(MBEDTLS_SHA256_ALT) +/* 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; +} + +/* + * 32-bit integer manipulation macros (big endian) + */ +#ifndef GET_UINT32_BE +#define GET_UINT32_BE(n,b,i) \ +do { \ + (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ + | ( (uint32_t) (b)[(i) + 1] << 16 ) \ + | ( (uint32_t) (b)[(i) + 2] << 8 ) \ + | ( (uint32_t) (b)[(i) + 3] ); \ +} while( 0 ) +#endif + +#ifndef PUT_UINT32_BE +#define PUT_UINT32_BE(n,b,i) \ +do { \ + (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) ); \ +} while( 0 ) +#endif + void mbedtls_sha256_init( mbedtls_sha256_context *ctx ) { - SHA256_VALIDATE( ctx != NULL ); - memset( ctx, 0, sizeof( mbedtls_sha256_context ) ); } @@ -69,15 +88,12 @@ void mbedtls_sha256_free( mbedtls_sha256_context *ctx ) if( ctx == NULL ) return; - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha256_context ) ); + mbedtls_zeroize( ctx, sizeof( mbedtls_sha256_context ) ); } void mbedtls_sha256_clone( mbedtls_sha256_context *dst, const mbedtls_sha256_context *src ) { - SHA256_VALIDATE( dst != NULL ); - SHA256_VALIDATE( src != NULL ); - *dst = *src; } @@ -86,34 +102,10 @@ void mbedtls_sha256_clone( mbedtls_sha256_context *dst, */ int mbedtls_sha256_starts_ret( mbedtls_sha256_context *ctx, int is224 ) { - SHA256_VALIDATE_RET( ctx != NULL ); -#if defined(MBEDTLS_SHA256_NO_SHA224) - SHA256_VALIDATE_RET( is224 == 0 ); - (void) is224; -#else - SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 ); -#endif - ctx->total[0] = 0; ctx->total[1] = 0; -#if !defined(MBEDTLS_SHA256_NO_SHA224) - ctx->is224 = is224; - - if( is224 == 1 ) - { - /* SHA-224 */ - ctx->state[0] = 0xC1059ED8; - ctx->state[1] = 0x367CD507; - ctx->state[2] = 0x3070DD17; - ctx->state[3] = 0xF70E5939; - ctx->state[4] = 0xFFC00B31; - ctx->state[5] = 0x68581511; - ctx->state[6] = 0x64F98FA7; - ctx->state[7] = 0xBEFA4FA4; - } - else -#endif + if( is224 == 0 ) { /* SHA-256 */ ctx->state[0] = 0x6A09E667; @@ -125,6 +117,20 @@ int mbedtls_sha256_starts_ret( mbedtls_sha256_context *ctx, int is224 ) ctx->state[6] = 0x1F83D9AB; ctx->state[7] = 0x5BE0CD19; } + else + { + /* SHA-224 */ + ctx->state[0] = 0xC1059ED8; + ctx->state[1] = 0x367CD507; + ctx->state[2] = 0x3070DD17; + ctx->state[3] = 0xF70E5939; + ctx->state[4] = 0xFFC00B31; + ctx->state[5] = 0x68581511; + ctx->state[6] = 0x64F98FA7; + ctx->state[7] = 0xBEFA4FA4; + } + + ctx->is224 = is224; return( 0 ); } @@ -158,8 +164,8 @@ static const uint32_t K[] = 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2, }; -#define SHR(x,n) (((x) & 0xFFFFFFFF) >> (n)) -#define ROTR(x,n) (SHR(x,n) | ((x) << (32 - (n)))) +#define SHR(x,n) ((x & 0xFFFFFFFF) >> n) +#define ROTR(x,n) (SHR(x,n) | (x << (32 - n))) #define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3)) #define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10)) @@ -167,77 +173,48 @@ static const uint32_t K[] = #define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22)) #define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25)) -#define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y)))) -#define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z)))) +#define F0(x,y,z) ((x & y) | (z & (x | y))) +#define F1(x,y,z) (z ^ (x & (y ^ z))) #define R(t) \ - ( \ - W[t] = S1(W[(t) - 2]) + W[(t) - 7] + \ - S0(W[(t) - 15]) + W[(t) - 16] \ - ) +( \ + W[t] = S1(W[t - 2]) + W[t - 7] + \ + S0(W[t - 15]) + W[t - 16] \ +) -#define P(a,b,c,d,e,f,g,h,x,K) \ - do \ - { \ - temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \ - temp2 = S2(a) + F0((a),(b),(c)); \ - (d) += temp1; (h) = temp1 + temp2; \ - } while( 0 ) +#define P(a,b,c,d,e,f,g,h,x,K) \ +{ \ + temp1 = h + S3(e) + F1(e,f,g) + K + x; \ + temp2 = S2(a) + F0(a,b,c); \ + d += temp1; h = temp1 + temp2; \ +} int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx, const unsigned char data[64] ) { uint32_t temp1, temp2, W[64]; uint32_t A[8]; - volatile uint32_t flow_ctrl = 0; unsigned int i; - SHA256_VALIDATE_RET( ctx != NULL ); - SHA256_VALIDATE_RET( (const unsigned char *)data != NULL ); - for( i = 0; i < 8; i++ ) A[i] = ctx->state[i]; #if defined(MBEDTLS_SHA256_SMALLER) - { - uint32_t offset = mbedtls_platform_random_in_range(16); - mbedtls_platform_memset( W, 0, sizeof( W ) ); - - for( i = offset; i < 16; i++ ) - { - W[i] = (uint32_t)mbedtls_platform_get_uint32_be( &data[4 * i] ); - flow_ctrl++; - } - for( i = 0; i < offset; i++ ) - { - W[i] = (uint32_t)mbedtls_platform_get_uint32_be( &data[4 * i] ); - flow_ctrl++; - } - } - for( i = 0; i < 64; i++ ) { - if( i >= 16 ) + if( i < 16 ) + GET_UINT32_BE( W[i], data, 4 * i ); + else R( i ); P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i], K[i] ); temp1 = A[7]; A[7] = A[6]; A[6] = A[5]; A[5] = A[4]; A[4] = A[3]; A[3] = A[2]; A[2] = A[1]; A[1] = A[0]; A[0] = temp1; - flow_ctrl++; } - - if( flow_ctrl != 80 ) - { - return MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; - } - #else /* MBEDTLS_SHA256_SMALLER */ for( i = 0; i < 16; i++ ) - { - W[i] = (uint32_t)mbedtls_platform_get_uint32_be( &data[4 * i] ); - flow_ctrl++; - } + GET_UINT32_BE( W[i], data, 4 * i ); for( i = 0; i < 16; i += 8 ) { @@ -249,7 +226,6 @@ int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx, P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[i+5], K[i+5] ); P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[i+6], K[i+6] ); P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[i+7], K[i+7] ); - flow_ctrl++; } for( i = 16; i < 64; i += 8 ) @@ -262,32 +238,13 @@ int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx, P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(i+5), K[i+5] ); P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(i+6), K[i+6] ); P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(i+7), K[i+7] ); - flow_ctrl++; - } - - /* 16 from the first loop, 2 from the second and 6 from the third. */ - if( flow_ctrl != 24 ) - { - return MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; } #endif /* MBEDTLS_SHA256_SMALLER */ - flow_ctrl = 0; for( i = 0; i < 8; i++ ) - { ctx->state[i] += A[i]; - flow_ctrl++; - } - if( flow_ctrl == 8 ) - { - mbedtls_platform_random_delay(); - if( flow_ctrl == 8 ) - return( 0 ); - } - /* Free the ctx upon suspected FI */ - mbedtls_sha256_free( ctx ); - return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); + return( 0 ); } #if !defined(MBEDTLS_DEPRECATED_REMOVED) @@ -309,65 +266,44 @@ int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx, int ret; size_t fill; uint32_t left; - volatile const unsigned char *input_dup = input; - volatile size_t ilen_dup = ilen; - size_t ilen_change; - SHA256_VALIDATE_RET( ctx != NULL ); - SHA256_VALIDATE_RET( ilen == 0 || input != NULL ); - /* ilen_dup is used instead of ilen, to have it volatile for FI protection */ - if( ilen_dup == 0 ) + if( ilen == 0 ) return( 0 ); - if( ilen_dup > UINT32_MAX ) - return( MBEDTLS_ERR_SHA256_BAD_INPUT_DATA ); - left = ctx->total[0] & 0x3F; fill = 64 - left; - ctx->total[0] += (uint32_t) ilen_dup; + ctx->total[0] += (uint32_t) ilen; + ctx->total[0] &= 0xFFFFFFFF; - if( ctx->total[0] < (uint32_t) ilen_dup ) + if( ctx->total[0] < (uint32_t) ilen ) ctx->total[1]++; - if( left && ilen_dup >= fill ) + if( left && ilen >= fill ) { - mbedtls_platform_memcpy( (void *) (ctx->buffer + left), input, fill ); + memcpy( (void *) (ctx->buffer + left), input, fill ); if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 ) return( ret ); input += fill; - ilen_dup -= fill; + ilen -= fill; left = 0; } - while( ilen_dup >= 64 ) + while( ilen >= 64 ) { if( ( ret = mbedtls_internal_sha256_process( ctx, input ) ) != 0 ) return( ret ); input += 64; - ilen_dup -= 64; + ilen -= 64; } - if( ilen_dup > 0 ) - mbedtls_platform_memcpy( (void *) (ctx->buffer + left), input, ilen_dup ); + if( ilen > 0 ) + memcpy( (void *) (ctx->buffer + left), input, ilen ); - /* Re-check ilen_dup to protect from a FI attack */ - if( ilen_dup < 64 ) - { - mbedtls_platform_random_delay(); - /* Re-check that the calculated offsets are correct */ - ilen_change = ilen - ilen_dup; - if( ( input_dup + ilen_change ) == input ) - { - return( 0 ); - } - } - /* Free the ctx upon suspected FI */ - mbedtls_sha256_free( ctx ); - return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); + return( 0 ); } #if !defined(MBEDTLS_DEPRECATED_REMOVED) @@ -385,14 +321,9 @@ void mbedtls_sha256_update( mbedtls_sha256_context *ctx, int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx, unsigned char output[32] ) { - int ret, s_pos, o_pos; + int ret; uint32_t used; uint32_t high, low; - uint32_t offset = 0; - volatile uint32_t flow_ctrl = 0; - - SHA256_VALIDATE_RET( ctx != NULL ); - SHA256_VALIDATE_RET( (unsigned char *)output != NULL ); /* * Add padding: 0x80 then 0x00 until 8 bytes remain for the length @@ -400,22 +331,21 @@ int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx, used = ctx->total[0] & 0x3F; ctx->buffer[used++] = 0x80; - flow_ctrl++; if( used <= 56 ) { /* Enough room for padding + length in current block */ - mbedtls_platform_memset( ctx->buffer + used, 0, 56 - used ); + memset( ctx->buffer + used, 0, 56 - used ); } else { /* We'll need an extra block */ - mbedtls_platform_memset( ctx->buffer + used, 0, 64 - used ); + memset( ctx->buffer + used, 0, 64 - used ); if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 ) return( ret ); - mbedtls_platform_memset( ctx->buffer, 0, 56 ); + memset( ctx->buffer, 0, 56 ); } /* @@ -425,9 +355,8 @@ int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx, | ( ctx->total[1] << 3 ); low = ( ctx->total[0] << 3 ); - (void)mbedtls_platform_put_uint32_be( ctx->buffer + 56, high ); - (void)mbedtls_platform_put_uint32_be( ctx->buffer + 60, low ); - flow_ctrl++; + PUT_UINT32_BE( high, ctx->buffer, 56 ); + PUT_UINT32_BE( low, ctx->buffer, 60 ); if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 ) return( ret ); @@ -435,40 +364,18 @@ int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx, /* * Output final state */ - offset = mbedtls_platform_random_in_range(7); + PUT_UINT32_BE( ctx->state[0], output, 0 ); + PUT_UINT32_BE( ctx->state[1], output, 4 ); + PUT_UINT32_BE( ctx->state[2], output, 8 ); + PUT_UINT32_BE( ctx->state[3], output, 12 ); + PUT_UINT32_BE( ctx->state[4], output, 16 ); + PUT_UINT32_BE( ctx->state[5], output, 20 ); + PUT_UINT32_BE( ctx->state[6], output, 24 ); - mbedtls_platform_memset( output, 0, 32 ); - - for( s_pos = offset, o_pos = offset * 4; s_pos < 7; - s_pos++, o_pos += 4 ) - { - (void)mbedtls_platform_put_uint32_be( &output[o_pos], - ctx->state[s_pos] ); - flow_ctrl++; - } - -#if !defined(MBEDTLS_SHA256_NO_SHA224) if( ctx->is224 == 0 ) -#endif - (void)mbedtls_platform_put_uint32_be( &output[28], ctx->state[7] ); + PUT_UINT32_BE( ctx->state[7], output, 28 ); - for( s_pos = 0, o_pos = 0; s_pos < (int)offset; s_pos++, o_pos += 4 ) - { - (void)mbedtls_platform_put_uint32_be( &output[o_pos], - ctx->state[s_pos] ); - flow_ctrl++; - } - /* flow ctrl was incremented twice and then 7 times in two loops */ - if( flow_ctrl == 9 ) - { - mbedtls_platform_random_delay(); - if( flow_ctrl == 9 ) - return( 0 ); - } - /* Free the ctx and clear output upon suspected FI */ - mbedtls_sha256_free( ctx ); - mbedtls_platform_memset( output, 0, 32 ); - return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); + return( 0 ); } #if !defined(MBEDTLS_DEPRECATED_REMOVED) @@ -489,14 +396,8 @@ int mbedtls_sha256_ret( const unsigned char *input, unsigned char output[32], int is224 ) { - int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; + int ret; mbedtls_sha256_context ctx; - volatile const unsigned char *input_dup = input; - volatile size_t ilen_dup = ilen; - - SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 ); - SHA256_VALIDATE_RET( ilen == 0 || input != NULL ); - SHA256_VALIDATE_RET( (unsigned char *)output != NULL ); mbedtls_sha256_init( &ctx ); @@ -512,14 +413,7 @@ int mbedtls_sha256_ret( const unsigned char *input, exit: mbedtls_sha256_free( &ctx ); - if( input_dup == input && ilen_dup == ilen ) - { - mbedtls_platform_random_delay(); - if( input_dup == input && ilen_dup == ilen ) - return( ret ); - } - mbedtls_platform_memset( output, 0, 32 ); - return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); + return( ret ); } #if !defined(MBEDTLS_DEPRECATED_REMOVED) @@ -548,9 +442,8 @@ static const size_t sha256_test_buflen[3] = 3, 56, 1000 }; -static const unsigned char sha256_test_sum[][32] = +static const unsigned char sha256_test_sum[6][32] = { -#if !defined(MBEDTLS_SHA256_NO_SHA224) /* * SHA-224 test vectors */ @@ -566,7 +459,6 @@ static const unsigned char sha256_test_sum[][32] = 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B, 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE, 0x4E, 0xE7, 0xAD, 0x67 }, -#endif /* !MBEDTLS_SHA256_NO_SHA224 */ /* * SHA-256 test vectors @@ -585,9 +477,6 @@ static const unsigned char sha256_test_sum[][32] = 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 } }; -#define SHA256_TEST_SUM_N \ - ( sizeof( sha256_test_sum ) / sizeof( sha256_test_sum[0] ) ) - /* * Checkup routine */ @@ -609,14 +498,10 @@ int mbedtls_sha256_self_test( int verbose ) mbedtls_sha256_init( &ctx ); - for( i = 0; i < (int) SHA256_TEST_SUM_N; i++ ) + for( i = 0; i < 6; i++ ) { j = i % 3; -#if !defined(MBEDTLS_SHA256_NO_SHA224) k = i < 3; -#else - k = 0; -#endif if( verbose != 0 ) mbedtls_printf( " SHA-%d test #%d: ", 256 - k * 32, j + 1 ); diff --git a/APP_Framework/Framework/security/mbedtls/sha256.h b/APP_Framework/Framework/security/mbedtls/sha256.h index 42aa988c6..ffb16c277 100644 --- a/APP_Framework/Framework/security/mbedtls/sha256.h +++ b/APP_Framework/Framework/security/mbedtls/sha256.h @@ -1,10 +1,7 @@ /** * \file sha256.h * - * \brief This file contains SHA-224 and SHA-256 definitions and functions. - * - * The Secure Hash Algorithms 224 and 256 (SHA-224 and SHA-256) cryptographic - * hash functions are defined in FIPS 180-4: Secure Hash Standard (SHS). + * \brief The SHA-224 and SHA-256 cryptographic hash function. */ /* * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved @@ -36,18 +33,16 @@ #include #include -/* MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED is deprecated and should not be used. */ #define MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED -0x0037 /**< SHA-256 hardware accelerator failed */ -#define MBEDTLS_ERR_SHA256_BAD_INPUT_DATA -0x0074 /**< SHA-256 input data was malformed. */ - -#ifdef __cplusplus -extern "C" { -#endif #if !defined(MBEDTLS_SHA256_ALT) // Regular implementation // +#ifdef __cplusplus +extern "C" { +#endif + /** * \brief The SHA-256 context structure. * @@ -55,43 +50,36 @@ extern "C" { * checksum calculations. The choice between these two is * made in the call to mbedtls_sha256_starts_ret(). */ -typedef struct mbedtls_sha256_context +typedef struct { uint32_t total[2]; /*!< The number of Bytes processed. */ uint32_t state[8]; /*!< The intermediate digest state. */ unsigned char buffer[64]; /*!< The data block being processed. */ -#if !defined(MBEDTLS_SHA256_NO_SHA224) - int is224; /*!< Determines which function to use: - 0: Use SHA-256, or 1: Use SHA-224. */ -#endif + int is224; /*!< Determines which function to use. +
          • 0: Use SHA-256.
          • +
          • 1: Use SHA-224.
          */ } mbedtls_sha256_context; -#else /* MBEDTLS_SHA256_ALT */ -#include "sha256_alt.h" -#endif /* MBEDTLS_SHA256_ALT */ - /** * \brief This function initializes a SHA-256 context. * - * \param ctx The SHA-256 context to initialize. This must not be \c NULL. + * \param ctx The SHA-256 context to initialize. */ void mbedtls_sha256_init( mbedtls_sha256_context *ctx ); /** * \brief This function clears a SHA-256 context. * - * \param ctx The SHA-256 context to clear. This may be \c NULL, in which - * case this function returns immediately. If it is not \c NULL, - * it must point to an initialized SHA-256 context. + * \param ctx The SHA-256 context to clear. */ void mbedtls_sha256_free( mbedtls_sha256_context *ctx ); /** * \brief This function clones the state of a SHA-256 context. * - * \param dst The destination context. This must be initialized. - * \param src The context to clone. This must be initialized. + * \param dst The destination context. + * \param src The context to clone. */ void mbedtls_sha256_clone( mbedtls_sha256_context *dst, const mbedtls_sha256_context *src ); @@ -100,13 +88,12 @@ void mbedtls_sha256_clone( mbedtls_sha256_context *dst, * \brief This function starts a SHA-224 or SHA-256 checksum * calculation. * - * \param ctx The context to use. This must be initialized. - * \param is224 This determines which function to use. This must be - * either \c 0 for SHA-256, or \c 1 for SHA-224. - * If #MBEDTLS_SHA256_NO_SHA224 is defined, this must be \c 0. + * \param ctx The context to initialize. + * \param is224 Determines which function to use. + *
          • 0: Use SHA-256.
          • + *
          • 1: Use SHA-224.
          * * \return \c 0 on success. - * \return A negative error code on failure. */ int mbedtls_sha256_starts_ret( mbedtls_sha256_context *ctx, int is224 ); @@ -114,14 +101,11 @@ int mbedtls_sha256_starts_ret( mbedtls_sha256_context *ctx, int is224 ); * \brief This function feeds an input buffer into an ongoing * SHA-256 checksum calculation. * - * \param ctx The SHA-256 context. This must be initialized - * and have a hash operation started. - * \param input The buffer holding the data. This must be a readable - * buffer of length \p ilen Bytes. - * \param ilen The length of the input data in Bytes. At most UINT32_MAX. + * \param ctx SHA-256 context + * \param input buffer holding the data + * \param ilen length of the input data * * \return \c 0 on success. - * \return A negative error code on failure. */ int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx, const unsigned char *input, @@ -131,13 +115,10 @@ int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx, * \brief This function finishes the SHA-256 operation, and writes * the result to the output buffer. * - * \param ctx The SHA-256 context. This must be initialized - * and have a hash operation started. + * \param ctx The SHA-256 context. * \param output The SHA-224 or SHA-256 checksum result. - * This must be a writable buffer of length \c 32 Bytes. * * \return \c 0 on success. - * \return A negative error code on failure. */ int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx, unsigned char output[32] ); @@ -147,12 +128,10 @@ int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx, * the ongoing SHA-256 computation. This function is for * internal use only. * - * \param ctx The SHA-256 context. This must be initialized. - * \param data The buffer holding one block of data. This must - * be a readable buffer of length \c 64 Bytes. + * \param ctx The SHA-256 context. + * \param data The buffer holding one block of data. * * \return \c 0 on success. - * \return A negative error code on failure. */ int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx, const unsigned char data[64] ); @@ -164,15 +143,14 @@ int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx, #define MBEDTLS_DEPRECATED #endif /** - * \brief This function starts a SHA-224 or SHA-256 checksum - * calculation. + * \brief This function starts a SHA-256 checksum calculation. * * \deprecated Superseded by mbedtls_sha256_starts_ret() in 2.7.0. * - * \param ctx The context to use. This must be initialized. - * \param is224 Determines which function to use. This must be - * either \c 0 for SHA-256, or \c 1 for SHA-224. - * If #MBEDTLS_SHA256_NO_SHA224 is defined, this must be \c 0. + * \param ctx The SHA-256 context to initialize. + * \param is224 Determines which function to use. + *
          • 0: Use SHA-256.
          • + *
          • 1: Use SHA-224.
          */ MBEDTLS_DEPRECATED void mbedtls_sha256_starts( mbedtls_sha256_context *ctx, int is224 ); @@ -183,11 +161,9 @@ MBEDTLS_DEPRECATED void mbedtls_sha256_starts( mbedtls_sha256_context *ctx, * * \deprecated Superseded by mbedtls_sha256_update_ret() in 2.7.0. * - * \param ctx The SHA-256 context to use. This must be - * initialized and have a hash operation started. - * \param input The buffer holding the data. This must be a readable - * buffer of length \p ilen Bytes. - * \param ilen The length of the input data in Bytes. + * \param ctx The SHA-256 context to initialize. + * \param input The buffer holding the data. + * \param ilen The length of the input data. */ MBEDTLS_DEPRECATED void mbedtls_sha256_update( mbedtls_sha256_context *ctx, const unsigned char *input, @@ -199,10 +175,8 @@ MBEDTLS_DEPRECATED void mbedtls_sha256_update( mbedtls_sha256_context *ctx, * * \deprecated Superseded by mbedtls_sha256_finish_ret() in 2.7.0. * - * \param ctx The SHA-256 context. This must be initialized and - * have a hash operation started. - * \param output The SHA-224 or SHA-256 checksum result. This must be - * a writable buffer of length \c 32 Bytes. + * \param ctx The SHA-256 context. + * \param output The SHA-224or SHA-256 checksum result. */ MBEDTLS_DEPRECATED void mbedtls_sha256_finish( mbedtls_sha256_context *ctx, unsigned char output[32] ); @@ -214,15 +188,25 @@ MBEDTLS_DEPRECATED void mbedtls_sha256_finish( mbedtls_sha256_context *ctx, * * \deprecated Superseded by mbedtls_internal_sha256_process() in 2.7.0. * - * \param ctx The SHA-256 context. This must be initialized. - * \param data The buffer holding one block of data. This must be - * a readable buffer of size \c 64 Bytes. + * \param ctx The SHA-256 context. + * \param data The buffer holding one block of data. */ MBEDTLS_DEPRECATED void mbedtls_sha256_process( mbedtls_sha256_context *ctx, const unsigned char data[64] ); #undef MBEDTLS_DEPRECATED #endif /* !MBEDTLS_DEPRECATED_REMOVED */ +#ifdef __cplusplus +} +#endif + +#else /* MBEDTLS_SHA256_ALT */ +#include "sha256_alt.h" +#endif /* MBEDTLS_SHA256_ALT */ + +#ifdef __cplusplus +extern "C" { +#endif /** * \brief This function calculates the SHA-224 or SHA-256 @@ -234,14 +218,12 @@ MBEDTLS_DEPRECATED void mbedtls_sha256_process( mbedtls_sha256_context *ctx, * The SHA-256 result is calculated as * output = SHA-256(input buffer). * - * \param input The buffer holding the data. This must be a readable - * buffer of length \p ilen Bytes. - * \param ilen The length of the input data in Bytes. - * \param output The SHA-224 or SHA-256 checksum result. This must - * be a writable buffer of length \c 32 Bytes. - * \param is224 Determines which function to use. This must be - * either \c 0 for SHA-256, or \c 1 for SHA-224. - * If #MBEDTLS_SHA256_NO_SHA224 is defined, this must be \c 0. + * \param input The buffer holding the input data. + * \param ilen The length of the input data. + * \param output The SHA-224 or SHA-256 checksum result. + * \param is224 Determines which function to use. + *
          • 0: Use SHA-256.
          • + *
          • 1: Use SHA-224.
          */ int mbedtls_sha256_ret( const unsigned char *input, size_t ilen, @@ -267,14 +249,12 @@ int mbedtls_sha256_ret( const unsigned char *input, * * \deprecated Superseded by mbedtls_sha256_ret() in 2.7.0. * - * \param input The buffer holding the data. This must be a readable - * buffer of length \p ilen Bytes. - * \param ilen The length of the input data in Bytes. - * \param output The SHA-224 or SHA-256 checksum result. This must be - * a writable buffer of length \c 32 Bytes. - * \param is224 Determines which function to use. This must be either - * \c 0 for SHA-256, or \c 1 for SHA-224. - * If #MBEDTLS_SHA256_NO_SHA224 is defined, this must be \c 0. + * \param input The buffer holding the data. + * \param ilen The length of the input data. + * \param output The SHA-224 or SHA-256 checksum result. + * \param is224 Determines which function to use. + *
          • 0: Use SHA-256.
          • + *
          • 1: Use SHA-224.
          */ MBEDTLS_DEPRECATED void mbedtls_sha256( const unsigned char *input, size_t ilen, @@ -284,18 +264,13 @@ MBEDTLS_DEPRECATED void mbedtls_sha256( const unsigned char *input, #undef MBEDTLS_DEPRECATED #endif /* !MBEDTLS_DEPRECATED_REMOVED */ -#if defined(MBEDTLS_SELF_TEST) - /** * \brief The SHA-224 and SHA-256 checkup routine. * - * \return \c 0 on success. - * \return \c 1 on failure. + * \return \c 0 on success, or \c 1 on failure. */ int mbedtls_sha256_self_test( int verbose ); -#endif /* MBEDTLS_SELF_TEST */ - #ifdef __cplusplus } #endif diff --git a/APP_Framework/Framework/security/mbedtls/sha512.c b/APP_Framework/Framework/security/mbedtls/sha512.c new file mode 100644 index 000000000..b3cc96eed --- /dev/null +++ b/APP_Framework/Framework/security/mbedtls/sha512.c @@ -0,0 +1,614 @@ +/* + * FIPS-180-2 compliant SHA-384/512 implementation + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +/* + * The SHA-512 Secure Hash Standard was published by NIST in 2002. + * + * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_SHA512_C) + +#include "sha512.h" + +#if defined(_MSC_VER) || defined(__WATCOMC__) + #define UL64(x) x##ui64 +#else + #define UL64(x) x##ULL +#endif + +#include + +#if defined(MBEDTLS_SELF_TEST) +#if defined(MBEDTLS_PLATFORM_C) +#include "platform.h" +#else +#include +#include +#define mbedtls_printf printf +#define mbedtls_calloc calloc +#define mbedtls_free free +#endif /* MBEDTLS_PLATFORM_C */ +#endif /* MBEDTLS_SELF_TEST */ + +#if !defined(MBEDTLS_SHA512_ALT) + +/* 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; +} + +/* + * 64-bit integer manipulation macros (big endian) + */ +#ifndef GET_UINT64_BE +#define GET_UINT64_BE(n,b,i) \ +{ \ + (n) = ( (uint64_t) (b)[(i) ] << 56 ) \ + | ( (uint64_t) (b)[(i) + 1] << 48 ) \ + | ( (uint64_t) (b)[(i) + 2] << 40 ) \ + | ( (uint64_t) (b)[(i) + 3] << 32 ) \ + | ( (uint64_t) (b)[(i) + 4] << 24 ) \ + | ( (uint64_t) (b)[(i) + 5] << 16 ) \ + | ( (uint64_t) (b)[(i) + 6] << 8 ) \ + | ( (uint64_t) (b)[(i) + 7] ); \ +} +#endif /* GET_UINT64_BE */ + +#ifndef PUT_UINT64_BE +#define PUT_UINT64_BE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( (n) >> 56 ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 48 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 40 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) >> 32 ); \ + (b)[(i) + 4] = (unsigned char) ( (n) >> 24 ); \ + (b)[(i) + 5] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 6] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 7] = (unsigned char) ( (n) ); \ +} +#endif /* PUT_UINT64_BE */ + +void mbedtls_sha512_init( mbedtls_sha512_context *ctx ) +{ + memset( ctx, 0, sizeof( mbedtls_sha512_context ) ); +} + +void mbedtls_sha512_free( mbedtls_sha512_context *ctx ) +{ + if( ctx == NULL ) + return; + + mbedtls_zeroize( ctx, sizeof( mbedtls_sha512_context ) ); +} + +void mbedtls_sha512_clone( mbedtls_sha512_context *dst, + const mbedtls_sha512_context *src ) +{ + *dst = *src; +} + +/* + * SHA-512 context setup + */ +int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 ) +{ + ctx->total[0] = 0; + ctx->total[1] = 0; + + if( is384 == 0 ) + { + /* SHA-512 */ + ctx->state[0] = UL64(0x6A09E667F3BCC908); + ctx->state[1] = UL64(0xBB67AE8584CAA73B); + ctx->state[2] = UL64(0x3C6EF372FE94F82B); + ctx->state[3] = UL64(0xA54FF53A5F1D36F1); + ctx->state[4] = UL64(0x510E527FADE682D1); + ctx->state[5] = UL64(0x9B05688C2B3E6C1F); + ctx->state[6] = UL64(0x1F83D9ABFB41BD6B); + ctx->state[7] = UL64(0x5BE0CD19137E2179); + } + else + { + /* SHA-384 */ + ctx->state[0] = UL64(0xCBBB9D5DC1059ED8); + ctx->state[1] = UL64(0x629A292A367CD507); + ctx->state[2] = UL64(0x9159015A3070DD17); + ctx->state[3] = UL64(0x152FECD8F70E5939); + ctx->state[4] = UL64(0x67332667FFC00B31); + ctx->state[5] = UL64(0x8EB44A8768581511); + ctx->state[6] = UL64(0xDB0C2E0D64F98FA7); + ctx->state[7] = UL64(0x47B5481DBEFA4FA4); + } + + 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) + +/* + * Round constants + */ +static const uint64_t K[80] = +{ + UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD), + UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC), + UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019), + UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118), + UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE), + UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2), + UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1), + UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694), + UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3), + UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65), + UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483), + UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5), + UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210), + UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4), + UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725), + UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70), + UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926), + UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF), + UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8), + UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B), + UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001), + UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30), + UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910), + UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8), + UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53), + UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8), + UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB), + UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3), + UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60), + UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC), + UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9), + UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B), + UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207), + UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178), + UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6), + UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B), + UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493), + UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C), + UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A), + UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817) +}; + +int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx, + const unsigned char data[128] ) +{ + int i; + uint64_t temp1, temp2, W[80]; + uint64_t A, B, C, D, E, F, G, H; + +#define SHR(x,n) (x >> n) +#define ROTR(x,n) (SHR(x,n) | (x << (64 - n))) + +#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7)) +#define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6)) + +#define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39)) +#define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41)) + +#define F0(x,y,z) ((x & y) | (z & (x | y))) +#define F1(x,y,z) (z ^ (x & (y ^ z))) + +#define P(a,b,c,d,e,f,g,h,x,K) \ +{ \ + temp1 = h + S3(e) + F1(e,f,g) + K + x; \ + temp2 = S2(a) + F0(a,b,c); \ + d += temp1; h = temp1 + temp2; \ +} + + for( i = 0; i < 16; i++ ) + { + GET_UINT64_BE( W[i], data, i << 3 ); + } + + for( ; i < 80; i++ ) + { + W[i] = S1(W[i - 2]) + W[i - 7] + + S0(W[i - 15]) + W[i - 16]; + } + + A = ctx->state[0]; + B = ctx->state[1]; + C = ctx->state[2]; + D = ctx->state[3]; + E = ctx->state[4]; + F = ctx->state[5]; + G = ctx->state[6]; + H = ctx->state[7]; + i = 0; + + do + { + P( A, B, C, D, E, F, G, H, W[i], K[i] ); i++; + P( H, A, B, C, D, E, F, G, W[i], K[i] ); i++; + P( G, H, A, B, C, D, E, F, W[i], K[i] ); i++; + P( F, G, H, A, B, C, D, E, W[i], K[i] ); i++; + P( E, F, G, H, A, B, C, D, W[i], K[i] ); i++; + P( D, E, F, G, H, A, B, C, W[i], K[i] ); i++; + P( C, D, E, F, G, H, A, B, W[i], K[i] ); i++; + P( B, C, D, E, F, G, H, A, W[i], K[i] ); i++; + } + while( i < 80 ); + + ctx->state[0] += A; + ctx->state[1] += B; + ctx->state[2] += C; + ctx->state[3] += D; + ctx->state[4] += E; + ctx->state[5] += F; + ctx->state[6] += G; + 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 */ + +/* + * SHA-512 process buffer + */ +int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx, + const unsigned char *input, + size_t ilen ) +{ + int ret; + size_t fill; + unsigned int left; + + if( ilen == 0 ) + return( 0 ); + + left = (unsigned int) (ctx->total[0] & 0x7F); + fill = 128 - left; + + ctx->total[0] += (uint64_t) ilen; + + if( ctx->total[0] < (uint64_t) ilen ) + ctx->total[1]++; + + if( left && ilen >= fill ) + { + memcpy( (void *) (ctx->buffer + left), input, fill ); + + if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 ) + return( ret ); + + input += fill; + ilen -= fill; + left = 0; + } + + while( ilen >= 128 ) + { + if( ( ret = mbedtls_internal_sha512_process( ctx, input ) ) != 0 ) + return( ret ); + + input += 128; + ilen -= 128; + } + + if( ilen > 0 ) + memcpy( (void *) (ctx->buffer + left), input, ilen ); + + return( 0 ); +} + +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +void mbedtls_sha512_update( mbedtls_sha512_context *ctx, + const unsigned char *input, + size_t ilen ) +{ + mbedtls_sha512_update_ret( ctx, input, ilen ); +} +#endif + +/* + * SHA-512 final digest + */ +int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx, + unsigned char output[64] ) +{ + int ret; + unsigned used; + uint64_t high, low; + + /* + * 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 ) + | ( ctx->total[1] << 3 ); + low = ( ctx->total[0] << 3 ); + + PUT_UINT64_BE( high, ctx->buffer, 112 ); + PUT_UINT64_BE( low, ctx->buffer, 120 ); + + if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 ) + return( ret ); + + /* + * Output final state + */ + PUT_UINT64_BE( ctx->state[0], output, 0 ); + PUT_UINT64_BE( ctx->state[1], output, 8 ); + PUT_UINT64_BE( ctx->state[2], output, 16 ); + PUT_UINT64_BE( ctx->state[3], output, 24 ); + PUT_UINT64_BE( ctx->state[4], output, 32 ); + PUT_UINT64_BE( ctx->state[5], output, 40 ); + + if( ctx->is384 == 0 ) + { + PUT_UINT64_BE( ctx->state[6], output, 48 ); + 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 */ + +/* + * output = SHA-512( input buffer ) + */ +int mbedtls_sha512_ret( const unsigned char *input, + size_t ilen, + unsigned char output[64], + int is384 ) +{ + int ret; + mbedtls_sha512_context ctx; + + mbedtls_sha512_init( &ctx ); + + if( ( ret = mbedtls_sha512_starts_ret( &ctx, is384 ) ) != 0 ) + 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 ); + + 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) + +/* + * FIPS-180-2 test vectors + */ +static const unsigned char sha512_test_buf[3][113] = +{ + { "abc" }, + { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn" + "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" }, + { "" } +}; + +static const size_t sha512_test_buflen[3] = +{ + 3, 112, 1000 +}; + +static const unsigned char sha512_test_sum[6][64] = +{ + /* + * SHA-384 test vectors + */ + { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B, + 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07, + 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63, + 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED, + 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23, + 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 }, + { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8, + 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47, + 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2, + 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12, + 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9, + 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 }, + { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB, + 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C, + 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52, + 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B, + 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB, + 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 }, + + /* + * SHA-512 test vectors + */ + { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA, + 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31, + 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2, + 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A, + 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8, + 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD, + 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E, + 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F }, + { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA, + 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F, + 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1, + 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18, + 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4, + 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A, + 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54, + 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 }, + { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64, + 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63, + 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28, + 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB, + 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A, + 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B, + 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E, + 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B } +}; + +/* + * Checkup routine + */ +int mbedtls_sha512_self_test( int verbose ) +{ + int i, j, k, buflen, ret = 0; + unsigned char *buf; + unsigned char sha512sum[64]; + mbedtls_sha512_context ctx; + + buf = mbedtls_calloc( 1024, sizeof(unsigned char) ); + if( NULL == buf ) + { + if( verbose != 0 ) + mbedtls_printf( "Buffer allocation failed\n" ); + + return( 1 ); + } + + mbedtls_sha512_init( &ctx ); + + for( i = 0; i < 6; i++ ) + { + j = i % 3; + k = i < 3; + + if( verbose != 0 ) + mbedtls_printf( " SHA-%d test #%d: ", 512 - k * 128, j + 1 ); + + if( ( ret = mbedtls_sha512_starts_ret( &ctx, k ) ) != 0 ) + goto fail; + + if( j == 2 ) + { + memset( buf, 'a', buflen = 1000 ); + + for( j = 0; j < 1000; j++ ) + { + ret = mbedtls_sha512_update_ret( &ctx, buf, buflen ); + if( ret != 0 ) + goto fail; + } + } + else + { + ret = mbedtls_sha512_update_ret( &ctx, sha512_test_buf[j], + sha512_test_buflen[j] ); + if( ret != 0 ) + goto fail; + } + + if( ( ret = mbedtls_sha512_finish_ret( &ctx, sha512sum ) ) != 0 ) + goto fail; + + if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 ) + { + ret = 1; + goto fail; + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + } + + if( verbose != 0 ) + mbedtls_printf( "\n" ); + + goto exit; + +fail: + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + +exit: + mbedtls_sha512_free( &ctx ); + mbedtls_free( buf ); + + return( ret ); +} + +#endif /* MBEDTLS_SELF_TEST */ + +#endif /* MBEDTLS_SHA512_C */ diff --git a/APP_Framework/Framework/security/mbedtls/sha512.h b/APP_Framework/Framework/security/mbedtls/sha512.h index c06ceed1d..8404a2d59 100644 --- a/APP_Framework/Framework/security/mbedtls/sha512.h +++ b/APP_Framework/Framework/security/mbedtls/sha512.h @@ -1,9 +1,7 @@ /** * \file sha512.h - * \brief This file contains SHA-384 and SHA-512 definitions and functions. * - * The Secure Hash Algorithms 384 and 512 (SHA-384 and SHA-512) cryptographic - * hash functions are defined in FIPS 180-4: Secure Hash Standard (SHS). + * \brief The SHA-384 and SHA-512 cryptographic hash function. */ /* * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved @@ -35,18 +33,16 @@ #include #include -/* MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED is deprecated and should not be used. */ #define MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED -0x0039 /**< SHA-512 hardware accelerator failed */ -#define MBEDTLS_ERR_SHA512_BAD_INPUT_DATA -0x0075 /**< SHA-512 input data was malformed. */ - -#ifdef __cplusplus -extern "C" { -#endif #if !defined(MBEDTLS_SHA512_ALT) // Regular implementation // +#ifdef __cplusplus +extern "C" { +#endif + /** * \brief The SHA-512 context structure. * @@ -54,43 +50,36 @@ extern "C" { * checksum calculations. The choice between these two is * made in the call to mbedtls_sha512_starts_ret(). */ -typedef struct mbedtls_sha512_context +typedef struct { uint64_t total[2]; /*!< The number of Bytes processed. */ uint64_t state[8]; /*!< The intermediate digest state. */ unsigned char buffer[128]; /*!< The data block being processed. */ - int is384; /*!< Determines which function to use: - 0: Use SHA-512, or 1: Use SHA-384. */ + int is384; /*!< Determines which function to use. + *
          • 0: Use SHA-512.
          • + *
          • 1: Use SHA-384.
          */ } mbedtls_sha512_context; -#else /* MBEDTLS_SHA512_ALT */ -#include "sha512_alt.h" -#endif /* MBEDTLS_SHA512_ALT */ - /** * \brief This function initializes a SHA-512 context. * - * \param ctx The SHA-512 context to initialize. This must - * not be \c NULL. + * \param ctx The SHA-512 context to initialize. */ void mbedtls_sha512_init( mbedtls_sha512_context *ctx ); /** * \brief This function clears a SHA-512 context. * - * \param ctx The SHA-512 context to clear. This may be \c NULL, - * in which case this function does nothing. If it - * is not \c NULL, it must point to an initialized - * SHA-512 context. + * \param ctx The SHA-512 context to clear. */ void mbedtls_sha512_free( mbedtls_sha512_context *ctx ); /** * \brief This function clones the state of a SHA-512 context. * - * \param dst The destination context. This must be initialized. - * \param src The context to clone. This must be initialized. + * \param dst The destination context. + * \param src The context to clone. */ void mbedtls_sha512_clone( mbedtls_sha512_context *dst, const mbedtls_sha512_context *src ); @@ -99,12 +88,12 @@ void mbedtls_sha512_clone( mbedtls_sha512_context *dst, * \brief This function starts a SHA-384 or SHA-512 checksum * calculation. * - * \param ctx The SHA-512 context to use. This must be initialized. - * \param is384 Determines which function to use. This must be - * either \c for SHA-512, or \c 1 for SHA-384. + * \param ctx The SHA-512 context to initialize. + * \param is384 Determines which function to use. + *
          • 0: Use SHA-512.
          • + *
          • 1: Use SHA-384.
          * * \return \c 0 on success. - * \return A negative error code on failure. */ int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 ); @@ -112,14 +101,11 @@ int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 ); * \brief This function feeds an input buffer into an ongoing * SHA-512 checksum calculation. * - * \param ctx The SHA-512 context. This must be initialized - * and have a hash operation started. - * \param input The buffer holding the input data. This must - * be a readable buffer of length \p ilen Bytes. - * \param ilen The length of the input data in Bytes. + * \param ctx The SHA-512 context. + * \param input The buffer holding the input data. + * \param ilen The length of the input data. * * \return \c 0 on success. - * \return A negative error code on failure. */ int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx, const unsigned char *input, @@ -130,13 +116,10 @@ int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx, * the result to the output buffer. This function is for * internal use only. * - * \param ctx The SHA-512 context. This must be initialized - * and have a hash operation started. + * \param ctx The SHA-512 context. * \param output The SHA-384 or SHA-512 checksum result. - * This must be a writable buffer of length \c 64 Bytes. * * \return \c 0 on success. - * \return A negative error code on failure. */ int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx, unsigned char output[64] ); @@ -145,12 +128,10 @@ int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx, * \brief This function processes a single data block within * the ongoing SHA-512 computation. * - * \param ctx The SHA-512 context. This must be initialized. - * \param data The buffer holding one block of data. This - * must be a readable buffer of length \c 128 Bytes. + * \param ctx The SHA-512 context. + * \param data The buffer holding one block of data. * * \return \c 0 on success. - * \return A negative error code on failure. */ int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx, const unsigned char data[128] ); @@ -166,9 +147,10 @@ int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx, * * \deprecated Superseded by mbedtls_sha512_starts_ret() in 2.7.0 * - * \param ctx The SHA-512 context to use. This must be initialized. - * \param is384 Determines which function to use. This must be either - * \c 0 for SHA-512 or \c 1 for SHA-384. + * \param ctx The SHA-512 context to initialize. + * \param is384 Determines which function to use. + *
          • 0: Use SHA-512.
          • + *
          • 1: Use SHA-384.
          */ MBEDTLS_DEPRECATED void mbedtls_sha512_starts( mbedtls_sha512_context *ctx, int is384 ); @@ -177,13 +159,11 @@ MBEDTLS_DEPRECATED void mbedtls_sha512_starts( mbedtls_sha512_context *ctx, * \brief This function feeds an input buffer into an ongoing * SHA-512 checksum calculation. * - * \deprecated Superseded by mbedtls_sha512_update_ret() in 2.7.0. + * \deprecated Superseded by mbedtls_sha512_update_ret() in 2.7.0 * - * \param ctx The SHA-512 context. This must be initialized - * and have a hash operation started. - * \param input The buffer holding the data. This must be a readable - * buffer of length \p ilen Bytes. - * \param ilen The length of the input data in Bytes. + * \param ctx The SHA-512 context. + * \param input The buffer holding the data. + * \param ilen The length of the input data. */ MBEDTLS_DEPRECATED void mbedtls_sha512_update( mbedtls_sha512_context *ctx, const unsigned char *input, @@ -193,12 +173,10 @@ MBEDTLS_DEPRECATED void mbedtls_sha512_update( mbedtls_sha512_context *ctx, * \brief This function finishes the SHA-512 operation, and writes * the result to the output buffer. * - * \deprecated Superseded by mbedtls_sha512_finish_ret() in 2.7.0. + * \deprecated Superseded by mbedtls_sha512_finish_ret() in 2.7.0 * - * \param ctx The SHA-512 context. This must be initialized - * and have a hash operation started. - * \param output The SHA-384 or SHA-512 checksum result. This must - * be a writable buffer of size \c 64 Bytes. + * \param ctx The SHA-512 context. + * \param output The SHA-384 or SHA-512 checksum result. */ MBEDTLS_DEPRECATED void mbedtls_sha512_finish( mbedtls_sha512_context *ctx, unsigned char output[64] ); @@ -208,11 +186,10 @@ MBEDTLS_DEPRECATED void mbedtls_sha512_finish( mbedtls_sha512_context *ctx, * the ongoing SHA-512 computation. This function is for * internal use only. * - * \deprecated Superseded by mbedtls_internal_sha512_process() in 2.7.0. + * \deprecated Superseded by mbedtls_internal_sha512_process() in 2.7.0 * - * \param ctx The SHA-512 context. This must be initialized. - * \param data The buffer holding one block of data. This must be - * a readable buffer of length \c 128 Bytes. + * \param ctx The SHA-512 context. + * \param data The buffer holding one block of data. */ MBEDTLS_DEPRECATED void mbedtls_sha512_process( mbedtls_sha512_context *ctx, @@ -221,6 +198,18 @@ MBEDTLS_DEPRECATED void mbedtls_sha512_process( #undef MBEDTLS_DEPRECATED #endif /* !MBEDTLS_DEPRECATED_REMOVED */ +#ifdef __cplusplus +} +#endif + +#else /* MBEDTLS_SHA512_ALT */ +#include "sha512_alt.h" +#endif /* MBEDTLS_SHA512_ALT */ + +#ifdef __cplusplus +extern "C" { +#endif + /** * \brief This function calculates the SHA-512 or SHA-384 * checksum of a buffer. @@ -231,16 +220,14 @@ MBEDTLS_DEPRECATED void mbedtls_sha512_process( * The SHA-512 result is calculated as * output = SHA-512(input buffer). * - * \param input The buffer holding the input data. This must be - * a readable buffer of length \p ilen Bytes. - * \param ilen The length of the input data in Bytes. + * \param input The buffer holding the input data. + * \param ilen The length of the input data. * \param output The SHA-384 or SHA-512 checksum result. - * This must be a writable buffer of length \c 64 Bytes. - * \param is384 Determines which function to use. This must be either - * \c 0 for SHA-512, or \c 1 for SHA-384. + * \param is384 Determines which function to use. + *
          • 0: Use SHA-512.
          • + *
          • 1: Use SHA-384.
          * * \return \c 0 on success. - * \return A negative error code on failure. */ int mbedtls_sha512_ret( const unsigned char *input, size_t ilen, @@ -253,7 +240,6 @@ int mbedtls_sha512_ret( const unsigned char *input, #else #define MBEDTLS_DEPRECATED #endif - /** * \brief This function calculates the SHA-512 or SHA-384 * checksum of a buffer. @@ -266,13 +252,12 @@ int mbedtls_sha512_ret( const unsigned char *input, * * \deprecated Superseded by mbedtls_sha512_ret() in 2.7.0 * - * \param input The buffer holding the data. This must be a - * readable buffer of length \p ilen Bytes. - * \param ilen The length of the input data in Bytes. - * \param output The SHA-384 or SHA-512 checksum result. This must - * be a writable buffer of length \c 64 Bytes. - * \param is384 Determines which function to use. This must be either - * \c 0 for SHA-512, or \c 1 for SHA-384. + * \param input The buffer holding the data. + * \param ilen The length of the input data. + * \param output The SHA-384 or SHA-512 checksum result. + * \param is384 Determines which function to use. + *
          • 0: Use SHA-512.
          • + *
          • 1: Use SHA-384.
          */ MBEDTLS_DEPRECATED void mbedtls_sha512( const unsigned char *input, size_t ilen, @@ -281,17 +266,12 @@ MBEDTLS_DEPRECATED void mbedtls_sha512( const unsigned char *input, #undef MBEDTLS_DEPRECATED #endif /* !MBEDTLS_DEPRECATED_REMOVED */ - -#if defined(MBEDTLS_SELF_TEST) - /** * \brief The SHA-384 or SHA-512 checkup routine. * - * \return \c 0 on success. - * \return \c 1 on failure. + * \return \c 0 on success, or \c 1 on failure. */ int mbedtls_sha512_self_test( int verbose ); -#endif /* MBEDTLS_SELF_TEST */ #ifdef __cplusplus } diff --git a/APP_Framework/Framework/security/mbedtls/ssl.h b/APP_Framework/Framework/security/mbedtls/ssl.h index c0a4a5504..5593a5282 100644 --- a/APP_Framework/Framework/security/mbedtls/ssl.h +++ b/APP_Framework/Framework/security/mbedtls/ssl.h @@ -31,6 +31,9 @@ #endif #include "bignum.h" +#include "ecp.h" + +#include "ssl_ciphersuites.h" #if defined(MBEDTLS_X509_CRT_PARSE_C) #include "x509_crt.h" @@ -41,24 +44,11 @@ #include "dhm.h" #endif -#if defined(MBEDTLS_ECP_C) -#include "ecp.h" -#endif - -#if defined(MBEDTLS_USE_TINYCRYPT) -#include "tinycrypt/ecc.h" +#if defined(MBEDTLS_ECDH_C) +#include "ecdh.h" #endif #if defined(MBEDTLS_ZLIB_SUPPORT) - -#if defined(MBEDTLS_DEPRECATED_WARNING) -#warning "Record compression support via MBEDTLS_ZLIB_SUPPORT is deprecated and will be removed in the next major revision of the library" -#endif - -#if defined(MBEDTLS_DEPRECATED_REMOVED) -#error "Record compression support via MBEDTLS_ZLIB_SUPPORT is deprecated and cannot be used if MBEDTLS_DEPRECATED_REMOVED is set" -#endif - #include "zlib.h" #endif @@ -66,18 +56,6 @@ #include "platform_time.h" #endif -#if defined(MBEDTLS_SSL_CONF_MAX_MAJOR_VER) && \ - defined(MBEDTLS_SSL_CONF_MIN_MAJOR_VER) && \ - ( MBEDTLS_SSL_CONF_MAX_MAJOR_VER == MBEDTLS_SSL_CONF_MIN_MAJOR_VER ) -#define MBEDTLS_SSL_CONF_FIXED_MAJOR_VER MBEDTLS_SSL_CONF_MIN_MAJOR_VER -#endif - -#if defined(MBEDTLS_SSL_CONF_MAX_MINOR_VER) && \ - defined(MBEDTLS_SSL_CONF_MIN_MINOR_VER) && \ - ( MBEDTLS_SSL_CONF_MAX_MINOR_VER == MBEDTLS_SSL_CONF_MIN_MINOR_VER ) -#define MBEDTLS_SSL_CONF_FIXED_MINOR_VER MBEDTLS_SSL_CONF_MIN_MINOR_VER -#endif - /* * SSL Error codes */ @@ -125,41 +103,22 @@ #define MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED -0x6A80 /**< DTLS client must retry for hello verification */ #define MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL -0x6A00 /**< A buffer is too small to receive or write a message */ #define MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE -0x6980 /**< None of the common ciphersuites is usable (eg, no suitable certificate, see debug messages). */ -/* - * MBEDTLS_ERR_SSL_WANT_READ and MBEDTLS_ERR_SSL_WANT_WRITE are dismissable errors, - * therefore the hamming distance to other non-dismissable errors should be - * large to prevent bit-flipping a non-dismissable error to dismissable. - */ -#define MBEDTLS_ERR_SSL_WANT_READ -0xFF6900 /**< No data of requested type currently available on underlying transport. */ -#define MBEDTLS_ERR_SSL_WANT_WRITE -0xFF6880 /**< Connection requires a write call. */ +#define MBEDTLS_ERR_SSL_WANT_READ -0x6900 /**< Connection requires a read call. */ +#define MBEDTLS_ERR_SSL_WANT_WRITE -0x6880 /**< Connection requires a write call. */ #define MBEDTLS_ERR_SSL_TIMEOUT -0x6800 /**< The operation timed out. */ #define MBEDTLS_ERR_SSL_CLIENT_RECONNECT -0x6780 /**< The client initiated a reconnect from the same port. */ #define MBEDTLS_ERR_SSL_UNEXPECTED_RECORD -0x6700 /**< Record header looks valid but is not expected. */ #define MBEDTLS_ERR_SSL_NON_FATAL -0x6680 /**< The alert message received indicates a non-fatal error. */ #define MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH -0x6600 /**< Couldn't set the hash for verifying CertificateVerify */ -#define MBEDTLS_ERR_SSL_CONTINUE_PROCESSING -0x6580 /**< Internal-only message signaling that further message-processing should be done */ -#define MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS -0x6500 /**< The asynchronous operation is not completed yet. */ -#define MBEDTLS_ERR_SSL_EARLY_MESSAGE -0x6480 /**< Internal-only message signaling that a message arrived early. */ -#define MBEDTLS_ERR_SSL_UNEXPECTED_CID -0x6000 /**< An encrypted DTLS-frame with an unexpected CID was received. */ -#define MBEDTLS_ERR_SSL_VERSION_MISMATCH -0x5F00 /**< An operation failed due to an unexpected version or configuration. */ -#define MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS -0x7000 /**< A cryptographic operation is in progress. Try again later. */ /* * Various constants */ -#if !defined(MBEDTLS_SSL_PROTO_NO_TLS) #define MBEDTLS_SSL_MAJOR_VERSION_3 3 #define MBEDTLS_SSL_MINOR_VERSION_0 0 /*!< SSL v3.0 */ #define MBEDTLS_SSL_MINOR_VERSION_1 1 /*!< TLS v1.0 */ #define MBEDTLS_SSL_MINOR_VERSION_2 2 /*!< TLS v1.1 */ #define MBEDTLS_SSL_MINOR_VERSION_3 3 /*!< TLS v1.2 */ -#else /* MBEDTLS_SSL_PROTO_NO_TLS */ -#define MBEDTLS_SSL_MAJOR_VERSION_3 254 -#define MBEDTLS_SSL_MINOR_VERSION_0 257 /*!< unused */ -#define MBEDTLS_SSL_MINOR_VERSION_1 256 /*!< unused */ -#define MBEDTLS_SSL_MINOR_VERSION_2 255 /*!< DTLS v1.0 */ -#define MBEDTLS_SSL_MINOR_VERSION_3 253 /*!< DTLS v1.2 */ -#endif /* MBEDTLS_SSL_PROTO_NO_TLS */ #define MBEDTLS_SSL_TRANSPORT_STREAM 0 /*!< TLS */ #define MBEDTLS_SSL_TRANSPORT_DATAGRAM 1 /*!< DTLS */ @@ -184,22 +143,16 @@ #define MBEDTLS_SSL_EXTENDED_MS_DISABLED 0 #define MBEDTLS_SSL_EXTENDED_MS_ENABLED 1 -#define MBEDTLS_SSL_EXTENDED_MS_ENFORCE_DISABLED 0 -#define MBEDTLS_SSL_EXTENDED_MS_ENFORCE_ENABLED 1 - -#define MBEDTLS_SSL_CID_DISABLED 0 -#define MBEDTLS_SSL_CID_ENABLED 1 - #define MBEDTLS_SSL_ETM_DISABLED 0 #define MBEDTLS_SSL_ETM_ENABLED 1 #define MBEDTLS_SSL_COMPRESS_NULL 0 #define MBEDTLS_SSL_COMPRESS_DEFLATE 1 -#define MBEDTLS_SSL_VERIFY_NONE 0x0 -#define MBEDTLS_SSL_VERIFY_OPTIONAL 0xf -#define MBEDTLS_SSL_VERIFY_REQUIRED 0x33 -#define MBEDTLS_SSL_VERIFY_UNSET 0x3c /* Used only for sni_authmode */ +#define MBEDTLS_SSL_VERIFY_NONE 0 +#define MBEDTLS_SSL_VERIFY_OPTIONAL 1 +#define MBEDTLS_SSL_VERIFY_REQUIRED 2 +#define MBEDTLS_SSL_VERIFY_UNSET 3 /* Used only for sni_authmode */ #define MBEDTLS_SSL_LEGACY_RENEGOTIATION 0 #define MBEDTLS_SSL_SECURE_RENEGOTIATION 1 @@ -256,7 +209,7 @@ #endif /* - * Maximum fragment length in bytes, + * Maxium fragment length in bytes, * determines the size of each of the two internal I/O buffers. * * Note: the RFC defines the default size of SSL / TLS messages. If you @@ -270,37 +223,6 @@ #define MBEDTLS_SSL_MAX_CONTENT_LEN 16384 /**< Size of the input / output buffer */ #endif -#if !defined(MBEDTLS_SSL_IN_CONTENT_LEN) -#define MBEDTLS_SSL_IN_CONTENT_LEN MBEDTLS_SSL_MAX_CONTENT_LEN -#endif - -#if !defined(MBEDTLS_SSL_OUT_CONTENT_LEN) -#define MBEDTLS_SSL_OUT_CONTENT_LEN MBEDTLS_SSL_MAX_CONTENT_LEN -#endif - -/* - * Maximum number of heap-allocated bytes for the purpose of - * DTLS handshake message reassembly and future message buffering. - */ -#if !defined(MBEDTLS_SSL_DTLS_MAX_BUFFERING) -#define MBEDTLS_SSL_DTLS_MAX_BUFFERING 32768 -#endif - -/* - * Maximum length of CIDs for incoming and outgoing messages. - */ -#if !defined(MBEDTLS_SSL_CID_IN_LEN_MAX) -#define MBEDTLS_SSL_CID_IN_LEN_MAX 32 -#endif - -#if !defined(MBEDTLS_SSL_CID_OUT_LEN_MAX) -#define MBEDTLS_SSL_CID_OUT_LEN_MAX 32 -#endif - -#if !defined(MBEDTLS_SSL_CID_PADDING_GRANULARITY) -#define MBEDTLS_SSL_CID_PADDING_GRANULARITY 16 -#endif - /* \} name SECTION: Module settings */ /* @@ -348,7 +270,6 @@ #define MBEDTLS_SSL_MSG_ALERT 21 #define MBEDTLS_SSL_MSG_HANDSHAKE 22 #define MBEDTLS_SSL_MSG_APPLICATION_DATA 23 -#define MBEDTLS_SSL_MSG_CID 25 #define MBEDTLS_SSL_ALERT_LEVEL_WARNING 1 #define MBEDTLS_SSL_ALERT_LEVEL_FATAL 2 @@ -382,7 +303,6 @@ #define MBEDTLS_SSL_ALERT_MSG_UNRECOGNIZED_NAME 112 /* 0x70 */ #define MBEDTLS_SSL_ALERT_MSG_UNKNOWN_PSK_IDENTITY 115 /* 0x73 */ #define MBEDTLS_SSL_ALERT_MSG_NO_APPLICATION_PROTOCOL 120 /* 0x78 */ -#define MBEDTLS_SSL_ALERT_MSG_NONE 255 /* internal */ #define MBEDTLS_SSL_HS_HELLO_REQUEST 0 #define MBEDTLS_SSL_HS_CLIENT_HELLO 1 @@ -419,93 +339,10 @@ #define MBEDTLS_TLS_EXT_SESSION_TICKET 35 -/* The value of the CID extension is still TBD as of - * draft-ietf-tls-dtls-connection-id-05 - * (https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05) */ -#define MBEDTLS_TLS_EXT_CID 254 /* TBD */ - #define MBEDTLS_TLS_EXT_ECJPAKE_KKPP 256 /* experimental */ #define MBEDTLS_TLS_EXT_RENEGOTIATION_INFO 0xFF01 -/* - * Helper macros indicating whether certain classes - * of key exchanges are enabled in the configuration. - */ - -/* Key exchanges using a certificate */ -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) -#define MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED -#endif - -/* Key exchanges allowing client certificate requests */ -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) -#define MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED -#endif - -/* Key exchanges involving server signature in ServerKeyExchange */ -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) -#define MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED -#endif - -/* Key exchanges using ECDH */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) -#define MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED -#endif - -/* Key exchanges that don't involve ephemeral keys */ -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED) -#define MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED -#endif - -/* Key exchanges that involve ephemeral keys */ -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) -#define MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED -#endif - -/* Key exchanges using a PSK */ -#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) -#define MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED -#endif - -/* Key exchanges using DHE */ -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) -#define MBEDTLS_KEY_EXCHANGE__SOME__DHE_ENABLED -#endif - -/* Key exchanges using ECDHE */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) -#define MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED -#endif - /* * Size defines */ @@ -526,13 +363,8 @@ union mbedtls_ssl_premaster_secret defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) -#if defined(MBEDTLS_ECDH_C) unsigned char _pms_ecdh[MBEDTLS_ECP_MAX_BYTES]; /* RFC 4492 5.10 */ #endif -#if defined(MBEDTLS_USE_TINYCRYPT) - unsigned char _pms_ecdh_uecc[ NUM_ECC_BYTES ]; -#endif /* MBEDTLS_USE_TINYCRYPT */ -#endif #if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) unsigned char _pms_psk[4 + 2 * MBEDTLS_PSK_MAX_LEN]; /* RFC 4279 2 */ #endif @@ -544,15 +376,9 @@ union mbedtls_ssl_premaster_secret unsigned char _pms_rsa_psk[52 + MBEDTLS_PSK_MAX_LEN]; /* RFC 4279 4 */ #endif #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) -#if defined(MBEDTLS_USE_TINYCRYPT) - unsigned char _pms_ecdhe_psk_uecc[4 + NUM_ECC_BYTES + - + MBEDTLS_PSK_MAX_LEN]; /* RFC 5489 2 */ -#endif /* MBEDTLS_USE_TINYCRYPT */ -#if defined(MBEDTLS_ECP_C) unsigned char _pms_ecdhe_psk[4 + MBEDTLS_ECP_MAX_BYTES + MBEDTLS_PSK_MAX_LEN]; /* RFC 5489 2 */ #endif -#endif #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) unsigned char _pms_ecjpake[32]; /* Thread spec: SHA-256 output */ #endif @@ -569,26 +395,25 @@ extern "C" { */ typedef enum { - MBEDTLS_SSL_HELLO_REQUEST = 0x0, - MBEDTLS_SSL_CLIENT_HELLO = 0x0000FFFF, - MBEDTLS_SSL_SERVER_HELLO = 0x00FF00FF, - MBEDTLS_SSL_SERVER_CERTIFICATE = 0x00FFFF00, - MBEDTLS_SSL_SERVER_KEY_EXCHANGE = 0x0F0F0F0F, - MBEDTLS_SSL_CERTIFICATE_REQUEST = 0x0F0FF0F0, - MBEDTLS_SSL_SERVER_HELLO_DONE = 0x0FF00FF0, - MBEDTLS_SSL_CLIENT_CERTIFICATE = 0x0FF0F00F, - MBEDTLS_SSL_CLIENT_KEY_EXCHANGE = 0x33333333, - MBEDTLS_SSL_CERTIFICATE_VERIFY = 0x3333CCCC, - MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC = 0x33CC33CC, - MBEDTLS_SSL_CLIENT_FINISHED = 0x33CCCC33, - MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC = 0x3C3C3C3C, - MBEDTLS_SSL_SERVER_FINISHED = 0x3C3CC3C3, - MBEDTLS_SSL_FLUSH_BUFFERS = 0x3CC33CC3, - MBEDTLS_SSL_HANDSHAKE_WRAPUP = 0x3CC3C33C, - MBEDTLS_SSL_HANDSHAKE_OVER = 0x55555555, - MBEDTLS_SSL_SERVER_NEW_SESSION_TICKET = 0x5555AAAA, - MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT = 0x55AA55AA, - MBEDTLS_SSL_INVALID = 0x55AAAA55 + MBEDTLS_SSL_HELLO_REQUEST, + MBEDTLS_SSL_CLIENT_HELLO, + MBEDTLS_SSL_SERVER_HELLO, + MBEDTLS_SSL_SERVER_CERTIFICATE, + MBEDTLS_SSL_SERVER_KEY_EXCHANGE, + MBEDTLS_SSL_CERTIFICATE_REQUEST, + MBEDTLS_SSL_SERVER_HELLO_DONE, + MBEDTLS_SSL_CLIENT_CERTIFICATE, + MBEDTLS_SSL_CLIENT_KEY_EXCHANGE, + MBEDTLS_SSL_CERTIFICATE_VERIFY, + MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC, + MBEDTLS_SSL_CLIENT_FINISHED, + MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC, + MBEDTLS_SSL_SERVER_FINISHED, + MBEDTLS_SSL_FLUSH_BUFFERS, + MBEDTLS_SSL_HANDSHAKE_WRAPUP, + MBEDTLS_SSL_HANDSHAKE_OVER, + MBEDTLS_SSL_SERVER_NEW_SESSION_TICKET, + MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT, } mbedtls_ssl_states; @@ -701,6 +526,7 @@ typedef void mbedtls_ssl_set_timer_t( void * ctx, */ typedef int mbedtls_ssl_get_timer_t( void * ctx ); + /* Defined below */ typedef struct mbedtls_ssl_session mbedtls_ssl_session; typedef struct mbedtls_ssl_context mbedtls_ssl_context; @@ -717,271 +543,22 @@ typedef struct mbedtls_ssl_key_cert mbedtls_ssl_key_cert; typedef struct mbedtls_ssl_flight_item mbedtls_ssl_flight_item; #endif -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) -#if defined(MBEDTLS_X509_CRT_PARSE_C) -/** - * \brief Callback type: start external signature operation. - * - * This callback is called during an SSL handshake to start - * a signature decryption operation using an - * external processor. The parameter \p cert contains - * the public key; it is up to the callback function to - * determine how to access the associated private key. - * - * This function typically sends or enqueues a request, and - * does not wait for the operation to complete. This allows - * the handshake step to be non-blocking. - * - * The parameters \p ssl and \p cert are guaranteed to remain - * valid throughout the handshake. On the other hand, this - * function must save the contents of \p hash if the value - * is needed for later processing, because the \p hash buffer - * is no longer valid after this function returns. - * - * This function may call mbedtls_ssl_set_async_operation_data() - * to store an operation context for later retrieval - * by the resume or cancel callback. - * - * \note For RSA signatures, this function must produce output - * that is consistent with PKCS#1 v1.5 in the same way as - * mbedtls_rsa_pkcs1_sign(). Before the private key operation, - * apply the padding steps described in RFC 8017, section 9.2 - * "EMSA-PKCS1-v1_5" as follows. - * - If \p md_alg is #MBEDTLS_MD_NONE, apply the PKCS#1 v1.5 - * encoding, treating \p hash as the DigestInfo to be - * padded. In other words, apply EMSA-PKCS1-v1_5 starting - * from step 3, with `T = hash` and `tLen = hash_len`. - * - If `md_alg != MBEDTLS_MD_NONE`, apply the PKCS#1 v1.5 - * encoding, treating \p hash as the hash to be encoded and - * padded. In other words, apply EMSA-PKCS1-v1_5 starting - * from step 2, with `digestAlgorithm` obtained by calling - * mbedtls_oid_get_oid_by_md() on \p md_alg. - * - * \note For ECDSA signatures, the output format is the DER encoding - * `Ecdsa-Sig-Value` defined in - * [RFC 4492 section 5.4](https://tools.ietf.org/html/rfc4492#section-5.4). - * - * \param ssl The SSL connection instance. It should not be - * modified other than via - * mbedtls_ssl_set_async_operation_data(). - * \param cert Certificate containing the public key. - * In simple cases, this is one of the pointers passed to - * mbedtls_ssl_conf_own_cert() when configuring the SSL - * connection. However, if other callbacks are used, this - * property may not hold. For example, if an SNI callback - * is registered with mbedtls_ssl_conf_sni(), then - * this callback determines what certificate is used. - * \param md_alg Hash algorithm. - * \param hash Buffer containing the hash. This buffer is - * no longer valid when the function returns. - * \param hash_len Size of the \c hash buffer in bytes. - * - * \return 0 if the operation was started successfully and the SSL - * stack should call the resume callback immediately. - * \return #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if the operation - * was started successfully and the SSL stack should return - * immediately without calling the resume callback yet. - * \return #MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH if the external - * processor does not support this key. The SSL stack will - * use the private key object instead. - * \return Any other error indicates a fatal failure and is - * propagated up the call chain. The callback should - * use \c MBEDTLS_ERR_PK_xxx error codes, and must not - * use \c MBEDTLS_ERR_SSL_xxx error codes except as - * directed in the documentation of this callback. - */ -typedef int mbedtls_ssl_async_sign_t( mbedtls_ssl_context *ssl, - mbedtls_x509_crt *cert, - mbedtls_md_type_t md_alg, - const unsigned char *hash, - size_t hash_len ); - -/** - * \brief Callback type: start external decryption operation. - * - * This callback is called during an SSL handshake to start - * an RSA decryption operation using an - * external processor. The parameter \p cert contains - * the public key; it is up to the callback function to - * determine how to access the associated private key. - * - * This function typically sends or enqueues a request, and - * does not wait for the operation to complete. This allows - * the handshake step to be non-blocking. - * - * The parameters \p ssl and \p cert are guaranteed to remain - * valid throughout the handshake. On the other hand, this - * function must save the contents of \p input if the value - * is needed for later processing, because the \p input buffer - * is no longer valid after this function returns. - * - * This function may call mbedtls_ssl_set_async_operation_data() - * to store an operation context for later retrieval - * by the resume or cancel callback. - * - * \warning RSA decryption as used in TLS is subject to a potential - * timing side channel attack first discovered by Bleichenbacher - * in 1998. This attack can be remotely exploitable - * in practice. To avoid this attack, you must ensure that - * if the callback performs an RSA decryption, the time it - * takes to execute and return the result does not depend - * on whether the RSA decryption succeeded or reported - * invalid padding. - * - * \param ssl The SSL connection instance. It should not be - * modified other than via - * mbedtls_ssl_set_async_operation_data(). - * \param cert Certificate containing the public key. - * In simple cases, this is one of the pointers passed to - * mbedtls_ssl_conf_own_cert() when configuring the SSL - * connection. However, if other callbacks are used, this - * property may not hold. For example, if an SNI callback - * is registered with mbedtls_ssl_conf_sni(), then - * this callback determines what certificate is used. - * \param input Buffer containing the input ciphertext. This buffer - * is no longer valid when the function returns. - * \param input_len Size of the \p input buffer in bytes. - * - * \return 0 if the operation was started successfully and the SSL - * stack should call the resume callback immediately. - * \return #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if the operation - * was started successfully and the SSL stack should return - * immediately without calling the resume callback yet. - * \return #MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH if the external - * processor does not support this key. The SSL stack will - * use the private key object instead. - * \return Any other error indicates a fatal failure and is - * propagated up the call chain. The callback should - * use \c MBEDTLS_ERR_PK_xxx error codes, and must not - * use \c MBEDTLS_ERR_SSL_xxx error codes except as - * directed in the documentation of this callback. - */ -typedef int mbedtls_ssl_async_decrypt_t( mbedtls_ssl_context *ssl, - mbedtls_x509_crt *cert, - const unsigned char *input, - size_t input_len ); -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -/** - * \brief Callback type: resume external operation. - * - * This callback is called during an SSL handshake to resume - * an external operation started by the - * ::mbedtls_ssl_async_sign_t or - * ::mbedtls_ssl_async_decrypt_t callback. - * - * This function typically checks the status of a pending - * request or causes the request queue to make progress, and - * does not wait for the operation to complete. This allows - * the handshake step to be non-blocking. - * - * This function may call mbedtls_ssl_get_async_operation_data() - * to retrieve an operation context set by the start callback. - * It may call mbedtls_ssl_set_async_operation_data() to modify - * this context. - * - * Note that when this function returns a status other than - * #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS, it must free any - * resources associated with the operation. - * - * \param ssl The SSL connection instance. It should not be - * modified other than via - * mbedtls_ssl_set_async_operation_data(). - * \param output Buffer containing the output (signature or decrypted - * data) on success. - * \param output_len On success, number of bytes written to \p output. - * \param output_size Size of the \p output buffer in bytes. - * - * \return 0 if output of the operation is available in the - * \p output buffer. - * \return #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if the operation - * is still in progress. Subsequent requests for progress - * on the SSL connection will call the resume callback - * again. - * \return Any other error means that the operation is aborted. - * The SSL handshake is aborted. The callback should - * use \c MBEDTLS_ERR_PK_xxx error codes, and must not - * use \c MBEDTLS_ERR_SSL_xxx error codes except as - * directed in the documentation of this callback. - */ -typedef int mbedtls_ssl_async_resume_t( mbedtls_ssl_context *ssl, - unsigned char *output, - size_t *output_len, - size_t output_size ); - -/** - * \brief Callback type: cancel external operation. - * - * This callback is called if an SSL connection is closed - * while an asynchronous operation is in progress. Note that - * this callback is not called if the - * ::mbedtls_ssl_async_resume_t callback has run and has - * returned a value other than - * #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS, since in that case - * the asynchronous operation has already completed. - * - * This function may call mbedtls_ssl_get_async_operation_data() - * to retrieve an operation context set by the start callback. - * - * \param ssl The SSL connection instance. It should not be - * modified. - */ -typedef void mbedtls_ssl_async_cancel_t( mbedtls_ssl_context *ssl ); -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ - -#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) && \ - !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) -#define MBEDTLS_SSL_PEER_CERT_DIGEST_MAX_LEN 48 -#if defined(MBEDTLS_SHA256_C) -#define MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_TYPE MBEDTLS_MD_SHA256 -#define MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN 32 -#elif defined(MBEDTLS_SHA512_C) -#define MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_TYPE MBEDTLS_MD_SHA384 -#define MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN 48 -#elif defined(MBEDTLS_SHA1_C) -#define MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_TYPE MBEDTLS_MD_SHA1 -#define MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN 20 -#else -/* This is already checked in check_config.h, but be sure. */ -#error "Bad configuration - need SHA-1, SHA-256 or SHA-512 enabled to compute digest of peer CRT." -#endif -#endif /* MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED && - !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - /* * This structure is used for storing current session data. - * - * Note: when changing this definition, we need to check and update: - * - in tests/suites/test_suite_ssl.function: - * ssl_populate_session() and ssl_serialize_session_save_load() - * - in library/ssl_tls.c: - * mbedtls_ssl_session_init() and mbedtls_ssl_session_free() - * mbedtls_ssl_session_save() and ssl_session_load() - * ssl_session_copy() */ struct mbedtls_ssl_session { #if defined(MBEDTLS_HAVE_TIME) mbedtls_time_t start; /*!< starting time */ #endif -#if !defined(MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE) int ciphersuite; /*!< chosen ciphersuite */ -#endif /* MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE */ -#if defined(MBEDTLS_ZLIB_SUPPORT) int compression; /*!< chosen compression */ -#endif /* MBEDTLS_ZLIB_SUPPORT */ size_t id_len; /*!< session id length */ + unsigned char id[32]; /*!< session identifier */ + unsigned char master[48]; /*!< the master secret */ #if defined(MBEDTLS_X509_CRT_PARSE_C) -#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - mbedtls_x509_crt *peer_cert; /*!< peer X.509 cert chain */ -#elif defined(MBEDTLS_SSL_RENEGOTIATION) - /*! The digest of the peer's end-CRT. This must be kept to detect CRT - * changes during renegotiation, mitigating the triple handshake attack. */ - unsigned char *peer_cert_digest; - size_t peer_cert_digest_len; - mbedtls_md_type_t peer_cert_digest_type; -#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE && MBEDTLS_SSL_RENEGOTIATION */ + mbedtls_x509_crt *peer_cert; /*!< peer X.509 cert chain */ #endif /* MBEDTLS_X509_CRT_PARSE_C */ uint32_t verify_result; /*!< verification result */ @@ -1002,9 +579,6 @@ struct mbedtls_ssl_session #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) int encrypt_then_mac; /*!< flag for EtM activation */ #endif - - unsigned char id[32]; /*!< session identifier */ - unsigned char master[48]; /*!< the master secret */ }; /** @@ -1012,152 +586,27 @@ struct mbedtls_ssl_session */ struct mbedtls_ssl_config { - /* Group items by size (smallest first) to minimize padding overhead */ - - /* - * Flags (bytes) - */ - -#if !defined(MBEDTLS_SSL_CONF_ENDPOINT) - uint8_t endpoint; /*!< 0: client, 1: server */ -#endif /* !MBEDTLS_SSL_CONF_ENDPOINT */ -#if !defined(MBEDTLS_SSL_CONF_TRANSPORT) - uint8_t transport; /*!< stream (TLS) or datagram (DTLS) */ -#endif /* !MBEDTLS_SSL_CONF_TRANSPORT */ -#if !defined(MBEDTLS_SSL_CONF_AUTHMODE) - uint8_t authmode; /*!< MBEDTLS_SSL_VERIFY_XXX */ -#endif /* !MBEDTLS_SSL_CONF_AUTHMODE */ -#if !defined(MBEDTLS_SSL_CONF_ALLOW_LEGACY_RENEGOTIATION) - /* needed even with renego disabled for LEGACY_BREAK_HANDSHAKE */ - uint8_t allow_legacy_renegotiation; /*!< MBEDTLS_LEGACY_XXX */ -#endif /* !MBEDTLS_SSL_CONF_ALLOW_LEGACY_RENEGOTIATION */ -#if defined(MBEDTLS_ARC4_C) - uint8_t arc4_disabled; /*!< blacklist RC4 ciphersuites? */ -#endif -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) - uint8_t mfl_code; /*!< desired fragment length */ -#endif -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) - uint8_t encrypt_then_mac; /*!< negotiate encrypt-then-mac? */ -#endif -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) -#if !defined(MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET) - uint8_t extended_ms; /*!< negotiate extended master secret? */ -#endif /* !MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ -#if !defined(MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET) - uint8_t enforce_extended_master_secret; /*!< enforce the usage of - * extended master secret */ -#endif /* !MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET */ -#endif -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) -#if !defined(MBEDTLS_SSL_CONF_ANTI_REPLAY) - uint8_t anti_replay; /*!< detect and prevent replay? */ -#endif /* !MBEDTLS_SSL_CONF_ANTI_REPLAY */ -#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */ -#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) - uint8_t cbc_record_splitting; /*!< do cbc record splitting */ -#endif -#if defined(MBEDTLS_SSL_RENEGOTIATION) - uint8_t disable_renegotiation; /*!< disable renegotiation? */ -#endif -#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) - uint8_t trunc_hmac; /*!< negotiate truncated hmac? */ -#endif -#if defined(MBEDTLS_SSL_SESSION_TICKETS) - uint8_t session_tickets; /*!< use session tickets? */ -#endif -#if defined(MBEDTLS_SSL_FALLBACK_SCSV) && defined(MBEDTLS_SSL_CLI_C) - uint8_t fallback; /*!< is this a fallback? */ -#endif -#if defined(MBEDTLS_SSL_SRV_C) -#if !defined(MBEDTLS_SSL_CONF_CERT_REQ_CA_LIST) - uint8_t cert_req_ca_list; /*!< enable sending CA list in - Certificate Request messages? */ -#endif /* !MBEDTLS_SSL_CONF_CERT_REQ_CA_LIST */ -#endif -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) -#if !defined(MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID) - uint8_t ignore_unexpected_cid; /*!< Determines whether DTLS record - * with unexpected CID should - * lead to failure. */ -#endif /* !MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID */ -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - - /* - * Numerical settings - */ - -#if !defined(MBEDTLS_SSL_CONF_MIN_MAJOR_VER) - unsigned char min_major_ver; /*!< min. major version used */ -#endif /* !MBEDTLS_SSL_CONF_MIN_MAJOR_VER */ -#if !defined(MBEDTLS_SSL_CONF_MAX_MAJOR_VER) - unsigned char max_major_ver; /*!< max. major version used */ -#endif /* !MBEDTLS_SSL_CONF_MAX_MAJOR_VER */ -#if !defined(MBEDTLS_SSL_CONF_MIN_MINOR_VER) - uint16_t min_minor_ver; /*!< min. minor version used */ -#endif /* !MBEDTLS_SSL_CONF_MIN_MINOR_VER */ -#if !defined(MBEDTLS_SSL_CONF_MAX_MINOR_VER) - uint16_t max_minor_ver; /*!< max. minor version used */ -#endif /* !MBEDTLS_SSL_CONF_MAX_MINOR_VER */ - -#if !defined(MBEDTLS_SSL_CONF_READ_TIMEOUT) - uint32_t read_timeout; /*!< timeout for mbedtls_ssl_read (ms) */ -#endif /* !MBEDTLS_SSL_CONF_READ_TIMEOUT */ - -#if defined(MBEDTLS_SSL_PROTO_DTLS) -#if !defined(MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN) - uint32_t hs_timeout_min; /*!< initial value of the handshake - retransmission timeout (ms) */ -#endif /* !MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN */ -#if !defined(MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX) - uint32_t hs_timeout_max; /*!< maximum value of the handshake - retransmission timeout (ms) */ -#endif /* !MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX */ -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - -#if defined(MBEDTLS_SSL_RENEGOTIATION) - int renego_max_records; /*!< grace period for renegotiation */ - unsigned char renego_period[8]; /*!< value of the record counters - that triggers renegotiation */ -#endif - -#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) -#if !defined(MBEDTLS_SSL_CONF_BADMAC_LIMIT) - unsigned int badmac_limit; /*!< limit of records with a bad MAC */ -#endif /* !MBEDTLS_SSL_CONF_BADMAC_LIMIT */ -#endif - -#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_CLI_C) - unsigned int dhm_min_bitlen; /*!< min. bit length of the DHM prime */ -#endif + /* Group items by size (largest first) to minimize padding overhead */ /* * Pointers */ -#if !defined(MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE) const int *ciphersuite_list[4]; /*!< allowed ciphersuites per version */ -#endif /* MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE */ -#if defined(MBEDTLS_DEBUG_C) /** Callback for printing debug output */ void (*f_dbg)(void *, int, const char *, int, const char *); void *p_dbg; /*!< context for the debug function */ -#endif /* MBEDTLS_DEBUG_C */ -#if !defined(MBEDTLS_SSL_CONF_RNG) /** Callback for getting (pseudo-)random numbers */ int (*f_rng)(void *, unsigned char *, size_t); void *p_rng; /*!< context for the RNG function */ -#endif /* !MBEDTLS_SSL_CONF_RNG */ -#if defined(MBEDTLS_SSL_SRV_C) && !defined(MBEDTLS_SSL_NO_SESSION_CACHE) /** Callback to retrieve a session from the cache */ int (*f_get_cache)(void *, mbedtls_ssl_session *); /** Callback to store a session into the cache */ int (*f_set_cache)(void *, const mbedtls_ssl_session *); void *p_cache; /*!< context for cache callbacks */ -#endif /* MBEDTLS_SSL_SRV_C && !MBEDTLS_SSL_NO_SESSION_CACHE */ #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) /** Callback for setting cert according to SNI extension */ @@ -1165,8 +614,7 @@ struct mbedtls_ssl_config void *p_sni; /*!< context for SNI callback */ #endif -#if defined(MBEDTLS_X509_CRT_PARSE_C) && \ - !defined(MBEDTLS_X509_REMOVE_VERIFY_CALLBACK) +#if defined(MBEDTLS_X509_CRT_PARSE_C) /** Callback to customize X.509 certificate chain verification */ int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *); void *p_vrfy; /*!< context for X.509 verify calllback */ @@ -1204,12 +652,6 @@ struct mbedtls_ssl_config void *p_export_keys; /*!< context for key export callback */ #endif -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) -#if !defined(MBEDTLS_SSL_CONF_CID_LEN) - size_t cid_len; /*!< The length of CIDs for incoming DTLS records. */ -#endif /* !MBEDTLS_SSL_CONF_CID_LEN */ -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - #if defined(MBEDTLS_X509_CRT_PARSE_C) const mbedtls_x509_crt_profile *cert_profile; /*!< verification profile */ mbedtls_ssl_key_cert *key_cert; /*!< own certificate/key pair(s) */ @@ -1217,26 +659,12 @@ struct mbedtls_ssl_config mbedtls_x509_crl *ca_crl; /*!< trusted CAs CRLs */ #endif /* MBEDTLS_X509_CRT_PARSE_C */ -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) -#if defined(MBEDTLS_X509_CRT_PARSE_C) - mbedtls_ssl_async_sign_t *f_async_sign_start; /*!< start asynchronous signature operation */ - mbedtls_ssl_async_decrypt_t *f_async_decrypt_start; /*!< start asynchronous decryption operation */ -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - mbedtls_ssl_async_resume_t *f_async_resume; /*!< resume asynchronous operation */ - mbedtls_ssl_async_cancel_t *f_async_cancel; /*!< cancel asynchronous operation */ - void *p_async_config_data; /*!< Configuration data set by mbedtls_ssl_conf_async_private_cb(). */ -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ - #if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) -#if !defined(MBEDTLS_SSL_CONF_SINGLE_SIG_HASH) const int *sig_hashes; /*!< allowed signature hashes */ -#endif /* !MBEDTLS_SSL_CONF_SINGLE_SIG_HASH */ #endif #if defined(MBEDTLS_ECP_C) -#if !defined(MBEDTLS_SSL_CONF_SINGLE_EC) const mbedtls_ecp_group_id *curve_list; /*!< allowed curves */ -#endif /* MBEDTLS_SSL_CONF_SINGLE_EC */ #endif #if defined(MBEDTLS_DHM_C) @@ -1245,47 +673,96 @@ struct mbedtls_ssl_config #endif #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) - unsigned char *psk; /*!< pre-shared key. This field should - only be set via - mbedtls_ssl_conf_psk() */ - size_t psk_len; /*!< length of the pre-shared key. This - field should only be set via - mbedtls_ssl_conf_psk() */ - unsigned char *psk_identity; /*!< identity for PSK negotiation. This - field should only be set via - mbedtls_ssl_conf_psk() */ - size_t psk_identity_len;/*!< length of identity. This field should - only be set via - mbedtls_ssl_conf_psk() */ + unsigned char *psk; /*!< pre-shared key */ + size_t psk_len; /*!< length of the pre-shared key */ + unsigned char *psk_identity; /*!< identity for PSK negotiation */ + size_t psk_identity_len;/*!< length of identity */ #endif #if defined(MBEDTLS_SSL_ALPN) const char **alpn_list; /*!< ordered list of protocols */ #endif + /* + * Numerical settings (int then char) + */ + + uint32_t read_timeout; /*!< timeout for mbedtls_ssl_read (ms) */ + +#if defined(MBEDTLS_SSL_PROTO_DTLS) + uint32_t hs_timeout_min; /*!< initial value of the handshake + retransmission timeout (ms) */ + uint32_t hs_timeout_max; /*!< maximum value of the handshake + retransmission timeout (ms) */ +#endif + +#if defined(MBEDTLS_SSL_RENEGOTIATION) + int renego_max_records; /*!< grace period for renegotiation */ + unsigned char renego_period[8]; /*!< value of the record counters + that triggers renegotiation */ +#endif + +#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) + unsigned int badmac_limit; /*!< limit of records with a bad MAC */ +#endif + +#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_CLI_C) + unsigned int dhm_min_bitlen; /*!< min. bit length of the DHM prime */ +#endif + + unsigned char max_major_ver; /*!< max. major version used */ + unsigned char max_minor_ver; /*!< max. minor version used */ + unsigned char min_major_ver; /*!< min. major version used */ + unsigned char min_minor_ver; /*!< min. minor version used */ + + /* + * Flags (bitfields) + */ + + unsigned int endpoint : 1; /*!< 0: client, 1: server */ + unsigned int transport : 1; /*!< stream (TLS) or datagram (DTLS) */ + unsigned int authmode : 2; /*!< MBEDTLS_SSL_VERIFY_XXX */ + /* needed even with renego disabled for LEGACY_BREAK_HANDSHAKE */ + unsigned int allow_legacy_renegotiation : 2 ; /*!< MBEDTLS_LEGACY_XXX */ +#if defined(MBEDTLS_ARC4_C) + unsigned int arc4_disabled : 1; /*!< blacklist RC4 ciphersuites? */ +#endif +#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) + unsigned int mfl_code : 3; /*!< desired fragment length */ +#endif +#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) + unsigned int encrypt_then_mac : 1 ; /*!< negotiate encrypt-then-mac? */ +#endif +#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) + unsigned int extended_ms : 1; /*!< negotiate extended master secret? */ +#endif +#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) + unsigned int anti_replay : 1; /*!< detect and prevent replay? */ +#endif +#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) + unsigned int cbc_record_splitting : 1; /*!< do cbc record splitting */ +#endif +#if defined(MBEDTLS_SSL_RENEGOTIATION) + unsigned int disable_renegotiation : 1; /*!< disable renegotiation? */ +#endif +#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) + unsigned int trunc_hmac : 1; /*!< negotiate truncated hmac? */ +#endif +#if defined(MBEDTLS_SSL_SESSION_TICKETS) + unsigned int session_tickets : 1; /*!< use session tickets? */ +#endif +#if defined(MBEDTLS_SSL_FALLBACK_SCSV) && defined(MBEDTLS_SSL_CLI_C) + unsigned int fallback : 1; /*!< is this a fallback? */ +#endif +#if defined(MBEDTLS_SSL_SRV_C) + unsigned int cert_req_ca_list : 1; /*!< enable sending CA list in + Certificate Request messages? */ +#endif }; + struct mbedtls_ssl_context { -#if defined(MBEDTLS_SSL_PROTO_DTLS) - uint8_t disable_datagram_packing; /*!< Disable packing multiple records - * within a single datagram. */ -#endif /* MBEDTLS_SSL_PROTO_DTLS */ -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - /* CID configuration to use in subsequent handshakes. */ - uint8_t own_cid_len; /*!< The length of \c own_cid. */ - uint8_t negotiate_cid; /*!< This indicates whether the CID extension should - * be negotiated in the next handshake or not. - * Possible values are #MBEDTLS_SSL_CID_ENABLED - * and #MBEDTLS_SSL_CID_DISABLED. */ -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - - unsigned char pending_fatal_alert_msg; /*!< Type of a fatal alert - * pending to be delivered. */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - uint16_t in_epoch; /*!< DTLS epoch for incoming records */ - uint16_t mtu; /*!< path mtu, used to fragment outgoing messages */ -#endif /* MBEDTLS_SSL_PROTO_DTLS */ const mbedtls_ssl_config *conf; /*!< configuration information */ /* @@ -1297,18 +774,21 @@ struct mbedtls_ssl_context int renego_records_seen; /*!< Records since renego request, or with DTLS, number of retransmissions of request if renego_max_records is < 0 */ -#endif /* MBEDTLS_SSL_RENEGOTIATION */ +#endif -#if !defined(MBEDTLS_SSL_CONF_FIXED_MAJOR_VER) int major_ver; /*!< equal to MBEDTLS_SSL_MAJOR_VERSION_3 */ -#endif /* !MBEDTLS_SSL_CONF_FIXED_MAJOR_VER */ -#if !defined(MBEDTLS_SSL_CONF_FIXED_MINOR_VER) int minor_ver; /*!< either 0 (SSL3) or 1 (TLS1.0) */ -#endif /* !MBEDTLS_SSL_CONF_FIXED_MINOR_VER */ #if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) unsigned badmac_seen; /*!< records with a bad MAC received */ -#endif /* MBEDTLS_SSL_DTLS_BADMAC_LIMIT */ +#endif + + mbedtls_ssl_send_t *f_send; /*!< Callback for network send */ + mbedtls_ssl_recv_t *f_recv; /*!< Callback for network receive */ + mbedtls_ssl_recv_timeout_t *f_recv_timeout; + /*!< Callback for network receive with timeout */ + + void *p_bio; /*!< context for I/O operations */ /* * Session layer @@ -1321,6 +801,22 @@ struct mbedtls_ssl_context mbedtls_ssl_handshake_params *handshake; /*!< params required only during the handshake process */ + /* + * Record layer transformations + */ + mbedtls_ssl_transform *transform_in; /*!< current transform params (in) */ + mbedtls_ssl_transform *transform_out; /*!< current transform params (in) */ + mbedtls_ssl_transform *transform; /*!< negotiated transform params */ + mbedtls_ssl_transform *transform_negotiate; /*!< transform params in negotiation */ + + /* + * Timers + */ + void *p_timer; /*!< context for the timer callbacks */ + + mbedtls_ssl_set_timer_t *f_set_timer; /*!< set timer callback */ + mbedtls_ssl_get_timer_t *f_get_timer; /*!< get timer callback */ + /* * Record layer (incoming data) */ @@ -1329,25 +825,23 @@ struct mbedtls_ssl_context TLS: maintained by us DTLS: read from peer */ unsigned char *in_hdr; /*!< start of record header */ -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - unsigned char *in_cid; /*!< The start of the CID; - * (the end is marked by in_len). */ -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ unsigned char *in_len; /*!< two-bytes message length field */ + unsigned char *in_iv; /*!< ivlen-byte IV */ unsigned char *in_msg; /*!< message contents (in_iv+ivlen) */ unsigned char *in_offt; /*!< read offset in application data */ int in_msgtype; /*!< record header: message type */ size_t in_msglen; /*!< record header: message length */ size_t in_left; /*!< amount of data read so far */ -#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) - size_t in_buf_len; /*!< length of input buffer */ -#endif - #if defined(MBEDTLS_SSL_PROTO_DTLS) + uint16_t in_epoch; /*!< DTLS epoch for incoming records */ size_t next_record_offset; /*!< offset of the next record in datagram (equal to in_left if none) */ -#endif /* MBEDTLS_SSL_PROTO_DTLS */ +#endif +#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) + uint64_t in_window_top; /*!< last validated record seq_num */ + uint64_t in_window; /*!< bitmask for replay detection */ +#endif size_t in_hslen; /*!< current handshake message length, including the handshake header */ @@ -1362,10 +856,6 @@ struct mbedtls_ssl_context unsigned char *out_buf; /*!< output buffer */ unsigned char *out_ctr; /*!< 64-bit outgoing message counter */ unsigned char *out_hdr; /*!< start of record header */ -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - unsigned char *out_cid; /*!< The start of the CID; - * (the end is marked by in_len). */ -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ unsigned char *out_len; /*!< two-bytes message length field */ unsigned char *out_iv; /*!< ivlen-byte IV */ unsigned char *out_msg; /*!< message contents (out_iv+ivlen) */ @@ -1373,49 +863,13 @@ struct mbedtls_ssl_context int out_msgtype; /*!< record header: message type */ size_t out_msglen; /*!< record header: message length */ size_t out_left; /*!< amount of data not yet written */ -#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) - size_t out_buf_len; /*!< length of output buffer */ -#endif #if defined(MBEDTLS_ZLIB_SUPPORT) unsigned char *compress_buf; /*!< zlib data buffer */ -#endif /* MBEDTLS_ZLIB_SUPPORT */ +#endif #if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) signed char split_done; /*!< current record already splitted? */ -#endif /* MBEDTLS_SSL_CBC_RECORD_SPLITTING */ - - /* - * Record layer transformations - */ - mbedtls_ssl_transform *transform_in; /*!< current transform params (in) */ - mbedtls_ssl_transform *transform_out; /*!< current transform params (in) */ - mbedtls_ssl_transform *transform; /*!< negotiated transform params */ - mbedtls_ssl_transform *transform_negotiate; /*!< transform params in negotiation */ - -#if !defined(MBEDTLS_SSL_CONF_SEND) - mbedtls_ssl_send_t *f_send; /*!< Callback for network send */ -#endif /* !MBEDTLS_SSL_CONF_SEND */ -#if !defined(MBEDTLS_SSL_CONF_RECV) - mbedtls_ssl_recv_t *f_recv; /*!< Callback for network receive */ -#endif /* !MBEDTLS_SSL_CONF_RECV */ -#if !defined(MBEDTLS_SSL_CONF_RECV_TIMEOUT) - mbedtls_ssl_recv_timeout_t *f_recv_timeout; -#endif /* !MBEDTLS_SSL_CONF_RECV_TIMEOUT */ - /*!< Callback for network receive with timeout */ - - void *p_bio; /*!< context for I/O operations */ - - /* - * Timers - */ - void *p_timer; /*!< context for the timer callbacks */ - -#if !defined(MBEDTLS_SSL_CONF_SET_TIMER) - mbedtls_ssl_set_timer_t *f_set_timer; /*!< set timer callback */ -#endif /* !MBEDTLS_SSL_CONF_SET_TIMER */ -#if !defined(MBEDTLS_SSL_CONF_GET_TIMER) - mbedtls_ssl_get_timer_t *f_get_timer; /*!< get timer callback */ -#endif /* !MBEDTLS_SSL_CONF_GET_TIMER */ +#endif /* * PKI layer @@ -1425,14 +879,14 @@ struct mbedtls_ssl_context /* * User settings */ -#if defined(MBEDTLS_X509_CRT_PARSE_C) && !defined(MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION) +#if defined(MBEDTLS_X509_CRT_PARSE_C) char *hostname; /*!< expected peer CN for verification (and SNI if available) */ -#endif /* MBEDTLS_X509_CRT_PARSE_C && !MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION */ +#endif #if defined(MBEDTLS_SSL_ALPN) const char *alpn_chosen; /*!< negotiated protocol */ -#endif /* MBEDTLS_SSL_ALPN */ +#endif /* * Information for DTLS hello verify @@ -1440,7 +894,7 @@ struct mbedtls_ssl_context #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C) unsigned char *cli_id; /*!< transport-level ID of the client */ size_t cli_id_len; /*!< length of cli_id */ -#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY && MBEDTLS_SSL_SRV_C */ +#endif /* * Secure renegotiation @@ -1452,27 +906,6 @@ struct mbedtls_ssl_context size_t verify_data_len; /*!< length of verify data stored */ char own_verify_data[MBEDTLS_SSL_VERIFY_DATA_MAX_LEN]; /*!< previous handshake verify data */ char peer_verify_data[MBEDTLS_SSL_VERIFY_DATA_MAX_LEN]; /*!< previous handshake verify data */ -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - - unsigned char cur_out_ctr[8]; /*!< Outgoing record sequence number. */ - -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) - uint64_t in_window_top; /*!< last validated record seq_num */ - uint64_t in_window; /*!< bitmask for replay detection */ -#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */ - -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - /* CID configuration to use in subsequent handshakes. */ - - /*! The next incoming CID, chosen by the user and applying to - * all subsequent handshakes. This may be different from the - * CID currently used in case the user has re-configured the CID - * after an initial handshake. */ - unsigned char own_cid[ MBEDTLS_SSL_CID_IN_LEN_MAX ]; -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ -#if defined(MBEDTLS_FI_COUNTERMEASURES) - unsigned char *out_msg_dup; /*!< out msg ptr duplication */ - size_t out_msglen_dup; /*!< out msg size duplication */ #endif }; @@ -1559,40 +992,29 @@ int mbedtls_ssl_setup( mbedtls_ssl_context *ssl, */ int mbedtls_ssl_session_reset( mbedtls_ssl_context *ssl ); -#if !defined(MBEDTLS_SSL_CONF_ENDPOINT) /** * \brief Set the current endpoint type * - * \note On constrained systems, this can also be configured - * at compile-time via MBEDTLS_SSL_CONF_ENDPOINT. - * * \param conf SSL configuration * \param endpoint must be MBEDTLS_SSL_IS_CLIENT or MBEDTLS_SSL_IS_SERVER */ void mbedtls_ssl_conf_endpoint( mbedtls_ssl_config *conf, int endpoint ); -#endif /* !MBEDTLS_SSL_CONF_ENDPOINT */ -#if !defined(MBEDTLS_SSL_CONF_TRANSPORT) /** * \brief Set the transport type (TLS or DTLS). - * Default: TLS unless #MBEDTLS_SSL_PROTO_NO_TLS is defined, - * else DTLS. + * Default: TLS * * \note For DTLS, you must either provide a recv callback that * doesn't block, or one that handles timeouts, see * \c mbedtls_ssl_set_bio(). You also need to provide timer * callbacks with \c mbedtls_ssl_set_timer_cb(). * - * \note On constrained systems, this can also be configured - * at compile-time via MBEDTLS_SSL_CONF_TRANSPORT. - * * \param conf SSL configuration * \param transport transport type: * MBEDTLS_SSL_TRANSPORT_STREAM for TLS, * MBEDTLS_SSL_TRANSPORT_DATAGRAM for DTLS. */ void mbedtls_ssl_conf_transport( mbedtls_ssl_config *conf, int transport ); -#endif /* !MBEDTLS_SSL_CONF_TRANSPORT */ /** * \brief Set the certificate verification mode @@ -1622,8 +1044,7 @@ void mbedtls_ssl_conf_transport( mbedtls_ssl_config *conf, int transport ); */ void mbedtls_ssl_conf_authmode( mbedtls_ssl_config *conf, int authmode ); -#if defined(MBEDTLS_X509_CRT_PARSE_C) && \ - !defined(MBEDTLS_X509_REMOVE_VERIFY_CALLBACK) +#if defined(MBEDTLS_X509_CRT_PARSE_C) /** * \brief Set the verification callback (Optional). * @@ -1638,15 +1059,11 @@ void mbedtls_ssl_conf_authmode( mbedtls_ssl_config *conf, int authmode ); void mbedtls_ssl_conf_verify( mbedtls_ssl_config *conf, int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), void *p_vrfy ); -#endif /* MBEDTLS_X509_CRT_PARSE_C && !MBEDTLS_X509_REMOVE_VERIFY_CALLBACK */ +#endif /* MBEDTLS_X509_CRT_PARSE_C */ -#if !defined(MBEDTLS_SSL_CONF_RNG) /** * \brief Set the random number generator callback * - * \note On constrained systems, the RNG can also be configured at - * compile-time via the option MBEDTLS_SSL_CONF_RNG. - * * \param conf SSL configuration * \param f_rng RNG function * \param p_rng RNG parameter @@ -1654,9 +1071,7 @@ void mbedtls_ssl_conf_verify( mbedtls_ssl_config *conf, void mbedtls_ssl_conf_rng( mbedtls_ssl_config *conf, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); -#endif /* MBEDTLS_SSL_CONF_RNG */ -#if defined(MBEDTLS_DEBUG_C) /** * \brief Set the debug callback * @@ -1674,11 +1089,7 @@ void mbedtls_ssl_conf_rng( mbedtls_ssl_config *conf, void mbedtls_ssl_conf_dbg( mbedtls_ssl_config *conf, void (*f_dbg)(void *, int, const char *, int, const char *), void *p_dbg ); -#endif /* MBEDTLS_DEBUG_C */ -#if !defined(MBEDTLS_SSL_CONF_RECV) && \ - !defined(MBEDTLS_SSL_CONF_SEND) && \ - !defined(MBEDTLS_SSL_CONF_RECV_TIMEOUT) /** * \brief Set the underlying BIO callbacks for write, read and * read-with-timeout. @@ -1704,11 +1115,6 @@ void mbedtls_ssl_conf_dbg( mbedtls_ssl_config *conf, * \c mbedtls_ssl_recv_t and \c mbedtls_ssl_recv_timeout_t for * the conventions those callbacks must follow. * - * \note On constrained systems, the pointers \p f_send, \p f_recv, - * and \p f_recv_timeout can also be configured at compile-time - * via the macros MBEDTLS_SSL_CONF_RECV, MBEDTLS_SSL_CONF_SEND - * and MBEDTLS_SSL_CONF_RECV_TIMEOUT. - * * \note On some platforms, net_sockets.c provides * \c mbedtls_net_send(), \c mbedtls_net_recv() and * \c mbedtls_net_recv_timeout() that are suitable to be used @@ -1719,206 +1125,7 @@ void mbedtls_ssl_set_bio( mbedtls_ssl_context *ssl, mbedtls_ssl_send_t *f_send, mbedtls_ssl_recv_t *f_recv, mbedtls_ssl_recv_timeout_t *f_recv_timeout ); -#else /* !( MBEDTLS_SSL_CONF_RECV && - MBEDTLS_SSL_CONF_SEND && - MBEDTLS_SSL_CONF_RECV_TIMEOUT ) */ -/** - * \brief Set the context to be passed to the underlying BIO callbacks - * for write, read and read-with-timeout. - * - * \param ssl The SSL context to configure. - * \param p_bio The parameter (context) to be used for the BIO callbacks. - * - */ -void mbedtls_ssl_set_bio_ctx( mbedtls_ssl_context *ssl, - void *p_bio ); -#endif /* MBEDTLS_SSL_CONF_RECV && - MBEDTLS_SSL_CONF_SEND && - MBEDTLS_SSL_CONF_RECV_TIMEOUT */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - - -/** - * \brief Configure the use of the Connection ID (CID) - * extension in the next handshake. - * - * Reference: draft-ietf-tls-dtls-connection-id-05 - * https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05 - * - * The DTLS CID extension allows the reliable association of - * DTLS records to DTLS connections across changes in the - * underlying transport (changed IP and Port metadata) by - * adding explicit connection identifiers (CIDs) to the - * headers of encrypted DTLS records. The desired CIDs are - * configured by the application layer and are exchanged in - * new `ClientHello` / `ServerHello` extensions during the - * handshake, where each side indicates the CID it wants the - * peer to use when writing encrypted messages. The CIDs are - * put to use once records get encrypted: the stack discards - * any incoming records that don't include the configured CID - * in their header, and adds the peer's requested CID to the - * headers of outgoing messages. - * - * This API enables or disables the use of the CID extension - * in the next handshake and sets the value of the CID to - * be used for incoming messages. - * - * \param ssl The SSL context to configure. This must be initialized. - * \param enable This value determines whether the CID extension should - * be used or not. Possible values are: - * - MBEDTLS_SSL_CID_ENABLED to enable the use of the CID. - * - MBEDTLS_SSL_CID_DISABLED (default) to disable the use - * of the CID. - * \param own_cid The address of the readable buffer holding the CID we want - * the peer to use when sending encrypted messages to us. - * This may be \c NULL if \p own_cid_len is \c 0. - * This parameter is unused if \p enabled is set to - * MBEDTLS_SSL_CID_DISABLED. - * \param own_cid_len The length of \p own_cid. - * This parameter is unused if \p enabled is set to - * MBEDTLS_SSL_CID_DISABLED. - * - * \note The value of \p own_cid_len must match the value of the - * \c len parameter passed to mbedtls_ssl_conf_cid() - * when configuring the ::mbedtls_ssl_config that \p ssl - * is bound to. - * - * \note This CID configuration applies to subsequent handshakes - * performed on the SSL context \p ssl, but does not trigger - * one. You still have to call `mbedtls_ssl_handshake()` - * (for the initial handshake) or `mbedtls_ssl_renegotiate()` - * (for a renegotiation handshake) explicitly after a - * successful call to this function to run the handshake. - * - * \note This call cannot guarantee that the use of the CID - * will be successfully negotiated in the next handshake, - * because the peer might not support it. Specifically: - * - On the Client, enabling the use of the CID through - * this call implies that the `ClientHello` in the next - * handshake will include the CID extension, thereby - * offering the use of the CID to the server. Only if - * the `ServerHello` contains the CID extension, too, - * the CID extension will actually be put to use. - * - On the Server, enabling the use of the CID through - * this call implies that that the server will look for - * the CID extension in a `ClientHello` from the client, - * and, if present, reply with a CID extension in its - * `ServerHello`. - * - * \note To check whether the use of the CID was negotiated - * after the subsequent handshake has completed, please - * use the API mbedtls_ssl_get_peer_cid(). - * - * \warning If the use of the CID extension is enabled in this call - * and the subsequent handshake negotiates its use, Mbed TLS - * will silently drop every packet whose CID does not match - * the CID configured in \p own_cid. It is the responsibility - * of the user to adapt the underlying transport to take care - * of CID-based demultiplexing before handing datagrams to - * Mbed TLS. - * - * \return \c 0 on success. In this case, the CID configuration - * applies to the next handshake. - * \return A negative error code on failure. - */ -int mbedtls_ssl_set_cid( mbedtls_ssl_context *ssl, - int enable, - unsigned char const *own_cid, - size_t own_cid_len ); - -/** - * \brief Get information about the use of the CID extension - * in the current connection. - * - * \param ssl The SSL context to query. - * \param enabled The address at which to store whether the CID extension - * is currently in use or not. If the CID is in use, - * `*enabled` is set to MBEDTLS_SSL_CID_ENABLED; - * otherwise, it is set to MBEDTLS_SSL_CID_DISABLED. - * \param peer_cid The address of the buffer in which to store the CID - * chosen by the peer (if the CID extension is used). - * This may be \c NULL in case the value of peer CID - * isn't needed. If it is not \c NULL, \p peer_cid_len - * must not be \c NULL. - * \param peer_cid_len The address at which to store the size of the CID - * chosen by the peer (if the CID extension is used). - * This is also the number of Bytes in \p peer_cid that - * have been written. - * This may be \c NULL in case the length of the peer CID - * isn't needed. If it is \c NULL, \p peer_cid must be - * \c NULL, too. - * - * \note This applies to the state of the CID negotiated in - * the last complete handshake. If a handshake is in - * progress, this function will attempt to complete - * the handshake first. - * - * \note If CID extensions have been exchanged but both client - * and server chose to use an empty CID, this function - * sets `*enabled` to #MBEDTLS_SSL_CID_DISABLED - * (the rationale for this is that the resulting - * communication is the same as if the CID extensions - * hadn't been used). - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_ssl_get_peer_cid( mbedtls_ssl_context *ssl, - int *enabled, - unsigned char peer_cid[ MBEDTLS_SSL_CID_OUT_LEN_MAX ], - size_t *peer_cid_len ); - -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - -/** - * \brief Set the Maximum Tranport Unit (MTU). - * Special value: 0 means unset (no limit). - * This represents the maximum size of a datagram payload - * handled by the transport layer (usually UDP) as determined - * by the network link and stack. In practice, this controls - * the maximum size datagram the DTLS layer will pass to the - * \c f_send() callback set using \c mbedtls_ssl_set_bio(). - * - * \note The limit on datagram size is converted to a limit on - * record payload by subtracting the current overhead of - * encapsulation and encryption/authentication if any. - * - * \note This can be called at any point during the connection, for - * example when a Path Maximum Transfer Unit (PMTU) - * estimate becomes available from other sources, - * such as lower (or higher) protocol layers. - * - * \note This setting only controls the size of the packets we send, - * and does not restrict the size of the datagrams we're - * willing to receive. Client-side, you can request the - * server to use smaller records with \c - * mbedtls_ssl_conf_max_frag_len(). - * - * \note If both a MTU and a maximum fragment length have been - * configured (or negotiated with the peer), the resulting - * lower limit on record payload (see first note) is used. - * - * \note This can only be used to decrease the maximum size - * of datagrams (hence records, see first note) sent. It - * cannot be used to increase the maximum size of records over - * the limit set by #MBEDTLS_SSL_OUT_CONTENT_LEN. - * - * \note Values lower than the current record layer expansion will - * result in an error when trying to send data. - * - * \note Using record compression together with a non-zero MTU value - * will result in an error when trying to send data. - * - * \param ssl SSL context - * \param mtu Value of the path MTU in bytes - */ -void mbedtls_ssl_set_mtu( mbedtls_ssl_context *ssl, uint16_t mtu ); -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - -#if !defined(MBEDTLS_SSL_CONF_READ_TIMEOUT) /** * \brief Set the timeout period for mbedtls_ssl_read() * (Default: no timeout.) @@ -1932,107 +1139,35 @@ void mbedtls_ssl_set_mtu( mbedtls_ssl_context *ssl, uint16_t mtu ); * With non-blocking I/O, this will only work if timer * callbacks were set with \c mbedtls_ssl_set_timer_cb(). * - * \note On constrained systems, this option can also be configured - * at compile-time via MBEDTLS_SSL_CONF_READ_TIMEOUT. - * * \note With non-blocking I/O, you may also skip this function * altogether and handle timeouts at the application layer. */ void mbedtls_ssl_conf_read_timeout( mbedtls_ssl_config *conf, uint32_t timeout ); -#endif /* !MBEDTLS_SSL_CONF_READ_TIMEOUT */ -#if defined(MBEDTLS_SSL_RECORD_CHECKING) /** - * \brief Check whether a buffer contains a valid, fresh - * and authentic record (DTLS only). + * \brief Set the timer callbacks (Mandatory for DTLS.) * - * This function does not change the user-visible state - * of the SSL context. Its sole purpose is to provide - * an indication of the legitimacy of an incoming record. - * - * This can be useful e.g. in distributed server environments - * using the DTLS Connection ID feature, in which connections - * might need to be passed between service instances on a change - * of peer address, but where such disruptive operations should - * only happen after the validity of incoming records has been - * confirmed. - * - * \param ssl The SSL context to use. - * \param buf The address of the buffer holding the record to be checked. - * This must be an R/W buffer of length \p buflen Bytes. - * \param buflen The length of \p buf in Bytes. - * - * \note This routine only checks whether the provided buffer begins - * with a valid, fresh and authentic record, but does not check - * potential data following the initial record. In particular, - * it is possible to pass DTLS datagrams containing multiple - * records, in which case only the first record is checked. - * - * \note This function modifies the input buffer \p buf. If you need - * to preserve the original record, you have to maintain a copy. - * - * \return \c 0 if the record is valid, fresh and authentic. - * \return MBEDTLS_ERR_SSL_INVALID_MAC if the check completed - * successfully but the record was found to be not authentic. - * \return MBEDTLS_ERR_SSL_INVALID_RECORD if the check completed - * successfully but the record was found to be invalid for - * a reason different from authenticity checking. - * \return MBEDTLS_ERR_SSL_UNEXPECTED_RECORD if the check completed - * successfully but the record was found to be unexpected - * in the state of the SSL context, including replayed records. - * \return Another negative error code on different kinds of failure. - * In this case, the SSL context becomes unusable and needs - * to be freed or reset before reuse. - */ -int mbedtls_ssl_check_record( mbedtls_ssl_context const *ssl, - unsigned char *buf, - size_t buflen ); -#endif /* MBEDTLS_SSL_RECORD_CHECKING */ - -#if !defined(MBEDTLS_SSL_CONF_SET_TIMER) && \ - !defined(MBEDTLS_SSL_CONF_GET_TIMER) -/** - * \brief Set the timer callbacks (Mandatory for DTLS.) - * - * \param ssl SSL context - * \param p_timer parameter (context) shared by timer callbacks + * \param ssl SSL context + * \param p_timer parameter (context) shared by timer callbacks * \param f_set_timer set timer callback * \param f_get_timer get timer callback. Must return: * - * \note See the documentation of \c mbedtls_ssl_set_timer_t and - * \c mbedtls_ssl_get_timer_t for the conventions this pair of - * callbacks must follow. + * \note See the documentation of \c mbedtls_ssl_set_timer_t and + * \c mbedtls_ssl_get_timer_t for the conventions this pair of + * callbacks must follow. * - * \note On some platforms, timing.c provides - * \c mbedtls_timing_set_delay() and - * \c mbedtls_timing_get_delay() that are suitable for using - * here, except if using an event-driven style. + * \note On some platforms, timing.c provides + * \c mbedtls_timing_set_delay() and + * \c mbedtls_timing_get_delay() that are suitable for using + * here, except if using an event-driven style. * - * \note On constrained systems, the timer callbacks \p f_set_timer - * and \p f_get_timer may also be configured at compile-time - * via MBEDTLS_SSL_CONF_GET_TIMER and MBEDTLS_SSL_CONF_SET_TIMER. - * - * \note See also the "DTLS tutorial" article in our knowledge base. - * https://tls.mbed.org/kb/how-to/dtls-tutorial + * \note See also the "DTLS tutorial" article in our knowledge base. + * https://tls.mbed.org/kb/how-to/dtls-tutorial */ void mbedtls_ssl_set_timer_cb( mbedtls_ssl_context *ssl, void *p_timer, mbedtls_ssl_set_timer_t *f_set_timer, mbedtls_ssl_get_timer_t *f_get_timer ); -#else /* !( MBEDTLS_SSL_CONF_SET_TIMER && - MBEDTLS_SSL_CONF_GET_TIMER ) */ -/** - * \brief Set the context to be passed to the timer callbacks - * (Mandatory for DTLS.) - * - * \param ssl The SSL context to configure. - * \param p_timer The context to be passed to the timer callbacks. - * - */ -void mbedtls_ssl_set_timer_cb_ctx( mbedtls_ssl_context *ssl, - void *p_timer ); -#endif /* MBEDTLS_SSL_CONF_SET_TIMER && - MBEDTLS_SSL_CONF_GET_TIMER */ /** * \brief Callback type: generate and write session ticket @@ -2154,85 +1289,6 @@ void mbedtls_ssl_conf_export_keys_cb( mbedtls_ssl_config *conf, void *p_export_keys ); #endif /* MBEDTLS_SSL_EXPORT_KEYS */ -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) -/** - * \brief Configure asynchronous private key operation callbacks. - * - * \param conf SSL configuration context - * \param f_async_sign Callback to start a signature operation. See - * the description of ::mbedtls_ssl_async_sign_t - * for more information. This may be \c NULL if the - * external processor does not support any signature - * operation; in this case the private key object - * associated with the certificate will be used. - * \param f_async_decrypt Callback to start a decryption operation. See - * the description of ::mbedtls_ssl_async_decrypt_t - * for more information. This may be \c NULL if the - * external processor does not support any decryption - * operation; in this case the private key object - * associated with the certificate will be used. - * \param f_async_resume Callback to resume an asynchronous operation. See - * the description of ::mbedtls_ssl_async_resume_t - * for more information. This may not be \c NULL unless - * \p f_async_sign and \p f_async_decrypt are both - * \c NULL. - * \param f_async_cancel Callback to cancel an asynchronous operation. See - * the description of ::mbedtls_ssl_async_cancel_t - * for more information. This may be \c NULL if - * no cleanup is needed. - * \param config_data A pointer to configuration data which can be - * retrieved with - * mbedtls_ssl_conf_get_async_config_data(). The - * library stores this value without dereferencing it. - */ -void mbedtls_ssl_conf_async_private_cb( mbedtls_ssl_config *conf, - mbedtls_ssl_async_sign_t *f_async_sign, - mbedtls_ssl_async_decrypt_t *f_async_decrypt, - mbedtls_ssl_async_resume_t *f_async_resume, - mbedtls_ssl_async_cancel_t *f_async_cancel, - void *config_data ); - -/** - * \brief Retrieve the configuration data set by - * mbedtls_ssl_conf_async_private_cb(). - * - * \param conf SSL configuration context - * \return The configuration data set by - * mbedtls_ssl_conf_async_private_cb(). - */ -void *mbedtls_ssl_conf_get_async_config_data( const mbedtls_ssl_config *conf ); - -/** - * \brief Retrieve the asynchronous operation user context. - * - * \note This function may only be called while a handshake - * is in progress. - * - * \param ssl The SSL context to access. - * - * \return The asynchronous operation user context that was last - * set during the current handshake. If - * mbedtls_ssl_set_async_operation_data() has not yet been - * called during the current handshake, this function returns - * \c NULL. - */ -void *mbedtls_ssl_get_async_operation_data( const mbedtls_ssl_context *ssl ); - -/** - * \brief Retrieve the asynchronous operation user context. - * - * \note This function may only be called while a handshake - * is in progress. - * - * \param ssl The SSL context to access. - * \param ctx The new value of the asynchronous operation user context. - * Call mbedtls_ssl_get_async_operation_data() later during the - * same handshake to retrieve this value. - */ -void mbedtls_ssl_set_async_operation_data( mbedtls_ssl_context *ssl, - void *ctx ); -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ - /** * \brief Callback type: generate a cookie * @@ -2327,16 +1383,14 @@ int mbedtls_ssl_set_client_transport_id( mbedtls_ssl_context *ssl, #endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY && MBEDTLS_SSL_SRV_C */ -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) && \ - !defined(MBEDTLS_SSL_CONF_ANTI_REPLAY) +#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) /** * \brief Enable or disable anti-replay protection for DTLS. * (DTLS only, no effect on TLS.) * Default: enabled. * * \param conf SSL configuration - * \param mode MBEDTLS_SSL_ANTI_REPLAY_ENABLED or - * MBEDTLS_SSL_ANTI_REPLAY_DISABLED. + * \param mode MBEDTLS_SSL_ANTI_REPLAY_ENABLED or MBEDTLS_SSL_ANTI_REPLAY_DISABLED. * * \warning Disabling this is a security risk unless the application * protocol handles duplicated packets in a safe way. You @@ -2344,16 +1398,11 @@ int mbedtls_ssl_set_client_transport_id( mbedtls_ssl_context *ssl, * However, if your application already detects duplicated * packets and needs information about them to adjust its * transmission strategy, then you'll want to disable this. - * - * \note On constrained systems, this option can also be - * fixed at compile-time by defining the constant - * MBEDTLS_SSL_CONF_ANTI_REPLAY. */ void mbedtls_ssl_conf_dtls_anti_replay( mbedtls_ssl_config *conf, char mode ); -#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY && !MBEDTLS_SSL_CONF_ANTI_REPLAY */ +#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */ -#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) && \ - !defined(MBEDTLS_SSL_CONF_BADMAC_LIMIT) +#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) /** * \brief Set a limit on the number of records with a bad MAC * before terminating the connection. @@ -2376,47 +1425,11 @@ void mbedtls_ssl_conf_dtls_anti_replay( mbedtls_ssl_config *conf, char mode ); * connection. On the other hand, a high limit or no limit * might make us waste resources checking authentication on * many bogus packets. - * - * \note On constrained systems, this option can also be - * fixed at compile-time by defining the constant - * MBEDTLS_SSL_CONF_BADMAC_LIMIT. */ void mbedtls_ssl_conf_dtls_badmac_limit( mbedtls_ssl_config *conf, unsigned limit ); -#endif /* MBEDTLS_SSL_DTLS_BADMAC_LIMIT && !MBEDTLS_SSL_CONF_BADMAC_LIMIT */ +#endif /* MBEDTLS_SSL_DTLS_BADMAC_LIMIT */ #if defined(MBEDTLS_SSL_PROTO_DTLS) - -/** - * \brief Allow or disallow packing of multiple handshake records - * within a single datagram. - * - * \param ssl The SSL context to configure. - * \param allow_packing This determines whether datagram packing may - * be used or not. A value of \c 0 means that every - * record will be sent in a separate datagram; a - * value of \c 1 means that, if space permits, - * multiple handshake messages (including CCS) belonging to - * a single flight may be packed within a single datagram. - * - * \note This is enabled by default and should only be disabled - * for test purposes, or if datagram packing causes - * interoperability issues with peers that don't support it. - * - * \note Allowing datagram packing reduces the network load since - * there's less overhead if multiple messages share the same - * datagram. Also, it increases the handshake efficiency - * since messages belonging to a single datagram will not - * be reordered in transit, and so future message buffering - * or flight retransmission (if no buffering is used) as - * means to deal with reordering are needed less frequently. - * - * \note Application records are not affected by this option and - * are currently always sent in separate datagrams. - * - */ -void mbedtls_ssl_set_datagram_packing( mbedtls_ssl_context *ssl, - unsigned allow_packing ); - /** * \brief Set retransmit timeout values for the DTLS handshake. * (DTLS only, no effect on TLS.) @@ -2451,7 +1464,7 @@ void mbedtls_ssl_set_datagram_packing( mbedtls_ssl_context *ssl, void mbedtls_ssl_conf_handshake_timeout( mbedtls_ssl_config *conf, uint32_t min, uint32_t max ); #endif /* MBEDTLS_SSL_PROTO_DTLS */ -#if defined(MBEDTLS_SSL_SRV_C) && !defined(MBEDTLS_SSL_NO_SESSION_CACHE) +#if defined(MBEDTLS_SSL_SRV_C) /** * \brief Set the session cache callbacks (server-side only) * If not set, no session resuming is done (except if session @@ -2493,9 +1506,9 @@ void mbedtls_ssl_conf_session_cache( mbedtls_ssl_config *conf, void *p_cache, int (*f_get_cache)(void *, mbedtls_ssl_session *), int (*f_set_cache)(void *, const mbedtls_ssl_session *) ); -#endif /* MBEDTLS_SSL_SRV_C && !MBEDTLS_SSL_NO_SESSION_CACHE */ +#endif /* MBEDTLS_SSL_SRV_C */ -#if defined(MBEDTLS_SSL_CLI_C) && !defined(MBEDTLS_SSL_NO_SESSION_RESUMPTION) +#if defined(MBEDTLS_SSL_CLI_C) /** * \brief Request resumption of session (client-side only) * Session data is copied from presented session structure. @@ -2511,93 +1524,8 @@ void mbedtls_ssl_conf_session_cache( mbedtls_ssl_config *conf, * \sa mbedtls_ssl_get_session() */ int mbedtls_ssl_set_session( mbedtls_ssl_context *ssl, const mbedtls_ssl_session *session ); -#endif /* MBEDTLS_SSL_CLI_C && !MBEDTLS_SSL_NO_SESSION_RESUMPTION */ +#endif /* MBEDTLS_SSL_CLI_C */ -/** - * \brief Load serialized session data into a session structure. - * On client, this can be used for loading saved sessions - * before resuming them with mbedstls_ssl_set_session(). - * On server, this can be used for alternative implementations - * of session cache or session tickets. - * - * \warning If a peer certificate chain is associated with the session, - * the serialized state will only contain the peer's - * end-entity certificate and the result of the chain - * verification (unless verification was disabled), but not - * the rest of the chain. - * - * \see mbedtls_ssl_session_save() - * \see mbedtls_ssl_set_session() - * - * \param session The session structure to be populated. It must have been - * initialised with mbedtls_ssl_session_init() but not - * populated yet. - * \param buf The buffer holding the serialized session data. It must be a - * readable buffer of at least \p len bytes. - * \param len The size of the serialized data in bytes. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_SSL_ALLOC_FAILED if memory allocation failed. - * \return #MBEDTLS_ERR_SSL_BAD_INPUT_DATA if input data is invalid. - * \return #MBEDTLS_ERR_SSL_VERSION_MISMATCH if the serialized data - * was generated in a different version or configuration of - * Mbed TLS. - * \return Another negative value for other kinds of errors (for - * example, unsupported features in the embedded certificate). - */ -int mbedtls_ssl_session_load( mbedtls_ssl_session *session, - const unsigned char *buf, - size_t len ); - -/** - * \brief Save session structure as serialized data in a buffer. - * On client, this can be used for saving session data, - * potentially in non-volatile storage, for resuming later. - * On server, this can be used for alternative implementations - * of session cache or session tickets. - * - * \see mbedtls_ssl_session_load() - * \see mbedtls_ssl_get_session_pointer() - * - * \param session The session structure to be saved. - * \param buf The buffer to write the serialized data to. It must be a - * writeable buffer of at least \p len bytes, or may be \c - * NULL if \p len is \c 0. - * \param buf_len The number of bytes available for writing in \p buf. - * \param olen The size in bytes of the data that has been or would have - * been written. It must point to a valid \c size_t. - * - * \note \p olen is updated to the correct value regardless of - * whether \p buf_len was large enough. This makes it possible - * to determine the necessary size by calling this function - * with \p buf set to \c NULL and \p buf_len to \c 0. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL if \p buf is too small. - */ -int mbedtls_ssl_session_save( const mbedtls_ssl_session *session, - unsigned char *buf, - size_t buf_len, - size_t *olen ); - -/** - * \brief Get a pointer to the current session structure, for example - * to serialize it. - * - * \warning Ownership of the session remains with the SSL context, and - * the returned pointer is only guaranteed to be valid until - * the next API call operating on the same \p ssl context. - * - * \see mbedtls_ssl_session_save() - * - * \param ssl The SSL context. - * - * \return A pointer to the current session if successful. - * \return \c NULL if no session is active. - */ -const mbedtls_ssl_session *mbedtls_ssl_get_session_pointer( const mbedtls_ssl_context *ssl ); - -#if !defined(MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE) /** * \brief Set the list of allowed ciphersuites and the preference * order. First in the list has the highest preference. @@ -2610,15 +1538,11 @@ const mbedtls_ssl_session *mbedtls_ssl_get_session_pointer( const mbedtls_ssl_co * over the preference of the client unless * MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE is defined! * - * \note On constrained systems, support for a single ciphersuite - * (in all versions) can be fixed at compile-time through - * the configuration option MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE. - * * \param conf SSL configuration * \param ciphersuites 0-terminated list of allowed ciphersuites */ void mbedtls_ssl_conf_ciphersuites( mbedtls_ssl_config *conf, - const int *ciphersuites ); + const int *ciphersuites ); /** * \brief Set the list of allowed ciphersuites and the @@ -2638,62 +1562,10 @@ void mbedtls_ssl_conf_ciphersuites( mbedtls_ssl_config *conf, * * \note With DTLS, use MBEDTLS_SSL_MINOR_VERSION_2 for DTLS 1.0 * and MBEDTLS_SSL_MINOR_VERSION_3 for DTLS 1.2 - * - * \note On constrained systems, support for a single ciphersuite - * (in all versions) can be fixed at compile-time through - * the configuration option MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE. */ void mbedtls_ssl_conf_ciphersuites_for_version( mbedtls_ssl_config *conf, const int *ciphersuites, int major, int minor ); -#endif /* !MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE */ - -#define MBEDTLS_SSL_UNEXPECTED_CID_IGNORE 0 -#define MBEDTLS_SSL_UNEXPECTED_CID_FAIL 1 -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \ - !defined(MBEDTLS_SSL_CONF_CID_LEN) && \ - !defined(MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID) -/** - * \brief Specify the length of Connection IDs for incoming - * encrypted DTLS records, as well as the behaviour - * on unexpected CIDs. - * - * By default, the CID length is set to \c 0, - * and unexpected CIDs are silently ignored. - * - * \param conf The SSL configuration to modify. - * \param len The length in Bytes of the CID fields in encrypted - * DTLS records using the CID mechanism. This must - * not be larger than #MBEDTLS_SSL_CID_OUT_LEN_MAX. - * \param ignore_other_cids This determines the stack's behaviour when - * receiving a record with an unexpected CID. - * Possible values are: - * - #MBEDTLS_SSL_UNEXPECTED_CID_IGNORE - * In this case, the record is silently ignored. - * - #MBEDTLS_SSL_UNEXPECTED_CID_FAIL - * In this case, the stack fails with the specific - * error code #MBEDTLS_ERR_SSL_UNEXPECTED_CID. - * - * \note The CID specification allows implementations to either - * use a common length for all incoming connection IDs or - * allow variable-length incoming IDs. Mbed TLS currently - * requires a common length for all connections sharing the - * same SSL configuration; this allows simpler parsing of - * record headers. - * - * \note On constrained systems, this configuration can also be - * fixed at compile-time via MBEDTLS_SSL_CONF_CID_LEN and - * MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_SSL_BAD_INPUT_DATA if \p own_cid_len - * is too large. - */ -int mbedtls_ssl_conf_cid( mbedtls_ssl_config *conf, size_t len, - int ignore_other_cids ); -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID && - !MBEDTLS_SSL_CONF_CID_LEN && - !MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID */ #if defined(MBEDTLS_X509_CRT_PARSE_C) /** @@ -2735,7 +1607,7 @@ void mbedtls_ssl_conf_ca_chain( mbedtls_ssl_config *conf, * provision more than one cert/key pair (eg one ECDSA, one * RSA with SHA-256, one RSA with SHA-1). An adequate * certificate will be selected according to the client's - * advertised capabilities. In case multiple certificates are + * advertised capabilities. In case mutliple certificates are * adequate, preference is given to the one set by the first * call to this function, then second, etc. * @@ -2908,7 +1780,6 @@ void mbedtls_ssl_conf_dhm_min_bitlen( mbedtls_ssl_config *conf, #endif /* MBEDTLS_DHM_C && MBEDTLS_SSL_CLI_C */ #if defined(MBEDTLS_ECP_C) -#if !defined(MBEDTLS_SSL_CONF_SINGLE_EC) /** * \brief Set the allowed curves in order of preference. * (Default: all defined curves.) @@ -2932,17 +1803,12 @@ void mbedtls_ssl_conf_dhm_min_bitlen( mbedtls_ssl_config *conf, * \note This list should be ordered by decreasing preference * (preferred curve first). * - * \note On highly constrained systems, the support for a single - * fixed elliptic curve can be configured at compile time - * through the option MBEDTLS_SSL_CONF_SINGLE_EC. - * * \param conf SSL configuration * \param curves Ordered list of allowed curves, * terminated by MBEDTLS_ECP_DP_NONE. */ void mbedtls_ssl_conf_curves( mbedtls_ssl_config *conf, const mbedtls_ecp_group_id *curves ); -#endif /* !MBEDTLS_SSL_CONF_SINGLE_EC */ #endif /* MBEDTLS_ECP_C */ #if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) @@ -2960,10 +1826,6 @@ void mbedtls_ssl_conf_curves( mbedtls_ssl_config *conf, * \note This list should be ordered by decreasing preference * (preferred hash first). * - * \note On highly constrained systems, the support for a single - * fixed signature hash algorithm can be configured at compile - * time through the option MBEDTLS_SSL_CONF_SINGLE_SIG_HASH. - * * \param conf SSL configuration * \param hashes Ordered list of allowed signature hashes, * terminated by \c MBEDTLS_MD_NONE. @@ -2972,7 +1834,7 @@ void mbedtls_ssl_conf_sig_hashes( mbedtls_ssl_config *conf, const int *hashes ); #endif /* MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ -#if defined(MBEDTLS_X509_CRT_PARSE_C) && !defined(MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION) +#if defined(MBEDTLS_X509_CRT_PARSE_C) /** * \brief Set or reset the hostname to check against the received * server certificate. It sets the ServerName TLS extension, @@ -2980,7 +1842,7 @@ void mbedtls_ssl_conf_sig_hashes( mbedtls_ssl_config *conf, * * \param ssl SSL context * \param hostname the server hostname, may be NULL to clear hostname - + * * \note Maximum hostname length MBEDTLS_SSL_MAX_HOST_NAME_LEN. * * \return 0 if successful, MBEDTLS_ERR_SSL_ALLOC_FAILED on @@ -2992,7 +1854,7 @@ void mbedtls_ssl_conf_sig_hashes( mbedtls_ssl_config *conf, * On too long input failure, old hostname is unchanged. */ int mbedtls_ssl_set_hostname( mbedtls_ssl_context *ssl, const char *hostname ); -#endif /* MBEDTLS_X509_CRT_PARSE_C && !MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION */ +#endif /* MBEDTLS_X509_CRT_PARSE_C */ #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) /** @@ -3118,8 +1980,6 @@ int mbedtls_ssl_conf_alpn_protocols( mbedtls_ssl_config *conf, const char **prot const char *mbedtls_ssl_get_alpn_protocol( const mbedtls_ssl_context *ssl ); #endif /* MBEDTLS_SSL_ALPN */ -#if !defined(MBEDTLS_SSL_CONF_MAX_MINOR_VER) || \ - !defined(MBEDTLS_SSL_CONF_MAX_MAJOR_VER) /** * \brief Set the maximum supported version sent from the client side * and/or accepted at the server side @@ -3130,11 +1990,6 @@ const char *mbedtls_ssl_get_alpn_protocol( const mbedtls_ssl_context *ssl ); * \note With DTLS, use MBEDTLS_SSL_MINOR_VERSION_2 for DTLS 1.0 and * MBEDTLS_SSL_MINOR_VERSION_3 for DTLS 1.2 * - * \note On constrained systems, the maximum major/minor version can - * also be configured at compile-time by setting - * MBEDTLS_SSL_CONF_MAX_MAJOR_VER and - * MBEDTLS_SSL_CONF_MAX_MINOR_VER. - * * \param conf SSL configuration * \param major Major version number (only MBEDTLS_SSL_MAJOR_VERSION_3 supported) * \param minor Minor version number (MBEDTLS_SSL_MINOR_VERSION_0, @@ -3142,11 +1997,7 @@ const char *mbedtls_ssl_get_alpn_protocol( const mbedtls_ssl_context *ssl ); * MBEDTLS_SSL_MINOR_VERSION_3 supported) */ void mbedtls_ssl_conf_max_version( mbedtls_ssl_config *conf, int major, int minor ); -#endif /* MBEDTLS_SSL_CONF_MAX_MINOR_VER || - MBEDTLS_SSL_CONF_MAX_MAJOR_VER */ -#if !defined(MBEDTLS_SSL_CONF_MIN_MINOR_VER) || \ - !defined(MBEDTLS_SSL_CONF_MIN_MAJOR_VER) /** * \brief Set the minimum accepted SSL/TLS protocol version * (Default: TLS 1.0) @@ -3159,11 +2010,6 @@ void mbedtls_ssl_conf_max_version( mbedtls_ssl_config *conf, int major, int mino * \note With DTLS, use MBEDTLS_SSL_MINOR_VERSION_2 for DTLS 1.0 and * MBEDTLS_SSL_MINOR_VERSION_3 for DTLS 1.2 * - * \note On constrained systems, the minimum major/minor version can - * also be configured at compile-time by setting - * MBEDTLS_SSL_CONF_MIN_MAJOR_VER and - * MBEDTLS_SSL_CONF_MIN_MINOR_VER. - * * \param conf SSL configuration * \param major Major version number (only MBEDTLS_SSL_MAJOR_VERSION_3 supported) * \param minor Minor version number (MBEDTLS_SSL_MINOR_VERSION_0, @@ -3171,8 +2017,6 @@ void mbedtls_ssl_conf_max_version( mbedtls_ssl_config *conf, int major, int mino * MBEDTLS_SSL_MINOR_VERSION_3 supported) */ void mbedtls_ssl_conf_min_version( mbedtls_ssl_config *conf, int major, int minor ); -#endif /* MBEDTLS_SSL_CONF_MIN_MINOR_VER || - MBEDTLS_SSL_CONF_MIN_MAJOR_VER */ #if defined(MBEDTLS_SSL_FALLBACK_SCSV) && defined(MBEDTLS_SSL_CLI_C) /** @@ -3213,7 +2057,6 @@ void mbedtls_ssl_conf_encrypt_then_mac( mbedtls_ssl_config *conf, char etm ); #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) -#if !defined(MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET) /** * \brief Enable or disable Extended Master Secret negotiation. * (Default: MBEDTLS_SSL_EXTENDED_MS_ENABLED) @@ -3222,47 +2065,10 @@ void mbedtls_ssl_conf_encrypt_then_mac( mbedtls_ssl_config *conf, char etm ); * protocol, and should not cause any interoperability issue * (used only if the peer supports it too). * - * \note On constrained systems, this option can also be - * fixed at compile-time by defining the constant - * MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET - * as MBEDTLS_SSL_EXTENDED_MS_ENABLED or - * MBEDTLS_SSL_EXTENDED_MS_DISABLED. - * * \param conf SSL configuration - * \param ems MBEDTLS_SSL_EXTENDED_MS_ENABLED or - * MBEDTLS_SSL_EXTENDED_MS_DISABLED + * \param ems MBEDTLS_SSL_EXTENDED_MS_ENABLED or MBEDTLS_SSL_EXTENDED_MS_DISABLED */ void mbedtls_ssl_conf_extended_master_secret( mbedtls_ssl_config *conf, char ems ); -#endif /* !MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET */ - -#if !defined(MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET) -/** - * \brief Enable or disable Extended Master Secret enforcing. - * (Default: MBEDTLS_SSL_EXTENDED_MS_ENFORCE_DISABLED) - * - * \note If the use of extended master secret is configured (see - * `mbedtls_ssl_conf_extended_master_secret()`) and this - * option is set, handshakes not leading to the use of the - * extended master secret will be aborted: On the server, fail - * the handshake if the client doesn't advertise the - * ExtendedMasterSecret extension. On the client: Fail the - * handshake if the server doesn't consent to the use of the - * ExtendedMasterSecret extension in its ServerHello. - * - * \param conf Currently used SSL configuration struct. - * \param ems_enf MBEDTLS_SSL_EXTENDED_MS_ENFORCE_ENABLED or - * MBEDTLS_SSL_EXTENDED_MS_ENFORCE_DISABLED - - * \note On constrained systems, this option can also be - * fixed at compile-time by defining the constant - * MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET - * as MBEDTLS_SSL_EXTENDED_MS_ENFORCE_ENABLED or - * MBEDTLS_SSL_EXTENDED_MS_ENFORCE_DISABLED. - * - */ -void mbedtls_ssl_conf_extended_master_secret_enforce( mbedtls_ssl_config *conf, - char ems_enf ); -#endif /* !MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET */ #endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ #if defined(MBEDTLS_ARC4_C) @@ -3284,50 +2090,28 @@ void mbedtls_ssl_conf_extended_master_secret_enforce( mbedtls_ssl_config *conf, void mbedtls_ssl_conf_arc4_support( mbedtls_ssl_config *conf, char arc4 ); #endif /* MBEDTLS_ARC4_C */ -#if defined(MBEDTLS_SSL_SRV_C) && !defined(MBEDTLS_SSL_CONF_CERT_REQ_CA_LIST) +#if defined(MBEDTLS_SSL_SRV_C) /** * \brief Whether to send a list of acceptable CAs in * CertificateRequest messages. * (Default: do send) * - * \note On constrained systems, this options can also be configured - * at compile-time via MBEDTLS_SSL_CONF_CERT_REQ_CA_LIST. - * * \param conf SSL configuration * \param cert_req_ca_list MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED or * MBEDTLS_SSL_CERT_REQ_CA_LIST_DISABLED */ void mbedtls_ssl_conf_cert_req_ca_list( mbedtls_ssl_config *conf, char cert_req_ca_list ); -#endif /* MBEDTLS_SSL_SRV_C && !MBEDTLS_SSL_CONF_CERT_REQ_CA_LIST */ +#endif /* MBEDTLS_SSL_SRV_C */ #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) /** - * \brief Set the maximum fragment length to emit and/or negotiate. - * (Typical: the smaller of #MBEDTLS_SSL_IN_CONTENT_LEN and - * #MBEDTLS_SSL_OUT_CONTENT_LEN, usually `2^14` bytes) + * \brief Set the maximum fragment length to emit and/or negotiate + * (Default: MBEDTLS_SSL_MAX_CONTENT_LEN, usually 2^14 bytes) * (Server: set maximum fragment length to emit, - * usually negotiated by the client during handshake) + * usually negotiated by the client during handshake * (Client: set maximum fragment length to emit *and* * negotiate with the server during handshake) - * (Default: #MBEDTLS_SSL_MAX_FRAG_LEN_NONE) - * - * \note On the client side, the maximum fragment length extension - * *will not* be used, unless the maximum fragment length has - * been set via this function to a value different than - * #MBEDTLS_SSL_MAX_FRAG_LEN_NONE. - * - * \note This sets the maximum length for a record's payload, - * excluding record overhead that will be added to it, see - * \c mbedtls_ssl_get_record_expansion(). - * - * \note With TLS, this currently only affects ApplicationData (sent - * with \c mbedtls_ssl_read()), not handshake messages. - * With DTLS, this affects both ApplicationData and handshake. - * - * \note For DTLS, it is also possible to set a limit for the total - * size of daragrams passed to the transport layer, including - * record overhead, see \c mbedtls_ssl_set_mtu(). * * \param conf SSL configuration * \param mfl_code Code for maximum fragment length (allowed values: @@ -3401,7 +2185,6 @@ void mbedtls_ssl_conf_session_tickets( mbedtls_ssl_config *conf, int use_tickets void mbedtls_ssl_conf_renegotiation( mbedtls_ssl_config *conf, int renegotiation ); #endif /* MBEDTLS_SSL_RENEGOTIATION */ -#if !defined(MBEDTLS_SSL_CONF_ALLOW_LEGACY_RENEGOTIATION) /** * \brief Prevent or allow legacy renegotiation. * (Default: MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION) @@ -3428,14 +2211,8 @@ void mbedtls_ssl_conf_renegotiation( mbedtls_ssl_config *conf, int renegotiation * \param allow_legacy Prevent or allow (SSL_NO_LEGACY_RENEGOTIATION, * SSL_ALLOW_LEGACY_RENEGOTIATION or * MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE) - * - * - * \note On constrained systems, this option can also be - * fixed at compile-time by defining the constant - * MBEDTLS_SSL_CONF_ALLOW_LEGACY_RENEGOTIATION. */ void mbedtls_ssl_conf_legacy_renegotiation( mbedtls_ssl_config *conf, int allow_legacy ); -#endif /* !MBEDTLS_SSL_CONF_ALLOW_LEGACY_RENEGOTIATION */ #if defined(MBEDTLS_SSL_RENEGOTIATION) /** @@ -3482,7 +2259,7 @@ void mbedtls_ssl_conf_renegotiation_enforced( mbedtls_ssl_config *conf, int max_ * (Default: 2^48 - 1) * * Renegotiation is automatically triggered when a record - * counter (outgoing or incoming) crosses the defined + * counter (outgoing or ingoing) crosses the defined * threshold. The default value is meant to prevent the * connection from being closed when the counter is about to * reached its maximal value (it is not allowed to wrap). @@ -3507,59 +2284,11 @@ void mbedtls_ssl_conf_renegotiation_period( mbedtls_ssl_config *conf, #endif /* MBEDTLS_SSL_RENEGOTIATION */ /** - * \brief Check if there is data already read from the - * underlying transport but not yet processed. + * \brief Return the number of data bytes available to read * * \param ssl SSL context * - * \return 0 if nothing's pending, 1 otherwise. - * - * \note This is different in purpose and behaviour from - * \c mbedtls_ssl_get_bytes_avail in that it considers - * any kind of unprocessed data, not only unread - * application data. If \c mbedtls_ssl_get_bytes - * returns a non-zero value, this function will - * also signal pending data, but the converse does - * not hold. For example, in DTLS there might be - * further records waiting to be processed from - * the current underlying transport's datagram. - * - * \note If this function returns 1 (data pending), this - * does not imply that a subsequent call to - * \c mbedtls_ssl_read will provide any data; - * e.g., the unprocessed data might turn out - * to be an alert or a handshake message. - * - * \note This function is useful in the following situation: - * If the SSL/TLS module successfully returns from an - * operation - e.g. a handshake or an application record - * read - and you're awaiting incoming data next, you - * must not immediately idle on the underlying transport - * to have data ready, but you need to check the value - * of this function first. The reason is that the desired - * data might already be read but not yet processed. - * If, in contrast, a previous call to the SSL/TLS module - * returned MBEDTLS_ERR_SSL_WANT_READ, it is not necessary - * to call this function, as the latter error code entails - * that all internal data has been processed. - * - */ -int mbedtls_ssl_check_pending( const mbedtls_ssl_context *ssl ); - -/** - * \brief Return the number of application data bytes - * remaining to be read from the current record. - * - * \param ssl SSL context - * - * \return How many bytes are available in the application - * data record read buffer. - * - * \note When working over a datagram transport, this is - * useful to detect the current datagram's boundary - * in case \c mbedtls_ssl_read has written the maximal - * amount of data fitting into the input buffer. - * + * \return how many bytes are available in the read buffer */ size_t mbedtls_ssl_get_bytes_avail( const mbedtls_ssl_context *ssl ); @@ -3599,9 +2328,6 @@ const char *mbedtls_ssl_get_version( const mbedtls_ssl_context *ssl ); * \brief Return the (maximum) number of bytes added by the record * layer: header + encryption/MAC overhead (inc. padding) * - * \note This function is not available (always returns an error) - * when record compression is enabled. - * * \param ssl SSL context * * \return Current maximum record expansion in bytes, or @@ -3612,69 +2338,9 @@ int mbedtls_ssl_get_record_expansion( const mbedtls_ssl_context *ssl ); #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) /** - * \brief Return the maximum fragment length (payload, in bytes) for - * the output buffer. For the client, this is the configured - * value. For the server, it is the minimum of two - the - * configured value and the negotiated one. - * - * \sa mbedtls_ssl_conf_max_frag_len() - * \sa mbedtls_ssl_get_max_record_payload() - * - * \param ssl SSL context - * - * \return Current maximum fragment length for the output buffer. - */ -size_t mbedtls_ssl_get_output_max_frag_len( const mbedtls_ssl_context *ssl ); - -/** - * \brief Return the maximum fragment length (payload, in bytes) for - * the input buffer. This is the negotiated maximum fragment - * length, or, if there is none, MBEDTLS_SSL_MAX_CONTENT_LEN. - * If it is not defined either, the value is 2^14. This function - * works as its predecessor, \c mbedtls_ssl_get_max_frag_len(). - * - * \sa mbedtls_ssl_conf_max_frag_len() - * \sa mbedtls_ssl_get_max_record_payload() - * - * \param ssl SSL context - * - * \return Current maximum fragment length for the output buffer. - */ -size_t mbedtls_ssl_get_input_max_frag_len( const mbedtls_ssl_context *ssl ); - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) - -#if defined(MBEDTLS_DEPRECATED_WARNING) -#define MBEDTLS_DEPRECATED __attribute__((deprecated)) -#else -#define MBEDTLS_DEPRECATED -#endif - -/** - * \brief This function is a deprecated approach to getting the max - * fragment length. Its an alias for - * \c mbedtls_ssl_get_output_max_frag_len(), as the behaviour - * is the same. See \c mbedtls_ssl_get_output_max_frag_len() for - * more detail. - * - * \sa mbedtls_ssl_get_input_max_frag_len() - * \sa mbedtls_ssl_get_output_max_frag_len() - * - * \param ssl SSL context - * - * \return Current maximum fragment length for the output buffer. - */ -MBEDTLS_DEPRECATED size_t mbedtls_ssl_get_max_frag_len( - const mbedtls_ssl_context *ssl ); -#endif /* MBEDTLS_DEPRECATED_REMOVED */ -#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ - -/** - * \brief Return the current maximum outgoing record payload in bytes. - * This takes into account the config.h setting \c - * MBEDTLS_SSL_OUT_CONTENT_LEN, the configured and negotiated - * max fragment length extension if used, and for DTLS the - * path MTU as configured and current record expansion. + * \brief Return the maximum fragment length (payload, in bytes). + * This is the value negotiated with peer if any, + * or the locally configured value. * * \note With DTLS, \c mbedtls_ssl_write() will return an error if * called with a larger length value. @@ -3683,51 +2349,27 @@ MBEDTLS_DEPRECATED size_t mbedtls_ssl_get_max_frag_len( * to the caller to call \c mbedtls_ssl_write() again in * order to send the remaining bytes if any. * - * \note This function is not available (always returns an error) - * when record compression is enabled. - * - * \sa mbedtls_ssl_set_mtu() - * \sa mbedtls_ssl_get_output_max_frag_len() - * \sa mbedtls_ssl_get_input_max_frag_len() - * \sa mbedtls_ssl_get_record_expansion() - * * \param ssl SSL context * - * \return Current maximum payload for an outgoing record, - * or a negative error code. + * \return Current maximum fragment length. */ -int mbedtls_ssl_get_max_out_record_payload( const mbedtls_ssl_context *ssl ); +size_t mbedtls_ssl_get_max_frag_len( const mbedtls_ssl_context *ssl ); +#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ #if defined(MBEDTLS_X509_CRT_PARSE_C) /** - * \brief Return the peer certificate from the current connection. + * \brief Return the peer certificate from the current connection * - * \param ssl The SSL context to use. This must be initialized and setup. + * Note: Can be NULL in case no certificate was sent during + * the handshake. Different calls for the same connection can + * return the same or different pointers for the same + * certificate and even a different certificate altogether. + * The peer cert CAN change in a single connection if + * renegotiation is performed. * - * \return The current peer certificate, if available. - * The returned certificate is owned by the SSL context and - * is valid only until the next call to the SSL API. - * \return \c NULL if no peer certificate is available. This might - * be because the chosen ciphersuite doesn't use CRTs - * (PSK-based ciphersuites, for example), or because - * #MBEDTLS_SSL_KEEP_PEER_CERTIFICATE has been disabled, - * allowing the stack to free the peer's CRT to save memory. + * \param ssl SSL context * - * \note For one-time inspection of the peer's certificate during - * the handshake, consider registering an X.509 CRT verification - * callback through mbedtls_ssl_conf_verify() instead of calling - * this function. Using mbedtls_ssl_conf_verify() also comes at - * the benefit of allowing you to influence the verification - * process, for example by masking expected and tolerated - * verification failures. - * - * \warning You must not use the pointer returned by this function - * after any further call to the SSL API, including - * mbedtls_ssl_read() and mbedtls_ssl_write(); this is - * because the pointer might change during renegotiation, - * which happens transparently to the user. - * If you want to use the certificate across API calls, - * you must make a copy. + * \return the current peer certificate */ const mbedtls_x509_crt *mbedtls_ssl_get_peer_cert( const mbedtls_ssl_context *ssl ); #endif /* MBEDTLS_X509_CRT_PARSE_C */ @@ -3767,50 +2409,21 @@ int mbedtls_ssl_get_session( const mbedtls_ssl_context *ssl, mbedtls_ssl_session * * \param ssl SSL context * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_SSL_WANT_READ or #MBEDTLS_ERR_SSL_WANT_WRITE - * if the handshake is incomplete and waiting for data to - * be available for reading from or writing to the underlying - * transport - in this case you must call this function again - * when the underlying transport is ready for the operation. - * \return #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if an asynchronous - * operation is in progress (see - * mbedtls_ssl_conf_async_private_cb()) - in this case you - * must call this function again when the operation is ready. - * \return #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS if a cryptographic - * operation is in progress (see mbedtls_ecp_set_max_ops()) - - * in this case you must call this function again to complete - * the handshake when you're done attending other tasks. - * \return #MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED if DTLS is in use - * and the client did not demonstrate reachability yet - in - * this case you must stop using the context (see below). - * \return Another SSL error code - in this case you must stop using - * the context (see below). + * \return 0 if successful, or + * MBEDTLS_ERR_SSL_WANT_READ or MBEDTLS_ERR_SSL_WANT_WRITE, or + * MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED (see below), or + * a specific SSL error code. * - * \warning If this function returns something other than - * \c 0, - * #MBEDTLS_ERR_SSL_WANT_READ, - * #MBEDTLS_ERR_SSL_WANT_WRITE, - * #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS or - * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS, - * you must stop using the SSL context for reading or writing, - * and either free it or call \c mbedtls_ssl_session_reset() - * on it before re-using it for a new connection; the current - * connection must be closed. + * \note If this function returns something other than 0 or + * MBEDTLS_ERR_SSL_WANT_READ/WRITE, then the ssl context + * becomes unusable, and you should either free it or call + * \c mbedtls_ssl_session_reset() on it before re-using it for + * a new connection; the current connection must be closed. * * \note If DTLS is in use, then you may choose to handle - * #MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED specially for logging + * MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED specially for logging * purposes, as it is an expected return value rather than an * actual error, but you still need to reset/free the context. - * - * \note Remarks regarding event-driven DTLS: - * If the function returns #MBEDTLS_ERR_SSL_WANT_READ, no datagram - * from the underlying transport layer is currently being processed, - * and it is safe to idle until the timer or the underlying transport - * signal a new event. This is not true for a successful handshake, - * in which case the datagram of the underlying transport that is - * currently being processed might or might not contain further - * DTLS records. */ int mbedtls_ssl_handshake( mbedtls_ssl_context *ssl ); @@ -3818,21 +2431,20 @@ int mbedtls_ssl_handshake( mbedtls_ssl_context *ssl ); * \brief Perform a single step of the SSL handshake * * \note The state of the context (ssl->state) will be at - * the next state after this function returns \c 0. Do not + * the next state after execution of this function. Do not * call this function if state is MBEDTLS_SSL_HANDSHAKE_OVER. * + * \note If this function returns something other than 0 or + * MBEDTLS_ERR_SSL_WANT_READ/WRITE, then the ssl context + * becomes unusable, and you should either free it or call + * \c mbedtls_ssl_session_reset() on it before re-using it for + * a new connection; the current connection must be closed. + * * \param ssl SSL context * - * \return See mbedtls_ssl_handshake(). - * - * \warning If this function returns something other than \c 0, - * #MBEDTLS_ERR_SSL_WANT_READ, #MBEDTLS_ERR_SSL_WANT_WRITE, - * #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS or - * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS, you must stop using - * the SSL context for reading or writing, and either free it - * or call \c mbedtls_ssl_session_reset() on it before - * re-using it for a new connection; the current connection - * must be closed. + * \return 0 if successful, or + * MBEDTLS_ERR_SSL_WANT_READ or MBEDTLS_ERR_SSL_WANT_WRITE, or + * a specific SSL error code. */ int mbedtls_ssl_handshake_step( mbedtls_ssl_context *ssl ); @@ -3847,18 +2459,13 @@ int mbedtls_ssl_handshake_step( mbedtls_ssl_context *ssl ); * \param ssl SSL context * * \return 0 if successful, or any mbedtls_ssl_handshake() return - * value except #MBEDTLS_ERR_SSL_CLIENT_RECONNECT that can't - * happen during a renegotiation. - * - * \warning If this function returns something other than \c 0, - * #MBEDTLS_ERR_SSL_WANT_READ, #MBEDTLS_ERR_SSL_WANT_WRITE, - * #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS or - * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS, you must stop using - * the SSL context for reading or writing, and either free it - * or call \c mbedtls_ssl_session_reset() on it before - * re-using it for a new connection; the current connection - * must be closed. + * value. * + * \note If this function returns something other than 0 or + * MBEDTLS_ERR_SSL_WANT_READ/WRITE, then the ssl context + * becomes unusable, and you should either free it or call + * \c mbedtls_ssl_session_reset() on it before re-using it for + * a new connection; the current connection must be closed. */ int mbedtls_ssl_renegotiate( mbedtls_ssl_context *ssl ); #endif /* MBEDTLS_SSL_RENEGOTIATION */ @@ -3870,68 +2477,32 @@ int mbedtls_ssl_renegotiate( mbedtls_ssl_context *ssl ); * \param buf buffer that will hold the data * \param len maximum number of bytes to read * - * \return The (positive) number of bytes read if successful. - * \return \c 0 if the read end of the underlying transport was closed - * - in this case you must stop using the context (see below). - * \return #MBEDTLS_ERR_SSL_WANT_READ or #MBEDTLS_ERR_SSL_WANT_WRITE - * if the handshake is incomplete and waiting for data to - * be available for reading from or writing to the underlying - * transport - in this case you must call this function again - * when the underlying transport is ready for the operation. - * \return #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if an asynchronous - * operation is in progress (see - * mbedtls_ssl_conf_async_private_cb()) - in this case you - * must call this function again when the operation is ready. - * \return #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS if a cryptographic - * operation is in progress (see mbedtls_ecp_set_max_ops()) - - * in this case you must call this function again to complete - * the handshake when you're done attending other tasks. - * \return #MBEDTLS_ERR_SSL_CLIENT_RECONNECT if we're at the server - * side of a DTLS connection and the client is initiating a - * new connection using the same source port. See below. - * \return Another SSL error code - in this case you must stop using - * the context (see below). + * \return the number of bytes read, or + * 0 for EOF, or + * MBEDTLS_ERR_SSL_WANT_READ or MBEDTLS_ERR_SSL_WANT_WRITE, or + * MBEDTLS_ERR_SSL_CLIENT_RECONNECT (see below), or + * another negative error code. * - * \warning If this function returns something other than - * a positive value, - * #MBEDTLS_ERR_SSL_WANT_READ, - * #MBEDTLS_ERR_SSL_WANT_WRITE, - * #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS, - * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS or - * #MBEDTLS_ERR_SSL_CLIENT_RECONNECT, - * you must stop using the SSL context for reading or writing, - * and either free it or call \c mbedtls_ssl_session_reset() - * on it before re-using it for a new connection; the current - * connection must be closed. + * \note If this function returns something other than a positive + * value or MBEDTLS_ERR_SSL_WANT_READ/WRITE or + * MBEDTLS_ERR_SSL_CLIENT_RECONNECT, then the ssl context + * becomes unusable, and you should either free it or call + * \c mbedtls_ssl_session_reset() on it before re-using it for + * a new connection; the current connection must be closed. * - * \note When this function returns #MBEDTLS_ERR_SSL_CLIENT_RECONNECT + * \note When this function return MBEDTLS_ERR_SSL_CLIENT_RECONNECT * (which can only happen server-side), it means that a client * is initiating a new connection using the same source port. * You can either treat that as a connection close and wait * for the client to resend a ClientHello, or directly * continue with \c mbedtls_ssl_handshake() with the same - * context (as it has been reset internally). Either way, you - * must make sure this is seen by the application as a new + * context (as it has beeen reset internally). Either way, you + * should make sure this is seen by the application as a new * connection: application state, if any, should be reset, and * most importantly the identity of the client must be checked * again. WARNING: not validating the identity of the client * again, or not transmitting the new identity to the * application layer, would allow authentication bypass! - * - * \note Remarks regarding event-driven DTLS: - * - If the function returns #MBEDTLS_ERR_SSL_WANT_READ, no datagram - * from the underlying transport layer is currently being processed, - * and it is safe to idle until the timer or the underlying transport - * signal a new event. - * - This function may return MBEDTLS_ERR_SSL_WANT_READ even if data was - * initially available on the underlying transport, as this data may have - * been only e.g. duplicated messages or a renegotiation request. - * Therefore, you must be prepared to receive MBEDTLS_ERR_SSL_WANT_READ even - * when reacting to an incoming-data event from the underlying transport. - * - On success, the datagram of the underlying transport that is currently - * being processed may contain further DTLS records. You should call - * \c mbedtls_ssl_check_pending to check for remaining records. - * */ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ); @@ -3948,39 +2519,21 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) * \param buf buffer holding the data * \param len how many bytes must be written * - * \return The (non-negative) number of bytes actually written if - * successful (may be less than \p len). - * \return #MBEDTLS_ERR_SSL_WANT_READ or #MBEDTLS_ERR_SSL_WANT_WRITE - * if the handshake is incomplete and waiting for data to - * be available for reading from or writing to the underlying - * transport - in this case you must call this function again - * when the underlying transport is ready for the operation. - * \return #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if an asynchronous - * operation is in progress (see - * mbedtls_ssl_conf_async_private_cb()) - in this case you - * must call this function again when the operation is ready. - * \return #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS if a cryptographic - * operation is in progress (see mbedtls_ecp_set_max_ops()) - - * in this case you must call this function again to complete - * the handshake when you're done attending other tasks. - * \return Another SSL error code - in this case you must stop using - * the context (see below). + * \return the number of bytes actually written (may be less than len), + * or MBEDTLS_ERR_SSL_WANT_WRITE or MBEDTLS_ERR_SSL_WANT_READ, + * or another negative error code. * - * \warning If this function returns something other than - * a non-negative value, - * #MBEDTLS_ERR_SSL_WANT_READ, - * #MBEDTLS_ERR_SSL_WANT_WRITE, - * #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS or - * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS, - * you must stop using the SSL context for reading or writing, - * and either free it or call \c mbedtls_ssl_session_reset() - * on it before re-using it for a new connection; the current - * connection must be closed. + * \note If this function returns something other than 0, a positive + * value or MBEDTLS_ERR_SSL_WANT_READ/WRITE, you must stop + * using the SSL context for reading or writing, and either + * free it or call \c mbedtls_ssl_session_reset() on it before + * re-using it for a new connection; the current connection + * must be closed. * - * \note When this function returns #MBEDTLS_ERR_SSL_WANT_WRITE/READ, + * \note When this function returns MBEDTLS_ERR_SSL_WANT_WRITE/READ, * it must be called later with the *same* arguments, * until it returns a value greater that or equal to 0. When - * the function returns #MBEDTLS_ERR_SSL_WANT_WRITE there may be + * the function returns MBEDTLS_ERR_SSL_WANT_WRITE there may be * some partial data in the output buffer, however this is not * yet sent. * @@ -3989,8 +2542,8 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) * or negotiated with the peer), then: * - with TLS, less bytes than requested are written. * - with DTLS, MBEDTLS_ERR_SSL_BAD_INPUT_DATA is returned. - * \c mbedtls_ssl_get_output_max_frag_len() may be used to - * query the active maximum fragment length. + * \c mbedtls_ssl_get_max_frag_len() may be used to query the + * active maximum fragment length. * * \note Attempting to write 0 bytes will result in an empty TLS * application record being sent. @@ -4008,10 +2561,10 @@ int mbedtls_ssl_write( mbedtls_ssl_context *ssl, const unsigned char *buf, size_ * \return 0 if successful, or a specific SSL error code. * * \note If this function returns something other than 0 or - * MBEDTLS_ERR_SSL_WANT_READ/WRITE, you must stop using - * the SSL context for reading or writing, and either free it or - * call \c mbedtls_ssl_session_reset() on it before re-using it - * for a new connection; the current connection must be closed. + * MBEDTLS_ERR_SSL_WANT_READ/WRITE, then the ssl context + * becomes unusable, and you should either free it or call + * \c mbedtls_ssl_session_reset() on it before re-using it for + * a new connection; the current connection must be closed. */ int mbedtls_ssl_send_alert_message( mbedtls_ssl_context *ssl, unsigned char level, @@ -4024,10 +2577,10 @@ int mbedtls_ssl_send_alert_message( mbedtls_ssl_context *ssl, * \return 0 if successful, or a specific SSL error code. * * \note If this function returns something other than 0 or - * MBEDTLS_ERR_SSL_WANT_READ/WRITE, you must stop using - * the SSL context for reading or writing, and either free it or - * call \c mbedtls_ssl_session_reset() on it before re-using it - * for a new connection; the current connection must be closed. + * MBEDTLS_ERR_SSL_WANT_READ/WRITE, then the ssl context + * becomes unusable, and you should either free it or call + * \c mbedtls_ssl_session_reset() on it before re-using it for + * a new connection; the current connection must be closed. */ int mbedtls_ssl_close_notify( mbedtls_ssl_context *ssl ); @@ -4038,137 +2591,13 @@ int mbedtls_ssl_close_notify( mbedtls_ssl_context *ssl ); */ void mbedtls_ssl_free( mbedtls_ssl_context *ssl ); -#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION) -/** - * \brief Save an active connection as serialized data in a buffer. - * This allows the freeing or re-using of the SSL context - * while still picking up the connection later in a way that - * it entirely transparent to the peer. - * - * \see mbedtls_ssl_context_load() - * - * \note This feature is currently only available under certain - * conditions, see the documentation of the return value - * #MBEDTLS_ERR_SSL_BAD_INPUT_DATA for details. - * - * \note When this function succeeds, it calls - * mbedtls_ssl_session_reset() on \p ssl which as a result is - * no longer associated with the connection that has been - * serialized. This avoids creating copies of the connection - * state. You're then free to either re-use the context - * structure for a different connection, or call - * mbedtls_ssl_free() on it. See the documentation of - * mbedtls_ssl_session_reset() for more details. - * - * \param ssl The SSL context to save. On success, it is no longer - * associated with the connection that has been serialized. - * \param buf The buffer to write the serialized data to. It must be a - * writeable buffer of at least \p len bytes, or may be \c - * NULL if \p len is \c 0. - * \param buf_len The number of bytes available for writing in \p buf. - * \param olen The size in bytes of the data that has been or would have - * been written. It must point to a valid \c size_t. - * - * \note \p olen is updated to the correct value regardless of - * whether \p buf_len was large enough. This makes it possible - * to determine the necessary size by calling this function - * with \p buf set to \c NULL and \p buf_len to \c 0. However, - * the value of \p olen is only guaranteed to be correct when - * the function returns #MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL or - * \c 0. If the return value is different, then the value of - * \p olen is undefined. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL if \p buf is too small. - * \return #MBEDTLS_ERR_SSL_ALLOC_FAILED if memory allocation failed - * while reseting the context. - * \return #MBEDTLS_ERR_SSL_BAD_INPUT_DATA if a handshake is in - * progress, or there is pending data for reading or sending, - * or the connection does not use DTLS 1.2 with an AEAD - * ciphersuite, or renegotiation is enabled. - */ -int mbedtls_ssl_context_save( mbedtls_ssl_context *ssl, - unsigned char *buf, - size_t buf_len, - size_t *olen ); - -/** - * \brief Load serialized connection data to an SSL context. - * - * \see mbedtls_ssl_context_save() - * - * \warning The same serialized data must never be loaded into more - * that one context. In order to ensure that, after - * successfully loading serialized data to an SSL context, you - * should immediately destroy or invalidate all copies of the - * serialized data that was loaded. Loading the same data in - * more than one context would cause severe security failures - * including but not limited to loss of confidentiality. - * - * \note Before calling this function, the SSL context must be - * prepared in one of the two following ways. The first way is - * to take a context freshly initialised with - * mbedtls_ssl_init() and call mbedtls_ssl_setup() on it with - * the same ::mbedtls_ssl_config structure that was used in - * the original connection. The second way is to - * call mbedtls_ssl_session_reset() on a context that was - * previously prepared as above but used in the meantime. - * Either way, you must not use the context to perform a - * handshake between calling mbedtls_ssl_setup() or - * mbedtls_ssl_session_reset() and calling this function. You - * may however call other setter functions in that time frame - * as indicated in the note below. - * - * \note Before or after calling this function successfully, you - * also need to configure some connection-specific callbacks - * and settings before you can use the connection again - * (unless they were already set before calling - * mbedtls_ssl_session_reset() and the values are suitable for - * the present connection). Specifically, you want to call - * at least mbedtls_ssl_set_bio() and - * mbedtls_ssl_set_timer_cb(). All other SSL setter functions - * are not necessary to call, either because they're only used - * in handshakes, or because the setting is already saved. You - * might choose to call them anyway, for example in order to - * share code between the cases of establishing a new - * connection and the case of loading an already-established - * connection. - * - * \note If you have new information about the path MTU, you want to - * call mbedtls_ssl_set_mtu() after calling this function, as - * otherwise this function would overwrite your - * newly-configured value with the value that was active when - * the context was saved. - * - * \note When this function returns an error code, it calls - * mbedtls_ssl_free() on \p ssl. In this case, you need to - * prepare the context with the usual sequence starting with a - * call to mbedtls_ssl_init() if you want to use it again. - * - * \param ssl The SSL context structure to be populated. It must have - * been prepared as described in the note above. - * \param buf The buffer holding the serialized connection data. It must - * be a readable buffer of at least \p len bytes. - * \param len The size of the serialized data in bytes. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_SSL_ALLOC_FAILED if memory allocation failed. - * \return #MBEDTLS_ERR_SSL_VERSION_MISMATCH if the serialized data - * comes from a different Mbed TLS version or build. - * \return #MBEDTLS_ERR_SSL_BAD_INPUT_DATA if input data is invalid. - */ -int mbedtls_ssl_context_load( mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len ); -#endif /* MBEDTLS_SSL_CONTEXT_SERIALIZATION */ - /** * \brief Initialize an SSL configuration context * Just makes the context ready for * mbedtls_ssl_config_defaults() or mbedtls_ssl_config_free(). * * \note You need to call mbedtls_ssl_config_defaults() unless you - * manually set all of the relevant fields yourself. + * manually set all of the relevent fields yourself. * * \param conf SSL configuration context */ @@ -4217,8 +2646,6 @@ void mbedtls_ssl_session_init( mbedtls_ssl_session *session ); */ void mbedtls_ssl_session_free( mbedtls_ssl_session *session ); -#include "ssl_ciphersuites.h" - #ifdef __cplusplus } #endif diff --git a/APP_Framework/Framework/security/mbedtls/ssl_cache.c b/APP_Framework/Framework/security/mbedtls/ssl_cache.c new file mode 100644 index 000000000..884a9f193 --- /dev/null +++ b/APP_Framework/Framework/security/mbedtls/ssl_cache.c @@ -0,0 +1,327 @@ +/* + * SSL session cache implementation + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +/* + * These session callbacks use a simple chained list + * to store and retrieve the session information. + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_SSL_CACHE_C) + +#if defined(MBEDTLS_PLATFORM_C) +#include "platform.h" +#else +#include +#define mbedtls_calloc calloc +#define mbedtls_free free +#endif + +#include "ssl_cache.h" + +#include + +void mbedtls_ssl_cache_init( mbedtls_ssl_cache_context *cache ) +{ + memset( cache, 0, sizeof( mbedtls_ssl_cache_context ) ); + + cache->timeout = MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT; + cache->max_entries = MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES; + +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_init( &cache->mutex ); +#endif +} + +int mbedtls_ssl_cache_get( void *data, mbedtls_ssl_session *session ) +{ + int ret = 1; +#if defined(MBEDTLS_HAVE_TIME) + mbedtls_time_t t = mbedtls_time( NULL ); +#endif + mbedtls_ssl_cache_context *cache = (mbedtls_ssl_cache_context *) data; + mbedtls_ssl_cache_entry *cur, *entry; + +#if defined(MBEDTLS_THREADING_C) + if( mbedtls_mutex_lock( &cache->mutex ) != 0 ) + return( 1 ); +#endif + + cur = cache->chain; + entry = NULL; + + while( cur != NULL ) + { + entry = cur; + cur = cur->next; + +#if defined(MBEDTLS_HAVE_TIME) + if( cache->timeout != 0 && + (int) ( t - entry->timestamp ) > cache->timeout ) + continue; +#endif + + if( session->ciphersuite != entry->session.ciphersuite || + session->compression != entry->session.compression || + session->id_len != entry->session.id_len ) + continue; + + if( memcmp( session->id, entry->session.id, + entry->session.id_len ) != 0 ) + continue; + + memcpy( session->master, entry->session.master, 48 ); + + session->verify_result = entry->session.verify_result; + +#if defined(MBEDTLS_X509_CRT_PARSE_C) + /* + * Restore peer certificate (without rest of the original chain) + */ + if( entry->peer_cert.p != NULL ) + { + if( ( session->peer_cert = mbedtls_calloc( 1, + sizeof(mbedtls_x509_crt) ) ) == NULL ) + { + ret = 1; + goto exit; + } + + mbedtls_x509_crt_init( session->peer_cert ); + if( mbedtls_x509_crt_parse( session->peer_cert, entry->peer_cert.p, + entry->peer_cert.len ) != 0 ) + { + mbedtls_free( session->peer_cert ); + session->peer_cert = NULL; + ret = 1; + goto exit; + } + } +#endif /* MBEDTLS_X509_CRT_PARSE_C */ + + ret = 0; + goto exit; + } + +exit: +#if defined(MBEDTLS_THREADING_C) + if( mbedtls_mutex_unlock( &cache->mutex ) != 0 ) + ret = 1; +#endif + + return( ret ); +} + +int mbedtls_ssl_cache_set( void *data, const mbedtls_ssl_session *session ) +{ + int ret = 1; +#if defined(MBEDTLS_HAVE_TIME) + mbedtls_time_t t = mbedtls_time( NULL ), oldest = 0; + mbedtls_ssl_cache_entry *old = NULL; +#endif + mbedtls_ssl_cache_context *cache = (mbedtls_ssl_cache_context *) data; + mbedtls_ssl_cache_entry *cur, *prv; + int count = 0; + +#if defined(MBEDTLS_THREADING_C) + if( ( ret = mbedtls_mutex_lock( &cache->mutex ) ) != 0 ) + return( ret ); +#endif + + cur = cache->chain; + prv = NULL; + + while( cur != NULL ) + { + count++; + +#if defined(MBEDTLS_HAVE_TIME) + if( cache->timeout != 0 && + (int) ( t - cur->timestamp ) > cache->timeout ) + { + cur->timestamp = t; + break; /* expired, reuse this slot, update timestamp */ + } +#endif + + if( memcmp( session->id, cur->session.id, cur->session.id_len ) == 0 ) + break; /* client reconnected, keep timestamp for session id */ + +#if defined(MBEDTLS_HAVE_TIME) + if( oldest == 0 || cur->timestamp < oldest ) + { + oldest = cur->timestamp; + old = cur; + } +#endif + + prv = cur; + cur = cur->next; + } + + if( cur == NULL ) + { +#if defined(MBEDTLS_HAVE_TIME) + /* + * Reuse oldest entry if max_entries reached + */ + if( count >= cache->max_entries ) + { + if( old == NULL ) + { + ret = 1; + goto exit; + } + + cur = old; + } +#else /* MBEDTLS_HAVE_TIME */ + /* + * Reuse first entry in chain if max_entries reached, + * but move to last place + */ + if( count >= cache->max_entries ) + { + if( cache->chain == NULL ) + { + ret = 1; + goto exit; + } + + cur = cache->chain; + cache->chain = cur->next; + cur->next = NULL; + prv->next = cur; + } +#endif /* MBEDTLS_HAVE_TIME */ + else + { + /* + * max_entries not reached, create new entry + */ + cur = mbedtls_calloc( 1, sizeof(mbedtls_ssl_cache_entry) ); + if( cur == NULL ) + { + ret = 1; + goto exit; + } + + if( prv == NULL ) + cache->chain = cur; + else + prv->next = cur; + } + +#if defined(MBEDTLS_HAVE_TIME) + cur->timestamp = t; +#endif + } + + memcpy( &cur->session, session, sizeof( mbedtls_ssl_session ) ); + +#if defined(MBEDTLS_X509_CRT_PARSE_C) + /* + * If we're reusing an entry, free its certificate first + */ + if( cur->peer_cert.p != NULL ) + { + mbedtls_free( cur->peer_cert.p ); + memset( &cur->peer_cert, 0, sizeof(mbedtls_x509_buf) ); + } + + /* + * Store peer certificate + */ + if( session->peer_cert != NULL ) + { + cur->peer_cert.p = mbedtls_calloc( 1, session->peer_cert->raw.len ); + if( cur->peer_cert.p == NULL ) + { + ret = 1; + goto exit; + } + + memcpy( cur->peer_cert.p, session->peer_cert->raw.p, + session->peer_cert->raw.len ); + cur->peer_cert.len = session->peer_cert->raw.len; + + cur->session.peer_cert = NULL; + } +#endif /* MBEDTLS_X509_CRT_PARSE_C */ + + ret = 0; + +exit: +#if defined(MBEDTLS_THREADING_C) + if( mbedtls_mutex_unlock( &cache->mutex ) != 0 ) + ret = 1; +#endif + + return( ret ); +} + +#if defined(MBEDTLS_HAVE_TIME) +void mbedtls_ssl_cache_set_timeout( mbedtls_ssl_cache_context *cache, int timeout ) +{ + if( timeout < 0 ) timeout = 0; + + cache->timeout = timeout; +} +#endif /* MBEDTLS_HAVE_TIME */ + +void mbedtls_ssl_cache_set_max_entries( mbedtls_ssl_cache_context *cache, int max ) +{ + if( max < 0 ) max = 0; + + cache->max_entries = max; +} + +void mbedtls_ssl_cache_free( mbedtls_ssl_cache_context *cache ) +{ + mbedtls_ssl_cache_entry *cur, *prv; + + cur = cache->chain; + + while( cur != NULL ) + { + prv = cur; + cur = cur->next; + + mbedtls_ssl_session_free( &prv->session ); + +#if defined(MBEDTLS_X509_CRT_PARSE_C) + mbedtls_free( prv->peer_cert.p ); +#endif /* MBEDTLS_X509_CRT_PARSE_C */ + + mbedtls_free( prv ); + } + +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_free( &cache->mutex ); +#endif + cache->chain = NULL; +} + +#endif /* MBEDTLS_SSL_CACHE_C */ diff --git a/APP_Framework/Framework/security/mbedtls/ssl_cache.h b/APP_Framework/Framework/security/mbedtls/ssl_cache.h index 84254d3d1..52ba0948c 100644 --- a/APP_Framework/Framework/security/mbedtls/ssl_cache.h +++ b/APP_Framework/Framework/security/mbedtls/ssl_cache.h @@ -70,8 +70,7 @@ struct mbedtls_ssl_cache_entry mbedtls_time_t timestamp; /*!< entry timestamp */ #endif mbedtls_ssl_session session; /*!< entry session */ -#if defined(MBEDTLS_X509_CRT_PARSE_C) && \ - defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) +#if defined(MBEDTLS_X509_CRT_PARSE_C) mbedtls_x509_buf peer_cert; /*!< entry peer_cert */ #endif mbedtls_ssl_cache_entry *next; /*!< chain pointer */ diff --git a/APP_Framework/Framework/security/mbedtls/ssl_ciphersuites.c b/APP_Framework/Framework/security/mbedtls/ssl_ciphersuites.c new file mode 100644 index 000000000..2778699c5 --- /dev/null +++ b/APP_Framework/Framework/security/mbedtls/ssl_ciphersuites.c @@ -0,0 +1,1890 @@ +/** + * \file ssl_ciphersuites.c + * + * \brief SSL ciphersuites for mbed TLS + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_SSL_TLS_C) + +#if defined(MBEDTLS_PLATFORM_C) +#include "platform.h" +#else +#include +#endif + +#include "ssl_ciphersuites.h" +#include "ssl.h" + +#include + +/* + * Ordered from most preferred to least preferred in terms of security. + * + * Current rule (except RC4 and 3DES, weak and null which come last): + * 1. By key exchange: + * Forward-secure non-PSK > forward-secure PSK > ECJPAKE > other non-PSK > other PSK + * 2. By key length and cipher: + * AES-256 > Camellia-256 > AES-128 > Camellia-128 + * 3. By cipher mode when relevant GCM > CCM > CBC > CCM_8 + * 4. By hash function used when relevant + * 5. By key exchange/auth again: EC > non-EC + */ +static const int ciphersuite_preference[] = +{ +#if defined(MBEDTLS_SSL_CIPHERSUITES) + MBEDTLS_SSL_CIPHERSUITES, +#else + /* All AES-256 ephemeral suites */ + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM, + MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM, + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, + MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, + MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, + MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA, + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8, + MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM_8, + + /* All CAMELLIA-256 ephemeral suites */ + MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384, + MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384, + MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384, + MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, + MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384, + MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256, + MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, + + /* All AES-128 ephemeral suites */ + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM, + MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM, + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, + MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, + MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, + MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA, + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, + MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM_8, + + /* All CAMELLIA-128 ephemeral suites */ + MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256, + MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256, + MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256, + MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, + MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, + MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, + MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, + + /* The PSK ephemeral suites */ + MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384, + MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM, + MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384, + MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384, + MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA, + MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA, + MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384, + MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, + MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, + MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM_8, + + MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256, + MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM, + MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, + MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256, + MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, + MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA, + MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256, + MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, + MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, + MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM_8, + + /* The ECJPAKE suite */ + MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8, + + /* All AES-256 suites */ + MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384, + MBEDTLS_TLS_RSA_WITH_AES_256_CCM, + MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256, + MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA, + MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, + MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, + MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, + MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, + MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, + MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, + MBEDTLS_TLS_RSA_WITH_AES_256_CCM_8, + + /* All CAMELLIA-256 suites */ + MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384, + MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256, + MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, + MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384, + MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384, + MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384, + MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, + + /* All AES-128 suites */ + MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256, + MBEDTLS_TLS_RSA_WITH_AES_128_CCM, + MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256, + MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA, + MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, + MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, + MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, + MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, + MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, + MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, + MBEDTLS_TLS_RSA_WITH_AES_128_CCM_8, + + /* All CAMELLIA-128 suites */ + MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256, + MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256, + MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA, + MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256, + MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256, + MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256, + MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, + + /* The RSA PSK suites */ + MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384, + MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384, + MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA, + MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384, + MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384, + + MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256, + MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256, + MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA, + MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256, + MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256, + + /* The PSK suites */ + MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384, + MBEDTLS_TLS_PSK_WITH_AES_256_CCM, + MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384, + MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA, + MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384, + MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384, + MBEDTLS_TLS_PSK_WITH_AES_256_CCM_8, + + MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256, + MBEDTLS_TLS_PSK_WITH_AES_128_CCM, + MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256, + MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA, + MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256, + MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256, + MBEDTLS_TLS_PSK_WITH_AES_128_CCM_8, + + /* 3DES suites */ + MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, + MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, + MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, + MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA, + MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA, + MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA, + MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, + MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, + MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA, + MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA, + + /* RC4 suites */ + MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, + MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA, + MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA, + MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA, + MBEDTLS_TLS_RSA_WITH_RC4_128_SHA, + MBEDTLS_TLS_RSA_WITH_RC4_128_MD5, + MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA, + MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA, + MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA, + MBEDTLS_TLS_PSK_WITH_RC4_128_SHA, + + /* Weak suites */ + MBEDTLS_TLS_DHE_RSA_WITH_DES_CBC_SHA, + MBEDTLS_TLS_RSA_WITH_DES_CBC_SHA, + + /* NULL suites */ + MBEDTLS_TLS_ECDHE_ECDSA_WITH_NULL_SHA, + MBEDTLS_TLS_ECDHE_RSA_WITH_NULL_SHA, + MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA384, + MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA256, + MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA, + MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA384, + MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA256, + MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA, + + MBEDTLS_TLS_RSA_WITH_NULL_SHA256, + MBEDTLS_TLS_RSA_WITH_NULL_SHA, + MBEDTLS_TLS_RSA_WITH_NULL_MD5, + MBEDTLS_TLS_ECDH_RSA_WITH_NULL_SHA, + MBEDTLS_TLS_ECDH_ECDSA_WITH_NULL_SHA, + MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA384, + MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA256, + MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA, + MBEDTLS_TLS_PSK_WITH_NULL_SHA384, + MBEDTLS_TLS_PSK_WITH_NULL_SHA256, + MBEDTLS_TLS_PSK_WITH_NULL_SHA, + +#endif /* MBEDTLS_SSL_CIPHERSUITES */ + 0 +}; + +static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] = +{ +#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) +#if defined(MBEDTLS_AES_C) +#if defined(MBEDTLS_SHA1_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) + { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, "TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA", + MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, + { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, "TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA", + MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#endif /* MBEDTLS_SHA1_C */ +#if defined(MBEDTLS_SHA256_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) + { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, "TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA256", + MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#if defined(MBEDTLS_GCM_C) + { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, "TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256", + MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_GCM_C */ +#endif /* MBEDTLS_SHA256_C */ +#if defined(MBEDTLS_SHA512_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) + { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, "TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA384", + MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#if defined(MBEDTLS_GCM_C) + { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, "TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384", + MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_GCM_C */ +#endif /* MBEDTLS_SHA512_C */ +#if defined(MBEDTLS_CCM_C) + { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM, "TLS-ECDHE-ECDSA-WITH-AES-256-CCM", + MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, + { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8, "TLS-ECDHE-ECDSA-WITH-AES-256-CCM-8", + MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_SHORT_TAG }, + { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM, "TLS-ECDHE-ECDSA-WITH-AES-128-CCM", + MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, + { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, "TLS-ECDHE-ECDSA-WITH-AES-128-CCM-8", + MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_SHORT_TAG }, +#endif /* MBEDTLS_CCM_C */ +#endif /* MBEDTLS_AES_C */ + +#if defined(MBEDTLS_CAMELLIA_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-ECDHE-ECDSA-WITH-CAMELLIA-128-CBC-SHA256", + MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA256_C */ +#if defined(MBEDTLS_SHA512_C) + { MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDHE-ECDSA-WITH-CAMELLIA-256-CBC-SHA384", + MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA512_C */ +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_GCM_C) +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256, "TLS-ECDHE-ECDSA-WITH-CAMELLIA-128-GCM-SHA256", + MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA256_C */ +#if defined(MBEDTLS_SHA512_C) + { MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-ECDHE-ECDSA-WITH-CAMELLIA-256-GCM-SHA384", + MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA512_C */ +#endif /* MBEDTLS_GCM_C */ +#endif /* MBEDTLS_CAMELLIA_C */ + +#if defined(MBEDTLS_DES_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, "TLS-ECDHE-ECDSA-WITH-3DES-EDE-CBC-SHA", + MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#endif /* MBEDTLS_DES_C */ + +#if defined(MBEDTLS_ARC4_C) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, "TLS-ECDHE-ECDSA-WITH-RC4-128-SHA", + MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_NODTLS }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_ARC4_C */ + +#if defined(MBEDTLS_CIPHER_NULL_CIPHER) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_ECDHE_ECDSA_WITH_NULL_SHA, "TLS-ECDHE-ECDSA-WITH-NULL-SHA", + MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_WEAK }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_CIPHER_NULL_CIPHER */ +#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ + +#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) +#if defined(MBEDTLS_AES_C) +#if defined(MBEDTLS_SHA1_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) + { MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, "TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA", + MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, + { MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, "TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA", + MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#endif /* MBEDTLS_SHA1_C */ +#if defined(MBEDTLS_SHA256_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) + { MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, "TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA256", + MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#if defined(MBEDTLS_GCM_C) + { MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, "TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256", + MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_GCM_C */ +#endif /* MBEDTLS_SHA256_C */ +#if defined(MBEDTLS_SHA512_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) + { MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, "TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA384", + MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#if defined(MBEDTLS_GCM_C) + { MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, "TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384", + MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_GCM_C */ +#endif /* MBEDTLS_SHA512_C */ +#endif /* MBEDTLS_AES_C */ + +#if defined(MBEDTLS_CAMELLIA_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-ECDHE-RSA-WITH-CAMELLIA-128-CBC-SHA256", + MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA256_C */ +#if defined(MBEDTLS_SHA512_C) + { MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDHE-RSA-WITH-CAMELLIA-256-CBC-SHA384", + MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA512_C */ +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_GCM_C) +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256, "TLS-ECDHE-RSA-WITH-CAMELLIA-128-GCM-SHA256", + MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA256_C */ +#if defined(MBEDTLS_SHA512_C) + { MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-ECDHE-RSA-WITH-CAMELLIA-256-GCM-SHA384", + MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA512_C */ +#endif /* MBEDTLS_GCM_C */ +#endif /* MBEDTLS_CAMELLIA_C */ + +#if defined(MBEDTLS_DES_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, "TLS-ECDHE-RSA-WITH-3DES-EDE-CBC-SHA", + MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#endif /* MBEDTLS_DES_C */ + +#if defined(MBEDTLS_ARC4_C) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA, "TLS-ECDHE-RSA-WITH-RC4-128-SHA", + MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_NODTLS }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_ARC4_C */ + +#if defined(MBEDTLS_CIPHER_NULL_CIPHER) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_ECDHE_RSA_WITH_NULL_SHA, "TLS-ECDHE-RSA-WITH-NULL-SHA", + MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_WEAK }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_CIPHER_NULL_CIPHER */ +#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED */ + +#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) +#if defined(MBEDTLS_AES_C) +#if defined(MBEDTLS_SHA512_C) && defined(MBEDTLS_GCM_C) + { MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, "TLS-DHE-RSA-WITH-AES-256-GCM-SHA384", + MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA512_C && MBEDTLS_GCM_C */ + +#if defined(MBEDTLS_SHA256_C) +#if defined(MBEDTLS_GCM_C) + { MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, "TLS-DHE-RSA-WITH-AES-128-GCM-SHA256", + MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_GCM_C */ + +#if defined(MBEDTLS_CIPHER_MODE_CBC) + { MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, "TLS-DHE-RSA-WITH-AES-128-CBC-SHA256", + MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, + + { MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, "TLS-DHE-RSA-WITH-AES-256-CBC-SHA256", + MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#endif /* MBEDTLS_SHA256_C */ + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA, "TLS-DHE-RSA-WITH-AES-128-CBC-SHA", + MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, + + { MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA, "TLS-DHE-RSA-WITH-AES-256-CBC-SHA", + MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#if defined(MBEDTLS_CCM_C) + { MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM, "TLS-DHE-RSA-WITH-AES-256-CCM", + MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, + { MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM_8, "TLS-DHE-RSA-WITH-AES-256-CCM-8", + MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_SHORT_TAG }, + { MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM, "TLS-DHE-RSA-WITH-AES-128-CCM", + MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, + { MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM_8, "TLS-DHE-RSA-WITH-AES-128-CCM-8", + MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_SHORT_TAG }, +#endif /* MBEDTLS_CCM_C */ +#endif /* MBEDTLS_AES_C */ + +#if defined(MBEDTLS_CAMELLIA_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA256", + MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, + + { MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256, "TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA256", + MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA256_C */ + +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, "TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA", + MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, + + { MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, "TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA", + MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#if defined(MBEDTLS_GCM_C) +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256, "TLS-DHE-RSA-WITH-CAMELLIA-128-GCM-SHA256", + MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA256_C */ + +#if defined(MBEDTLS_SHA512_C) + { MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-DHE-RSA-WITH-CAMELLIA-256-GCM-SHA384", + MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA512_C */ +#endif /* MBEDTLS_GCM_C */ +#endif /* MBEDTLS_CAMELLIA_C */ + +#if defined(MBEDTLS_DES_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, "TLS-DHE-RSA-WITH-3DES-EDE-CBC-SHA", + MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#endif /* MBEDTLS_DES_C */ +#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */ + +#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) +#if defined(MBEDTLS_AES_C) +#if defined(MBEDTLS_SHA512_C) && defined(MBEDTLS_GCM_C) + { MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384, "TLS-RSA-WITH-AES-256-GCM-SHA384", + MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA512_C && MBEDTLS_GCM_C */ + +#if defined(MBEDTLS_SHA256_C) +#if defined(MBEDTLS_GCM_C) + { MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256, "TLS-RSA-WITH-AES-128-GCM-SHA256", + MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_GCM_C */ + +#if defined(MBEDTLS_CIPHER_MODE_CBC) + { MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256, "TLS-RSA-WITH-AES-128-CBC-SHA256", + MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, + + { MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256, "TLS-RSA-WITH-AES-256-CBC-SHA256", + MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#endif /* MBEDTLS_SHA256_C */ + +#if defined(MBEDTLS_SHA1_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) + { MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA, "TLS-RSA-WITH-AES-128-CBC-SHA", + MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, + + { MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA, "TLS-RSA-WITH-AES-256-CBC-SHA", + MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#endif /* MBEDTLS_SHA1_C */ +#if defined(MBEDTLS_CCM_C) + { MBEDTLS_TLS_RSA_WITH_AES_256_CCM, "TLS-RSA-WITH-AES-256-CCM", + MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, + { MBEDTLS_TLS_RSA_WITH_AES_256_CCM_8, "TLS-RSA-WITH-AES-256-CCM-8", + MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_SHORT_TAG }, + { MBEDTLS_TLS_RSA_WITH_AES_128_CCM, "TLS-RSA-WITH-AES-128-CCM", + MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, + { MBEDTLS_TLS_RSA_WITH_AES_128_CCM_8, "TLS-RSA-WITH-AES-128-CCM-8", + MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_SHORT_TAG }, +#endif /* MBEDTLS_CCM_C */ +#endif /* MBEDTLS_AES_C */ + +#if defined(MBEDTLS_CAMELLIA_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-RSA-WITH-CAMELLIA-128-CBC-SHA256", + MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, + + { MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256, "TLS-RSA-WITH-CAMELLIA-256-CBC-SHA256", + MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA256_C */ + +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA, "TLS-RSA-WITH-CAMELLIA-128-CBC-SHA", + MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, + + { MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, "TLS-RSA-WITH-CAMELLIA-256-CBC-SHA", + MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_GCM_C) +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256, "TLS-RSA-WITH-CAMELLIA-128-GCM-SHA256", + MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA256_C */ + +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-RSA-WITH-CAMELLIA-256-GCM-SHA384", + MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_GCM_C */ +#endif /* MBEDTLS_CAMELLIA_C */ + +#if defined(MBEDTLS_DES_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA, "TLS-RSA-WITH-3DES-EDE-CBC-SHA", + MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#endif /* MBEDTLS_DES_C */ + +#if defined(MBEDTLS_ARC4_C) +#if defined(MBEDTLS_MD5_C) + { MBEDTLS_TLS_RSA_WITH_RC4_128_MD5, "TLS-RSA-WITH-RC4-128-MD5", + MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_MD5, MBEDTLS_KEY_EXCHANGE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_NODTLS }, +#endif + +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_RSA_WITH_RC4_128_SHA, "TLS-RSA-WITH-RC4-128-SHA", + MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_NODTLS }, +#endif +#endif /* MBEDTLS_ARC4_C */ +#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */ + +#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) +#if defined(MBEDTLS_AES_C) +#if defined(MBEDTLS_SHA1_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) + { MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, "TLS-ECDH-RSA-WITH-AES-128-CBC-SHA", + MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, + { MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, "TLS-ECDH-RSA-WITH-AES-256-CBC-SHA", + MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#endif /* MBEDTLS_SHA1_C */ +#if defined(MBEDTLS_SHA256_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) + { MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, "TLS-ECDH-RSA-WITH-AES-128-CBC-SHA256", + MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#if defined(MBEDTLS_GCM_C) + { MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, "TLS-ECDH-RSA-WITH-AES-128-GCM-SHA256", + MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_GCM_C */ +#endif /* MBEDTLS_SHA256_C */ +#if defined(MBEDTLS_SHA512_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) + { MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, "TLS-ECDH-RSA-WITH-AES-256-CBC-SHA384", + MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#if defined(MBEDTLS_GCM_C) + { MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, "TLS-ECDH-RSA-WITH-AES-256-GCM-SHA384", + MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_GCM_C */ +#endif /* MBEDTLS_SHA512_C */ +#endif /* MBEDTLS_AES_C */ + +#if defined(MBEDTLS_CAMELLIA_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-ECDH-RSA-WITH-CAMELLIA-128-CBC-SHA256", + MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA256_C */ +#if defined(MBEDTLS_SHA512_C) + { MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDH-RSA-WITH-CAMELLIA-256-CBC-SHA384", + MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA512_C */ +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_GCM_C) +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256, "TLS-ECDH-RSA-WITH-CAMELLIA-128-GCM-SHA256", + MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA256_C */ +#if defined(MBEDTLS_SHA512_C) + { MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-ECDH-RSA-WITH-CAMELLIA-256-GCM-SHA384", + MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA512_C */ +#endif /* MBEDTLS_GCM_C */ +#endif /* MBEDTLS_CAMELLIA_C */ + +#if defined(MBEDTLS_DES_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, "TLS-ECDH-RSA-WITH-3DES-EDE-CBC-SHA", + MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#endif /* MBEDTLS_DES_C */ + +#if defined(MBEDTLS_ARC4_C) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA, "TLS-ECDH-RSA-WITH-RC4-128-SHA", + MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_NODTLS }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_ARC4_C */ + +#if defined(MBEDTLS_CIPHER_NULL_CIPHER) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_ECDH_RSA_WITH_NULL_SHA, "TLS-ECDH-RSA-WITH-NULL-SHA", + MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_WEAK }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_CIPHER_NULL_CIPHER */ +#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED */ + +#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) +#if defined(MBEDTLS_AES_C) +#if defined(MBEDTLS_SHA1_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) + { MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, "TLS-ECDH-ECDSA-WITH-AES-128-CBC-SHA", + MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, + { MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, "TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA", + MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#endif /* MBEDTLS_SHA1_C */ +#if defined(MBEDTLS_SHA256_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) + { MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, "TLS-ECDH-ECDSA-WITH-AES-128-CBC-SHA256", + MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#if defined(MBEDTLS_GCM_C) + { MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, "TLS-ECDH-ECDSA-WITH-AES-128-GCM-SHA256", + MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_GCM_C */ +#endif /* MBEDTLS_SHA256_C */ +#if defined(MBEDTLS_SHA512_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) + { MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, "TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA384", + MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#if defined(MBEDTLS_GCM_C) + { MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, "TLS-ECDH-ECDSA-WITH-AES-256-GCM-SHA384", + MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_GCM_C */ +#endif /* MBEDTLS_SHA512_C */ +#endif /* MBEDTLS_AES_C */ + +#if defined(MBEDTLS_CAMELLIA_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-ECDH-ECDSA-WITH-CAMELLIA-128-CBC-SHA256", + MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA256_C */ +#if defined(MBEDTLS_SHA512_C) + { MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDH-ECDSA-WITH-CAMELLIA-256-CBC-SHA384", + MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA512_C */ +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_GCM_C) +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256, "TLS-ECDH-ECDSA-WITH-CAMELLIA-128-GCM-SHA256", + MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA256_C */ +#if defined(MBEDTLS_SHA512_C) + { MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-ECDH-ECDSA-WITH-CAMELLIA-256-GCM-SHA384", + MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA512_C */ +#endif /* MBEDTLS_GCM_C */ +#endif /* MBEDTLS_CAMELLIA_C */ + +#if defined(MBEDTLS_DES_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, "TLS-ECDH-ECDSA-WITH-3DES-EDE-CBC-SHA", + MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#endif /* MBEDTLS_DES_C */ + +#if defined(MBEDTLS_ARC4_C) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA, "TLS-ECDH-ECDSA-WITH-RC4-128-SHA", + MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_NODTLS }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_ARC4_C */ + +#if defined(MBEDTLS_CIPHER_NULL_CIPHER) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_ECDH_ECDSA_WITH_NULL_SHA, "TLS-ECDH-ECDSA-WITH-NULL-SHA", + MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_WEAK }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_CIPHER_NULL_CIPHER */ +#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ + +#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) +#if defined(MBEDTLS_AES_C) +#if defined(MBEDTLS_GCM_C) +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256, "TLS-PSK-WITH-AES-128-GCM-SHA256", + MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA256_C */ + +#if defined(MBEDTLS_SHA512_C) + { MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384, "TLS-PSK-WITH-AES-256-GCM-SHA384", + MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA512_C */ +#endif /* MBEDTLS_GCM_C */ + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256, "TLS-PSK-WITH-AES-128-CBC-SHA256", + MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA256_C */ + +#if defined(MBEDTLS_SHA512_C) + { MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384, "TLS-PSK-WITH-AES-256-CBC-SHA384", + MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA512_C */ + +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA, "TLS-PSK-WITH-AES-128-CBC-SHA", + MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, + + { MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA, "TLS-PSK-WITH-AES-256-CBC-SHA", + MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#if defined(MBEDTLS_CCM_C) + { MBEDTLS_TLS_PSK_WITH_AES_256_CCM, "TLS-PSK-WITH-AES-256-CCM", + MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, + { MBEDTLS_TLS_PSK_WITH_AES_256_CCM_8, "TLS-PSK-WITH-AES-256-CCM-8", + MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_SHORT_TAG }, + { MBEDTLS_TLS_PSK_WITH_AES_128_CCM, "TLS-PSK-WITH-AES-128-CCM", + MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, + { MBEDTLS_TLS_PSK_WITH_AES_128_CCM_8, "TLS-PSK-WITH-AES-128-CCM-8", + MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_SHORT_TAG }, +#endif /* MBEDTLS_CCM_C */ +#endif /* MBEDTLS_AES_C */ + +#if defined(MBEDTLS_CAMELLIA_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256, "TLS-PSK-WITH-CAMELLIA-128-CBC-SHA256", + MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA256_C */ + +#if defined(MBEDTLS_SHA512_C) + { MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384, "TLS-PSK-WITH-CAMELLIA-256-CBC-SHA384", + MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA512_C */ +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_GCM_C) +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256, "TLS-PSK-WITH-CAMELLIA-128-GCM-SHA256", + MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA256_C */ + +#if defined(MBEDTLS_SHA512_C) + { MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384, "TLS-PSK-WITH-CAMELLIA-256-GCM-SHA384", + MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA512_C */ +#endif /* MBEDTLS_GCM_C */ +#endif /* MBEDTLS_CAMELLIA_C */ + +#if defined(MBEDTLS_DES_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA, "TLS-PSK-WITH-3DES-EDE-CBC-SHA", + MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#endif /* MBEDTLS_DES_C */ + +#if defined(MBEDTLS_ARC4_C) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_PSK_WITH_RC4_128_SHA, "TLS-PSK-WITH-RC4-128-SHA", + MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_NODTLS }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_ARC4_C */ +#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */ + +#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) +#if defined(MBEDTLS_AES_C) +#if defined(MBEDTLS_GCM_C) +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256, "TLS-DHE-PSK-WITH-AES-128-GCM-SHA256", + MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA256_C */ + +#if defined(MBEDTLS_SHA512_C) + { MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384, "TLS-DHE-PSK-WITH-AES-256-GCM-SHA384", + MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA512_C */ +#endif /* MBEDTLS_GCM_C */ + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256, "TLS-DHE-PSK-WITH-AES-128-CBC-SHA256", + MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA256_C */ + +#if defined(MBEDTLS_SHA512_C) + { MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384, "TLS-DHE-PSK-WITH-AES-256-CBC-SHA384", + MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA512_C */ + +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA, "TLS-DHE-PSK-WITH-AES-128-CBC-SHA", + MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, + + { MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA, "TLS-DHE-PSK-WITH-AES-256-CBC-SHA", + MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#if defined(MBEDTLS_CCM_C) + { MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM, "TLS-DHE-PSK-WITH-AES-256-CCM", + MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, + { MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM_8, "TLS-DHE-PSK-WITH-AES-256-CCM-8", + MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_SHORT_TAG }, + { MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM, "TLS-DHE-PSK-WITH-AES-128-CCM", + MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, + { MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM_8, "TLS-DHE-PSK-WITH-AES-128-CCM-8", + MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_SHORT_TAG }, +#endif /* MBEDTLS_CCM_C */ +#endif /* MBEDTLS_AES_C */ + +#if defined(MBEDTLS_CAMELLIA_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, "TLS-DHE-PSK-WITH-CAMELLIA-128-CBC-SHA256", + MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA256_C */ + +#if defined(MBEDTLS_SHA512_C) + { MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, "TLS-DHE-PSK-WITH-CAMELLIA-256-CBC-SHA384", + MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA512_C */ +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_GCM_C) +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256, "TLS-DHE-PSK-WITH-CAMELLIA-128-GCM-SHA256", + MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA256_C */ + +#if defined(MBEDTLS_SHA512_C) + { MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384, "TLS-DHE-PSK-WITH-CAMELLIA-256-GCM-SHA384", + MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA512_C */ +#endif /* MBEDTLS_GCM_C */ +#endif /* MBEDTLS_CAMELLIA_C */ + +#if defined(MBEDTLS_DES_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA, "TLS-DHE-PSK-WITH-3DES-EDE-CBC-SHA", + MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#endif /* MBEDTLS_DES_C */ + +#if defined(MBEDTLS_ARC4_C) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA, "TLS-DHE-PSK-WITH-RC4-128-SHA", + MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_NODTLS }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_ARC4_C */ +#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ + +#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) +#if defined(MBEDTLS_AES_C) + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, "TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA256", + MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA256_C */ + +#if defined(MBEDTLS_SHA512_C) + { MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384, "TLS-ECDHE-PSK-WITH-AES-256-CBC-SHA384", + MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA512_C */ + +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, "TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA", + MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, + + { MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA, "TLS-ECDHE-PSK-WITH-AES-256-CBC-SHA", + MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#endif /* MBEDTLS_AES_C */ + +#if defined(MBEDTLS_CAMELLIA_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, "TLS-ECDHE-PSK-WITH-CAMELLIA-128-CBC-SHA256", + MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA256_C */ + +#if defined(MBEDTLS_SHA512_C) + { MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDHE-PSK-WITH-CAMELLIA-256-CBC-SHA384", + MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA512_C */ +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#endif /* MBEDTLS_CAMELLIA_C */ + +#if defined(MBEDTLS_DES_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA, "TLS-ECDHE-PSK-WITH-3DES-EDE-CBC-SHA", + MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#endif /* MBEDTLS_DES_C */ + +#if defined(MBEDTLS_ARC4_C) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA, "TLS-ECDHE-PSK-WITH-RC4-128-SHA", + MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_NODTLS }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_ARC4_C */ +#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ + +#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) +#if defined(MBEDTLS_AES_C) +#if defined(MBEDTLS_GCM_C) +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256, "TLS-RSA-PSK-WITH-AES-128-GCM-SHA256", + MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA256_C */ + +#if defined(MBEDTLS_SHA512_C) + { MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384, "TLS-RSA-PSK-WITH-AES-256-GCM-SHA384", + MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA512_C */ +#endif /* MBEDTLS_GCM_C */ + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256, "TLS-RSA-PSK-WITH-AES-128-CBC-SHA256", + MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA256_C */ + +#if defined(MBEDTLS_SHA512_C) + { MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384, "TLS-RSA-PSK-WITH-AES-256-CBC-SHA384", + MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA512_C */ + +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA, "TLS-RSA-PSK-WITH-AES-128-CBC-SHA", + MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, + + { MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA, "TLS-RSA-PSK-WITH-AES-256-CBC-SHA", + MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#endif /* MBEDTLS_AES_C */ + +#if defined(MBEDTLS_CAMELLIA_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256, "TLS-RSA-PSK-WITH-CAMELLIA-128-CBC-SHA256", + MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA256_C */ + +#if defined(MBEDTLS_SHA512_C) + { MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384, "TLS-RSA-PSK-WITH-CAMELLIA-256-CBC-SHA384", + MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA512_C */ +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_GCM_C) +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256, "TLS-RSA-PSK-WITH-CAMELLIA-128-GCM-SHA256", + MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA256_C */ + +#if defined(MBEDTLS_SHA512_C) + { MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384, "TLS-RSA-PSK-WITH-CAMELLIA-256-GCM-SHA384", + MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA512_C */ +#endif /* MBEDTLS_GCM_C */ +#endif /* MBEDTLS_CAMELLIA_C */ + +#if defined(MBEDTLS_DES_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA, "TLS-RSA-PSK-WITH-3DES-EDE-CBC-SHA", + MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#endif /* MBEDTLS_DES_C */ + +#if defined(MBEDTLS_ARC4_C) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA, "TLS-RSA-PSK-WITH-RC4-128-SHA", + MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_NODTLS }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_ARC4_C */ +#endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ + +#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) +#if defined(MBEDTLS_AES_C) +#if defined(MBEDTLS_CCM_C) + { MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8, "TLS-ECJPAKE-WITH-AES-128-CCM-8", + MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECJPAKE, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_SHORT_TAG }, +#endif /* MBEDTLS_CCM_C */ +#endif /* MBEDTLS_AES_C */ +#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ + +#if defined(MBEDTLS_ENABLE_WEAK_CIPHERSUITES) +#if defined(MBEDTLS_CIPHER_NULL_CIPHER) +#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) +#if defined(MBEDTLS_MD5_C) + { MBEDTLS_TLS_RSA_WITH_NULL_MD5, "TLS-RSA-WITH-NULL-MD5", + MBEDTLS_CIPHER_NULL, MBEDTLS_MD_MD5, MBEDTLS_KEY_EXCHANGE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_WEAK }, +#endif + +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_RSA_WITH_NULL_SHA, "TLS-RSA-WITH-NULL-SHA", + MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_WEAK }, +#endif + +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_RSA_WITH_NULL_SHA256, "TLS-RSA-WITH-NULL-SHA256", + MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_WEAK }, +#endif +#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */ + +#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_PSK_WITH_NULL_SHA, "TLS-PSK-WITH-NULL-SHA", + MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_WEAK }, +#endif /* MBEDTLS_SHA1_C */ + +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_PSK_WITH_NULL_SHA256, "TLS-PSK-WITH-NULL-SHA256", + MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_WEAK }, +#endif + +#if defined(MBEDTLS_SHA512_C) + { MBEDTLS_TLS_PSK_WITH_NULL_SHA384, "TLS-PSK-WITH-NULL-SHA384", + MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_WEAK }, +#endif +#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */ + +#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA, "TLS-DHE-PSK-WITH-NULL-SHA", + MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_WEAK }, +#endif /* MBEDTLS_SHA1_C */ + +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA256, "TLS-DHE-PSK-WITH-NULL-SHA256", + MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_WEAK }, +#endif + +#if defined(MBEDTLS_SHA512_C) + { MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA384, "TLS-DHE-PSK-WITH-NULL-SHA384", + MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_WEAK }, +#endif +#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ + +#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA, "TLS-ECDHE-PSK-WITH-NULL-SHA", + MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_WEAK }, +#endif /* MBEDTLS_SHA1_C */ + +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA256, "TLS-ECDHE-PSK-WITH-NULL-SHA256", + MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_WEAK }, +#endif + +#if defined(MBEDTLS_SHA512_C) + { MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA384, "TLS-ECDHE-PSK-WITH-NULL-SHA384", + MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_WEAK }, +#endif +#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ + +#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA, "TLS-RSA-PSK-WITH-NULL-SHA", + MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_WEAK }, +#endif /* MBEDTLS_SHA1_C */ + +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA256, "TLS-RSA-PSK-WITH-NULL-SHA256", + MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_WEAK }, +#endif + +#if defined(MBEDTLS_SHA512_C) + { MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA384, "TLS-RSA-PSK-WITH-NULL-SHA384", + MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_WEAK }, +#endif +#endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ +#endif /* MBEDTLS_CIPHER_NULL_CIPHER */ + +#if defined(MBEDTLS_DES_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_DHE_RSA_WITH_DES_CBC_SHA, "TLS-DHE-RSA-WITH-DES-CBC-SHA", + MBEDTLS_CIPHER_DES_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_WEAK }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */ + +#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_RSA_WITH_DES_CBC_SHA, "TLS-RSA-WITH-DES-CBC-SHA", + MBEDTLS_CIPHER_DES_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_WEAK }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */ +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#endif /* MBEDTLS_DES_C */ +#endif /* MBEDTLS_ENABLE_WEAK_CIPHERSUITES */ + + { 0, "", + MBEDTLS_CIPHER_NONE, MBEDTLS_MD_NONE, MBEDTLS_KEY_EXCHANGE_NONE, + 0, 0, 0, 0, 0 } +}; + +#if defined(MBEDTLS_SSL_CIPHERSUITES) +const int *mbedtls_ssl_list_ciphersuites( void ) +{ + return( ciphersuite_preference ); +} +#else +#define MAX_CIPHERSUITES sizeof( ciphersuite_definitions ) / \ + sizeof( ciphersuite_definitions[0] ) +static int supported_ciphersuites[MAX_CIPHERSUITES]; +static int supported_init = 0; + +static int ciphersuite_is_removed( const mbedtls_ssl_ciphersuite_t *cs_info ) +{ + (void)cs_info; + +#if defined(MBEDTLS_REMOVE_ARC4_CIPHERSUITES) + if( cs_info->cipher == MBEDTLS_CIPHER_ARC4_128 ) + return( 1 ); +#endif /* MBEDTLS_REMOVE_ARC4_CIPHERSUITES */ + +#if defined(MBEDTLS_REMOVE_3DES_CIPHERSUITES) + if( cs_info->cipher == MBEDTLS_CIPHER_DES_EDE3_ECB || + cs_info->cipher == MBEDTLS_CIPHER_DES_EDE3_CBC ) + { + return( 1 ); + } +#endif /* MBEDTLS_REMOVE_3DES_CIPHERSUITES */ + + return( 0 ); +} + +const int *mbedtls_ssl_list_ciphersuites( void ) +{ + /* + * On initial call filter out all ciphersuites not supported by current + * build based on presence in the ciphersuite_definitions. + */ + if( supported_init == 0 ) + { + const int *p; + int *q; + + for( p = ciphersuite_preference, q = supported_ciphersuites; + *p != 0 && q < supported_ciphersuites + MAX_CIPHERSUITES - 1; + p++ ) + { + const mbedtls_ssl_ciphersuite_t *cs_info; + if( ( cs_info = mbedtls_ssl_ciphersuite_from_id( *p ) ) != NULL && + !ciphersuite_is_removed( cs_info ) ) + { + *(q++) = *p; + } + } + *q = 0; + + supported_init = 1; + } + + return( supported_ciphersuites ); +} +#endif /* MBEDTLS_SSL_CIPHERSUITES */ + +const mbedtls_ssl_ciphersuite_t *mbedtls_ssl_ciphersuite_from_string( + const char *ciphersuite_name ) +{ + const mbedtls_ssl_ciphersuite_t *cur = ciphersuite_definitions; + + if( NULL == ciphersuite_name ) + return( NULL ); + + while( cur->id != 0 ) + { + if( 0 == strcmp( cur->name, ciphersuite_name ) ) + return( cur ); + + cur++; + } + + return( NULL ); +} + +const mbedtls_ssl_ciphersuite_t *mbedtls_ssl_ciphersuite_from_id( int ciphersuite ) +{ + const mbedtls_ssl_ciphersuite_t *cur = ciphersuite_definitions; + + while( cur->id != 0 ) + { + if( cur->id == ciphersuite ) + return( cur ); + + cur++; + } + + return( NULL ); +} + +const char *mbedtls_ssl_get_ciphersuite_name( const int ciphersuite_id ) +{ + const mbedtls_ssl_ciphersuite_t *cur; + + cur = mbedtls_ssl_ciphersuite_from_id( ciphersuite_id ); + + if( cur == NULL ) + return( "unknown" ); + + return( cur->name ); +} + +int mbedtls_ssl_get_ciphersuite_id( const char *ciphersuite_name ) +{ + const mbedtls_ssl_ciphersuite_t *cur; + + cur = mbedtls_ssl_ciphersuite_from_string( ciphersuite_name ); + + if( cur == NULL ) + return( 0 ); + + return( cur->id ); +} + +#if defined(MBEDTLS_PK_C) +mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_pk_alg( const mbedtls_ssl_ciphersuite_t *info ) +{ + switch( info->key_exchange ) + { + case MBEDTLS_KEY_EXCHANGE_RSA: + case MBEDTLS_KEY_EXCHANGE_DHE_RSA: + case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: + case MBEDTLS_KEY_EXCHANGE_RSA_PSK: + return( MBEDTLS_PK_RSA ); + + case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: + return( MBEDTLS_PK_ECDSA ); + + case MBEDTLS_KEY_EXCHANGE_ECDH_RSA: + case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA: + return( MBEDTLS_PK_ECKEY ); + + default: + return( MBEDTLS_PK_NONE ); + } +} + +mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_alg( const mbedtls_ssl_ciphersuite_t *info ) +{ + switch( info->key_exchange ) + { + case MBEDTLS_KEY_EXCHANGE_RSA: + case MBEDTLS_KEY_EXCHANGE_DHE_RSA: + case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: + return( MBEDTLS_PK_RSA ); + + case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: + return( MBEDTLS_PK_ECDSA ); + + default: + return( MBEDTLS_PK_NONE ); + } +} + +#endif /* MBEDTLS_PK_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 ) +{ + switch( info->key_exchange ) + { + case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: + case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: + case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK: + case MBEDTLS_KEY_EXCHANGE_ECDH_RSA: + case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA: + case MBEDTLS_KEY_EXCHANGE_ECJPAKE: + return( 1 ); + + default: + return( 0 ); + } +} +#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED*/ + +#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) +int mbedtls_ssl_ciphersuite_uses_psk( const mbedtls_ssl_ciphersuite_t *info ) +{ + switch( info->key_exchange ) + { + case MBEDTLS_KEY_EXCHANGE_PSK: + case MBEDTLS_KEY_EXCHANGE_RSA_PSK: + case MBEDTLS_KEY_EXCHANGE_DHE_PSK: + case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK: + return( 1 ); + + default: + return( 0 ); + } +} +#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ + +#endif /* MBEDTLS_SSL_TLS_C */ diff --git a/APP_Framework/Framework/security/mbedtls/ssl_ciphersuites.h b/APP_Framework/Framework/security/mbedtls/ssl_ciphersuites.h index f0f817c47..655d130b7 100644 --- a/APP_Framework/Framework/security/mbedtls/ssl_ciphersuites.h +++ b/APP_Framework/Framework/security/mbedtls/ssl_ciphersuites.h @@ -33,8 +33,6 @@ #include "pk.h" #include "cipher.h" #include "md.h" -#include "ssl.h" -#include #ifdef __cplusplus extern "C" { @@ -177,45 +175,6 @@ extern "C" { #define MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA256 0xC03A /**< Weak! No SSL3! */ #define MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA384 0xC03B /**< Weak! No SSL3! */ -#define MBEDTLS_TLS_RSA_WITH_ARIA_128_CBC_SHA256 0xC03C /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_WITH_ARIA_256_CBC_SHA384 0xC03D /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256 0xC044 /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384 0xC045 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256 0xC048 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384 0xC049 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256 0xC04A /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384 0xC04B /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256 0xC04C /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384 0xC04D /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256 0xC04E /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384 0xC04F /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_WITH_ARIA_128_GCM_SHA256 0xC050 /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_WITH_ARIA_256_GCM_SHA384 0xC051 /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256 0xC052 /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384 0xC053 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 0xC05C /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384 0xC05D /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256 0xC05E /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384 0xC05F /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256 0xC060 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384 0xC061 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256 0xC062 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384 0xC063 /**< TLS 1.2 */ -#define MBEDTLS_TLS_PSK_WITH_ARIA_128_CBC_SHA256 0xC064 /**< TLS 1.2 */ -#define MBEDTLS_TLS_PSK_WITH_ARIA_256_CBC_SHA384 0xC065 /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256 0xC066 /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384 0xC067 /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256 0xC068 /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384 0xC069 /**< TLS 1.2 */ -#define MBEDTLS_TLS_PSK_WITH_ARIA_128_GCM_SHA256 0xC06A /**< TLS 1.2 */ -#define MBEDTLS_TLS_PSK_WITH_ARIA_256_GCM_SHA384 0xC06B /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256 0xC06C /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384 0xC06D /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256 0xC06E /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384 0xC06F /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256 0xC070 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384 0xC071 /**< TLS 1.2 */ - #define MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 0xC072 /**< Not in SSL3! */ #define MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 0xC073 /**< Not in SSL3! */ #define MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 0xC074 /**< Not in SSL3! */ @@ -279,15 +238,6 @@ extern "C" { #define MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8 0xC0FF /**< experimental */ -/* RFC 7905 */ -#define MBEDTLS_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 0xCCA8 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 0xCCA9 /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 0xCCAA /**< TLS 1.2 */ -#define MBEDTLS_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256 0xCCAB /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 0xCCAC /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256 0xCCAD /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256 0xCCAE /**< TLS 1.2 */ - /* Reminder: update mbedtls_ssl_premaster_secret when adding a new key exchange. * Reminder: update MBEDTLS_KEY_EXCHANGE__xxx below */ @@ -306,6 +256,79 @@ typedef enum { MBEDTLS_KEY_EXCHANGE_ECJPAKE, } mbedtls_key_exchange_type_t; +/* Key exchanges using a certificate */ +#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) +#define MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED +#endif + +/* Key exchanges allowing client certificate requests */ +#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) +#define MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED +#endif + +/* Key exchanges involving server signature in ServerKeyExchange */ +#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) +#define MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED +#endif + +/* Key exchanges using ECDH */ +#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) +#define MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED +#endif + +/* Key exchanges that don't involve ephemeral keys */ +#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED) +#define MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED +#endif + +/* Key exchanges that involve ephemeral keys */ +#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) +#define MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED +#endif + +/* Key exchanges using a PSK */ +#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) +#define MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED +#endif + +/* Key exchanges using DHE */ +#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) +#define MBEDTLS_KEY_EXCHANGE__SOME__DHE_ENABLED +#endif + +/* Key exchanges using ECDHE */ +#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) +#define MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED +#endif + typedef struct mbedtls_ssl_ciphersuite_t mbedtls_ssl_ciphersuite_t; #define MBEDTLS_CIPHERSUITE_WEAK 0x01 /**< Weak ciphersuite flag */ @@ -313,61 +336,6 @@ typedef struct mbedtls_ssl_ciphersuite_t mbedtls_ssl_ciphersuite_t; eg for CCM_8 */ #define MBEDTLS_CIPHERSUITE_NODTLS 0x04 /**< Can't be used with DTLS */ -/* - * Ciphersuite macro definitions - * - * This is highly incomplete and only contains those ciphersuites for - * which we need to be able to build the library with support for that - * ciphersuite only (currently MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 - * as an example). - */ - -#define MBEDTLS_SUITE_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8_ID MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 -#define MBEDTLS_SUITE_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8_NAME "TLS-ECDHE-ECDSA-WITH-AES-128-CCM-8" -#define MBEDTLS_SUITE_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8_CIPHER MBEDTLS_CIPHER_AES_128_CCM -#define MBEDTLS_SUITE_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8_MAC MBEDTLS_MD_SHA256 -#define MBEDTLS_SUITE_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8_KEY_EXCHANGE MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA -#define MBEDTLS_SUITE_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8_MIN_MAJOR_VER MBEDTLS_SSL_MAJOR_VERSION_3 -#define MBEDTLS_SUITE_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8_MIN_MINOR_VER MBEDTLS_SSL_MINOR_VERSION_3 -#define MBEDTLS_SUITE_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8_MAX_MAJOR_VER MBEDTLS_SSL_MAJOR_VERSION_3 -#define MBEDTLS_SUITE_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8_MAX_MINOR_VER MBEDTLS_SSL_MINOR_VERSION_3 -#define MBEDTLS_SUITE_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8_FLAGS MBEDTLS_CIPHERSUITE_SHORT_TAG - -/* This is just to make check-names.sh happy -- don't uncomment. */ -//#define MBEDTLS_SUITE_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 - -/* - * Helper macros to extract fields from ciphersuites. - */ - -#define MBEDTLS_SSL_SUITE_ID_T( SUITE ) SUITE ## _ID -#define MBEDTLS_SSL_SUITE_NAME_T( SUITE ) SUITE ## _NAME -#define MBEDTLS_SSL_SUITE_CIPHER_T( SUITE ) SUITE ## _CIPHER -#define MBEDTLS_SSL_SUITE_MAC_T( SUITE ) SUITE ## _MAC -#define MBEDTLS_SSL_SUITE_KEY_EXCHANGE_T( SUITE ) SUITE ## _KEY_EXCHANGE -#define MBEDTLS_SSL_SUITE_MIN_MAJOR_VER_T( SUITE ) SUITE ## _MIN_MAJOR_VER -#define MBEDTLS_SSL_SUITE_MIN_MINOR_VER_T( SUITE ) SUITE ## _MIN_MINOR_VER -#define MBEDTLS_SSL_SUITE_MAX_MAJOR_VER_T( SUITE ) SUITE ## _MAX_MAJOR_VER -#define MBEDTLS_SSL_SUITE_MAX_MINOR_VER_T( SUITE ) SUITE ## _MAX_MINOR_VER -#define MBEDTLS_SSL_SUITE_FLAGS_T( SUITE ) SUITE ## _FLAGS - -/* Wrapper around MBEDTLS_SSL_SUITE_XXX_T() which makes sure that - * the argument is macro-expanded before concatenated with the - * field name. This allows to call these macros as - * MBEDTLS_SSL_SUITE_XXX( MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE ), - * where MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE expands to MBEDTLS_SSL_SUITE_XXX. */ -#define MBEDTLS_SSL_SUITE_ID( SUITE ) MBEDTLS_SSL_SUITE_ID_T( SUITE ) -#define MBEDTLS_SSL_SUITE_NAME( SUITE ) MBEDTLS_SSL_SUITE_NAME_T( SUITE ) -#define MBEDTLS_SSL_SUITE_CIPHER( SUITE ) MBEDTLS_SSL_SUITE_CIPHER_T( SUITE ) -#define MBEDTLS_SSL_SUITE_MAC( SUITE ) MBEDTLS_SSL_SUITE_MAC_T( SUITE ) -#define MBEDTLS_SSL_SUITE_KEY_EXCHANGE( SUITE ) MBEDTLS_SSL_SUITE_KEY_EXCHANGE_T( SUITE ) -#define MBEDTLS_SSL_SUITE_MIN_MAJOR_VER( SUITE ) MBEDTLS_SSL_SUITE_MIN_MAJOR_VER_T( SUITE ) -#define MBEDTLS_SSL_SUITE_MIN_MINOR_VER( SUITE ) MBEDTLS_SSL_SUITE_MIN_MINOR_VER_T( SUITE ) -#define MBEDTLS_SSL_SUITE_MAX_MAJOR_VER( SUITE ) MBEDTLS_SSL_SUITE_MAX_MAJOR_VER_T( SUITE ) -#define MBEDTLS_SSL_SUITE_MAX_MINOR_VER( SUITE ) MBEDTLS_SSL_SUITE_MAX_MINOR_VER_T( SUITE ) -#define MBEDTLS_SSL_SUITE_FLAGS( SUITE ) MBEDTLS_SSL_SUITE_FLAGS_T( SUITE ) - -#if !defined(MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE) /** * \brief This structure is used for storing ciphersuite information */ @@ -388,386 +356,23 @@ struct mbedtls_ssl_ciphersuite_t unsigned char flags; }; -typedef mbedtls_ssl_ciphersuite_t const * mbedtls_ssl_ciphersuite_handle_t; -#define MBEDTLS_SSL_CIPHERSUITE_INVALID_HANDLE ( (mbedtls_ssl_ciphersuite_handle_t) NULL ) - -/** - * \brief This macro builds an instance of ::mbedtls_ssl_ciphersuite_t - * from an \c MBEDTLS_SUITE_XXX identifier. - */ -#define MBEDTLS_SSL_SUITE_INFO( SUITE ) \ - { MBEDTLS_SSL_SUITE_ID( SUITE ), \ - MBEDTLS_SSL_SUITE_NAME( SUITE ), \ - MBEDTLS_SSL_SUITE_CIPHER( SUITE ), \ - MBEDTLS_SSL_SUITE_MAC( SUITE ), \ - MBEDTLS_SSL_SUITE_KEY_EXCHANGE( SUITE ), \ - MBEDTLS_SSL_SUITE_MIN_MAJOR_VER( SUITE ), \ - MBEDTLS_SSL_SUITE_MIN_MINOR_VER( SUITE ), \ - MBEDTLS_SSL_SUITE_MAX_MAJOR_VER( SUITE ), \ - MBEDTLS_SSL_SUITE_MAX_MINOR_VER( SUITE ), \ - MBEDTLS_SSL_SUITE_FLAGS( SUITE ) } - -#else /* !MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE */ - -typedef unsigned char mbedtls_ssl_ciphersuite_handle_t; -#define MBEDTLS_SSL_CIPHERSUITE_INVALID_HANDLE ( (mbedtls_ssl_ciphersuite_handle_t) 0 ) -#define MBEDTLS_SSL_CIPHERSUITE_UNIQUE_VALID_HANDLE ( (mbedtls_ssl_ciphersuite_handle_t) 1 ) - -#endif /* MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE */ - -#if !defined(MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE) -static inline int mbedtls_ssl_session_get_ciphersuite( - mbedtls_ssl_session const * session ) -{ - return( session->ciphersuite ); -} -#else /* !MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE */ -static inline int mbedtls_ssl_session_get_ciphersuite( - mbedtls_ssl_session const * session ) -{ - ((void) session); - return( MBEDTLS_SSL_SUITE_ID( MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE ) ); -} -#endif /* MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE */ - -/* - * Getter functions for the extraction of ciphersuite attributes - * from a ciphersuite handle. - * - * Warning: These functions have the validity of the handle as a precondition! - * Their behaviour is undefined when MBEDTLS_SSL_CIPHERSUITE_INVALID_HANDLE - * is passed. - */ - -#if !defined(MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE) -/* - * Implementation of getter functions when the ciphersuite handle - * is a pointer to the ciphersuite information structure. - * - * The precondition that the handle is valid means that - * we don't need to check that info != NULL. - */ -static inline int mbedtls_ssl_suite_get_id( - mbedtls_ssl_ciphersuite_handle_t const info ) -{ - return( info->id ); -} -static inline const char* mbedtls_ssl_suite_get_name( - mbedtls_ssl_ciphersuite_handle_t const info ) -{ - return( info->name ); -} -static inline mbedtls_cipher_type_t mbedtls_ssl_suite_get_cipher( - mbedtls_ssl_ciphersuite_handle_t const info ) -{ - return( info->cipher ); -} -static inline mbedtls_md_type_t mbedtls_ssl_suite_get_mac( - mbedtls_ssl_ciphersuite_handle_t const info ) -{ - return( info->mac ); -} -static inline mbedtls_key_exchange_type_t mbedtls_ssl_suite_get_key_exchange( - mbedtls_ssl_ciphersuite_handle_t const info ) -{ - return( info->key_exchange ); -} -static inline int mbedtls_ssl_suite_get_min_major_ver( - mbedtls_ssl_ciphersuite_handle_t const info ) -{ - return( info->min_major_ver ); -} -static inline int mbedtls_ssl_suite_get_min_minor_ver( - mbedtls_ssl_ciphersuite_handle_t const info ) -{ - return( info->min_minor_ver ); -} -static inline int mbedtls_ssl_suite_get_max_major_ver( - mbedtls_ssl_ciphersuite_handle_t const info ) -{ - return( info->max_major_ver ); -} -static inline int mbedtls_ssl_suite_get_max_minor_ver( - mbedtls_ssl_ciphersuite_handle_t const info ) -{ - return( info->max_minor_ver ); -} -static inline unsigned char mbedtls_ssl_suite_get_flags( - mbedtls_ssl_ciphersuite_handle_t const info ) -{ - return( info->flags ); -} -#else /* !MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE */ -/* - * Implementations of getter functions in the case of only a single possible - * ciphersuite. In this case, the handle is logically a boolean (either the - * invalid handle or the unique valid handle representing the single enabled - * ciphersuite), and the precondition that the handle is valid means that we - * can statically return the hardcoded attribute of the enabled ciphersuite. - */ -static inline int mbedtls_ssl_suite_get_id( - mbedtls_ssl_ciphersuite_handle_t const info ) -{ - ((void) info); - return( MBEDTLS_SSL_SUITE_ID( MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE ) ); -} -static inline const char* mbedtls_ssl_suite_get_name( - mbedtls_ssl_ciphersuite_handle_t const info ) -{ - ((void) info); - return( MBEDTLS_SSL_SUITE_NAME( MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE ) ); -} -static inline mbedtls_cipher_type_t mbedtls_ssl_suite_get_cipher( - mbedtls_ssl_ciphersuite_handle_t const info ) -{ - ((void) info); - return( MBEDTLS_SSL_SUITE_CIPHER( MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE ) ); -} -static inline mbedtls_md_type_t mbedtls_ssl_suite_get_mac( - mbedtls_ssl_ciphersuite_handle_t const info ) -{ - ((void) info); - return( MBEDTLS_SSL_SUITE_MAC( MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE ) ); -} -static inline mbedtls_key_exchange_type_t mbedtls_ssl_suite_get_key_exchange( - mbedtls_ssl_ciphersuite_handle_t const info ) -{ - ((void) info); - return( MBEDTLS_SSL_SUITE_KEY_EXCHANGE( MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE ) ); -} -static inline int mbedtls_ssl_suite_get_min_major_ver( - mbedtls_ssl_ciphersuite_handle_t const info ) -{ - ((void) info); - return( MBEDTLS_SSL_SUITE_MIN_MAJOR_VER( MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE ) ); -} -static inline int mbedtls_ssl_suite_get_min_minor_ver( - mbedtls_ssl_ciphersuite_handle_t const info ) -{ - ((void) info); - return( MBEDTLS_SSL_SUITE_MIN_MINOR_VER( MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE ) ); -} -static inline int mbedtls_ssl_suite_get_max_major_ver( - mbedtls_ssl_ciphersuite_handle_t const info ) -{ - ((void) info); - return( MBEDTLS_SSL_SUITE_MAX_MAJOR_VER( MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE ) ); -} -static inline int mbedtls_ssl_suite_get_max_minor_ver( - mbedtls_ssl_ciphersuite_handle_t const info ) -{ - ((void) info); - return( MBEDTLS_SSL_SUITE_MAX_MINOR_VER( MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE ) ); -} -static inline unsigned char mbedtls_ssl_suite_get_flags( - mbedtls_ssl_ciphersuite_handle_t const info ) -{ - ((void) info); - return( MBEDTLS_SSL_SUITE_FLAGS( MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE ) ); -} -#endif /* MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE */ - const int *mbedtls_ssl_list_ciphersuites( void ); -/* - * Various small helper functions for ciphersuites. - * - * Like the getter functions, they assume that the provided ciphersuite - * handle is valid, and hence can be optimized in case there's only one - * ciphersuite enabled. - * - * To avoid code-duplication between inline and non-inline implementations - * of this, we define internal static inline versions of all functions first, - * and define wrappers around these either here or in ssl_ciphersuites.c, - * depending on whether MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE is defined. - */ +const mbedtls_ssl_ciphersuite_t *mbedtls_ssl_ciphersuite_from_string( const char *ciphersuite_name ); +const mbedtls_ssl_ciphersuite_t *mbedtls_ssl_ciphersuite_from_id( int ciphersuite_id ); #if defined(MBEDTLS_PK_C) -static inline mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_pk_alg_internal( - mbedtls_ssl_ciphersuite_handle_t info ) +mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_pk_alg( const mbedtls_ssl_ciphersuite_t *info ); +mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_alg( const mbedtls_ssl_ciphersuite_t *info ); +#endif + +int mbedtls_ssl_ciphersuite_uses_ec( const mbedtls_ssl_ciphersuite_t *info ); +int mbedtls_ssl_ciphersuite_uses_psk( const mbedtls_ssl_ciphersuite_t *info ); + +#if defined(MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED) +static inline int mbedtls_ssl_ciphersuite_has_pfs( const mbedtls_ssl_ciphersuite_t *info ) { - switch( mbedtls_ssl_suite_get_key_exchange( info ) ) - { - case MBEDTLS_KEY_EXCHANGE_RSA: - case MBEDTLS_KEY_EXCHANGE_DHE_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: - case MBEDTLS_KEY_EXCHANGE_RSA_PSK: - return( MBEDTLS_PK_RSA ); - - case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: - return( MBEDTLS_PK_ECDSA ); - - case MBEDTLS_KEY_EXCHANGE_ECDH_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA: - return( MBEDTLS_PK_ECKEY ); - - default: - return( MBEDTLS_PK_NONE ); - } -} - -static inline mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_alg_internal( - mbedtls_ssl_ciphersuite_handle_t info ) -{ - switch( mbedtls_ssl_suite_get_key_exchange( info ) ) - { - case MBEDTLS_KEY_EXCHANGE_RSA: - case MBEDTLS_KEY_EXCHANGE_DHE_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: - return( MBEDTLS_PK_RSA ); - - case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: - return( MBEDTLS_PK_ECDSA ); - - default: - return( MBEDTLS_PK_NONE ); - } -} - -#endif /* MBEDTLS_PK_C */ - -#if defined(MBEDTLS_USE_TINYCRYPT) || \ - defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) -static inline int mbedtls_ssl_ciphersuite_uses_ec_internal( - mbedtls_ssl_ciphersuite_handle_t info ) -{ - switch( mbedtls_ssl_suite_get_key_exchange( info ) ) - { - case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: - case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK: - case MBEDTLS_KEY_EXCHANGE_ECDH_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA: - case MBEDTLS_KEY_EXCHANGE_ECJPAKE: - return( 1 ); - - default: - return( 0 ); - } -} -#endif /* MBEDTLS_USE_TINYCRYPT || - MBEDTLS_ECDH_C || - MBEDTLS_ECDSA_C || - MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) -static inline int mbedtls_ssl_ciphersuite_uses_psk_internal( - mbedtls_ssl_ciphersuite_handle_t info ) -{ - switch( mbedtls_ssl_suite_get_key_exchange( info ) ) - { - case MBEDTLS_KEY_EXCHANGE_PSK: - case MBEDTLS_KEY_EXCHANGE_RSA_PSK: - case MBEDTLS_KEY_EXCHANGE_DHE_PSK: - case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK: - return( 1 ); - - default: - return( 0 ); - } -} -#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ - -/* - * Wrappers around internal helper functions to be used by the rest of - * the library, either defined static inline here or in ssl_ciphersuites.c. - */ - -#if !defined(MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE) - -mbedtls_ssl_ciphersuite_handle_t mbedtls_ssl_ciphersuite_from_string( - const char *ciphersuite_name ); -mbedtls_ssl_ciphersuite_handle_t mbedtls_ssl_ciphersuite_from_id( - int ciphersuite_id ); - -#if defined(MBEDTLS_PK_C) -mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_pk_alg( - mbedtls_ssl_ciphersuite_handle_t info ); -mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_alg( - mbedtls_ssl_ciphersuite_handle_t info ); -#endif /* MBEDTLS_PK_C */ - -#if defined(MBEDTLS_USE_TINYCRYPT) || \ - defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) -int mbedtls_ssl_ciphersuite_uses_ec( mbedtls_ssl_ciphersuite_handle_t info ); -#endif /* MBEDTLS_USE_TINYCRYPT || - MBEDTLS_ECDH_C || - MBEDTLS_ECDSA_C || - MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) -int mbedtls_ssl_ciphersuite_uses_psk( mbedtls_ssl_ciphersuite_handle_t info ); -#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ - -#else /* !MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE */ - -#if defined(MBEDTLS_PK_C) -static inline mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_pk_alg( - mbedtls_ssl_ciphersuite_handle_t info ) -{ - return( mbedtls_ssl_get_ciphersuite_sig_pk_alg_internal( info ) ); -} - -static inline mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_alg( - mbedtls_ssl_ciphersuite_handle_t info ) -{ - return( mbedtls_ssl_get_ciphersuite_sig_alg_internal( info ) ); -} -#endif /* MBEDTLS_PK_C */ - -#if defined(MBEDTLS_USE_TINYCRYPT) || \ - defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) -static inline int mbedtls_ssl_ciphersuite_uses_ec( - mbedtls_ssl_ciphersuite_handle_t info ) -{ - return( mbedtls_ssl_ciphersuite_uses_ec_internal( info ) ); -} -#endif /* MBEDTLS_USE_TINYCRYPT || - MBEDTLS_ECDH_C || - MBEDTLS_ECDSA_C || - MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) -static inline int mbedtls_ssl_ciphersuite_uses_psk( - mbedtls_ssl_ciphersuite_handle_t info ) -{ - return( mbedtls_ssl_ciphersuite_uses_psk_internal( info ) ); -} -#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ - -static inline mbedtls_ssl_ciphersuite_handle_t mbedtls_ssl_ciphersuite_from_id( - int ciphersuite ) -{ - static const int single_suite_id = - MBEDTLS_SSL_SUITE_ID( MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE ); - - if( ciphersuite == single_suite_id ) - return( MBEDTLS_SSL_CIPHERSUITE_UNIQUE_VALID_HANDLE ); - - return( MBEDTLS_SSL_CIPHERSUITE_INVALID_HANDLE ); -} - -static inline mbedtls_ssl_ciphersuite_handle_t mbedtls_ssl_ciphersuite_from_string( - const char *ciphersuite_name ) -{ - static const char * const single_suite_name = - MBEDTLS_SSL_SUITE_NAME( MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE ); - - if( strcmp( ciphersuite_name, single_suite_name ) == 0 ) - return( MBEDTLS_SSL_CIPHERSUITE_UNIQUE_VALID_HANDLE ); - - return( MBEDTLS_SSL_CIPHERSUITE_INVALID_HANDLE ); -} - -#endif /* MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE */ - -static inline int mbedtls_ssl_ciphersuite_has_pfs( - mbedtls_ssl_ciphersuite_handle_t info ) -{ - switch( mbedtls_ssl_suite_get_key_exchange( info ) ) + switch( info->key_exchange ) { case MBEDTLS_KEY_EXCHANGE_DHE_RSA: case MBEDTLS_KEY_EXCHANGE_DHE_PSK: @@ -781,11 +386,12 @@ static inline int mbedtls_ssl_ciphersuite_has_pfs( return( 0 ); } } +#endif /* MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED */ -static inline int mbedtls_ssl_ciphersuite_no_pfs( - mbedtls_ssl_ciphersuite_handle_t info ) +#if defined(MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED) +static inline int mbedtls_ssl_ciphersuite_no_pfs( const mbedtls_ssl_ciphersuite_t *info ) { - switch( mbedtls_ssl_suite_get_key_exchange( info ) ) + switch( info->key_exchange ) { case MBEDTLS_KEY_EXCHANGE_ECDH_RSA: case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA: @@ -798,12 +404,12 @@ static inline int mbedtls_ssl_ciphersuite_no_pfs( return( 0 ); } } +#endif /* MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED */ - -static inline int mbedtls_ssl_ciphersuite_uses_ecdh( - mbedtls_ssl_ciphersuite_handle_t info ) +#if defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED) +static inline int mbedtls_ssl_ciphersuite_uses_ecdh( const mbedtls_ssl_ciphersuite_t *info ) { - switch( mbedtls_ssl_suite_get_key_exchange( info ) ) + switch( info->key_exchange ) { case MBEDTLS_KEY_EXCHANGE_ECDH_RSA: case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA: @@ -813,11 +419,11 @@ static inline int mbedtls_ssl_ciphersuite_uses_ecdh( return( 0 ); } } +#endif /* MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED */ -static inline int mbedtls_ssl_ciphersuite_cert_req_allowed( - mbedtls_ssl_ciphersuite_handle_t info ) +static inline int mbedtls_ssl_ciphersuite_cert_req_allowed( const mbedtls_ssl_ciphersuite_t *info ) { - switch( mbedtls_ssl_suite_get_key_exchange( info ) ) + switch( info->key_exchange ) { case MBEDTLS_KEY_EXCHANGE_RSA: case MBEDTLS_KEY_EXCHANGE_DHE_RSA: @@ -832,29 +438,10 @@ static inline int mbedtls_ssl_ciphersuite_cert_req_allowed( } } -static inline int mbedtls_ssl_ciphersuite_uses_srv_cert( - mbedtls_ssl_ciphersuite_handle_t info ) +#if defined(MBEDTLS_KEY_EXCHANGE__SOME__DHE_ENABLED) +static inline int mbedtls_ssl_ciphersuite_uses_dhe( const mbedtls_ssl_ciphersuite_t *info ) { - switch( mbedtls_ssl_suite_get_key_exchange( info ) ) - { - case MBEDTLS_KEY_EXCHANGE_RSA: - case MBEDTLS_KEY_EXCHANGE_RSA_PSK: - case MBEDTLS_KEY_EXCHANGE_DHE_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDH_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA: - case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: - return( 1 ); - - default: - return( 0 ); - } -} - -static inline int mbedtls_ssl_ciphersuite_uses_dhe( - mbedtls_ssl_ciphersuite_handle_t info ) -{ - switch( mbedtls_ssl_suite_get_key_exchange( info ) ) + switch( info->key_exchange ) { case MBEDTLS_KEY_EXCHANGE_DHE_RSA: case MBEDTLS_KEY_EXCHANGE_DHE_PSK: @@ -864,11 +451,12 @@ static inline int mbedtls_ssl_ciphersuite_uses_dhe( return( 0 ); } } +#endif /* MBEDTLS_KEY_EXCHANGE__SOME__DHE_ENABLED) */ -static inline int mbedtls_ssl_ciphersuite_uses_ecdhe( - mbedtls_ssl_ciphersuite_handle_t info ) +#if defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED) +static inline int mbedtls_ssl_ciphersuite_uses_ecdhe( const mbedtls_ssl_ciphersuite_t *info ) { - switch( mbedtls_ssl_suite_get_key_exchange( info ) ) + switch( info->key_exchange ) { case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: @@ -879,11 +467,12 @@ static inline int mbedtls_ssl_ciphersuite_uses_ecdhe( return( 0 ); } } +#endif /* MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED) */ -static inline int mbedtls_ssl_ciphersuite_uses_server_signature( - mbedtls_ssl_ciphersuite_handle_t info ) +#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) +static inline int mbedtls_ssl_ciphersuite_uses_server_signature( const mbedtls_ssl_ciphersuite_t *info ) { - switch( mbedtls_ssl_suite_get_key_exchange( info ) ) + switch( info->key_exchange ) { case MBEDTLS_KEY_EXCHANGE_DHE_RSA: case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: @@ -894,6 +483,7 @@ static inline int mbedtls_ssl_ciphersuite_uses_server_signature( return( 0 ); } } +#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */ #ifdef __cplusplus } diff --git a/APP_Framework/Framework/security/mbedtls/ssl_cli.c b/APP_Framework/Framework/security/mbedtls/ssl_cli.c index d6f6d4c89..68de78977 100644 --- a/APP_Framework/Framework/security/mbedtls/ssl_cli.c +++ b/APP_Framework/Framework/security/mbedtls/ssl_cli.c @@ -27,9 +27,9 @@ #if defined(MBEDTLS_SSL_CLI_C) +#if defined(MBEDTLS_PLATFORM_C) #include "platform.h" - -#if !defined(MBEDTLS_PLATFORM_C) +#else #include #define mbedtls_calloc calloc #define mbedtls_free free @@ -47,18 +47,20 @@ #include "platform_time.h" #endif -#include "platform.h" #if defined(MBEDTLS_SSL_SESSION_TICKETS) -#include "platform_util.h" +/* 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; +} #endif -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) && !defined(MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION) +#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) static void ssl_write_hostname_ext( mbedtls_ssl_context *ssl, unsigned char *buf, size_t *olen ) { unsigned char *p = buf; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; size_t hostname_len; *olen = 0; @@ -103,20 +105,24 @@ static void ssl_write_hostname_ext( mbedtls_ssl_context *ssl, * } ServerNameList; * */ + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SERVERNAME >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SERVERNAME ) & 0xFF ); - p = mbedtls_platform_put_uint16_be( p, MBEDTLS_TLS_EXT_SERVERNAME ); - p = mbedtls_platform_put_uint16_be( p, hostname_len + 5 ); - p = mbedtls_platform_put_uint16_be( p, hostname_len + 3 ); + *p++ = (unsigned char)( ( (hostname_len + 5) >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( (hostname_len + 5) ) & 0xFF ); + + *p++ = (unsigned char)( ( (hostname_len + 3) >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( (hostname_len + 3) ) & 0xFF ); *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SERVERNAME_HOSTNAME ) & 0xFF ); + *p++ = (unsigned char)( ( hostname_len >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( hostname_len ) & 0xFF ); - p = mbedtls_platform_put_uint16_be( p, hostname_len ); - - mbedtls_platform_memcpy( p, ssl->hostname, hostname_len ); + memcpy( p, ssl->hostname, hostname_len ); *olen = hostname_len + 9; } -#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION && !MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION */ +#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ #if defined(MBEDTLS_SSL_RENEGOTIATION) static void ssl_write_renegotiation_ext( mbedtls_ssl_context *ssl, @@ -124,7 +130,7 @@ static void ssl_write_renegotiation_ext( mbedtls_ssl_context *ssl, size_t *olen ) { unsigned char *p = buf; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; *olen = 0; @@ -145,13 +151,14 @@ static void ssl_write_renegotiation_ext( mbedtls_ssl_context *ssl, /* * Secure renegotiation */ - p = mbedtls_platform_put_uint16_be( p, MBEDTLS_TLS_EXT_RENEGOTIATION_INFO ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO ) & 0xFF ); *p++ = 0x00; *p++ = ( ssl->verify_data_len + 1 ) & 0xFF; *p++ = ssl->verify_data_len & 0xFF; - mbedtls_platform_memcpy( p, ssl->own_verify_data, ssl->verify_data_len ); + memcpy( p, ssl->own_verify_data, ssl->verify_data_len ); *olen = 5 + ssl->verify_data_len; } @@ -167,32 +174,29 @@ static void ssl_write_signature_algorithms_ext( mbedtls_ssl_context *ssl, size_t *olen ) { unsigned char *p = buf; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; size_t sig_alg_len = 0; -#if defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECDSA_C) || \ - defined(MBEDTLS_USE_TINYCRYPT) + const int *md; +#if defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECDSA_C) unsigned char *sig_alg_list = buf + 6; #endif *olen = 0; - if( mbedtls_ssl_conf_get_max_minor_ver( ssl->conf ) != - MBEDTLS_SSL_MINOR_VERSION_3 ) - { + if( ssl->conf->max_minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 ) return; - } MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding signature_algorithms extension" ) ); - MBEDTLS_SSL_BEGIN_FOR_EACH_SIG_HASH_TLS( hash ) - ((void) hash); -#if defined(MBEDTLS_ECDSA_C) || defined(MBEDTLS_USE_TINYCRYPT) - sig_alg_len += 2; + for( md = ssl->conf->sig_hashes; *md != MBEDTLS_MD_NONE; md++ ) + { +#if defined(MBEDTLS_ECDSA_C) + sig_alg_len += 2; #endif #if defined(MBEDTLS_RSA_C) - sig_alg_len += 2; + sig_alg_len += 2; #endif - MBEDTLS_SSL_END_FOR_EACH_SIG_HASH_TLS + } if( end < p || (size_t)( end - p ) < sig_alg_len + 6 ) { @@ -205,16 +209,17 @@ static void ssl_write_signature_algorithms_ext( mbedtls_ssl_context *ssl, */ sig_alg_len = 0; - MBEDTLS_SSL_BEGIN_FOR_EACH_SIG_HASH_TLS( hash ) -#if defined(MBEDTLS_ECDSA_C) || defined(MBEDTLS_USE_TINYCRYPT) - sig_alg_list[sig_alg_len++] = hash; - sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_ECDSA; + for( md = ssl->conf->sig_hashes; *md != MBEDTLS_MD_NONE; md++ ) + { +#if defined(MBEDTLS_ECDSA_C) + sig_alg_list[sig_alg_len++] = mbedtls_ssl_hash_from_md_alg( *md ); + sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_ECDSA; #endif #if defined(MBEDTLS_RSA_C) - sig_alg_list[sig_alg_len++] = hash; - sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_RSA; + sig_alg_list[sig_alg_len++] = mbedtls_ssl_hash_from_md_alg( *md ); + sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_RSA; #endif - MBEDTLS_SSL_END_FOR_EACH_SIG_HASH_TLS + } /* * enum { @@ -233,47 +238,58 @@ static void ssl_write_signature_algorithms_ext( mbedtls_ssl_context *ssl, * SignatureAndHashAlgorithm * supported_signature_algorithms<2..2^16-2>; */ + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SIG_ALG >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SIG_ALG ) & 0xFF ); + + *p++ = (unsigned char)( ( ( sig_alg_len + 2 ) >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( ( sig_alg_len + 2 ) ) & 0xFF ); + + *p++ = (unsigned char)( ( sig_alg_len >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( sig_alg_len ) & 0xFF ); - p = mbedtls_platform_put_uint16_be( p, MBEDTLS_TLS_EXT_SIG_ALG ); - p = mbedtls_platform_put_uint16_be( p, ( sig_alg_len + 2 ) ); - p = mbedtls_platform_put_uint16_be( p, sig_alg_len ); *olen = 6 + sig_alg_len; } #endif /* MBEDTLS_SSL_PROTO_TLS1_2 && MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ -#if defined(MBEDTLS_ECDH_C) || \ - defined(MBEDTLS_ECDSA_C) || \ - defined(MBEDTLS_USE_TINYCRYPT) || \ +#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) -static size_t ssl_get_ec_curve_list_length( mbedtls_ssl_context *ssl ) -{ - size_t ec_list_len = 0; - - MBEDTLS_SSL_BEGIN_FOR_EACH_SUPPORTED_EC_TLS_ID( tls_id ) - ((void) tls_id); - ec_list_len++; - MBEDTLS_SSL_END_FOR_EACH_SUPPORTED_EC_TLS_ID - - return( ec_list_len ); -} - static void ssl_write_supported_elliptic_curves_ext( mbedtls_ssl_context *ssl, unsigned char *buf, size_t *olen ) { unsigned char *p = buf; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; + unsigned char *elliptic_curve_list = p + 6; size_t elliptic_curve_len = 0; + const mbedtls_ecp_curve_info *info; +#if defined(MBEDTLS_ECP_C) + const mbedtls_ecp_group_id *grp_id; +#else + ((void) ssl); +#endif *olen = 0; MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding supported_elliptic_curves extension" ) ); - /* Each elliptic curve is encoded in 2 bytes. */ - elliptic_curve_len = 2 * ssl_get_ec_curve_list_length( ssl ); - if( elliptic_curve_len == 0 ) - return; +#if defined(MBEDTLS_ECP_C) + for( grp_id = ssl->conf->curve_list; *grp_id != MBEDTLS_ECP_DP_NONE; grp_id++ ) +#else + for( info = mbedtls_ecp_curve_list(); info->grp_id != MBEDTLS_ECP_DP_NONE; info++ ) +#endif + { +#if defined(MBEDTLS_ECP_C) + info = mbedtls_ecp_curve_info_from_grp_id( *grp_id ); +#endif + if( info == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid curve in ssl configuration" ) ); + return; + } + + elliptic_curve_len += 2; + } if( end < p || (size_t)( end - p ) < 6 + elliptic_curve_len ) { @@ -281,14 +297,32 @@ static void ssl_write_supported_elliptic_curves_ext( mbedtls_ssl_context *ssl, return; } - p = mbedtls_platform_put_uint16_be( p, MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES ); - p = mbedtls_platform_put_uint16_be( p, elliptic_curve_len + 2 ); - p = mbedtls_platform_put_uint16_be( p, elliptic_curve_len ); + elliptic_curve_len = 0; - MBEDTLS_SSL_BEGIN_FOR_EACH_SUPPORTED_EC_TLS_ID( tls_id ) - p = mbedtls_platform_put_uint16_be( p, tls_id ); +#if defined(MBEDTLS_ECP_C) + for( grp_id = ssl->conf->curve_list; *grp_id != MBEDTLS_ECP_DP_NONE; grp_id++ ) +#else + for( info = mbedtls_ecp_curve_list(); info->grp_id != MBEDTLS_ECP_DP_NONE; info++ ) +#endif + { +#if defined(MBEDTLS_ECP_C) + info = mbedtls_ecp_curve_info_from_grp_id( *grp_id ); +#endif + elliptic_curve_list[elliptic_curve_len++] = info->tls_id >> 8; + elliptic_curve_list[elliptic_curve_len++] = info->tls_id & 0xFF; + } - MBEDTLS_SSL_END_FOR_EACH_SUPPORTED_EC_TLS_ID + if( elliptic_curve_len == 0 ) + return; + + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES ) & 0xFF ); + + *p++ = (unsigned char)( ( ( elliptic_curve_len + 2 ) >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( ( elliptic_curve_len + 2 ) ) & 0xFF ); + + *p++ = (unsigned char)( ( ( elliptic_curve_len ) >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( ( elliptic_curve_len ) ) & 0xFF ); *olen = 6 + elliptic_curve_len; } @@ -298,7 +332,7 @@ static void ssl_write_supported_point_formats_ext( mbedtls_ssl_context *ssl, size_t *olen ) { unsigned char *p = buf; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; *olen = 0; @@ -310,17 +344,18 @@ static void ssl_write_supported_point_formats_ext( mbedtls_ssl_context *ssl, return; } - p = mbedtls_platform_put_uint16_be( p, MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS ) & 0xFF ); *p++ = 0x00; *p++ = 2; *p++ = 1; - *p++ = MBEDTLS_SSL_EC_PF_UNCOMPRESSED; + *p++ = MBEDTLS_ECP_PF_UNCOMPRESSED; *olen = 6; } -#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || MBEDTLS_USE_TINYCRYPT || +#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) @@ -330,7 +365,7 @@ static void ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl, { int ret; unsigned char *p = buf; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; size_t kkpp_len; *olen = 0; @@ -347,7 +382,8 @@ static void ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl, return; } - p = mbedtls_platform_put_uint16_be( p, MBEDTLS_TLS_EXT_ECJPAKE_KKPP ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP ) & 0xFF ); /* * We may need to send ClientHello multiple times for Hello verification. @@ -361,8 +397,7 @@ static void ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl, ret = mbedtls_ecjpake_write_round_one( &ssl->handshake->ecjpake_ctx, p + 2, end - p - 2, &kkpp_len, - mbedtls_ssl_conf_get_frng( ssl->conf ), - mbedtls_ssl_conf_get_prng( ssl->conf ) ); + ssl->conf->f_rng, ssl->conf->p_rng ); if( ret != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1 , "mbedtls_ecjpake_write_round_one", ret ); @@ -376,7 +411,7 @@ static void ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl, return; } - mbedtls_platform_memcpy( ssl->handshake->ecjpake_cache, p + 2, kkpp_len ); + memcpy( ssl->handshake->ecjpake_cache, p + 2, kkpp_len ); ssl->handshake->ecjpake_cache_len = kkpp_len; } else @@ -391,70 +426,23 @@ static void ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl, return; } - mbedtls_platform_memcpy( p + 2, ssl->handshake->ecjpake_cache, kkpp_len ); + memcpy( p + 2, ssl->handshake->ecjpake_cache, kkpp_len ); } - p = mbedtls_platform_put_uint16_be( p, kkpp_len ); + *p++ = (unsigned char)( ( kkpp_len >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( kkpp_len ) & 0xFF ); *olen = kkpp_len + 4; } #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) -static void ssl_write_cid_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, - size_t *olen ) -{ - unsigned char *p = buf; - size_t ext_len; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; - - /* - * Quoting draft-ietf-tls-dtls-connection-id-05 - * https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05 - * - * struct { - * opaque cid<0..2^8-1>; - * } ConnectionId; - */ - - *olen = 0; - if( MBEDTLS_SSL_TRANSPORT_IS_TLS( ssl->conf->transport ) || - ssl->negotiate_cid == MBEDTLS_SSL_CID_DISABLED ) - { - return; - } - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding CID extension" ) ); - - /* ssl->own_cid_len is at most MBEDTLS_SSL_CID_IN_LEN_MAX - * which is at most 255, so the increment cannot overflow. */ - if( end < p || (size_t)( end - p ) < (unsigned)( ssl->own_cid_len + 5 ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); - return; - } - - /* Add extension ID + size */ - p = mbedtls_platform_put_uint16_be( p, MBEDTLS_TLS_EXT_CID ); - ext_len = (size_t) ssl->own_cid_len + 1; - - p = mbedtls_platform_put_uint16_be( p, ext_len ); - - *p++ = (uint8_t) ssl->own_cid_len; - /* Not using more secure mbedtls_platform_memcpy as cid is public */ - memcpy( p, ssl->own_cid, ssl->own_cid_len ); - - *olen = ssl->own_cid_len + 5; -} -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) static void ssl_write_max_fragment_length_ext( mbedtls_ssl_context *ssl, unsigned char *buf, size_t *olen ) { unsigned char *p = buf; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; *olen = 0; @@ -470,7 +458,8 @@ static void ssl_write_max_fragment_length_ext( mbedtls_ssl_context *ssl, return; } - p = mbedtls_platform_put_uint16_be( p, MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH ) & 0xFF ); *p++ = 0x00; *p++ = 1; @@ -486,7 +475,7 @@ static void ssl_write_truncated_hmac_ext( mbedtls_ssl_context *ssl, unsigned char *buf, size_t *olen ) { unsigned char *p = buf; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; *olen = 0; @@ -503,7 +492,8 @@ static void ssl_write_truncated_hmac_ext( mbedtls_ssl_context *ssl, return; } - p = mbedtls_platform_put_uint16_be( p, MBEDTLS_TLS_EXT_TRUNCATED_HMAC ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC ) & 0xFF ); *p++ = 0x00; *p++ = 0x00; @@ -517,13 +507,12 @@ static void ssl_write_encrypt_then_mac_ext( mbedtls_ssl_context *ssl, unsigned char *buf, size_t *olen ) { unsigned char *p = buf; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; *olen = 0; if( ssl->conf->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED || - mbedtls_ssl_conf_get_max_minor_ver( ssl->conf ) == - MBEDTLS_SSL_MINOR_VERSION_0 ) + ssl->conf->max_minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) { return; } @@ -537,7 +526,8 @@ static void ssl_write_encrypt_then_mac_ext( mbedtls_ssl_context *ssl, return; } - p = mbedtls_platform_put_uint16_be( p, MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC ) & 0xFF ); *p++ = 0x00; *p++ = 0x00; @@ -551,14 +541,12 @@ static void ssl_write_extended_ms_ext( mbedtls_ssl_context *ssl, unsigned char *buf, size_t *olen ) { unsigned char *p = buf; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; *olen = 0; - if( mbedtls_ssl_conf_get_ems( ssl->conf ) == - MBEDTLS_SSL_EXTENDED_MS_DISABLED || - mbedtls_ssl_conf_get_max_minor_ver( ssl->conf ) == - MBEDTLS_SSL_MINOR_VERSION_0 ) + if( ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED || + ssl->conf->max_minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) { return; } @@ -572,7 +560,8 @@ static void ssl_write_extended_ms_ext( mbedtls_ssl_context *ssl, return; } - p = mbedtls_platform_put_uint16_be( p, MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET ) & 0xFF ); *p++ = 0x00; *p++ = 0x00; @@ -586,7 +575,7 @@ static void ssl_write_session_ticket_ext( mbedtls_ssl_context *ssl, unsigned char *buf, size_t *olen ) { unsigned char *p = buf; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; size_t tlen = ssl->session_negotiate->ticket_len; *olen = 0; @@ -604,8 +593,11 @@ static void ssl_write_session_ticket_ext( mbedtls_ssl_context *ssl, return; } - p = mbedtls_platform_put_uint16_be( p, MBEDTLS_TLS_EXT_SESSION_TICKET ); - p = mbedtls_platform_put_uint16_be( p, tlen ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET ) & 0xFF ); + + *p++ = (unsigned char)( ( tlen >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( tlen ) & 0xFF ); *olen = 4; @@ -616,7 +608,7 @@ static void ssl_write_session_ticket_ext( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_MSG( 3, ( "sending session ticket of length %d", tlen ) ); - mbedtls_platform_memcpy( p, ssl->session_negotiate->ticket, tlen ); + memcpy( p, ssl->session_negotiate->ticket, tlen ); *olen += tlen; } @@ -627,7 +619,7 @@ static void ssl_write_alpn_ext( mbedtls_ssl_context *ssl, unsigned char *buf, size_t *olen ) { unsigned char *p = buf; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; size_t alpnlen = 0; const char **cur; @@ -649,7 +641,8 @@ static void ssl_write_alpn_ext( mbedtls_ssl_context *ssl, return; } - p = mbedtls_platform_put_uint16_be( p, MBEDTLS_TLS_EXT_ALPN ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN ) & 0xFF ); /* * opaque ProtocolName<1..2^8-1>; @@ -665,16 +658,19 @@ static void ssl_write_alpn_ext( mbedtls_ssl_context *ssl, for( cur = ssl->conf->alpn_list; *cur != NULL; cur++ ) { *p = (unsigned char)( strlen( *cur ) & 0xFF ); - mbedtls_platform_memcpy( p + 1, *cur, *p ); + memcpy( p + 1, *cur, *p ); p += 1 + *p; } *olen = p - buf; /* List length = olen - 2 (ext_type) - 2 (ext_len) - 2 (list_len) */ - (void)mbedtls_platform_put_uint16_be( &buf[4], ( *olen - 6 ) ); + buf[4] = (unsigned char)( ( ( *olen - 6 ) >> 8 ) & 0xFF ); + buf[5] = (unsigned char)( ( ( *olen - 6 ) ) & 0xFF ); + /* Extension length = olen - 2 (ext_type) - 2 (ext_len) */ - (void)mbedtls_platform_put_uint16_be( &buf[2], ( *olen - 4 ) ); + buf[2] = (unsigned char)( ( ( *olen - 4 ) >> 8 ) & 0xFF ); + buf[3] = (unsigned char)( ( ( *olen - 4 ) ) & 0xFF ); } #endif /* MBEDTLS_SSL_ALPN */ @@ -683,17 +679,17 @@ static void ssl_write_alpn_ext( mbedtls_ssl_context *ssl, */ static int ssl_generate_random( mbedtls_ssl_context *ssl ) { - volatile int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; + int ret; unsigned char *p = ssl->handshake->randbytes; #if defined(MBEDTLS_HAVE_TIME) mbedtls_time_t t; #endif - ssl->handshake->hello_random_set = MBEDTLS_SSL_FI_FLAG_UNSET; + /* * When responding to a verify request, MUST reuse random (RFC 6347 4.2.1) */ #if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) && + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && ssl->handshake->verify_cookie != NULL ) { return( 0 ); @@ -702,35 +698,23 @@ static int ssl_generate_random( mbedtls_ssl_context *ssl ) #if defined(MBEDTLS_HAVE_TIME) t = mbedtls_time( NULL ); - p = mbedtls_platform_put_uint32_be( p, (uint32_t) t ); + *p++ = (unsigned char)( t >> 24 ); + *p++ = (unsigned char)( t >> 16 ); + *p++ = (unsigned char)( t >> 8 ); + *p++ = (unsigned char)( t ); + MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, current time: %lu", t ) ); #else - if( ( ret = mbedtls_ssl_conf_get_frng( ssl->conf ) - ( mbedtls_ssl_conf_get_prng( ssl->conf ), p, 4 ) ) != 0 ) - { + if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p, 4 ) ) != 0 ) return( ret ); - } p += 4; #endif /* MBEDTLS_HAVE_TIME */ - ret = mbedtls_ssl_conf_get_frng( ssl->conf ) - ( mbedtls_ssl_conf_get_prng( ssl->conf ), p, 28 ); - if( ret == 0 ) - { - mbedtls_platform_random_delay(); - if( ret == 0 ) - { - ssl->handshake->hello_random_set = MBEDTLS_SSL_FI_FLAG_SET; - return( 0 ); - } - else - { - ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; - } - } + if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p, 28 ) ) != 0 ) + return( ret ); - return( ret ); + return( 0 ); } /** @@ -743,46 +727,34 @@ static int ssl_generate_random( mbedtls_ssl_context *ssl ) * * \return 0 if valid, else 1 */ -static int ssl_validate_ciphersuite( mbedtls_ssl_ciphersuite_handle_t suite_info, +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 == MBEDTLS_SSL_CIPHERSUITE_INVALID_HANDLE ) + if( suite_info == NULL ) return( 1 ); - if( mbedtls_ssl_ver_gt( mbedtls_ssl_suite_get_min_minor_ver( suite_info ), - max_minor_ver ) || - mbedtls_ssl_ver_lt( mbedtls_ssl_suite_get_max_minor_ver( suite_info ), - min_minor_ver ) ) - { + 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( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) && - ( mbedtls_ssl_suite_get_flags( suite_info ) & - MBEDTLS_CIPHERSUITE_NODTLS ) != 0 ) - { + 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 && - mbedtls_ssl_suite_get_cipher( suite_info ) == MBEDTLS_CIPHER_ARC4_128 ) - { + suite_info->cipher == MBEDTLS_CIPHER_ARC4_128 ) return( 1 ); - } #endif #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - if( mbedtls_ssl_suite_get_key_exchange( suite_info ) == - MBEDTLS_KEY_EXCHANGE_ECJPAKE && - mbedtls_ecjpake_check( &ssl->handshake->ecjpake_ctx ) != 0 ) - { + if( suite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE && + mbedtls_ecjpake_check( &ssl->handshake->ecjpake_ctx ) != 0 ) return( 1 ); - } #endif return( 0 ); @@ -795,31 +767,30 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl ) unsigned char *buf; unsigned char *p, *q; unsigned char offer_compress; -#if defined(MBEDTLS_USE_TINYCRYPT) || \ - defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ + const int *ciphersuites; + 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" ) ); - if( mbedtls_ssl_conf_get_frng( ssl->conf ) == NULL ) + if( ssl->conf->f_rng == NULL ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "no RNG provided") ); return( MBEDTLS_ERR_SSL_NO_RNG ); } - if( mbedtls_ssl_get_renego_status( ssl ) == MBEDTLS_SSL_INITIAL_HANDSHAKE ) +#if defined(MBEDTLS_SSL_RENEGOTIATION) + if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE ) +#endif { -#if !defined(MBEDTLS_SSL_CONF_FIXED_MAJOR_VER) - ssl->major_ver = mbedtls_ssl_conf_get_min_major_ver( ssl->conf ); -#endif /* !MBEDTLS_SSL_CONF_FIXED_MAJOR_VER */ -#if !defined(MBEDTLS_SSL_CONF_FIXED_MINOR_VER) - ssl->minor_ver = mbedtls_ssl_conf_get_min_minor_ver( ssl->conf ); -#endif /* !MBEDTLS_SSL_CONF_FIXED_MINOR_VER */ + ssl->major_ver = ssl->conf->min_major_ver; + ssl->minor_ver = ssl->conf->min_minor_ver; } - if( mbedtls_ssl_conf_get_max_major_ver( ssl->conf ) == 0 ) + if( ssl->conf->max_major_ver == 0 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "configured max major version is invalid, " "consider using mbedtls_ssl_config_defaults()" ) ); @@ -836,9 +807,8 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl ) buf = ssl->out_msg; p = buf + 4; - mbedtls_ssl_write_version( mbedtls_ssl_conf_get_max_major_ver( ssl->conf ), - mbedtls_ssl_conf_get_max_minor_ver( ssl->conf ), - mbedtls_ssl_conf_get_transport( ssl->conf ), p ); + mbedtls_ssl_write_version( ssl->conf->max_major_ver, ssl->conf->max_minor_ver, + ssl->conf->transport, p ); p += 2; MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, max version: [%d:%d]", @@ -850,7 +820,7 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl ) return( ret ); } - mbedtls_platform_memcpy( p, ssl->handshake->randbytes, 32 ); + memcpy( p, ssl->handshake->randbytes, 32 ); MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, random bytes", p, 32 ); p += 32; @@ -866,41 +836,36 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl ) * .. . .. extensions length (2 bytes) * .. . .. extensions */ + n = ssl->session_negotiate->id_len; - /* - * We'll write a session of non-zero length if resumption was requested - * by the user, we're not renegotiating, and the session ID is of - * appropriate length. Otherwise make the length 0 (for now, see next code - * block for behaviour with tickets). - */ - if( mbedtls_ssl_handshake_get_resume( ssl->handshake ) == MBEDTLS_SSL_FI_FLAG_UNSET || - mbedtls_ssl_get_renego_status( ssl ) != MBEDTLS_SSL_INITIAL_HANDSHAKE || - ssl->session_negotiate->id_len < 16 || - ssl->session_negotiate->id_len > 32 ) + if( n < 16 || n > 32 || +#if defined(MBEDTLS_SSL_RENEGOTIATION) + ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE || +#endif + ssl->handshake->resume == 0 ) { n = 0; } - else - { - n = ssl->session_negotiate->id_len; - } #if defined(MBEDTLS_SSL_SESSION_TICKETS) /* * RFC 5077 section 3.4: "When presenting a ticket, the client MAY * generate and include a Session ID in the TLS ClientHello." */ - if( mbedtls_ssl_get_renego_status( ssl ) == MBEDTLS_SSL_INITIAL_HANDSHAKE && - ssl->session_negotiate->ticket != NULL && - ssl->session_negotiate->ticket_len != 0 ) +#if defined(MBEDTLS_SSL_RENEGOTIATION) + if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE ) +#endif { - ret = mbedtls_ssl_conf_get_frng( ssl->conf ) - ( mbedtls_ssl_conf_get_prng( ssl->conf ), ssl->session_negotiate->id, 32 ); + if( ssl->session_negotiate->ticket != NULL && + ssl->session_negotiate->ticket_len != 0 ) + { + ret = ssl->conf->f_rng( ssl->conf->p_rng, ssl->session_negotiate->id, 32 ); - if( ret != 0 ) - return( ret ); + if( ret != 0 ) + return( ret ); - ssl->session_negotiate->id_len = n = 32; + ssl->session_negotiate->id_len = n = 32; + } } #endif /* MBEDTLS_SSL_SESSION_TICKETS */ @@ -916,7 +881,7 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl ) * DTLS cookie */ #if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) ) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) { if( ssl->handshake->verify_cookie == NULL ) { @@ -930,7 +895,7 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl ) ssl->handshake->verify_cookie_len ); *p++ = ssl->handshake->verify_cookie_len; - mbedtls_platform_memcpy( p, ssl->handshake->verify_cookie, + memcpy( p, ssl->handshake->verify_cookie, ssl->handshake->verify_cookie_len ); p += ssl->handshake->verify_cookie_len; } @@ -940,49 +905,47 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl ) /* * Ciphersuite list */ + ciphersuites = ssl->conf->ciphersuite_list[ssl->minor_ver]; /* Skip writing ciphersuite length for now */ n = 0; q = p; p += 2; - MBEDTLS_SSL_BEGIN_FOR_EACH_CIPHERSUITE( ssl, - mbedtls_ssl_get_minor_ver( ssl ), - ciphersuite_info ) + for( i = 0; ciphersuites[i] != 0; i++ ) { + ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( ciphersuites[i] ); + if( ssl_validate_ciphersuite( ciphersuite_info, ssl, - mbedtls_ssl_conf_get_min_minor_ver( ssl->conf ), - mbedtls_ssl_conf_get_max_minor_ver( ssl->conf ) ) != 0 ) - { + ssl->conf->min_minor_ver, + ssl->conf->max_minor_ver ) != 0 ) continue; - } MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, add ciphersuite: %04x", - mbedtls_ssl_suite_get_id( ciphersuite_info ) ) ); + ciphersuites[i] ) ); -#if defined(MBEDTLS_USE_TINYCRYPT) || \ - defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ +#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++; - *p++ = (unsigned char)( - mbedtls_ssl_suite_get_id( ciphersuite_info ) >> 8 ); - *p++ = (unsigned char)( - mbedtls_ssl_suite_get_id( ciphersuite_info ) ); + *p++ = (unsigned char)( ciphersuites[i] >> 8 ); + *p++ = (unsigned char)( ciphersuites[i] ); } - MBEDTLS_SSL_END_FOR_EACH_CIPHERSUITE MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, got %d ciphersuites (excluding SCSVs)", n ) ); /* * Add TLS_EMPTY_RENEGOTIATION_INFO_SCSV */ - if( mbedtls_ssl_get_renego_status( ssl ) == MBEDTLS_SSL_INITIAL_HANDSHAKE ) +#if defined(MBEDTLS_SSL_RENEGOTIATION) + if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE ) +#endif { MBEDTLS_SSL_DEBUG_MSG( 3, ( "adding EMPTY_RENEGOTIATION_INFO_SCSV" ) ); - p = mbedtls_platform_put_uint16_be( p, MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO ); + *p++ = (unsigned char)( MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO >> 8 ); + *p++ = (unsigned char)( MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO ); n++; } @@ -991,7 +954,8 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl ) if( ssl->conf->fallback == MBEDTLS_SSL_IS_FALLBACK ) { MBEDTLS_SSL_DEBUG_MSG( 3, ( "adding FALLBACK_SCSV" ) ); - p = mbedtls_platform_put_uint16_be( p, MBEDTLS_SSL_FALLBACK_SCSV_VALUE ); + *p++ = (unsigned char)( MBEDTLS_SSL_FALLBACK_SCSV_VALUE >> 8 ); + *p++ = (unsigned char)( MBEDTLS_SSL_FALLBACK_SCSV_VALUE ); n++; } #endif @@ -1012,7 +976,7 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl ) * an actual need for it. */ #if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) ) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) offer_compress = 0; #endif @@ -1038,7 +1002,7 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl ) // First write extensions, then the total length // -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) && !defined(MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION) +#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) ssl_write_hostname_ext( ssl, p + 2 + ext_len, &olen ); ext_len += olen; #endif @@ -1056,10 +1020,7 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl ) ext_len += olen; #endif -#if defined(MBEDTLS_USE_TINYCRYPT) || \ - defined(MBEDTLS_ECDH_C) || \ - defined(MBEDTLS_ECDSA_C) || \ - defined(MBEDTLS_USE_TINYCRYPT) || \ +#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) if( uses_ec ) { @@ -1076,11 +1037,6 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl ) ext_len += olen; #endif -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - ssl_write_cid_ext( ssl, p + 2 + ext_len, &olen ); - ext_len += olen; -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) ssl_write_max_fragment_length_ext( ssl, p + 2 + ext_len, &olen ); ext_len += olen; @@ -1119,7 +1075,8 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl ) if( ext_len > 0 ) { - p = mbedtls_platform_put_uint16_be( p, ext_len ); + *p++ = (unsigned char)( ( ext_len >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( ext_len ) & 0xFF ); p += ext_len; } @@ -1127,34 +1084,19 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl ) ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; ssl->out_msg[0] = MBEDTLS_SSL_HS_CLIENT_HELLO; - ssl->state = MBEDTLS_SSL_SERVER_HELLO; + ssl->state++; #if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) ) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) mbedtls_ssl_send_flight_completed( ssl ); #endif - if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 ) + if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 ) { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret ); + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret ); return( ret ); } -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) ) - { -#if defined(MBEDTLS_SSL_IMMEDIATE_TRANSMISSION) - mbedtls_ssl_immediate_flight_done( ssl ); -#else - if( ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flight_transmit", ret ); - return( ret ); - } -#endif - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write client hello" ) ); return( 0 ); @@ -1170,14 +1112,14 @@ static int ssl_parse_renegotiation_info( mbedtls_ssl_context *ssl, /* Check verify-data in constant-time. The length OTOH is no secret */ if( len != 1 + ssl->verify_data_len * 2 || buf[0] != ssl->verify_data_len * 2 || - mbedtls_platform_memequal( buf + 1, + mbedtls_ssl_safer_memcmp( buf + 1, ssl->own_verify_data, ssl->verify_data_len ) != 0 || - mbedtls_platform_memequal( buf + 1 + ssl->verify_data_len, + mbedtls_ssl_safer_memcmp( buf + 1 + ssl->verify_data_len, ssl->peer_verify_data, ssl->verify_data_len ) != 0 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching renegotiation info" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); } } @@ -1187,8 +1129,8 @@ static int ssl_parse_renegotiation_info( mbedtls_ssl_context *ssl, if( len != 1 || buf[0] != 0x00 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-zero length renegotiation info" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); } @@ -1212,8 +1154,8 @@ static int ssl_parse_max_fragment_length_ext( mbedtls_ssl_context *ssl, buf[0] != ssl->conf->mfl_code ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching max fragment length extension" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); } @@ -1230,8 +1172,8 @@ static int ssl_parse_truncated_hmac_ext( mbedtls_ssl_context *ssl, len != 0 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching truncated HMAC extension" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); } @@ -1243,75 +1185,18 @@ static int ssl_parse_truncated_hmac_ext( mbedtls_ssl_context *ssl, } #endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) -static int ssl_parse_cid_ext( mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len ) -{ - size_t peer_cid_len; - - if( /* CID extension only makes sense in DTLS */ - MBEDTLS_SSL_TRANSPORT_IS_TLS( ssl->conf->transport ) || - /* The server must only send the CID extension if we have offered it. */ - ssl->negotiate_cid == MBEDTLS_SSL_CID_DISABLED ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "CID extension unexpected" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); - } - - if( len == 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "CID extension invalid" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); - } - - peer_cid_len = *buf++; - len--; - - if( peer_cid_len > MBEDTLS_SSL_CID_OUT_LEN_MAX ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "CID extension invalid" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); - } - - if( len != peer_cid_len ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "CID extension invalid" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); - } - - ssl->handshake->cid_in_use = MBEDTLS_SSL_CID_ENABLED; - ssl->handshake->peer_cid_len = (uint8_t) peer_cid_len; - /* Not using more secure mbedtls_platform_memcpy as peer_cid is public */ - memcpy( ssl->handshake->peer_cid, buf, peer_cid_len ); - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "Use of CID extension negotiated" ) ); - MBEDTLS_SSL_DEBUG_BUF( 3, "Server CID", buf, peer_cid_len ); - - return( 0 ); -} -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) static int ssl_parse_encrypt_then_mac_ext( mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len ) { if( ssl->conf->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED || - mbedtls_ssl_get_minor_ver( ssl ) == MBEDTLS_SSL_MINOR_VERSION_0 || + ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 || len != 0 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching encrypt-then-MAC extension" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); } @@ -1328,18 +1213,20 @@ static int ssl_parse_extended_ms_ext( mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len ) { - if( mbedtls_ssl_conf_get_ems( ssl->conf ) == - MBEDTLS_SSL_EXTENDED_MS_DISABLED || - mbedtls_ssl_get_minor_ver( ssl ) == MBEDTLS_SSL_MINOR_VERSION_0 || + if( ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED || + ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 || len != 0 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching extended master secret extension" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); } ((void) buf); + + ssl->handshake->extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED; + return( 0 ); } #endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ @@ -1353,8 +1240,8 @@ static int ssl_parse_session_ticket_ext( mbedtls_ssl_context *ssl, len != 0 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching session ticket extension" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); } @@ -1366,10 +1253,8 @@ static int ssl_parse_session_ticket_ext( mbedtls_ssl_context *ssl, } #endif /* MBEDTLS_SSL_SESSION_TICKETS */ -#if defined(MBEDTLS_ECDH_C) || \ - defined(MBEDTLS_ECDSA_C) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) || \ - defined(MBEDTLS_USE_TINYCRYPT) +#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) static int ssl_parse_supported_point_formats_ext( mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len ) @@ -1380,8 +1265,8 @@ static int ssl_parse_supported_point_formats_ext( mbedtls_ssl_context *ssl, if( len == 0 || (size_t)( buf[0] + 1 ) != len ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); } list_size = buf[0]; @@ -1389,10 +1274,10 @@ static int ssl_parse_supported_point_formats_ext( mbedtls_ssl_context *ssl, p = buf + 1; while( list_size > 0 ) { - if( p[0] == MBEDTLS_SSL_EC_PF_UNCOMPRESSED || - p[0] == MBEDTLS_SSL_EC_PF_COMPRESSED ) + if( p[0] == MBEDTLS_ECP_PF_UNCOMPRESSED || + p[0] == MBEDTLS_ECP_PF_COMPRESSED ) { -#if defined(MBEDTLS_ECDH_C) +#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) ssl->handshake->ecdh_ctx.point_format = p[0]; #endif #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) @@ -1407,11 +1292,11 @@ static int ssl_parse_supported_point_formats_ext( mbedtls_ssl_context *ssl, } MBEDTLS_SSL_DEBUG_MSG( 1, ( "no point format in common" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); } -#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || MBEDTLS_USE_TINYCRYPT || +#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) @@ -1421,9 +1306,8 @@ static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl, { int ret; - if( mbedtls_ssl_suite_get_key_exchange( - mbedtls_ssl_handshake_get_ciphersuite( ssl->handshake ) ) - != MBEDTLS_KEY_EXCHANGE_ECJPAKE ) + if( ssl->transform_negotiate->ciphersuite_info->key_exchange != + MBEDTLS_KEY_EXCHANGE_ECJPAKE ) { MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip ecjpake kkpp extension" ) ); return( 0 ); @@ -1438,8 +1322,8 @@ static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl, buf, len ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_one", ret ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( ret ); } @@ -1458,8 +1342,8 @@ static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl, if( ssl->conf->alpn_list == NULL ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching ALPN extension" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); } @@ -1476,24 +1360,24 @@ static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl, /* Min length is 2 (list_len) + 1 (name_len) + 1 (name) */ if( len < 4 ) { - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); } - list_len = mbedtls_platform_get_uint16_be( buf ); + list_len = ( buf[0] << 8 ) | buf[1]; if( list_len != len - 2 ) { - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); } name_len = buf[2]; if( name_len != list_len - 1 ) { - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); } @@ -1501,7 +1385,7 @@ static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl, for( p = ssl->conf->alpn_list; *p != NULL; p++ ) { if( name_len == strlen( *p ) && - mbedtls_platform_memequal( buf + 3, *p, name_len ) == 0 ) + memcmp( buf + 3, *p, name_len ) == 0 ) { ssl->alpn_chosen = *p; return( 0 ); @@ -1509,8 +1393,8 @@ static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl, } MBEDTLS_SSL_DEBUG_MSG( 1, ( "ALPN extension: no matching protocol" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); } #endif /* MBEDTLS_SSL_ALPN */ @@ -1527,19 +1411,6 @@ static int ssl_parse_hello_verify_request( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse hello verify request" ) ); - /* Check that there is enough room for: - * - 2 bytes of version - * - 1 byte of cookie_len - */ - if( mbedtls_ssl_hs_hdr_len( ssl ) + 3 > ssl->in_msglen ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, - ( "incoming HelloVerifyRequest message is too short" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); - } - /* * struct { * ProtocolVersion server_version; @@ -1547,39 +1418,37 @@ static int ssl_parse_hello_verify_request( mbedtls_ssl_context *ssl ) * } HelloVerifyRequest; */ MBEDTLS_SSL_DEBUG_BUF( 3, "server version", p, 2 ); - mbedtls_ssl_read_version( &major_ver, &minor_ver, - mbedtls_ssl_conf_get_transport( ssl->conf ), p ); + mbedtls_ssl_read_version( &major_ver, &minor_ver, ssl->conf->transport, p ); p += 2; /* * Since the RFC is not clear on this point, accept DTLS 1.0 (TLS 1.1) * even is lower than our min version. */ - if( mbedtls_ssl_ver_lt( major_ver, MBEDTLS_SSL_MAJOR_VERSION_3 ) || - mbedtls_ssl_ver_lt( minor_ver, MBEDTLS_SSL_MINOR_VERSION_2 ) || - mbedtls_ssl_ver_gt( major_ver, - mbedtls_ssl_conf_get_max_major_ver( ssl->conf ) ) || - mbedtls_ssl_ver_gt( minor_ver, - mbedtls_ssl_conf_get_max_minor_ver( ssl->conf ) ) ) + if( major_ver < MBEDTLS_SSL_MAJOR_VERSION_3 || + minor_ver < MBEDTLS_SSL_MINOR_VERSION_2 || + major_ver > ssl->conf->max_major_ver || + minor_ver > ssl->conf->max_minor_ver ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server version" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION ); return( MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION ); } cookie_len = *p++; + MBEDTLS_SSL_DEBUG_BUF( 3, "cookie", p, cookie_len ); + if( ( ssl->in_msg + ssl->in_msglen ) - p < cookie_len ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "cookie length does not match incoming message size" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); } - MBEDTLS_SSL_DEBUG_BUF( 3, "cookie", p, cookie_len ); mbedtls_free( ssl->handshake->verify_cookie ); @@ -1590,7 +1459,7 @@ static int ssl_parse_hello_verify_request( mbedtls_ssl_context *ssl ) return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); } - mbedtls_platform_memcpy( ssl->handshake->verify_cookie, p, cookie_len ); + memcpy( ssl->handshake->verify_cookie, p, cookie_len ); ssl->handshake->verify_cookie_len = cookie_len; /* Start over at ClientHello */ @@ -1617,26 +1486,21 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) #endif #if defined(MBEDTLS_SSL_RENEGOTIATION) int renegotiation_info_seen = 0; -#endif -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) - int extended_ms_seen = 0; #endif int handshake_failure = 0; - - /* The ciphersuite chosen by the server. */ - mbedtls_ssl_ciphersuite_handle_t server_suite_info; + const mbedtls_ssl_ciphersuite_t *suite_info; MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server hello" ) ); - if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 ) + buf = ssl->in_msg; + + if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 ) { /* No alert on a read error. */ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); return( ret ); } - buf = ssl->in_msg; - if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) { #if defined(MBEDTLS_SSL_RENEGOTIATION) @@ -1660,13 +1524,13 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) #endif /* MBEDTLS_SSL_RENEGOTIATION */ MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); } #if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) ) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) { if( buf[0] == MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST ) { @@ -1688,8 +1552,8 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) buf[0] != MBEDTLS_SSL_HS_SERVER_HELLO ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); } @@ -1706,57 +1570,34 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) */ buf += mbedtls_ssl_hs_hdr_len( ssl ); + MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, version", buf + 0, 2 ); + mbedtls_ssl_read_version( &ssl->major_ver, &ssl->minor_ver, + ssl->conf->transport, buf + 0 ); + + if( ssl->major_ver < ssl->conf->min_major_ver || + ssl->minor_ver < ssl->conf->min_minor_ver || + ssl->major_ver > ssl->conf->max_major_ver || + ssl->minor_ver > ssl->conf->max_minor_ver ) { - int major_ver, minor_ver; + MBEDTLS_SSL_DEBUG_MSG( 1, ( "server version out of bounds - " + " min: [%d:%d], server: [%d:%d], max: [%d:%d]", + ssl->conf->min_major_ver, ssl->conf->min_minor_ver, + ssl->major_ver, ssl->minor_ver, + ssl->conf->max_major_ver, ssl->conf->max_minor_ver ) ); - MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, version", buf + 0, 2 ); - mbedtls_ssl_read_version( &major_ver, &minor_ver, - mbedtls_ssl_conf_get_transport( ssl->conf ), - buf + 0 ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION ); - if( mbedtls_ssl_ver_lt( major_ver, - mbedtls_ssl_conf_get_min_major_ver( ssl->conf ) ) || - mbedtls_ssl_ver_lt( minor_ver, - mbedtls_ssl_conf_get_min_minor_ver( ssl->conf ) ) || - mbedtls_ssl_ver_gt( major_ver, - mbedtls_ssl_conf_get_max_major_ver( ssl->conf ) ) || - mbedtls_ssl_ver_gt( minor_ver, - mbedtls_ssl_conf_get_max_minor_ver( ssl->conf ) ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "server version out of bounds - " - " min: [%d:%d], server: [%d:%d], max: [%d:%d]", - mbedtls_ssl_conf_get_min_major_ver( ssl->conf ), - mbedtls_ssl_conf_get_min_minor_ver( ssl->conf ), - major_ver, minor_ver, - mbedtls_ssl_conf_get_max_major_ver( ssl->conf ), - mbedtls_ssl_conf_get_max_minor_ver( ssl->conf ) ) ); - - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION ); - - return( MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION ); - } - -#if !defined(MBEDTLS_SSL_CONF_FIXED_MINOR_VER) - ssl->minor_ver = minor_ver; -#endif /* !MBEDTLS_SSL_CONF_FIXED_MINOR_VER */ - -#if !defined(MBEDTLS_SSL_CONF_FIXED_MAJOR_VER) - ssl->major_ver = major_ver; -#endif /* !MBEDTLS_SSL_CONF_FIXED_MAJOR_VER */ + return( MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION ); } MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, current time: %lu", - (unsigned long)mbedtls_platform_get_uint32_be( &buf[2] ) ) ); + ( (uint32_t) buf[2] << 24 ) | + ( (uint32_t) buf[3] << 16 ) | + ( (uint32_t) buf[4] << 8 ) | + ( (uint32_t) buf[5] ) ) ); - ssl->handshake->hello_random_set = MBEDTLS_SSL_FI_FLAG_UNSET; - - mbedtls_platform_memcpy( ssl->handshake->randbytes + 32, buf + 2, 32 ); - - if( mbedtls_platform_memequal( ssl->handshake->randbytes + 32, buf + 2, 32 ) == 0 ) - { - ssl->handshake->hello_random_set = MBEDTLS_SSL_FI_FLAG_SET; - } + memcpy( ssl->handshake->randbytes + 32, buf + 2, 32 ); n = buf[34]; @@ -1765,21 +1606,22 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) if( n > 32 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); } if( ssl->in_hslen > mbedtls_ssl_hs_hdr_len( ssl ) + 39 + n ) { - ext_len = mbedtls_platform_get_uint16_be( &buf[38 + n] ); + ext_len = ( ( buf[38 + n] << 8 ) + | ( buf[39 + n] ) ); if( ( ext_len > 0 && ext_len < 4 ) || ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) + 40 + n + ext_len ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); } } @@ -1790,13 +1632,13 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) else { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); } /* ciphersuite (used later) */ - i = (int)mbedtls_platform_get_uint16_be( &buf[ 35 + n ] ); + i = ( buf[35 + n] << 8 ) | buf[36 + n]; /* * Read and check compression @@ -1805,7 +1647,12 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) #if defined(MBEDTLS_ZLIB_SUPPORT) /* See comments in ssl_write_client_hello() */ - accept_comp = MBEDTLS_SSL_TRANSPORT_IS_TLS( ssl->conf->transport ); +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + accept_comp = 0; + else +#endif + accept_comp = 1; if( comp != MBEDTLS_SSL_COMPRESS_NULL && ( comp != MBEDTLS_SSL_COMPRESS_DEFLATE || accept_comp == 0 ) ) @@ -1814,85 +1661,66 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) #endif/* MBEDTLS_ZLIB_SUPPORT */ { MBEDTLS_SSL_DEBUG_MSG( 1, ( "server hello, bad compression: %d", comp ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); } /* * Initialize update checksum functions */ - server_suite_info = mbedtls_ssl_ciphersuite_from_id( i ); -#if !defined(MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE) - ssl->handshake->ciphersuite_info = server_suite_info; -#endif - if( server_suite_info == MBEDTLS_SSL_CIPHERSUITE_INVALID_HANDLE ) + ssl->transform_negotiate->ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( i ); + + if( ssl->transform_negotiate->ciphersuite_info == NULL ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "ciphersuite info for %04x not found", i ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR ); return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); } + mbedtls_ssl_optimize_checksum( ssl, ssl->transform_negotiate->ciphersuite_info ); + MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, session id len.: %d", n ) ); MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, session id", buf + 35, n ); /* * Check if the session can be resumed - * - * We're only resuming a session if it was requested (handshake->resume - * already set to 1 by mbedtls_ssl_set_session()), and further conditions - * are satisfied (not renegotiating, ID and ciphersuite match, etc). - * - * Update handshake->resume to the value it will keep for the rest of the - * handshake, and that will be used to determine the relative order - * client/server last flights, as well as in handshake_wrapup(). */ -#if !defined(MBEDTLS_SSL_NO_SESSION_RESUMPTION) - if( n == 0 || - mbedtls_ssl_get_renego_status( ssl ) != MBEDTLS_SSL_INITIAL_HANDSHAKE || - mbedtls_ssl_session_get_ciphersuite( ssl->session_negotiate ) != i || - mbedtls_ssl_session_get_compression( ssl->session_negotiate ) != comp || + if( ssl->handshake->resume == 0 || n == 0 || +#if defined(MBEDTLS_SSL_RENEGOTIATION) + ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE || +#endif + ssl->session_negotiate->ciphersuite != i || + ssl->session_negotiate->compression != comp || ssl->session_negotiate->id_len != n || - mbedtls_platform_memequal( ssl->session_negotiate->id, buf + 35, n ) != 0 ) + memcmp( ssl->session_negotiate->id, buf + 35, n ) != 0 ) { - ssl->handshake->resume = MBEDTLS_SSL_FI_FLAG_UNSET; + ssl->state++; + ssl->handshake->resume = 0; +#if defined(MBEDTLS_HAVE_TIME) + ssl->session_negotiate->start = mbedtls_time( NULL ); +#endif + ssl->session_negotiate->ciphersuite = i; + ssl->session_negotiate->compression = comp; + ssl->session_negotiate->id_len = n; + memcpy( ssl->session_negotiate->id, buf + 35, n ); } -#endif /* !MBEDTLS_SSL_NO_SESSION_RESUMPTION */ - - if( mbedtls_ssl_handshake_get_resume( ssl->handshake ) == MBEDTLS_SSL_FI_FLAG_SET ) + else { - /* Resume a session */ ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC; if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR ); return( ret ); } } - else - { - /* Start a new session */ - ssl->state = MBEDTLS_SSL_SERVER_CERTIFICATE; -#if defined(MBEDTLS_HAVE_TIME) - ssl->session_negotiate->start = mbedtls_time( NULL ); -#endif -#if !defined(MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE) - ssl->session_negotiate->ciphersuite = i; -#endif /* MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE */ -#if defined(MBEDTLS_ZLIB_SUPPORT) - ssl->session_negotiate->compression = comp; -#endif - ssl->session_negotiate->id_len = n; - /* Not using more secure mbedtls_platform_memcpy as id is public */ - memcpy( ssl->session_negotiate->id, buf + 35, n ); - } MBEDTLS_SSL_DEBUG_MSG( 3, ( "%s session has been resumed", - mbedtls_ssl_handshake_get_resume( ssl->handshake ) ? "a" : "no" ) ); + ssl->handshake->resume ? "a" : "no" ) ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %04x", i ) ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, compress alg.: %d", buf[37 + n] ) ); @@ -1900,44 +1728,34 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) /* * Perform cipher suite validation in same way as in ssl_write_client_hello. */ - MBEDTLS_SSL_BEGIN_FOR_EACH_CIPHERSUITE( ssl, - mbedtls_ssl_get_minor_ver( ssl ), - ciphersuite_info ) + i = 0; + while( 1 ) { - if( ssl_validate_ciphersuite( ciphersuite_info, ssl, - mbedtls_ssl_conf_get_min_minor_ver( ssl->conf ), - mbedtls_ssl_conf_get_max_minor_ver( ssl->conf ) ) != 0 ) + if( ssl->conf->ciphersuite_list[ssl->minor_ver][i] == 0 ) { - continue; + 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 ); } - if( ciphersuite_info != server_suite_info ) - continue; - - goto server_picked_valid_suite; + if( ssl->conf->ciphersuite_list[ssl->minor_ver][i++] == + ssl->session_negotiate->ciphersuite ) + { + break; + } } - MBEDTLS_SSL_END_FOR_EACH_CIPHERSUITE - /* If we reach this code-path, the server's chosen ciphersuite - * wasn't among those advertised by us. */ - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); - -server_picked_valid_suite: - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %s", - mbedtls_ssl_suite_get_name( server_suite_info ) ) ); - -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( mbedtls_ssl_suite_get_key_exchange( server_suite_info ) == - MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA && - mbedtls_ssl_get_minor_ver( ssl ) == MBEDTLS_SSL_MINOR_VERSION_3 ) + 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 ) { - ssl->handshake->ecrs_enabled = 1; + 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 ); } -#endif + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %s", suite_info->name ) ); if( comp != MBEDTLS_SSL_COMPRESS_NULL #if defined(MBEDTLS_ZLIB_SUPPORT) @@ -1946,31 +1764,28 @@ server_picked_valid_suite: ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); } -#if defined(MBEDTLS_ZLIB_SUPPORT) ssl->session_negotiate->compression = comp; -#endif ext = buf + 40 + n; - MBEDTLS_SSL_DEBUG_MSG( 2, ( "server hello, total extension length: %d", - ext_len ) ); + MBEDTLS_SSL_DEBUG_MSG( 2, ( "server hello, total extension length: %d", ext_len ) ); while( ext_len ) { - unsigned int ext_id = (unsigned int) - mbedtls_platform_get_uint16_be( ext ); - unsigned int ext_size = (unsigned int) - mbedtls_platform_get_uint16_be( &ext[2] ); + unsigned int ext_id = ( ( ext[0] << 8 ) + | ( ext[1] ) ); + unsigned int ext_size = ( ( ext[2] << 8 ) + | ( ext[3] ) ); if( ext_size + 4 > ext_len ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); } @@ -2014,20 +1829,6 @@ server_picked_valid_suite: break; #endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - case MBEDTLS_TLS_EXT_CID: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "found CID extension" ) ); - - if( ( ret = ssl_parse_cid_ext( ssl, - ext + 4, - ext_size ) ) != 0 ) - { - return( ret ); - } - - break; -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) case MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC: MBEDTLS_SSL_DEBUG_MSG( 3, ( "found encrypt_then_mac extension" ) ); @@ -2050,7 +1851,6 @@ server_picked_valid_suite: { return( ret ); } - extended_ms_seen = 1; break; #endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ @@ -2068,8 +1868,7 @@ server_picked_valid_suite: break; #endif /* MBEDTLS_SSL_SESSION_TICKETS */ -#if defined(MBEDTLS_USE_TINYCRYPT) || \ - defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ +#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) case MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS: MBEDTLS_SSL_DEBUG_MSG( 3, ( "found supported_point_formats extension" ) ); @@ -2126,8 +1925,7 @@ server_picked_valid_suite: * Renegotiation security checks */ if( ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && - mbedtls_ssl_conf_get_allow_legacy_renegotiation( ssl->conf ) == - MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE ) + ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation, breaking off handshake" ) ); handshake_failure = 1; @@ -2142,8 +1940,7 @@ server_picked_valid_suite: } else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && - mbedtls_ssl_conf_get_allow_legacy_renegotiation( ssl->conf ) == - MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION ) + ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation not allowed" ) ); handshake_failure = 1; @@ -2157,33 +1954,10 @@ server_picked_valid_suite: } #endif /* MBEDTLS_SSL_RENEGOTIATION */ - /* - * Check if extended master secret is being enforced - */ -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) - if( mbedtls_ssl_conf_get_ems( ssl->conf ) == - MBEDTLS_SSL_EXTENDED_MS_ENABLED ) - { - if( extended_ms_seen ) - { -#if !defined(MBEDTLS_SSL_EXTENDED_MS_ENFORCED) - ssl->handshake->extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED; -#endif /* !MBEDTLS_SSL_EXTENDED_MS_ENFORCED */ - } - else if( mbedtls_ssl_conf_get_ems_enforced( ssl->conf ) == - MBEDTLS_SSL_EXTENDED_MS_ENFORCE_ENABLED ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "Peer not offering extended master " - "secret, while it is enforced") ); - handshake_failure = 1; - } - } -#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ - if( handshake_failure == 1 ) { - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); } @@ -2231,23 +2005,16 @@ static int ssl_parse_server_dh_params( mbedtls_ssl_context *ssl, unsigned char * #endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED || MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ -#if defined(MBEDTLS_ECDH_C) && \ - ( defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) ) +#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) static int ssl_check_server_ecdh_params( const mbedtls_ssl_context *ssl ) { const mbedtls_ecp_curve_info *curve_info; - mbedtls_ecp_group_id grp_id; -#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) - grp_id = ssl->handshake->ecdh_ctx.grp.id; -#else - grp_id = ssl->handshake->ecdh_ctx.grp_id; -#endif - curve_info = mbedtls_ecp_curve_info_from_grp_id( grp_id ); + curve_info = mbedtls_ecp_curve_info_from_grp_id( ssl->handshake->ecdh_ctx.grp.id ); if( curve_info == NULL ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); @@ -2257,29 +2024,26 @@ static int ssl_check_server_ecdh_params( const mbedtls_ssl_context *ssl ) MBEDTLS_SSL_DEBUG_MSG( 2, ( "ECDH curve: %s", curve_info->name ) ); #if defined(MBEDTLS_ECP_C) - if( mbedtls_ssl_check_curve( ssl, grp_id ) != 0 ) + if( mbedtls_ssl_check_curve( ssl, ssl->handshake->ecdh_ctx.grp.id ) != 0 ) #else if( ssl->handshake->ecdh_ctx.grp.nbits < 163 || ssl->handshake->ecdh_ctx.grp.nbits > 521 ) #endif return( -1 ); - MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx, - MBEDTLS_DEBUG_ECDH_QP ); + MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Qp", &ssl->handshake->ecdh_ctx.Qp ); return( 0 ); } -#endif /* MBEDTLS_ECDH_C && - ( MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED ) */ +#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || + MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED || + MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED || + MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED || + MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ -#if defined(MBEDTLS_ECDH_C) && \ - ( defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)) +#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) static int ssl_parse_server_ecdh_params( mbedtls_ssl_context *ssl, unsigned char **p, unsigned char *end ) @@ -2309,10 +2073,9 @@ static int ssl_parse_server_ecdh_params( mbedtls_ssl_context *ssl, return( ret ); } -#endif /* MBEDTLS_ECDH_C && - ( MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED ) */ +#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || + MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED || + MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) static int ssl_parse_server_psk_hint( mbedtls_ssl_context *ssl, @@ -2334,7 +2097,7 @@ static int ssl_parse_server_psk_hint( mbedtls_ssl_context *ssl, "(psk_identity_hint length)" ) ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); } - len = mbedtls_platform_get_uint16_be( *p ); + len = (*p)[0] << 8 | (*p)[1]; *p += 2; if( end - (*p) < (int) len ) @@ -2358,156 +2121,78 @@ static int ssl_parse_server_psk_hint( mbedtls_ssl_context *ssl, #if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) - -/* This function assumes that `out` points to a writable buffer - * of size 48 Bytes if `add_length_tag == 0` and size 50 Bytes - * if `add_length_tag != 0`. */ -static int ssl_rsa_generate_partial_pms( mbedtls_ssl_context *ssl, - unsigned char* out, - unsigned add_length_tag ) -{ - volatile int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; - - /* - * Generate (part of) the pre-master secret as - * struct { - * [ uint16 length(48) ] - * ProtocolVersion client_version; - * opaque random[46]; - * } PreMasterSecret; - */ - - if( add_length_tag ) - { - out[0] = 0; - out[1] = 48; - out += 2; - } - - mbedtls_ssl_write_version( mbedtls_ssl_conf_get_max_major_ver( ssl->conf ), - mbedtls_ssl_conf_get_max_minor_ver( ssl->conf ), - mbedtls_ssl_conf_get_transport( ssl->conf ), out ); - - ret = mbedtls_ssl_conf_get_frng( ssl->conf ) - ( mbedtls_ssl_conf_get_prng( ssl->conf ), out + 2, 46 ); - - if( ret == 0 ) - { - mbedtls_platform_random_delay(); - if( ret == 0 ) - { - ssl->handshake->premaster_generated = MBEDTLS_SSL_FI_FLAG_SET; - return( 0 ); - } - else - { - ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; - } - } - - MBEDTLS_SSL_DEBUG_RET( 1, "f_rng", ret ); - return( ret ); -} - /* - * Encrypt the randomly chosen part of the Premaster Secret with the - * server's RSA key and write it to the provided buffer. + * Generate a pre-master secret and encrypt it with the server's RSA key */ -static int ssl_rsa_encrypt_partial_pms( mbedtls_ssl_context *ssl, - unsigned char const *ppms, - unsigned char *out, size_t buflen, - size_t *olen ) +static int ssl_write_encrypted_pms( mbedtls_ssl_context *ssl, + size_t offset, size_t *olen, + size_t pms_offset ) { - volatile int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; - size_t len_bytes = mbedtls_ssl_get_minor_ver( ssl ) == - MBEDTLS_SSL_MINOR_VERSION_0 ? 0 : 2; - mbedtls_pk_context *peer_pk = NULL; + int ret; + size_t len_bytes = ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ? 0 : 2; + unsigned char *p = ssl->handshake->premaster + pms_offset; - if( buflen < len_bytes ) + if( offset + len_bytes > MBEDTLS_SSL_MAX_CONTENT_LEN ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small for encrypted pms" ) ); return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); } -#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - if( ssl->handshake->got_peer_pubkey ) - peer_pk = &ssl->handshake->peer_pubkey; -#else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - if( ssl->session_negotiate->peer_cert != NULL ) - { - ret = mbedtls_x509_crt_pk_acquire( ssl->session_negotiate->peer_cert, - &peer_pk ); - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_x509_crt_pk_acquire", ret ); - return( ret ); - } - } -#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ + /* + * Generate (part of) the pre-master as + * struct { + * ProtocolVersion client_version; + * opaque random[46]; + * } PreMasterSecret; + */ + mbedtls_ssl_write_version( ssl->conf->max_major_ver, ssl->conf->max_minor_ver, + ssl->conf->transport, p ); - if( peer_pk == NULL ) + if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p + 2, 46 ) ) != 0 ) { - /* Should never happen */ - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + MBEDTLS_SSL_DEBUG_RET( 1, "f_rng", ret ); + return( ret ); + } + + ssl->handshake->pmslen = 48; + + if( ssl->session_negotiate->peer_cert == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "certificate required" ) ); + return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); } /* - * Encrypt the partial premaster secret and write it out. + * Now write it out, encrypted */ - if( ! mbedtls_pk_can_do( peer_pk, MBEDTLS_PK_RSA ) ) + if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk, + MBEDTLS_PK_RSA ) ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "certificate key type mismatch" ) ); - ret = MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH; - goto cleanup; + return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH ); } - ret = mbedtls_pk_encrypt( peer_pk, - ppms, 48, out + len_bytes, - olen, buflen - len_bytes, - mbedtls_ssl_conf_get_frng( ssl->conf ), - mbedtls_ssl_conf_get_prng( ssl->conf ) ); - - if( ret == 0 ) - { - mbedtls_platform_random_delay(); - if( ret == 0 ) - { - ssl->handshake->premaster_generated = MBEDTLS_SSL_FI_FLAG_SET; - } - else - { - ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_rsa_pkcs1_encrypt", ret ); - goto cleanup; - } - } - else + if( ( ret = mbedtls_pk_encrypt( &ssl->session_negotiate->peer_cert->pk, + p, ssl->handshake->pmslen, + ssl->out_msg + offset + len_bytes, olen, + MBEDTLS_SSL_MAX_CONTENT_LEN - offset - len_bytes, + ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_rsa_pkcs1_encrypt", ret ); - goto cleanup; + return( ret ); } - #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ defined(MBEDTLS_SSL_PROTO_TLS1_2) if( len_bytes == 2 ) { - (void)mbedtls_platform_put_uint16_be( out, *olen ); + ssl->out_msg[offset+0] = (unsigned char)( *olen >> 8 ); + ssl->out_msg[offset+1] = (unsigned char)( *olen ); *olen += 2; } #endif -cleanup: - -#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - /* We don't need the peer's public key anymore. Free it. */ - mbedtls_pk_free( peer_pk ); -#else - mbedtls_x509_crt_pk_release( ssl->session_negotiate->peer_cert ); -#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - - return( ret ); + return( 0 ); } #endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED || MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ @@ -2527,7 +2212,7 @@ static int ssl_parse_signature_algorithm( mbedtls_ssl_context *ssl, *pk_alg = MBEDTLS_PK_NONE; /* Only in TLS 1.2 */ - if( mbedtls_ssl_get_minor_ver( ssl ) != MBEDTLS_SSL_MINOR_VERSION_3 ) + if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 ) { return( 0 ); } @@ -2581,253 +2266,135 @@ static int ssl_parse_signature_algorithm( mbedtls_ssl_context *ssl, static int ssl_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl ) { int ret; - mbedtls_pk_context * peer_pk; + const mbedtls_ecp_keypair *peer_key; - /* Acquire peer's PK context: In case we store peer's entire - * certificate, we extract the context from it. Otherwise, - * we can use a temporary copy we've made for the purpose of - * signature verification. */ - -#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - peer_pk = &ssl->handshake->peer_pubkey; -#else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ if( ssl->session_negotiate->peer_cert == NULL ) { - /* Should never happen */ - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + MBEDTLS_SSL_DEBUG_MSG( 2, ( "certificate required" ) ); + return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); } - ret = mbedtls_x509_crt_pk_acquire( ssl->session_negotiate->peer_cert, - &peer_pk ); - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_x509_crt_pk_acquire", ret ); - return( ret ); - } -#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - - if( ! mbedtls_pk_can_do( peer_pk, MBEDTLS_PK_ECKEY ) ) + if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk, + MBEDTLS_PK_ECKEY ) ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "server key not ECDH capable" ) ); - ret = MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH; - goto cleanup; + return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH ); } - /* Extract ECDH parameters from peer's PK context. */ + peer_key = mbedtls_pk_ec( ssl->session_negotiate->peer_cert->pk ); + if( ( ret = mbedtls_ecdh_get_params( &ssl->handshake->ecdh_ctx, peer_key, + MBEDTLS_ECDH_THEIRS ) ) != 0 ) { -#if defined(MBEDTLS_USE_TINYCRYPT) - mbedtls_uecc_keypair *peer_key = - mbedtls_pk_uecc( *peer_pk ); - - mbedtls_platform_memcpy( ssl->handshake->ecdh_peerkey, - peer_key->public_key, - sizeof( ssl->handshake->ecdh_peerkey ) ); -#else /* MBEDTLS_USE_TINYCRYPT */ - const mbedtls_ecp_keypair *peer_key; - peer_key = mbedtls_pk_ec( *peer_pk ); - - if( ( ret = mbedtls_ecdh_get_params( &ssl->handshake->ecdh_ctx, peer_key, - MBEDTLS_ECDH_THEIRS ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ecdh_get_params" ), ret ); - goto cleanup; - } - - if( ssl_check_server_ecdh_params( ssl ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server certificate (ECDH curve)" ) ); - ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE; - goto cleanup; - } -#endif /* MBEDTLS_USE_TINYCRYPT */ + MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ecdh_get_params" ), ret ); + return( ret ); } -cleanup: - -#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - /* We don't need the peer's public key anymore. Free it, - * so that more RAM is available for upcoming expensive - * operations like ECDHE. */ - mbedtls_pk_free( peer_pk ); -#else - mbedtls_x509_crt_pk_release( ssl->session_negotiate->peer_cert ); -#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ + if( ssl_check_server_ecdh_params( ssl ) != 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server certificate (ECDH curve)" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ); + } return( ret ); } #endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ -/* - * - * STATE HANDLING: ServerKeyExchange - * - */ - -/* - * Overview - */ - -/* Main entry point; orchestrates the other functions. */ -static int ssl_process_in_server_key_exchange( mbedtls_ssl_context *ssl ); - -/* Coordination: - * Check if a ServerKeyExchange message is expected, and skip if not. - * Returns a negative code on failure, or - * - SSL_SRV_KEY_EXCHANGE_SKIP - * - SSL_SRV_KEY_EXCHANGE_EXPECTED - * indicating if a ServerKeyExchange message is expected or not. - */ -#define SSL_SRV_KEY_EXCHANGE_SKIP 0 -#define SSL_SRV_KEY_EXCHANGE_EXPECTED 1 -static int ssl_in_server_key_exchange_coordinate( mbedtls_ssl_context *ssl ); -/* Preparation - * If applicable, prepare DH parameters from Server certificate. */ -static int ssl_in_server_key_exchange_prepare( mbedtls_ssl_context *ssl ); -/* Parse SrvKeyExchange message and store contents - * (PSK or DH parameters) in handshake structure. */ -static int ssl_in_server_key_exchange_parse( mbedtls_ssl_context *ssl, - unsigned char *buf, - size_t buflen ); -/* Update the handshake state */ -static int ssl_in_server_key_exchange_postprocess( mbedtls_ssl_context *ssl ); - -/* - * Implementation - */ - -static int ssl_in_server_key_exchange_prepare( mbedtls_ssl_context *ssl ) -{ - mbedtls_ssl_ciphersuite_handle_t ciphersuite_info = - mbedtls_ssl_handshake_get_ciphersuite( ssl->handshake ); - ((void) ciphersuite_info); - - /* If applicable, extract static DH parameters from Server CRT. */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) - if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) == - MBEDTLS_KEY_EXCHANGE_ECDH_RSA || - mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) == - MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA ) - { - int ret; - - if( ( ret = ssl_get_ecdh_params_from_cert( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "ssl_get_ecdh_params_from_cert", ret ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); - return( ret ); - } - } -#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ - - return( 0 ); -} - -static int ssl_in_server_key_exchange_coordinate( mbedtls_ssl_context *ssl ) +static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl ) { int ret; - mbedtls_ssl_ciphersuite_handle_t ciphersuite_info = - mbedtls_ssl_handshake_get_ciphersuite( ssl->handshake ); + const mbedtls_ssl_ciphersuite_t *ciphersuite_info = + ssl->transform_negotiate->ciphersuite_info; + unsigned char *p = NULL, *end = NULL; - /* The ServerKeyExchange message is not used for - * - RSA or - * - static ECDH - * ciphersuites. - * It MAY be used in PSK or RSA-PSK. - */ + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server key exchange" ) ); #if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) - if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) == - MBEDTLS_KEY_EXCHANGE_RSA ) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA ) { - return( SSL_SRV_KEY_EXCHANGE_SKIP ); + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse server key exchange" ) ); + ssl->state++; + return( 0 ); } + ((void) p); + ((void) end); #endif #if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) - if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) == - MBEDTLS_KEY_EXCHANGE_ECDH_RSA || - mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) == - MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA ) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_RSA || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA ) { - return( SSL_SRV_KEY_EXCHANGE_SKIP ); + if( ( ret = ssl_get_ecdh_params_from_cert( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "ssl_get_ecdh_params_from_cert", ret ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); + return( ret ); + } + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse server key exchange" ) ); + ssl->state++; + return( 0 ); } + ((void) p); + ((void) end); #endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED || MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ + if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); + return( ret ); + } + + if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); + return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); + } + /* * ServerKeyExchange may be skipped with PSK and RSA-PSK when the server - * doesn't use a psk_identity_hint. Peek at next message to decide whether - * the ServerKeyExchange is being skipped or not. + * doesn't use a psk_identity_hint */ - - if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_PSK || - mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_RSA_PSK ) + if( ssl->in_msg[0] != MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE ) { - if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); - return( ret ); - } - ssl->keep_current_message = 1; - - if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && - ssl->in_msg[0] != MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE ) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ) { /* Current message is probably either * CertificateRequest or ServerHelloDone */ - return( SSL_SRV_KEY_EXCHANGE_SKIP ); + ssl->keep_current_message = 1; + goto exit; } + + MBEDTLS_SSL_DEBUG_MSG( 1, ( "server key exchange message must " + "not be skipped" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); + + return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); } - return( SSL_SRV_KEY_EXCHANGE_EXPECTED ); -} - -static int ssl_in_server_key_exchange_parse( mbedtls_ssl_context *ssl, - unsigned char *buf, - size_t buflen ) -{ - /* - * Initialising to an error value would need a significant - * structural change to provide default flow assumes failure - */ - volatile int ret = 0; - volatile int ret_fi = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; - unsigned char *p; - unsigned char *end; - - mbedtls_ssl_ciphersuite_handle_t ciphersuite_info = - mbedtls_ssl_handshake_get_ciphersuite( ssl->handshake ); - - p = buf + mbedtls_ssl_hs_hdr_len( ssl ); - end = buf + buflen; - - MBEDTLS_SSL_DEBUG_BUF( 3, "server key exchange", p, end - p ); + p = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ); + end = ssl->in_msg + ssl->in_hslen; + MBEDTLS_SSL_DEBUG_BUF( 3, "server key exchange", p, end - p ); #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) - if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_PSK || - mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_RSA_PSK || - mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_DHE_PSK || - mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ) { if( ssl_parse_server_psk_hint( ssl, &p, end ) != 0 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); } } /* FALLTROUGH */ @@ -2835,114 +2402,63 @@ static int ssl_in_server_key_exchange_parse( mbedtls_ssl_context *ssl, #if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \ defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) - if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_PSK || - mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_RSA_PSK ) - { + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ) ; /* nothing more to do */ - } else #endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED || MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ #if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) - if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_DHE_RSA || - mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_DHE_PSK ) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ) { if( ssl_parse_server_dh_params( ssl, &p, end ) != 0 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); } } else #endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED || MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ -#if defined(MBEDTLS_USE_TINYCRYPT) - if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA || - mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || - mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA ) - { - static const unsigned char ecdh_group[] = { - MBEDTLS_SSL_EC_TLS_NAMED_CURVE, - 0 /* high bits of secp256r1 TLS ID */, - 23 /* low bits of secp256r1 TLS ID */, - }; - - /* Check for fixed ECDH parameter preamble. */ - if( (size_t)( end - p ) < sizeof( ecdh_group ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad server key exchange (too short)" ) ); - return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); - } - - if( mbedtls_platform_memequal( p, ecdh_group, sizeof( ecdh_group ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad server key exchange (unexpected header)" ) ); - return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); - } - p += sizeof( ecdh_group ); - - /* Read server's key share. */ - if( mbedtls_ssl_ecdh_read_peerkey( ssl, &p, end ) != 0 ) - return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); - } - else -#endif /* MBEDTLS_USE_TINYCRYPT */ -#if defined(MBEDTLS_ECDH_C) && \ - ( defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ) ) - if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA || - mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || - mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA ) +#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA ) { if( ssl_parse_server_ecdh_params( ssl, &p, end ) != 0 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); } } else -#endif /* MBEDTLS_ECDH_C && - ( MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ) */ +#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || + MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED || + MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) { ret = mbedtls_ecjpake_read_round_two( &ssl->handshake->ecjpake_ctx, p, end - p ); if( ret != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_two", ret ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); } } else #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ { - ((void) ret); - ((void) ret_fi); - ((void) p); - ((void) end); - ((void) ciphersuite_info); MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); } @@ -2956,30 +2472,27 @@ static int ssl_in_server_key_exchange_parse( mbedtls_ssl_context *ssl, mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE; unsigned char *params = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ); size_t params_len = p - params; - void * volatile rs_ctx = NULL; - - mbedtls_pk_context * peer_pk; /* * Handle the digitally-signed structure */ #if defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( mbedtls_ssl_get_minor_ver( ssl ) == MBEDTLS_SSL_MINOR_VERSION_3 ) + if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) { if( ssl_parse_signature_algorithm( ssl, &p, end, &md_alg, &pk_alg ) != 0 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); } if( pk_alg != mbedtls_ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info ) ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); } } @@ -2987,8 +2500,7 @@ static int ssl_in_server_key_exchange_parse( mbedtls_ssl_context *ssl, #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ defined(MBEDTLS_SSL_PROTO_TLS1_1) - if( mbedtls_ssl_ver_lt( mbedtls_ssl_get_minor_ver( ssl ), - MBEDTLS_SSL_MINOR_VERSION_3 ) ) + if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 ) { pk_alg = mbedtls_ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info ); @@ -3006,23 +2518,21 @@ static int ssl_in_server_key_exchange_parse( mbedtls_ssl_context *ssl, /* * Read signature */ - if( p > end - 2 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); } - - sig_len = mbedtls_platform_get_uint16_be( p ); + sig_len = ( p[0] << 8 ) | p[1]; p += 2; if( p != end - sig_len ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); } @@ -3048,9 +2558,10 @@ static int ssl_in_server_key_exchange_parse( mbedtls_ssl_context *ssl, defined(MBEDTLS_SSL_PROTO_TLS1_2) if( md_alg != MBEDTLS_MD_NONE ) { - ret = mbedtls_ssl_get_key_exchange_md_tls1_2( ssl, hash, &hashlen, - params, params_len, - md_alg ); + /* Info from md_alg will be used instead */ + hashlen = 0; + ret = mbedtls_ssl_get_key_exchange_md_tls1_2( ssl, hash, params, + params_len, md_alg ); if( ret != 0 ) return( ret ); } @@ -3062,180 +2573,59 @@ static int ssl_in_server_key_exchange_parse( mbedtls_ssl_context *ssl, return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); } - MBEDTLS_SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen ); + MBEDTLS_SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen != 0 ? hashlen : + (unsigned int) ( mbedtls_md_get_size( mbedtls_md_info_from_type( md_alg ) ) ) ); -#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - peer_pk = &ssl->handshake->peer_pubkey; -#else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ if( ssl->session_negotiate->peer_cert == NULL ) { - /* Should never happen */ - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + MBEDTLS_SSL_DEBUG_MSG( 2, ( "certificate required" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); + return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); } - ret = mbedtls_x509_crt_pk_acquire( ssl->session_negotiate->peer_cert, - &peer_pk ); - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_x509_crt_pk_acquire", ret ); - return( ret ); - } -#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - /* * Verify signature */ - if( !mbedtls_pk_can_do( peer_pk, pk_alg ) ) + if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk, pk_alg ) ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); -#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - mbedtls_x509_crt_pk_release( ssl->session_negotiate->peer_cert ); -#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH ); } -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( ssl->handshake->ecrs_enabled ) - rs_ctx = &ssl->handshake->ecrs_ctx.pk; -#endif - - ret = mbedtls_pk_verify_restartable( peer_pk, - md_alg, hash, hashlen, p, sig_len, rs_ctx ); - - if( ret == 0 ) + if( ( ret = mbedtls_pk_verify( &ssl->session_negotiate->peer_cert->pk, + md_alg, hash, hashlen, p, sig_len ) ) != 0 ) { - mbedtls_platform_random_delay(); - - if( rs_ctx == NULL ) - { - ret_fi = mbedtls_pk_verify_restartable( peer_pk, - md_alg, hash, hashlen, p, sig_len, rs_ctx ); - } - else - { - ret_fi = 0; - } - if( ret == 0 && ret_fi == 0 ) - { -#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - /* We don't need the peer's public key anymore. Free it, - * so that more RAM is available for upcoming expensive - * operations like ECDHE. */ - mbedtls_pk_free( peer_pk ); -#else - mbedtls_x509_crt_pk_release( - ssl->session_negotiate->peer_cert ); -#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - return( ret ); - } - else - { - return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); - } - } -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS ) -#endif - { - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR ); - } + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR ); MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_verify", ret ); -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) - ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS; -#endif -#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - mbedtls_x509_crt_pk_release( ssl->session_negotiate->peer_cert ); -#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - + return( ret ); + } } #endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */ - return( ret ); -} - -static int ssl_in_server_key_exchange_postprocess( mbedtls_ssl_context *ssl ) -{ - ssl->state = MBEDTLS_SSL_CERTIFICATE_REQUEST; - return( 0 ); -} - -static int ssl_process_in_server_key_exchange( mbedtls_ssl_context *ssl ) -{ - int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server key exchange" ) ); - - /* Preparation: - * Potentially extract DH parameters from Server's certificate. - * - * Consider: Why don't we do this as post-processing after - * the server certificate has been read? - */ - MBEDTLS_SSL_CHK( ssl_in_server_key_exchange_prepare( ssl ) ); - - /* Coordination: - * Check if we expect a ServerKeyExchange */ - MBEDTLS_SSL_CHK( ssl_in_server_key_exchange_coordinate( ssl ) ); - - if( ret == SSL_SRV_KEY_EXCHANGE_EXPECTED ) - { - /* Reading step */ - if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); - return( ret ); - } - - if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE || - ssl->in_msg[0] != MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); - ret = MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; - goto cleanup; - } - else - { - MBEDTLS_SSL_CHK( ssl_in_server_key_exchange_parse( ssl, ssl->in_msg, - ssl->in_hslen ) ); - } - } - else if( ret == SSL_SRV_KEY_EXCHANGE_SKIP ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse server key exchange" ) ); - } - - /* Update state */ - MBEDTLS_SSL_CHK( ssl_in_server_key_exchange_postprocess( ssl ) ); - -cleanup: - -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( ret == MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS ) - ssl->keep_current_message = 1; -#endif +exit: + ssl->state++; MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse server key exchange" ) ); - return( ret ); + + return( 0 ); } #if ! defined(MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED) static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl ) { - mbedtls_ssl_ciphersuite_handle_t ciphersuite_info = - mbedtls_ssl_handshake_get_ciphersuite( ssl->handshake ); + const mbedtls_ssl_ciphersuite_t *ciphersuite_info = + ssl->transform_negotiate->ciphersuite_info; MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) ); if( ! mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) ) { MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate request" ) ); - ssl->state = MBEDTLS_SSL_SERVER_HELLO_DONE; + ssl->state++; return( 0 ); } @@ -3249,19 +2639,19 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl ) unsigned char *buf; size_t n = 0; size_t cert_type_len = 0, dn_len = 0; - mbedtls_ssl_ciphersuite_handle_t ciphersuite_info = - mbedtls_ssl_handshake_get_ciphersuite( ssl->handshake ); + const mbedtls_ssl_ciphersuite_t *ciphersuite_info = + ssl->transform_negotiate->ciphersuite_info; MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) ); if( ! mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) ) { MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate request" ) ); - ssl->state = MBEDTLS_SSL_SERVER_HELLO_DONE; + ssl->state++; return( 0 ); } - if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 ) + if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); return( ret ); @@ -3270,12 +2660,12 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl ) if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); } - ssl->state = MBEDTLS_SSL_SERVER_HELLO_DONE; + ssl->state++; ssl->client_auth = ( ssl->in_msg[0] == MBEDTLS_SSL_HS_CERTIFICATE_REQUEST ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "got %s certificate request", @@ -3318,8 +2708,8 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl ) if( ssl->in_hslen <= mbedtls_ssl_hs_hdr_len( ssl ) ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST ); } cert_type_len = buf[mbedtls_ssl_hs_hdr_len( ssl )]; @@ -3338,16 +2728,17 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl ) if( ssl->in_hslen <= mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST ); } /* supported_signature_algorithms */ #if defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( mbedtls_ssl_get_minor_ver( ssl ) == MBEDTLS_SSL_MINOR_VERSION_3 ) + if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) { - size_t sig_alg_len = mbedtls_platform_get_uint16_be( &buf[mbedtls_ssl_hs_hdr_len( ssl ) + 1 + n] ); + size_t sig_alg_len = ( ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 1 + n] << 8 ) + | ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n] ) ); #if defined(MBEDTLS_DEBUG_C) unsigned char* sig_alg; size_t i; @@ -3368,8 +2759,8 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl ) 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_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST ); } @@ -3387,14 +2778,15 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl ) #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ /* certificate_authorities */ - dn_len = mbedtls_platform_get_uint16_be( &buf[mbedtls_ssl_hs_hdr_len( ssl ) + 1 + n] ); + dn_len = ( ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 1 + n] << 8 ) + | ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n] ) ); n += dn_len; if( ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) + 3 + n ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST ); } @@ -3407,11 +2799,11 @@ exit: static int ssl_parse_server_hello_done( mbedtls_ssl_context *ssl ) { - int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; + int ret; MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server hello done" ) ); - if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 ) + if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); return( ret ); @@ -3427,307 +2819,114 @@ static int ssl_parse_server_hello_done( mbedtls_ssl_context *ssl ) ssl->in_msg[0] != MBEDTLS_SSL_HS_SERVER_HELLO_DONE ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello done message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO_DONE ); } - ssl->state = MBEDTLS_SSL_CLIENT_CERTIFICATE; + ssl->state++; #if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) ) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) mbedtls_ssl_recv_flight_completed( ssl ); #endif MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse server hello done" ) ); - return( ret ); -} - -/* - * - * STATE HANDLING: Client Key Exchange - * - */ - -/* - * Overview - */ - -/* Main entry point; orchestrates the other functions */ -static int ssl_process_out_client_key_exchange( mbedtls_ssl_context *ssl ); - -/* Preparation - * - For ECDH: Generate client params and derive premaster secret - * - For RSA-suites: Encrypt PMS - * - For ECJPAKE: Do Round 2 - */ -static int ssl_out_client_key_exchange_prepare( mbedtls_ssl_context *ssl ); -static int ssl_out_client_key_exchange_write( mbedtls_ssl_context *ssl, - unsigned char *buf, - size_t buflen, - size_t *olen ); -static int ssl_out_client_key_exchange_postprocess( mbedtls_ssl_context *ssl ); - -/* - * Implementation - */ - -static int ssl_process_out_client_key_exchange( mbedtls_ssl_context *ssl ) -{ - int ret = 0; - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> process client key exchange" ) ); - -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( ssl->handshake->ecrs_state == ssl_ecrs_cke_ecdh_calc_secret ) - goto cli_key_exchange_postprocess; - - if( ssl->handshake->ecrs_enabled ) - mbedtls_ecdh_enable_restart( &ssl->handshake->ecdh_ctx ); -#endif - - MBEDTLS_SSL_CHK( ssl_out_client_key_exchange_prepare( ssl ) ); - - /* Prepare CertificateVerify message in output buffer. */ - MBEDTLS_SSL_CHK( ssl_out_client_key_exchange_write( ssl, ssl->out_msg, - MBEDTLS_SSL_MAX_CONTENT_LEN, - &ssl->out_msglen ) ); - - ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; - ssl->out_msg[0] = MBEDTLS_SSL_HS_CLIENT_KEY_EXCHANGE; - - /* Calculate secrets and update state */ -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( ssl->handshake->ecrs_enabled ) - ssl->handshake->ecrs_state = ssl_ecrs_cke_ecdh_calc_secret; - -cli_key_exchange_postprocess: -#endif - - ret = ssl_out_client_key_exchange_postprocess( ssl ); -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) - ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS; -#endif /* MBEDTLS_SSL__ECP_RESTARTABLE */ - MBEDTLS_SSL_CHK( ret ); - - /* Dispatch message */ - - MBEDTLS_SSL_CHK( mbedtls_ssl_write_handshake_msg( ssl ) ); - - /* NOTE: For the new messaging layer, the postprocessing step - * might come after the dispatching step if the latter - * doesn't send the message immediately. - * At the moment, we must do the postprocessing - * prior to the dispatching because if the latter - * returns WANT_WRITE, we want the handshake state - * to be updated in order to not enter - * this function again on retry. */ - -cleanup: - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= process client key exchange" ) ); - return( ret ); -} - - - -static int ssl_out_client_key_exchange_prepare( mbedtls_ssl_context *ssl ) -{ - int ret = 0; - mbedtls_ssl_ciphersuite_handle_t ciphersuite_info = - mbedtls_ssl_handshake_get_ciphersuite( ssl->handshake ); - - ((void) ret); - ((void) ciphersuite_info); - - /* TODO: The current API for DH and ECDH does not allow - * to separate public key generation from public key export. - * - * Ideally, we would like to pick the private (EC)DH keys - * in this preparation step, exporting the corresponding - * public key in the writing step only. - * - * The necessary extension of the (EC)DH API is being - * considered, but until then we perform the public - * generation + export in the writing step. - * - */ - -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) - if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_RSA_PSK ) - { - /* For RSA-PSK, the premaster secret is composed of - * - Length tag with value 48, encoded as a uint16 - * - 2 bytes indicating the TLS version - * - 46 randomly chosen bytes - * - the chosen PSK. - * The following call takes care of all but the PSK. */ - ret = ssl_rsa_generate_partial_pms( ssl, ssl->handshake->premaster, - 1 /* Add length tag */ ); - if( ret != 0 ) - return( ret ); - } -#endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) - if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_RSA ) - { - /* For RSA, the premaster secret is composed of - * - 2 bytes indicating the TLS version - * - 46 randomly chosen bytes - * which the following call generates. */ - ret = ssl_rsa_generate_partial_pms( ssl, ssl->handshake->premaster, - 0 /* Omit length tag */ ); - if( ret != 0 ) - return( ret ); - } -#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */ - return( 0 ); } -/* Warning: Despite accepting a length argument, this function is currently - * still lacking some bounds checks and assumes that `buf` has length - * `MBEDTLS_SSL_OUT_CONTENT_LEN`. Eventually, it should be rewritten to work - * with any buffer + length pair, returning MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL - * on insufficient writing space. */ -static int ssl_out_client_key_exchange_write( mbedtls_ssl_context *ssl, - unsigned char *buf, - size_t buflen, - size_t *olen ) +static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl ) { - int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; - unsigned char *p, *end; - size_t n; - mbedtls_ssl_ciphersuite_handle_t ciphersuite_info = - mbedtls_ssl_handshake_get_ciphersuite( ssl->handshake ); + int ret; + size_t i, n; + const mbedtls_ssl_ciphersuite_t *ciphersuite_info = + ssl->transform_negotiate->ciphersuite_info; - /* NOTE: This function will generate different messages - * when it's called multiple times, because it currently - * includes private/public key generation in case of - * (EC)DH ciphersuites. - * - * It is therefore not suitable to be registered as a callback - * for retransmission, if such get introduced at some point. - * - * Also see the documentation of ssl_out_client_key_exchange_prepare(). - */ - - p = buf + 4; - end = buf + buflen; + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write client key exchange" ) ); #if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) - if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_DHE_RSA ) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA ) { /* * DHM key exchange -- send G^X mod P */ n = ssl->handshake->dhm_ctx.len; - if( (size_t)( end - p ) < n + 2 ) - return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); - p = mbedtls_platform_put_uint16_be( p, n ); + ssl->out_msg[4] = (unsigned char)( n >> 8 ); + ssl->out_msg[5] = (unsigned char)( n ); + i = 6; ret = mbedtls_dhm_make_public( &ssl->handshake->dhm_ctx, - (int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ), - p, n, mbedtls_ssl_conf_get_frng( ssl->conf ), - mbedtls_ssl_conf_get_prng( ssl->conf ) ); + (int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ), + &ssl->out_msg[i], n, + ssl->conf->f_rng, ssl->conf->p_rng ); if( ret != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_make_public", ret ); return( ret ); } + MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: X ", &ssl->handshake->dhm_ctx.X ); MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: GX", &ssl->handshake->dhm_ctx.GX ); - p += n; - } - else -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */ -#if defined(MBEDTLS_USE_TINYCRYPT) - if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA || - mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA || - mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_ECDH_RSA || - mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA ) - - { - ((void) n); - ((void) ret); - if( (size_t)( end - p ) < 2 * NUM_ECC_BYTES + 2 ) - return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); - - *p++ = 2 * NUM_ECC_BYTES + 1; - *p++ = 0x04; /* uncompressed point presentation */ - -#if defined(MBEDTLS_SSL_EARLY_KEY_COMPUTATION) - mbedtls_platform_memcpy( p, ssl->handshake->ecdh_publickey, - 2 * NUM_ECC_BYTES ); -#else - ret = uECC_make_key( p, ssl->handshake->ecdh_privkey ); - if( ret == UECC_FAULT_DETECTED ) - return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); - if( ret != UECC_SUCCESS ) - return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); -#endif /* MBEDTLS_SSL_EARLY_KEY_COMPUTATION && MBEDTLS_USE_TINYCRYPT */ - p += 2 * NUM_ECC_BYTES; - } - else -#endif /* MBEDTLS_USE_TINYCRYPT */ -#if defined(MBEDTLS_ECDH_C) && \ - ( defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) ) - if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA || - mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA || - mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_ECDH_RSA || - mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA ) - { - /* - * ECDH key exchange -- generate and send client public value - */ - - /* NOTE: If we ever switch the ECDH stack/API to allow - * independent key generation and export, we should have - * generated our key share in the preparation step, and - * we'd only do the export here. */ - ret = mbedtls_ecdh_make_public( &ssl->handshake->ecdh_ctx, - &n, p, end - p, - mbedtls_ssl_conf_get_frng( ssl->conf ), - mbedtls_ssl_conf_get_prng( ssl->conf ) ); - if( ret != 0 ) + if( ( ret = mbedtls_dhm_calc_secret( &ssl->handshake->dhm_ctx, + ssl->handshake->premaster, + MBEDTLS_PREMASTER_SIZE, + &ssl->handshake->pmslen, + ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_make_public", ret ); -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) - ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS; -#endif + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_calc_secret", ret ); return( ret ); } - MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx, - MBEDTLS_DEBUG_ECDH_Q ); - - p += n; + MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->handshake->dhm_ctx.K ); } else -#endif /* MBEDTLS_ECDH_C && ( - ( MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED ) */ +#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */ +#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_RSA || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA ) + { + /* + * ECDH key exchange -- send client public value + */ + i = 4; + + ret = mbedtls_ecdh_make_public( &ssl->handshake->ecdh_ctx, + &n, + &ssl->out_msg[i], 1000, + ssl->conf->f_rng, ssl->conf->p_rng ); + if( ret != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_make_public", ret ); + return( ret ); + } + + MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Q", &ssl->handshake->ecdh_ctx.Q ); + + if( ( ret = mbedtls_ecdh_calc_secret( &ssl->handshake->ecdh_ctx, + &ssl->handshake->pmslen, + ssl->handshake->premaster, + MBEDTLS_MPI_MAX_SIZE, + ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_calc_secret", ret ); + return( ret ); + } + + MBEDTLS_SSL_DEBUG_MPI( 3, "ECDH: z", &ssl->handshake->ecdh_ctx.z ); + } + else +#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || + MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED || + MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED || + MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) if( mbedtls_ssl_ciphersuite_uses_psk( ciphersuite_info ) ) { @@ -3740,110 +2939,83 @@ static int ssl_out_client_key_exchange_write( mbedtls_ssl_context *ssl, return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED ); } + i = 4; n = ssl->conf->psk_identity_len; - if( buflen < n + 2 ) + + if( i + 2 + n > MBEDTLS_SSL_MAX_CONTENT_LEN ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "psk identity too long or " "SSL buffer too short" ) ); return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); } - p = mbedtls_platform_put_uint16_be( p, n ); + ssl->out_msg[i++] = (unsigned char)( n >> 8 ); + ssl->out_msg[i++] = (unsigned char)( n ); - mbedtls_platform_memcpy( p, ssl->conf->psk_identity, n ); - p += ssl->conf->psk_identity_len; + memcpy( ssl->out_msg + i, ssl->conf->psk_identity, ssl->conf->psk_identity_len ); + i += ssl->conf->psk_identity_len; #if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) - if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_PSK ) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ) { - ((void) ret); - ((void) end); + n = 0; } else #endif #if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) - if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_RSA_PSK ) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ) { - if( ( ret = ssl_rsa_encrypt_partial_pms( ssl, - ssl->handshake->premaster + 2, - p, end - p, &n ) ) != 0 ) + if( ( ret = ssl_write_encrypted_pms( ssl, i, &n, 2 ) ) != 0 ) return( ret ); - p += n; } else #endif #if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) - if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_DHE_PSK ) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ) { /* * ClientDiffieHellmanPublic public (DHM send G^X mod P) */ - ((void) end); - n = ssl->handshake->dhm_ctx.len; - if( buflen < n + 2 ) + if( i + 2 + n > MBEDTLS_SSL_MAX_CONTENT_LEN ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "psk identity or DHM size too long" " or SSL buffer too short" ) ); return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); } - p = mbedtls_platform_put_uint16_be( p, n ); + ssl->out_msg[i++] = (unsigned char)( n >> 8 ); + ssl->out_msg[i++] = (unsigned char)( n ); ret = mbedtls_dhm_make_public( &ssl->handshake->dhm_ctx, - (int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ), - p, n, mbedtls_ssl_conf_get_frng( ssl->conf ), - mbedtls_ssl_conf_get_prng( ssl->conf ) ); + (int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ), + &ssl->out_msg[i], n, + ssl->conf->f_rng, ssl->conf->p_rng ); if( ret != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_make_public", ret ); return( ret ); } - - p += n; } else #endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) - if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ) { -#if defined(MBEDTLS_USE_TINYCRYPT) - ((void) n); - - if( (size_t)( end - p ) < 2 * NUM_ECC_BYTES + 2 ) - return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); - - *p++ = 2 * NUM_ECC_BYTES + 1; - *p++ = 0x04; /* uncompressed point presentation */ - - ret = uECC_make_key( p, ssl->handshake->ecdh_privkey ); - if( ret == UECC_FAULT_DETECTED ) - return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); - if( ret != UECC_SUCCESS ) - return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); - p += 2 * NUM_ECC_BYTES; -#else /* MBEDTLS_USE_TINYCRYPT */ /* * ClientECDiffieHellmanPublic public; */ ret = mbedtls_ecdh_make_public( &ssl->handshake->ecdh_ctx, &n, - p, buflen, - mbedtls_ssl_conf_get_frng( ssl->conf ), - mbedtls_ssl_conf_get_prng( ssl->conf ) ); + &ssl->out_msg[i], MBEDTLS_SSL_MAX_CONTENT_LEN - i, + ssl->conf->f_rng, ssl->conf->p_rng ); if( ret != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_make_public", ret ); return( ret ); } - MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Q", &ssl->handshake->ecdh_ctx.Q ); - p += n; -#endif /* MBEDTLS_USE_TINYCRYPT */ + MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Q", &ssl->handshake->ecdh_ctx.Q ); } else #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ @@ -3851,34 +3023,47 @@ static int ssl_out_client_key_exchange_write( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); } + + if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl, + ciphersuite_info->key_exchange ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_psk_derive_premaster", ret ); + return( ret ); + } } else #endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ #if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) - if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_RSA ) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA ) { - if( ( ret = ssl_rsa_encrypt_partial_pms( ssl, ssl->handshake->premaster, - p, end - p, &n ) ) != 0 ) + i = 4; + if( ( ret = ssl_write_encrypted_pms( ssl, i, &n, 0 ) ) != 0 ) return( ret ); - p += n; } else #endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */ #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) { + i = 4; + ret = mbedtls_ecjpake_write_round_two( &ssl->handshake->ecjpake_ctx, - p, end - p, &n, - mbedtls_ssl_conf_get_frng( ssl->conf ), - mbedtls_ssl_conf_get_prng( ssl->conf ) ); + ssl->out_msg + i, MBEDTLS_SSL_MAX_CONTENT_LEN - i, &n, + ssl->conf->f_rng, ssl->conf->p_rng ); if( ret != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_write_round_two", ret ); return( ret ); } - p += n; + + ret = mbedtls_ecjpake_derive_secret( &ssl->handshake->ecjpake_ctx, + ssl->handshake->premaster, 32, &ssl->handshake->pmslen, + ssl->conf->f_rng, ssl->conf->p_rng ); + if( ret != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_derive_secret", ret ); + return( ret ); + } } else #endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */ @@ -3888,30 +3073,33 @@ static int ssl_out_client_key_exchange_write( mbedtls_ssl_context *ssl, return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); } - *olen = p - buf; + ssl->out_msglen = i + n; + ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; + ssl->out_msg[0] = MBEDTLS_SSL_HS_CLIENT_KEY_EXCHANGE; - return( 0 ); -} + ssl->state++; -static int ssl_out_client_key_exchange_postprocess( mbedtls_ssl_context *ssl ) -{ - int ret; - - if( ( ret = mbedtls_ssl_build_pms( ssl ) ) != 0 ) + if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 ) { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_build_pms", ret ); + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret ); return( ret ); } - ssl->state = MBEDTLS_SSL_CERTIFICATE_VERIFY; + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write client key exchange" ) ); + return( 0 ); } -#if !defined(MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED) +#if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)&& \ + !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl ) { - mbedtls_ssl_ciphersuite_handle_t ciphersuite_info = - mbedtls_ssl_handshake_get_ciphersuite( ssl->handshake ); + const mbedtls_ssl_ciphersuite_t *ciphersuite_info = + ssl->transform_negotiate->ciphersuite_info; int ret; MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) ); @@ -3922,56 +3110,55 @@ static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl ) return( ret ); } - if( !mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) ) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) { MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) ); - ssl->state = MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC; + ssl->state++; return( 0 ); } MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); } -#else /* !MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED */ +#else static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl ) { int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; - mbedtls_ssl_ciphersuite_handle_t ciphersuite_info = - mbedtls_ssl_handshake_get_ciphersuite( ssl->handshake ); + const mbedtls_ssl_ciphersuite_t *ciphersuite_info = + ssl->transform_negotiate->ciphersuite_info; size_t n = 0, offset = 0; unsigned char hash[48]; unsigned char *hash_start = hash; mbedtls_md_type_t md_alg = MBEDTLS_MD_NONE; - size_t hashlen; - void *rs_ctx = NULL; + unsigned int hashlen; MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) ); -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( ssl->handshake->ecrs_enabled && - ssl->handshake->ecrs_state == ssl_ecrs_crt_vrfy_sign ) - { - goto sign; - } -#endif - if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret ); return( ret ); } - if( !mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) ) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) { MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) ); - ssl->state = MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC; + ssl->state++; return( 0 ); } if( ssl->client_auth == 0 || mbedtls_ssl_own_cert( ssl ) == NULL ) { MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) ); - ssl->state = MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC; + ssl->state++; return( 0 ); } @@ -3982,23 +3169,13 @@ static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl ) } /* - * Make a signature of the handshake digests + * Make an RSA signature of the handshake digests */ -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( ssl->handshake->ecrs_enabled ) - ssl->handshake->ecrs_state = ssl_ecrs_crt_vrfy_sign; - -sign: -#endif - - mbedtls_ssl_calc_verify( - mbedtls_ssl_get_minor_ver( ssl ), - mbedtls_ssl_suite_get_mac( ciphersuite_info ), - ssl, hash, &hashlen ); + ssl->handshake->calc_verify( ssl, hash ); #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ defined(MBEDTLS_SSL_PROTO_TLS1_1) - if( mbedtls_ssl_get_minor_ver( ssl ) != MBEDTLS_SSL_MINOR_VERSION_3 ) + if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 ) { /* * digitally-signed struct { @@ -4012,6 +3189,7 @@ sign: * sha_hash * SHA(handshake_messages); */ + hashlen = 36; md_alg = MBEDTLS_MD_NONE; /* @@ -4028,7 +3206,7 @@ sign: #endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || \ MBEDTLS_SSL_PROTO_TLS1_1 */ #if defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( mbedtls_ssl_get_minor_ver( ssl ) == MBEDTLS_SSL_MINOR_VERSION_3 ) + if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) { /* * digitally-signed struct { @@ -4045,9 +3223,8 @@ sign: * Reason: Otherwise we should have running hashes for SHA512 and SHA224 * in order to satisfy 'weird' needs from the server side. */ - if( mbedtls_ssl_suite_get_mac( - mbedtls_ssl_handshake_get_ciphersuite( ssl->handshake ) ) - == MBEDTLS_MD_SHA384 ) + if( ssl->transform_negotiate->ciphersuite_info->mac == + MBEDTLS_MD_SHA384 ) { md_alg = MBEDTLS_MD_SHA384; ssl->out_msg[4] = MBEDTLS_SSL_HASH_SHA384; @@ -4070,36 +3247,26 @@ sign: return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); } -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( ssl->handshake->ecrs_enabled ) - rs_ctx = &ssl->handshake->ecrs_ctx.pk; -#endif - - if( ( ret = mbedtls_pk_sign_restartable( mbedtls_ssl_own_key( ssl ), - md_alg, hash_start, hashlen, + if( ( ret = mbedtls_pk_sign( mbedtls_ssl_own_key( ssl ), md_alg, hash_start, hashlen, ssl->out_msg + 6 + offset, &n, - mbedtls_ssl_conf_get_frng( ssl->conf ), - mbedtls_ssl_conf_get_prng( ssl->conf ), rs_ctx ) ) != 0 ) + ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_sign", ret ); -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) - ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS; -#endif return( ret ); } - (void)mbedtls_platform_put_uint16_be( &ssl->out_msg[4 + offset], n ); + ssl->out_msg[4 + offset] = (unsigned char)( n >> 8 ); + ssl->out_msg[5 + offset] = (unsigned char)( n ); ssl->out_msglen = 6 + n + offset; ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; ssl->out_msg[0] = MBEDTLS_SSL_HS_CERTIFICATE_VERIFY; - ssl->state = MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC; + ssl->state++; - if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 ) + if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 ) { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret ); + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret ); return( ret ); } @@ -4107,7 +3274,12 @@ sign: return( ret ); } -#endif /* MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED */ +#endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED && + !MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED && + !MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED && + !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED && + !MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED && + !MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ #if defined(MBEDTLS_SSL_SESSION_TICKETS) static int ssl_parse_new_session_ticket( mbedtls_ssl_context *ssl ) @@ -4120,7 +3292,7 @@ static int ssl_parse_new_session_ticket( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse new session ticket" ) ); - if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 ) + if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); return( ret ); @@ -4129,8 +3301,8 @@ static int ssl_parse_new_session_ticket( mbedtls_ssl_context *ssl ) if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); } @@ -4148,22 +3320,23 @@ static int ssl_parse_new_session_ticket( mbedtls_ssl_context *ssl ) ssl->in_hslen < 6 + mbedtls_ssl_hs_hdr_len( ssl ) ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET ); } msg = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ); - lifetime = (uint32_t)mbedtls_platform_get_uint32_be( msg ); + lifetime = ( ((uint32_t) msg[0]) << 24 ) | ( msg[1] << 16 ) | + ( msg[2] << 8 ) | ( msg[3] ); - ticket_len = mbedtls_platform_get_uint16_be( &msg[4] ); + ticket_len = ( msg[4] << 8 ) | ( msg[5] ); if( ticket_len + 6 + mbedtls_ssl_hs_hdr_len( ssl ) != ssl->in_hslen ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET ); } @@ -4180,17 +3353,8 @@ static int ssl_parse_new_session_ticket( mbedtls_ssl_context *ssl ) if( ticket_len == 0 ) return( 0 ); - if( ssl->session != NULL && ssl->session->ticket != NULL ) - { - mbedtls_platform_zeroize( ssl->session->ticket, - ssl->session->ticket_len ); - mbedtls_free( ssl->session->ticket ); - ssl->session->ticket = NULL; - ssl->session->ticket_len = 0; - } - - mbedtls_platform_zeroize( ssl->session_negotiate->ticket, - ssl->session_negotiate->ticket_len ); + mbedtls_zeroize( ssl->session_negotiate->ticket, + ssl->session_negotiate->ticket_len ); mbedtls_free( ssl->session_negotiate->ticket ); ssl->session_negotiate->ticket = NULL; ssl->session_negotiate->ticket_len = 0; @@ -4198,12 +3362,12 @@ static int ssl_parse_new_session_ticket( mbedtls_ssl_context *ssl ) if( ( ticket = mbedtls_calloc( 1, ticket_len ) ) == NULL ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "ticket alloc failed" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR ); return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); } - mbedtls_platform_memcpy( ticket, msg + 6, ticket_len ); + memcpy( ticket, msg + 6, ticket_len ); ssl->session_negotiate->ticket = ticket; ssl->session_negotiate->ticket_len = ticket_len; @@ -4228,11 +3392,7 @@ static int ssl_parse_new_session_ticket( mbedtls_ssl_context *ssl ) */ int mbedtls_ssl_handshake_client_step( mbedtls_ssl_context *ssl ) { - int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; -#if defined(MBEDTLS_SSL_DELAYED_SERVER_CERT_VERIFICATION) - void *rs_ctx = NULL; - int authmode; -#endif /* MBEDTLS_SSL_DELAYED_SERVER_CERT_VERIFICATION */ + int ret = 0; if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER || ssl->handshake == NULL ) return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); @@ -4243,13 +3403,13 @@ int mbedtls_ssl_handshake_client_step( mbedtls_ssl_context *ssl ) return( ret ); #if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) && + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING ) { - if( ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 ) + if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 ) return( ret ); } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ +#endif /* Change state now, so that it is right in mbedtls_ssl_read_record(), used * by DTLS for dropping out-of-sequence ChangeCipherSpec records */ @@ -4261,12 +3421,10 @@ int mbedtls_ssl_handshake_client_step( mbedtls_ssl_context *ssl ) } #endif - ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; switch( ssl->state ) { case MBEDTLS_SSL_HELLO_REQUEST: ssl->state = MBEDTLS_SSL_CLIENT_HELLO; - ret = 0; break; /* @@ -4284,25 +3442,6 @@ int mbedtls_ssl_handshake_client_step( mbedtls_ssl_context *ssl ) * ServerHelloDone */ case MBEDTLS_SSL_SERVER_HELLO: -#if defined(MBEDTLS_SSL_EARLY_KEY_COMPUTATION) && defined(MBEDTLS_USE_TINYCRYPT) - { - volatile uint8_t ecdhe_computed = ssl->handshake->ecdhe_computed; - /* Make sure that the ECDHE pre-computation is only done once */ - if( ecdhe_computed == 0 ) - { - ret = uECC_make_key( ssl->handshake->ecdh_publickey, ssl->handshake->ecdh_privkey ); - if( ret == UECC_FAULT_DETECTED ) - return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); - if( ret != UECC_SUCCESS ) - return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); - ssl->handshake->ecdhe_computed = 1; - ecdhe_computed = 1; - } - if( ecdhe_computed == 0 || ssl->handshake->ecdhe_computed == 0 ) - return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); - } -#endif /* MBEDTLS_SSL_EARLY_KEY_COMPUTATION && MBEDTLS_USE_TINYCRYPT */ - ret = ssl_parse_server_hello( ssl ); break; @@ -4311,7 +3450,7 @@ int mbedtls_ssl_handshake_client_step( mbedtls_ssl_context *ssl ) break; case MBEDTLS_SSL_SERVER_KEY_EXCHANGE: - ret = ssl_process_in_server_key_exchange( ssl ); + ret = ssl_parse_server_key_exchange( ssl ); break; case MBEDTLS_SSL_CERTIFICATE_REQUEST: @@ -4334,7 +3473,7 @@ int mbedtls_ssl_handshake_client_step( mbedtls_ssl_context *ssl ) break; case MBEDTLS_SSL_CLIENT_KEY_EXCHANGE: - ret = ssl_process_out_client_key_exchange( ssl ); + ret = ssl_write_client_key_exchange( ssl ); break; case MBEDTLS_SSL_CERTIFICATE_VERIFY: @@ -4346,24 +3485,6 @@ int mbedtls_ssl_handshake_client_step( mbedtls_ssl_context *ssl ) break; case MBEDTLS_SSL_CLIENT_FINISHED: - -#if defined(MBEDTLS_SSL_DELAYED_SERVER_CERT_VERIFICATION) -#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - authmode = ssl->handshake->sni_authmode != MBEDTLS_SSL_VERIFY_UNSET - ? ssl->handshake->sni_authmode - : mbedtls_ssl_conf_get_authmode( ssl->conf ); -#else - authmode = mbedtls_ssl_conf_get_authmode( ssl->conf ); -#endif - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "execute delayed server certificate verification" ) ); - - ret = mbedtls_ssl_parse_delayed_certificate_verify( ssl, authmode, - ssl->session_negotiate->peer_cert, rs_ctx ); - if( ret != 0 ) - break; -#endif /* MBEDTLS_SSL_DELAYED_SERVER_CERT_VERIFICATION */ - ret = mbedtls_ssl_write_finished( ssl ); break; @@ -4389,14 +3510,12 @@ int mbedtls_ssl_handshake_client_step( mbedtls_ssl_context *ssl ) case MBEDTLS_SSL_FLUSH_BUFFERS: MBEDTLS_SSL_DEBUG_MSG( 2, ( "handshake: done" ) ); ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP; - ret = 0; break; case MBEDTLS_SSL_HANDSHAKE_WRAPUP: - ret = mbedtls_ssl_handshake_wrapup( ssl ); + mbedtls_ssl_handshake_wrapup( ssl ); break; - case MBEDTLS_SSL_INVALID: default: MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid state %d", ssl->state ) ); return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); diff --git a/APP_Framework/Framework/security/mbedtls/ssl_cookie.c b/APP_Framework/Framework/security/mbedtls/ssl_cookie.c new file mode 100644 index 000000000..d3133ab47 --- /dev/null +++ b/APP_Framework/Framework/security/mbedtls/ssl_cookie.c @@ -0,0 +1,260 @@ +/* + * DTLS cookie callbacks implementation + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +/* + * These session callbacks use a simple chained list + * to store and retrieve the session information. + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_SSL_COOKIE_C) + +#if defined(MBEDTLS_PLATFORM_C) +#include "platform.h" +#else +#define mbedtls_calloc calloc +#define mbedtls_free free +#endif + +#include "ssl_cookie.h" +#include "ssl_internal.h" + +#include + +/* 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; +} + +/* + * If DTLS is in use, then at least one of SHA-1, SHA-256, SHA-512 is + * available. Try SHA-256 first, 512 wastes resources since we need to stay + * with max 32 bytes of cookie for DTLS 1.0 + */ +#if defined(MBEDTLS_SHA256_C) +#define COOKIE_MD MBEDTLS_MD_SHA224 +#define COOKIE_MD_OUTLEN 32 +#define COOKIE_HMAC_LEN 28 +#elif defined(MBEDTLS_SHA512_C) +#define COOKIE_MD MBEDTLS_MD_SHA384 +#define COOKIE_MD_OUTLEN 48 +#define COOKIE_HMAC_LEN 28 +#elif defined(MBEDTLS_SHA1_C) +#define COOKIE_MD MBEDTLS_MD_SHA1 +#define COOKIE_MD_OUTLEN 20 +#define COOKIE_HMAC_LEN 20 +#else +#error "DTLS hello verify needs SHA-1 or SHA-2" +#endif + +/* + * Cookies are formed of a 4-bytes timestamp (or serial number) and + * an HMAC of timestemp and client ID. + */ +#define COOKIE_LEN ( 4 + COOKIE_HMAC_LEN ) + +void mbedtls_ssl_cookie_init( mbedtls_ssl_cookie_ctx *ctx ) +{ + mbedtls_md_init( &ctx->hmac_ctx ); +#if !defined(MBEDTLS_HAVE_TIME) + ctx->serial = 0; +#endif + ctx->timeout = MBEDTLS_SSL_COOKIE_TIMEOUT; + +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_init( &ctx->mutex ); +#endif +} + +void mbedtls_ssl_cookie_set_timeout( mbedtls_ssl_cookie_ctx *ctx, unsigned long delay ) +{ + ctx->timeout = delay; +} + +void mbedtls_ssl_cookie_free( mbedtls_ssl_cookie_ctx *ctx ) +{ + mbedtls_md_free( &ctx->hmac_ctx ); + +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_free( &ctx->mutex ); +#endif + + mbedtls_zeroize( ctx, sizeof( mbedtls_ssl_cookie_ctx ) ); +} + +int mbedtls_ssl_cookie_setup( mbedtls_ssl_cookie_ctx *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + unsigned char key[COOKIE_MD_OUTLEN]; + + if( ( ret = f_rng( p_rng, key, sizeof( key ) ) ) != 0 ) + return( ret ); + + ret = mbedtls_md_setup( &ctx->hmac_ctx, mbedtls_md_info_from_type( COOKIE_MD ), 1 ); + if( ret != 0 ) + return( ret ); + + ret = mbedtls_md_hmac_starts( &ctx->hmac_ctx, key, sizeof( key ) ); + if( ret != 0 ) + return( ret ); + + mbedtls_zeroize( key, sizeof( key ) ); + + return( 0 ); +} + +/* + * Generate the HMAC part of a cookie + */ +static int ssl_cookie_hmac( mbedtls_md_context_t *hmac_ctx, + const unsigned char time[4], + unsigned char **p, unsigned char *end, + const unsigned char *cli_id, size_t cli_id_len ) +{ + unsigned char hmac_out[COOKIE_MD_OUTLEN]; + + if( (size_t)( end - *p ) < COOKIE_HMAC_LEN ) + return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); + + if( mbedtls_md_hmac_reset( hmac_ctx ) != 0 || + mbedtls_md_hmac_update( hmac_ctx, time, 4 ) != 0 || + mbedtls_md_hmac_update( hmac_ctx, cli_id, cli_id_len ) != 0 || + mbedtls_md_hmac_finish( hmac_ctx, hmac_out ) != 0 ) + { + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } + + memcpy( *p, hmac_out, COOKIE_HMAC_LEN ); + *p += COOKIE_HMAC_LEN; + + return( 0 ); +} + +/* + * Generate cookie for DTLS ClientHello verification + */ +int mbedtls_ssl_cookie_write( void *p_ctx, + unsigned char **p, unsigned char *end, + const unsigned char *cli_id, size_t cli_id_len ) +{ + int ret; + mbedtls_ssl_cookie_ctx *ctx = (mbedtls_ssl_cookie_ctx *) p_ctx; + unsigned long t; + + if( ctx == NULL || cli_id == NULL ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + + if( (size_t)( end - *p ) < COOKIE_LEN ) + return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); + +#if defined(MBEDTLS_HAVE_TIME) + t = (unsigned long) mbedtls_time( NULL ); +#else + t = ctx->serial++; +#endif + + (*p)[0] = (unsigned char)( t >> 24 ); + (*p)[1] = (unsigned char)( t >> 16 ); + (*p)[2] = (unsigned char)( t >> 8 ); + (*p)[3] = (unsigned char)( t ); + *p += 4; + +#if defined(MBEDTLS_THREADING_C) + if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR + ret ); +#endif + + ret = ssl_cookie_hmac( &ctx->hmac_ctx, *p - 4, + p, end, cli_id, cli_id_len ); + +#if defined(MBEDTLS_THREADING_C) + if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR + + MBEDTLS_ERR_THREADING_MUTEX_ERROR ); +#endif + + return( ret ); +} + +/* + * Check a cookie + */ +int mbedtls_ssl_cookie_check( void *p_ctx, + const unsigned char *cookie, size_t cookie_len, + const unsigned char *cli_id, size_t cli_id_len ) +{ + unsigned char ref_hmac[COOKIE_HMAC_LEN]; + int ret = 0; + unsigned char *p = ref_hmac; + mbedtls_ssl_cookie_ctx *ctx = (mbedtls_ssl_cookie_ctx *) p_ctx; + unsigned long cur_time, cookie_time; + + if( ctx == NULL || cli_id == NULL ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + + if( cookie_len != COOKIE_LEN ) + return( -1 ); + +#if defined(MBEDTLS_THREADING_C) + if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR + ret ); +#endif + + if( ssl_cookie_hmac( &ctx->hmac_ctx, cookie, + &p, p + sizeof( ref_hmac ), + cli_id, cli_id_len ) != 0 ) + ret = -1; + +#if defined(MBEDTLS_THREADING_C) + if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR + + MBEDTLS_ERR_THREADING_MUTEX_ERROR ); +#endif + + if( ret != 0 ) + return( ret ); + + if( mbedtls_ssl_safer_memcmp( cookie + 4, ref_hmac, sizeof( ref_hmac ) ) != 0 ) + return( -1 ); + +#if defined(MBEDTLS_HAVE_TIME) + cur_time = (unsigned long) mbedtls_time( NULL ); +#else + cur_time = ctx->serial; +#endif + + cookie_time = ( (unsigned long) cookie[0] << 24 ) | + ( (unsigned long) cookie[1] << 16 ) | + ( (unsigned long) cookie[2] << 8 ) | + ( (unsigned long) cookie[3] ); + + if( ctx->timeout != 0 && cur_time - cookie_time > ctx->timeout ) + return( -1 ); + + return( 0 ); +} +#endif /* MBEDTLS_SSL_COOKIE_C */ diff --git a/APP_Framework/Framework/security/mbedtls/ssl_cookie.h b/APP_Framework/Framework/security/mbedtls/ssl_cookie.h index e34760ae8..6a7ff9c75 100644 --- a/APP_Framework/Framework/security/mbedtls/ssl_cookie.h +++ b/APP_Framework/Framework/security/mbedtls/ssl_cookie.h @@ -56,7 +56,7 @@ extern "C" { /** * \brief Context for the default cookie functions. */ -typedef struct mbedtls_ssl_cookie_ctx +typedef struct { mbedtls_md_context_t hmac_ctx; /*!< context for the HMAC portion */ #if !defined(MBEDTLS_HAVE_TIME) diff --git a/APP_Framework/Framework/security/mbedtls/ssl_internal.h b/APP_Framework/Framework/security/mbedtls/ssl_internal.h index 441109dd4..168d4a256 100644 --- a/APP_Framework/Framework/security/mbedtls/ssl_internal.h +++ b/APP_Framework/Framework/security/mbedtls/ssl_internal.h @@ -32,7 +32,6 @@ #include "ssl.h" #include "cipher.h" -#include "oid.h" #if defined(MBEDTLS_MD5_C) #include "md5.h" @@ -54,38 +53,11 @@ #include "ecjpake.h" #endif -#if defined(MBEDTLS_ECP_C) -#include "ecp.h" -#endif - -#if defined(MBEDTLS_ECDH_C) -#include "ecdh.h" -#endif - -#if defined(MBEDTLS_USE_TINYCRYPT) -#include "tinycrypt/ecc.h" -#include "tinycrypt/ecc_dh.h" -#endif - -#if defined(__GNUC__) || defined(__arm__) -#define MBEDTLS_ALWAYS_INLINE __attribute__((always_inline)) -#define MBEDTLS_NO_INLINE __attribute__((noinline)) -#else -#define MBEDTLS_ALWAYS_INLINE -#define MBEDTLS_NO_INLINE -#endif - #if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ !defined(inline) && !defined(__cplusplus) #define inline __inline #endif -/* The public option is negative for backwards compatibility, - * but internally a poisitive option is more convenient. */ -#if !defined(MBEDTLS_SSL_PROTO_NO_TLS) -#define MBEDTLS_SSL_PROTO_TLS -#endif - /* Determine minimum supported version */ #define MBEDTLS_SSL_MIN_MAJOR_VERSION MBEDTLS_SSL_MAJOR_VERSION_3 @@ -127,14 +99,6 @@ #endif /* MBEDTLS_SSL_PROTO_TLS1_1 */ #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ -/* Shorthand for restartable ECC */ -#if defined(MBEDTLS_ECP_RESTARTABLE) && \ - defined(MBEDTLS_SSL_CLI_C) && \ - defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) -#define MBEDTLS_SSL__ECP_RESTARTABLE -#endif - #define MBEDTLS_SSL_INITIAL_HANDSHAKE 0 #define MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS 1 /* In progress */ #define MBEDTLS_SSL_RENEGOTIATION_DONE 2 /* Done or aborted */ @@ -165,16 +129,7 @@ #define MBEDTLS_SSL_COMPRESSION_ADD 0 #endif -#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER) || \ - ( defined(MBEDTLS_CIPHER_MODE_CBC) && \ - ( defined(MBEDTLS_AES_C) || \ - defined(MBEDTLS_CAMELLIA_C) || \ - defined(MBEDTLS_ARIA_C) || \ - defined(MBEDTLS_DES_C) ) ) -#define MBEDTLS_SSL_SOME_MODES_USE_MAC -#endif - -#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC) +#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_MODE_CBC) /* Ciphersuites using HMAC */ #if defined(MBEDTLS_SHA512_C) #define MBEDTLS_SSL_MAC_ADD 48 /* SHA-384 used for HMAC */ @@ -183,7 +138,7 @@ #else #define MBEDTLS_SSL_MAC_ADD 20 /* SHA-1 used for HMAC */ #endif -#else /* MBEDTLS_SSL_SOME_MODES_USE_MAC */ +#else /* AEAD ciphersuites: GCM and CCM use a 128 bits tag */ #define MBEDTLS_SSL_MAC_ADD 16 #endif @@ -194,124 +149,32 @@ #define MBEDTLS_SSL_PADDING_ADD 0 #endif -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) -#define MBEDTLS_SSL_MAX_CID_EXPANSION MBEDTLS_SSL_CID_PADDING_GRANULARITY -#else -#define MBEDTLS_SSL_MAX_CID_EXPANSION 0 -#endif - -#define MBEDTLS_SSL_PAYLOAD_OVERHEAD ( MBEDTLS_SSL_COMPRESSION_ADD + \ - MBEDTLS_MAX_IV_LENGTH + \ - MBEDTLS_SSL_MAC_ADD + \ - MBEDTLS_SSL_PADDING_ADD + \ - MBEDTLS_SSL_MAX_CID_EXPANSION \ - ) - -#define MBEDTLS_SSL_IN_PAYLOAD_LEN ( MBEDTLS_SSL_PAYLOAD_OVERHEAD + \ - ( MBEDTLS_SSL_IN_CONTENT_LEN ) ) - -#define MBEDTLS_SSL_OUT_PAYLOAD_LEN ( MBEDTLS_SSL_PAYLOAD_OVERHEAD + \ - ( MBEDTLS_SSL_OUT_CONTENT_LEN ) ) - -/* The maximum number of buffered handshake messages. */ -#define MBEDTLS_SSL_MAX_BUFFERED_HS 4 - -/* Maximum length we can advertise as our max content length for - RFC 6066 max_fragment_length extension negotiation purposes - (the lesser of both sizes, if they are unequal.) - */ -#define MBEDTLS_TLS_EXT_ADV_CONTENT_LEN ( \ - (MBEDTLS_SSL_IN_CONTENT_LEN > MBEDTLS_SSL_OUT_CONTENT_LEN) \ - ? ( MBEDTLS_SSL_OUT_CONTENT_LEN ) \ - : ( MBEDTLS_SSL_IN_CONTENT_LEN ) \ - ) - -#define MBEDTLS_SSL_FI_FLAG_UNSET 0x0 -#define MBEDTLS_SSL_FI_FLAG_SET 0x7F +#define MBEDTLS_SSL_PAYLOAD_LEN ( MBEDTLS_SSL_MAX_CONTENT_LEN \ + + MBEDTLS_SSL_COMPRESSION_ADD \ + + MBEDTLS_MAX_IV_LENGTH \ + + MBEDTLS_SSL_MAC_ADD \ + + MBEDTLS_SSL_PADDING_ADD \ + ) /* * Check that we obey the standard's message size bounds */ #if MBEDTLS_SSL_MAX_CONTENT_LEN > 16384 -#error "Bad configuration - record content too large." +#error Bad configuration - record content too large. #endif -#if MBEDTLS_SSL_IN_CONTENT_LEN > MBEDTLS_SSL_MAX_CONTENT_LEN -#error "Bad configuration - incoming record content should not be larger than MBEDTLS_SSL_MAX_CONTENT_LEN." +#if MBEDTLS_SSL_PAYLOAD_LEN > 16384 + 2048 +#error Bad configuration - protected record payload too large. #endif -#if MBEDTLS_SSL_OUT_CONTENT_LEN > MBEDTLS_SSL_MAX_CONTENT_LEN -#error "Bad configuration - outgoing record content should not be larger than MBEDTLS_SSL_MAX_CONTENT_LEN." -#endif - -#if MBEDTLS_SSL_IN_PAYLOAD_LEN > MBEDTLS_SSL_MAX_CONTENT_LEN + 2048 -#error "Bad configuration - incoming protected record payload too large." -#endif - -#if MBEDTLS_SSL_OUT_PAYLOAD_LEN > MBEDTLS_SSL_MAX_CONTENT_LEN + 2048 -#error "Bad configuration - outgoing protected record payload too large." -#endif - -/* Calculate buffer sizes */ - /* Note: Even though the TLS record header is only 5 bytes long, we're internally using 8 bytes to store the implicit sequence number. */ #define MBEDTLS_SSL_HEADER_LEN 13 -#if !defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) -#define MBEDTLS_SSL_IN_BUFFER_LEN \ - ( ( MBEDTLS_SSL_HEADER_LEN ) + ( MBEDTLS_SSL_IN_PAYLOAD_LEN ) ) -#else -#define MBEDTLS_SSL_IN_BUFFER_LEN \ - ( ( MBEDTLS_SSL_HEADER_LEN ) + ( MBEDTLS_SSL_IN_PAYLOAD_LEN ) \ - + ( MBEDTLS_SSL_CID_IN_LEN_MAX ) ) -#endif - -#if !defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) -#define MBEDTLS_SSL_OUT_BUFFER_LEN \ - ( ( MBEDTLS_SSL_HEADER_LEN ) + ( MBEDTLS_SSL_OUT_PAYLOAD_LEN ) ) -#else -#define MBEDTLS_SSL_OUT_BUFFER_LEN \ - ( ( MBEDTLS_SSL_HEADER_LEN ) + ( MBEDTLS_SSL_OUT_PAYLOAD_LEN ) \ - + ( MBEDTLS_SSL_CID_OUT_LEN_MAX ) ) -#endif - -#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) -static inline uint32_t mbedtls_ssl_get_output_buflen( const mbedtls_ssl_context *ctx ) -{ -#if defined (MBEDTLS_SSL_DTLS_CONNECTION_ID) - return (uint32_t) mbedtls_ssl_get_output_max_frag_len( ctx ) - + MBEDTLS_SSL_HEADER_LEN + MBEDTLS_SSL_PAYLOAD_OVERHEAD - + MBEDTLS_SSL_CID_OUT_LEN_MAX; -#else - return (uint32_t) mbedtls_ssl_get_output_max_frag_len( ctx ) - + MBEDTLS_SSL_HEADER_LEN + MBEDTLS_SSL_PAYLOAD_OVERHEAD; -#endif -} - -static inline uint32_t mbedtls_ssl_get_input_buflen( const mbedtls_ssl_context *ctx ) -{ -#if defined (MBEDTLS_SSL_DTLS_CONNECTION_ID) - return (uint32_t) mbedtls_ssl_get_input_max_frag_len( ctx ) - + MBEDTLS_SSL_HEADER_LEN + MBEDTLS_SSL_PAYLOAD_OVERHEAD - + MBEDTLS_SSL_CID_IN_LEN_MAX; -#else - return (uint32_t) mbedtls_ssl_get_input_max_frag_len( ctx ) - + MBEDTLS_SSL_HEADER_LEN + MBEDTLS_SSL_PAYLOAD_OVERHEAD; -#endif -} -#endif - -#ifdef MBEDTLS_ZLIB_SUPPORT -/* Compression buffer holds both IN and OUT buffers, so should be size of the larger */ -#define MBEDTLS_SSL_COMPRESS_BUFFER_LEN ( \ - ( MBEDTLS_SSL_IN_BUFFER_LEN > MBEDTLS_SSL_OUT_BUFFER_LEN ) \ - ? MBEDTLS_SSL_IN_BUFFER_LEN \ - : MBEDTLS_SSL_OUT_BUFFER_LEN \ - ) -#endif +#define MBEDTLS_SSL_BUFFER_LEN \ + ( ( MBEDTLS_SSL_HEADER_LEN ) + ( MBEDTLS_SSL_PAYLOAD_LEN ) ) /* * TLS extension flags (for extensions with outgoing ServerHello content @@ -321,69 +184,6 @@ static inline uint32_t mbedtls_ssl_get_input_buflen( const mbedtls_ssl_context * #define MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT (1 << 0) #define MBEDTLS_TLS_EXT_ECJPAKE_KKPP_OK (1 << 1) -/* - * Helpers for code specific to TLS or DTLS. - * - * Goals for these helpers: - * - generate minimal code, eg don't test if mode is DTLS in a DTLS-only build - * - make the flow clear to the compiler, so that in TLS and DTLS combined - * builds, when there are two branches, it knows exactly one of them is taken - * - preserve readability - * - * There are three macros: - * - MBEDTLS_SSL_TRANSPORT_IS_TLS( transport ) - * - MBEDTLS_SSL_TRANSPORT_IS_DTLS( transport ) - * - MBEDTLS_SSL_TRANSPORT_ELSE - * - * The first two are macros rather than static inline functions because some - * compilers (eg arm-none-eabi-gcc 5.4.1 20160919) don't propagate constants - * well enough for us with static inline functions. - * - * Usage 1 (can replace DTLS with TLS): - * #if defined(MBEDTLS_SSL_PROTO_DTLS) - * if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( transport ) ) - * // DTLS-specific code - * #endif - * - * Usage 2 (can swap DTLS and TLS); - * #if defined(MBEDTLS_SSL_PROTO_DTLS) - * if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( transport ) ) - * // DTLS-specific code - * MBEDTLS_SSL_TRANSPORT_ELSE - * #endif - * #if defined(MBEDTLS_SSL_PROTO_TLS) - * // TLS-specific code - * #endif - */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) && defined(MBEDTLS_SSL_PROTO_TLS) /* both */ -#define MBEDTLS_SSL_TRANSPORT__BOTH /* shortcut for future tests */ -#define MBEDTLS_SSL_TRANSPORT_IS_TLS( transport ) \ - ( (transport) == MBEDTLS_SSL_TRANSPORT_STREAM ) -#define MBEDTLS_SSL_TRANSPORT_IS_DTLS( transport ) \ - ( (transport) == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) -#define MBEDTLS_SSL_TRANSPORT_ELSE else -#elif defined(MBEDTLS_SSL_PROTO_DTLS) /* DTLS only */ -#define MBEDTLS_SSL_TRANSPORT_IS_TLS( transport ) 0 -#define MBEDTLS_SSL_TRANSPORT_IS_DTLS( transport ) 1 -#define MBEDTLS_SSL_TRANSPORT_ELSE /* empty: no other branch */ -#else /* TLS only */ -#define MBEDTLS_SSL_TRANSPORT_IS_TLS( transport ) 1 -#define MBEDTLS_SSL_TRANSPORT_IS_DTLS( transport ) 0 -#define MBEDTLS_SSL_TRANSPORT_ELSE /* empty: no other branch */ -#endif /* TLS and/or DTLS */ - -/* Check if the use of the ExtendedMasterSecret extension - * is enforced at compile-time. If so, we don't need to - * track its status in the handshake parameters. */ -#if defined(MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET) && \ - defined(MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET) && \ - MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET == \ - MBEDTLS_SSL_EXTENDED_MS_ENABLED && \ - MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET == \ - MBEDTLS_SSL_EXTENDED_MS_ENFORCE_ENABLED -#define MBEDTLS_SSL_EXTENDED_MS_ENFORCED -#endif - #ifdef __cplusplus extern "C" { #endif @@ -411,35 +211,20 @@ struct mbedtls_ssl_sig_hash_set_t */ struct mbedtls_ssl_handshake_params { -#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - uint8_t got_peer_pubkey; /*!< Did we store the peer's public key from its certificate? */ -#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - volatile uint8_t peer_authenticated; /*!< Is the peer authenticated? */ - volatile uint8_t hello_random_set; /*!< Has the hello random been set? */ - volatile uint8_t key_derivation_done; /*!< Has the key derivation been done? */ - volatile uint8_t premaster_generated; /*!< Has the PMS been generated? */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - unsigned char verify_cookie_len; /*!< Cli: cookie length - Srv: flag for sending a cookie */ - unsigned char retransmit_state; /*!< Retransmission state */ -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - /* The state of CID configuration in this handshake. */ - - uint8_t cid_in_use; /*!< This indicates whether the use of the CID extension - * has been negotiated. Possible values are - * #MBEDTLS_SSL_CID_ENABLED and - * #MBEDTLS_SSL_CID_DISABLED. */ - uint8_t peer_cid_len; /*!< The length of - * \c peer_cid. */ -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - uint16_t mtu; /*!< Handshake mtu, used to fragment outgoing messages */ - -#endif /* MBEDTLS_SSL_PROTO_DTLS */ + /* + * Handshake specific crypto variables + */ #if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) mbedtls_ssl_sig_hash_set_t hash_algs; /*!< Set of suitable sig-hash pairs */ #endif +#if defined(MBEDTLS_DHM_C) + mbedtls_dhm_context dhm_ctx; /*!< DHM key exchange */ +#endif +#if defined(MBEDTLS_ECDH_C) + mbedtls_ecdh_context ecdh_ctx; /*!< ECDH key exchange */ +#endif #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) mbedtls_ecjpake_context ecjpake_ctx; /*!< EC J-PAKE key exchange */ #if defined(MBEDTLS_SSL_CLI_C) @@ -447,82 +232,16 @@ struct mbedtls_ssl_handshake_params size_t ecjpake_cache_len; /*!< Length of cached data */ #endif #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ -#if defined(MBEDTLS_ECDH_C) || \ - defined(MBEDTLS_ECDSA_C) || \ - defined(MBEDTLS_USE_TINYCRYPT) || \ +#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - uint16_t curve_tls_id; /*!< TLS ID of EC for ECDHE. */ + const mbedtls_ecp_curve_info **curves; /*!< Supported elliptic curves */ #endif - - size_t pmslen; /*!< premaster length */ - int cli_exts; /*!< client extension presence*/ - #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) unsigned char *psk; /*!< PSK from the callback */ size_t psk_len; /*!< Length of PSK from callback */ #endif -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - int ecrs_enabled; /*!< Handshake supports EC restart? */ - mbedtls_x509_crt_restart_ctx ecrs_ctx; /*!< restart context */ - enum { /* this complements ssl->state with info on intra-state operations */ - ssl_ecrs_none = 0, /*!< nothing going on (yet) */ - ssl_ecrs_crt_verify, /*!< Certificate: crt_verify() */ - ssl_ecrs_cke_ecdh_calc_secret, /*!< ClientKeyExchange: ECDH step 2 */ - ssl_ecrs_crt_vrfy_sign, /*!< CertificateVerify: pk_sign() */ - } ecrs_state; /*!< current (or last) operation */ - mbedtls_x509_crt *ecrs_peer_cert; /*!< The peer's CRT chain. */ -#endif -#if defined(MBEDTLS_SSL_PROTO_DTLS) - unsigned int out_msg_seq; /*!< Outgoing handshake sequence number */ - unsigned int in_msg_seq; /*!< Incoming handshake sequence number */ - - unsigned char *verify_cookie; /*!< Cli: HelloVerifyRequest cookie - Srv: unused */ - uint32_t retransmit_timeout; /*!< Current value of timeout */ - mbedtls_ssl_flight_item *flight; /*!< Current outgoing flight */ - mbedtls_ssl_flight_item *cur_msg; /*!< Current message in flight */ - unsigned char *cur_msg_p; /*!< Position in current message */ - unsigned int in_flight_start_seq; /*!< Minimum message sequence in the - flight being received */ - mbedtls_ssl_transform *alt_transform_out; /*!< Alternative transform for - resending messages */ - unsigned char alt_out_ctr[8]; /*!< Alternative record epoch/counter - for resending messages */ - struct - { - uint8_t seen_ccs; /*!< Indicates if a CCS message has - * been seen in the current flight. */ - - size_t total_bytes_buffered; /*!< Cumulative size of heap allocated - * buffers used for message buffering. */ - - struct - { - unsigned char *data; - size_t len; - unsigned epoch; - } future_record; - - struct mbedtls_ssl_hs_buffer - { - uint8_t is_valid; - uint8_t is_fragmented; - uint8_t is_complete; - unsigned char *data; - size_t data_len; - } hs[MBEDTLS_SSL_MAX_BUFFERED_HS]; - } buffering; -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - /* The state of CID configuration in this handshake. */ - unsigned char peer_cid[ MBEDTLS_SSL_CID_OUT_LEN_MAX ]; /*! The peer's CID */ -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ -#endif /* MBEDTLS_SSL_PROTO_DTLS */ #if defined(MBEDTLS_X509_CRT_PARSE_C) mbedtls_ssl_key_cert *key_cert; /*!< chosen key/cert pair (server) */ -#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - mbedtls_pk_context peer_pubkey; /*!< The public key from the peer. */ -#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) int sni_authmode; /*!< authmode from SNI callback */ mbedtls_ssl_key_cert *sni_key_cert; /*!< key/cert list from SNI */ @@ -530,55 +249,28 @@ struct mbedtls_ssl_handshake_params mbedtls_x509_crl *sni_ca_crl; /*!< trusted CAs CRLs from SNI */ #endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ #endif /* MBEDTLS_X509_CRT_PARSE_C */ - unsigned char randbytes[64]; /*!< random bytes */ - unsigned char premaster[MBEDTLS_PREMASTER_SIZE]; - /*!< premaster secret */ +#if defined(MBEDTLS_SSL_PROTO_DTLS) + unsigned int out_msg_seq; /*!< Outgoing handshake sequence number */ + unsigned int in_msg_seq; /*!< Incoming handshake sequence number */ -#if !defined(MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE) - mbedtls_ssl_ciphersuite_handle_t ciphersuite_info; -#endif /* !MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE */ + unsigned char *verify_cookie; /*!< Cli: HelloVerifyRequest cookie + Srv: unused */ + unsigned char verify_cookie_len; /*!< Cli: cookie length + Srv: flag for sending a cookie */ -#if !defined(MBEDTLS_SSL_NO_SESSION_RESUMPTION) - volatile int resume; /*!< session resume indicator*/ -#endif /* !MBEDTLS_SSL_NO_SESSION_RESUMPTION */ + unsigned char *hs_msg; /*!< Reassembled handshake message */ -#if defined(MBEDTLS_SSL_SRV_C) && \ - ( defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED ) ) - int max_major_ver; /*!< max. major version client*/ - int max_minor_ver; /*!< max. minor version client*/ -#endif /* MBEDTLS_SSL_SRV_C && ( MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED || - MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED ) */ - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) - int new_session_ticket; /*!< use NewSessionTicket? */ -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) && \ - !defined(MBEDTLS_SSL_EXTENDED_MS_ENFORCED) - int extended_ms; /*!< use Extended Master Secret? */ -#endif - -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) - uint8_t async_in_progress; /*!< an asynchronous operation is in progress */ -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ - -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) - /** Asynchronous operation context. This field is meant for use by the - * asynchronous operation callbacks (mbedtls_ssl_config::f_async_sign_start, - * mbedtls_ssl_config::f_async_decrypt_start, - * mbedtls_ssl_config::f_async_resume, mbedtls_ssl_config::f_async_cancel). - * The library does not use it internally. */ - void *user_async_ctx; -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ - -#if defined(MBEDTLS_USE_TINYCRYPT) - uint8_t ecdh_privkey[NUM_ECC_BYTES]; -#if defined(MBEDTLS_SSL_EARLY_KEY_COMPUTATION) - uint8_t ecdhe_computed; - uint8_t ecdh_publickey[2*NUM_ECC_BYTES]; -#endif /* MBEDTLS_SSL_EARLY_KEY_COMPUTATION */ - uint8_t ecdh_peerkey[2*NUM_ECC_BYTES]; -#endif /* MBEDTLS_USE_TINYCRYPT */ + uint32_t retransmit_timeout; /*!< Current value of timeout */ + unsigned char retransmit_state; /*!< Retransmission state */ + mbedtls_ssl_flight_item *flight; /*!< Current outgoing flight */ + mbedtls_ssl_flight_item *cur_msg; /*!< Current message in flight */ + unsigned int in_flight_start_seq; /*!< Minimum message sequence in the + flight being received */ + mbedtls_ssl_transform *alt_transform_out; /*!< Alternative transform for + resending messages */ + unsigned char alt_out_ctr[8]; /*!< Alternative record epoch/counter + for resending messages */ +#endif /* MBEDTLS_SSL_PROTO_DTLS */ /* * Checksum contexts @@ -597,163 +289,52 @@ struct mbedtls_ssl_handshake_params #endif #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ -#if defined(MBEDTLS_DHM_C) - mbedtls_dhm_context dhm_ctx; /*!< DHM key exchange */ -#endif -#if defined(MBEDTLS_ECDH_C) - mbedtls_ecdh_context ecdh_ctx; /*!< ECDH key exchange */ + void (*update_checksum)(mbedtls_ssl_context *, const unsigned char *, size_t); + void (*calc_verify)(mbedtls_ssl_context *, unsigned char *); + void (*calc_finished)(mbedtls_ssl_context *, unsigned char *, int); + int (*tls_prf)(const unsigned char *, size_t, const char *, + const unsigned char *, size_t, + unsigned char *, size_t); + + size_t pmslen; /*!< premaster length */ + + unsigned char randbytes[64]; /*!< random bytes */ + unsigned char premaster[MBEDTLS_PREMASTER_SIZE]; + /*!< premaster secret */ + + int resume; /*!< session resume indicator*/ + int max_major_ver; /*!< max. major version client*/ + int max_minor_ver; /*!< max. minor version client*/ + int cli_exts; /*!< client extension presence*/ + +#if defined(MBEDTLS_SSL_SESSION_TICKETS) + int new_session_ticket; /*!< use NewSessionTicket? */ +#endif /* MBEDTLS_SSL_SESSION_TICKETS */ +#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) + int extended_ms; /*!< use Extended Master Secret? */ #endif }; /* - * Getter functions for fields in mbedtls_ssl_handshake_params which - * may be statically implied by the configuration and hence be omitted - * from the structure. - */ -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) -static inline int mbedtls_ssl_hs_get_extended_ms( - mbedtls_ssl_handshake_params const *params ) -{ -#if !defined(MBEDTLS_SSL_EXTENDED_MS_ENFORCED) - return( params->extended_ms ); -#else - ((void) params); - return( MBEDTLS_SSL_EXTENDED_MS_ENABLED ); -#endif /* MBEDTLS_SSL_EXTENDED_MS_ENFORCED */ -} -#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ - -#if !defined(MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE) -static inline mbedtls_ssl_ciphersuite_handle_t mbedtls_ssl_handshake_get_ciphersuite( - mbedtls_ssl_handshake_params const *handshake ) -{ - return( handshake->ciphersuite_info ); -} -#else /* !MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE */ -static inline mbedtls_ssl_ciphersuite_handle_t mbedtls_ssl_handshake_get_ciphersuite( - mbedtls_ssl_handshake_params const *handshake ) -{ - ((void) handshake); - return( MBEDTLS_SSL_CIPHERSUITE_UNIQUE_VALID_HANDLE ); -} -#endif /* MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE */ - -typedef struct mbedtls_ssl_hs_buffer mbedtls_ssl_hs_buffer; - -/* - * Representation of decryption/encryption transformations on records - * - * There are the following general types of record transformations: - * - Stream transformations (TLS versions <= 1.2 only) - * Transformation adding a MAC and applying a stream-cipher - * to the authenticated message. - * - CBC block cipher transformations ([D]TLS versions <= 1.2 only) - * In addition to the distinction of the order of encryption and - * authentication, there's a fundamental difference between the - * handling in SSL3 & TLS 1.0 and TLS 1.1 and TLS 1.2: For SSL3 - * and TLS 1.0, the final IV after processing a record is used - * as the IV for the next record. No explicit IV is contained - * in an encrypted record. The IV for the first record is extracted - * at key extraction time. In contrast, for TLS 1.1 and 1.2, no - * IV is generated at key extraction time, but every encrypted - * record is explicitly prefixed by the IV with which it was encrypted. - * - AEAD transformations ([D]TLS versions >= 1.2 only) - * These come in two fundamentally different versions, the first one - * used in TLS 1.2, excluding ChaChaPoly ciphersuites, and the second - * one used for ChaChaPoly ciphersuites in TLS 1.2 as well as for TLS 1.3. - * In the first transformation, the IV to be used for a record is obtained - * as the concatenation of an explicit, static 4-byte IV and the 8-byte - * record sequence number, and explicitly prepending this sequence number - * to the encrypted record. In contrast, in the second transformation - * the IV is obtained by XOR'ing a static IV obtained at key extraction - * time with the 8-byte record sequence number, without prepending the - * latter to the encrypted record. - * - * In addition to type and version, the following parameters are relevant: - * - The symmetric cipher algorithm to be used. - * - The (static) encryption/decryption keys for the cipher. - * - For stream/CBC, the type of message digest to be used. - * - For stream/CBC, (static) encryption/decryption keys for the digest. - * - For AEAD transformations, the size (potentially 0) of an explicit, - * random initialization vector placed in encrypted records. - * - For some transformations (currently AEAD and CBC in SSL3 and TLS 1.0) - * an implicit IV. It may be static (e.g. AEAD) or dynamic (e.g. CBC) - * and (if present) is combined with the explicit IV in a transformation- - * dependent way (e.g. appending in TLS 1.2 and XOR'ing in TLS 1.3). - * - For stream/CBC, a flag determining the order of encryption and MAC. - * - The details of the transformation depend on the SSL/TLS version. - * - The length of the authentication tag. - * - * Note: Except for CBC in SSL3 and TLS 1.0, these parameters are - * constant across multiple encryption/decryption operations. - * For CBC, the implicit IV needs to be updated after each - * operation. - * - * The struct below refines this abstract view as follows: - * - The cipher underlying the transformation is managed in - * cipher contexts cipher_ctx_{enc/dec}, which must have the - * same cipher type. The mode of these cipher contexts determines - * the type of the transformation in the sense above: e.g., if - * the type is MBEDTLS_CIPHER_AES_256_CBC resp. MBEDTLS_CIPHER_AES_192_GCM - * then the transformation has type CBC resp. AEAD. - * - The cipher keys are never stored explicitly but - * are maintained within cipher_ctx_{enc/dec}. - * - For stream/CBC transformations, the message digest contexts - * used for the MAC's are stored in md_ctx_{enc/dec}. These contexts - * are unused for AEAD transformations. - * - For stream/CBC transformations and versions > SSL3, the - * MAC keys are not stored explicitly but maintained within - * md_ctx_{enc/dec}. - * - For stream/CBC transformations and version SSL3, the MAC - * keys are stored explicitly in mac_enc, mac_dec and have - * a fixed size of 20 bytes. These fields are unused for - * AEAD transformations or transformations >= TLS 1.0. - * - For transformations using an implicit IV maintained within - * the transformation context, its contents are stored within - * iv_{enc/dec}. - * - The value of ivlen indicates the length of the IV. - * This is redundant in case of stream/CBC transformations - * which always use 0 resp. the cipher's block length as the - * IV length, but is needed for AEAD ciphers and may be - * different from the underlying cipher's block length - * in this case. - * - The field fixed_ivlen is nonzero for AEAD transformations only - * and indicates the length of the static part of the IV which is - * constant throughout the communication, and which is stored in - * the first fixed_ivlen bytes of the iv_{enc/dec} arrays. - * Note: For CBC in SSL3 and TLS 1.0, the fields iv_{enc/dec} - * still store IV's for continued use across multiple transformations, - * so it is not true that fixed_ivlen == 0 means that iv_{enc/dec} are - * not being used! - * - minor_ver denotes the SSL/TLS version - * - For stream/CBC transformations, maclen denotes the length of the - * authentication tag, while taglen is unused and 0. - * - For AEAD transformations, taglen denotes the length of the - * authentication tag, while maclen is unused and 0. - * - For CBC transformations, encrypt_then_mac determines the - * order of encryption and authentication. This field is unused - * in other transformations. - * + * This structure contains a full set of runtime transform parameters + * either in negotiation or active. */ struct mbedtls_ssl_transform { -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - uint8_t in_cid_len; - uint8_t out_cid_len; -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ /* * Session specific crypto layer */ + const mbedtls_ssl_ciphersuite_t *ciphersuite_info; + /*!< Chosen cipersuite_info */ + unsigned int keylen; /*!< symmetric key length (bytes) */ + size_t minlen; /*!< min. ciphertext length */ size_t ivlen; /*!< IV length */ size_t fixed_ivlen; /*!< Fixed part of IV (AEAD) */ - size_t maclen; /*!< MAC(CBC) len */ - size_t taglen; /*!< TAG(AEAD) len */ + size_t maclen; /*!< MAC length */ unsigned char iv_enc[16]; /*!< IV (encryption) */ unsigned char iv_dec[16]; /*!< IV (decryption) */ -#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC) - #if defined(MBEDTLS_SSL_PROTO_SSL3) /* Needed only for SSL v3.0 secret */ unsigned char mac_enc[20]; /*!< SSL v3.0 secret (enc) */ @@ -763,20 +344,8 @@ struct mbedtls_ssl_transform mbedtls_md_context_t md_ctx_enc; /*!< MAC (encryption) */ mbedtls_md_context_t md_ctx_dec; /*!< MAC (decryption) */ -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) - int encrypt_then_mac; /*!< flag for EtM activation */ -#endif - -#endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */ - -#if !defined(MBEDTLS_SSL_CONF_FIXED_MINOR_VER) - int minor_ver; -#endif - -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - unsigned char in_cid [ MBEDTLS_SSL_CID_OUT_LEN_MAX ]; - unsigned char out_cid[ MBEDTLS_SSL_CID_OUT_LEN_MAX ]; -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ + mbedtls_cipher_context_t cipher_ctx_enc; /*!< encryption context */ + mbedtls_cipher_context_t cipher_ctx_dec; /*!< decryption context */ /* * Session specific compression layer @@ -785,107 +354,8 @@ struct mbedtls_ssl_transform z_stream ctx_deflate; /*!< compression context */ z_stream ctx_inflate; /*!< decompression context */ #endif - -#if defined(MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS) - unsigned char *key_enc; - unsigned char *key_dec; - unsigned int key_bitlen; - mbedtls_cipher_context_t cipher_ctx; /*!< encryption/decryption context */ -#if defined(MBEDTLS_VALIDATE_SSL_KEYS_INTEGRITY) - uint32_t key_enc_hash; /*!< hash of the encryption key */ - uint32_t key_dec_hash; /*!< hash of the decryption key */ -#endif -#else - mbedtls_cipher_context_t cipher_ctx_enc; /*!< encryption context */ - mbedtls_cipher_context_t cipher_ctx_dec; /*!< decryption context */ -#endif -#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION) - /* We need the Hello random bytes in order to re-derive keys from the - * Master Secret and other session info, see ssl_populate_transform() */ - unsigned char randbytes[64]; /*!< ServerHello.random+ClientHello.random */ -#endif /* MBEDTLS_SSL_CONTEXT_SERIALIZATION */ }; -static inline int mbedtls_ssl_transform_get_minor_ver( mbedtls_ssl_transform const *transform ) -{ -#if !defined(MBEDTLS_SSL_CONF_FIXED_MINOR_VER) - return( transform->minor_ver ); -#else - ((void) transform); - return( MBEDTLS_SSL_CONF_FIXED_MINOR_VER ); -#endif -} - -/* - * Return 1 if the transform uses an AEAD cipher, 0 otherwise. - * Equivalently, return 0 if a separate MAC is used, 1 otherwise. - */ -static inline int mbedtls_ssl_transform_uses_aead( - const mbedtls_ssl_transform *transform ) -{ -#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC) - return( transform->maclen == 0 && transform->taglen != 0 ); -#else - (void) transform; - return( 1 ); -#endif -} - -/* - * Internal representation of record frames - * - * Instances come in two flavors: - * (1) Encrypted - * These always have data_offset = 0 - * (2) Unencrypted - * These have data_offset set to the amount of - * pre-expansion during record protection. Concretely, - * this is the length of the fixed part of the explicit IV - * used for encryption, or 0 if no explicit IV is used - * (e.g. for CBC in TLS 1.0, or stream ciphers). - * - * The reason for the data_offset in the unencrypted case - * is to allow for in-place conversion of an unencrypted to - * an encrypted record. If the offset wasn't included, the - * encrypted content would need to be shifted afterwards to - * make space for the fixed IV. - * - */ -#if MBEDTLS_SSL_CID_OUT_LEN_MAX > MBEDTLS_SSL_CID_IN_LEN_MAX -#define MBEDTLS_SSL_CID_LEN_MAX MBEDTLS_SSL_CID_OUT_LEN_MAX -#else -#define MBEDTLS_SSL_CID_LEN_MAX MBEDTLS_SSL_CID_IN_LEN_MAX -#endif - -typedef struct -{ -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - uint8_t cid_len; /* Length of the CID (0 if not present) */ -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - uint8_t type; /* The record content type. */ - uint8_t ver[2]; /* SSL/TLS version as present on the wire. - * Convert to internal presentation of versions - * using mbedtls_ssl_read_version() and - * mbedtls_ssl_write_version(). - * Keep wire-format for MAC computations. */ - - unsigned char *buf; /* Memory buffer enclosing the record content */ - size_t buf_len; /* Buffer length */ - size_t data_offset; /* Offset of record content */ - size_t data_len; /* Length of record content */ - uint8_t ctr[8]; /* In TLS: The implicit record sequence number. - * In DTLS: The 2-byte epoch followed by - * the 6-byte sequence number. - * This is stored as a raw big endian byte array - * as opposed to a uint64_t because we rarely - * need to perform arithmetic on this, but do - * need it as a Byte array for the purpose of - * MAC computations. */ -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - unsigned char cid[ MBEDTLS_SSL_CID_LEN_MAX ]; /* The CID */ -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ -} mbedtls_record; - #if defined(MBEDTLS_X509_CRT_PARSE_C) /* * List of certificate + private key pairs @@ -946,19 +416,20 @@ void mbedtls_ssl_transform_free( mbedtls_ssl_transform *transform ); * \brief Free referenced items in an SSL handshake context and clear * memory * - * \param ssl SSL context + * \param handshake SSL handshake context */ -void mbedtls_ssl_handshake_free( mbedtls_ssl_context *ssl ); +void mbedtls_ssl_handshake_free( mbedtls_ssl_handshake_params *handshake ); int mbedtls_ssl_handshake_client_step( mbedtls_ssl_context *ssl ); int mbedtls_ssl_handshake_server_step( mbedtls_ssl_context *ssl ); -int mbedtls_ssl_handshake_wrapup( mbedtls_ssl_context *ssl ); +void mbedtls_ssl_handshake_wrapup( mbedtls_ssl_context *ssl ); int mbedtls_ssl_send_fatal_handshake_failure( mbedtls_ssl_context *ssl ); void mbedtls_ssl_reset_checksum( mbedtls_ssl_context *ssl ); int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl ); +int mbedtls_ssl_read_record_layer( mbedtls_ssl_context *ssl ); int mbedtls_ssl_handle_message_type( mbedtls_ssl_context *ssl ); int mbedtls_ssl_prepare_handshake_record( mbedtls_ssl_context *ssl ); void mbedtls_ssl_update_handshake_status( mbedtls_ssl_context *ssl ); @@ -970,10 +441,7 @@ void mbedtls_ssl_update_handshake_status( mbedtls_ssl_context *ssl ); * of the logic of (D)TLS from the implementation * of the secure transport. * - * \param ssl The SSL context to use. - * \param update_hs_digest This indicates if the handshake digest - * should be automatically updated in case - * a handshake message is found. + * \param ssl SSL context to use * * \return 0 or non-zero error code. * @@ -1039,12 +507,10 @@ void mbedtls_ssl_update_handshake_status( mbedtls_ssl_context *ssl ); * following the above definition. * */ -int mbedtls_ssl_read_record( mbedtls_ssl_context *ssl, - unsigned update_hs_digest ); +int mbedtls_ssl_read_record( mbedtls_ssl_context *ssl ); int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want ); -int mbedtls_ssl_write_handshake_msg( mbedtls_ssl_context *ssl ); -int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl, uint8_t force_flush ); +int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl ); int mbedtls_ssl_flush_output( mbedtls_ssl_context *ssl ); int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl ); @@ -1057,9 +523,7 @@ int mbedtls_ssl_parse_finished( mbedtls_ssl_context *ssl ); int mbedtls_ssl_write_finished( mbedtls_ssl_context *ssl ); void mbedtls_ssl_optimize_checksum( mbedtls_ssl_context *ssl, - mbedtls_ssl_ciphersuite_handle_t ciphersuite_info ); - -int mbedtls_ssl_build_pms( mbedtls_ssl_context *ssl ); + const mbedtls_ssl_ciphersuite_t *ciphersuite_info ); #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl, mbedtls_key_exchange_type_t key_ex ); @@ -1073,15 +537,10 @@ mbedtls_pk_type_t mbedtls_ssl_pk_alg_from_sig( unsigned char sig ); mbedtls_md_type_t mbedtls_ssl_md_alg_from_hash( unsigned char hash ); unsigned char mbedtls_ssl_hash_from_md_alg( int md ); - -#if defined(MBEDTLS_USE_TINYCRYPT) -int mbedtls_ssl_check_curve_uecc( const mbedtls_ssl_context *ssl, - mbedtls_uecc_group_id grp_id ); -#endif +int mbedtls_ssl_set_calc_verify_md( mbedtls_ssl_context *ssl, int md ); #if defined(MBEDTLS_ECP_C) -int mbedtls_ssl_check_curve( const mbedtls_ssl_context *ssl, - mbedtls_ecp_group_id grp_id ); +int mbedtls_ssl_check_curve( const mbedtls_ssl_context *ssl, mbedtls_ecp_group_id grp_id ); #endif #if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) @@ -1089,34 +548,6 @@ int mbedtls_ssl_check_sig_hash( const mbedtls_ssl_context *ssl, mbedtls_md_type_t md ); #endif -#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) && defined(MBEDTLS_SSL_DELAYED_SERVER_CERT_VERIFICATION) -int mbedtls_ssl_parse_delayed_certificate_verify( mbedtls_ssl_context *ssl, - int authmode, - mbedtls_x509_crt *chain, - void *rs_ctx ); -#endif /* MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED && MBEDTLS_SSL_DELAYED_SERVER_CERT_VERIFICATION */ - - -static inline int mbedtls_ssl_get_minor_ver( mbedtls_ssl_context const *ssl ) -{ -#if !defined(MBEDTLS_SSL_CONF_FIXED_MINOR_VER) - return( ssl->minor_ver ); -#else /* !MBEDTLS_SSL_CONF_FIXED_MINOR_VER */ - ((void) ssl); - return( MBEDTLS_SSL_CONF_FIXED_MINOR_VER ); -#endif /* MBEDTLS_SSL_CONF_FIXED_MINOR_VER */ -} - -static inline int mbedtls_ssl_get_major_ver( mbedtls_ssl_context const *ssl ) -{ -#if !defined(MBEDTLS_SSL_CONF_FIXED_MAJOR_VER) - return( ssl->major_ver ); -#else /* !MBEDTLS_SSL_CONF_FIXED_MAJOR_VER */ - ((void) ssl); - return( MBEDTLS_SSL_CONF_FIXED_MAJOR_VER ); -#endif /* MBEDTLS_SSL_CONF_FIXED_MAJOR_VER */ -} - #if defined(MBEDTLS_X509_CRT_PARSE_C) static inline mbedtls_pk_context *mbedtls_ssl_own_key( mbedtls_ssl_context *ssl ) { @@ -1152,70 +583,69 @@ static inline mbedtls_x509_crt *mbedtls_ssl_own_cert( mbedtls_ssl_context *ssl ) * Return 0 if everything is OK, -1 if not. */ int mbedtls_ssl_check_cert_usage( const mbedtls_x509_crt *cert, - mbedtls_ssl_ciphersuite_handle_t ciphersuite, + const mbedtls_ssl_ciphersuite_t *ciphersuite, int cert_endpoint, uint32_t *flags ); #endif /* MBEDTLS_X509_CRT_PARSE_C */ -static inline size_t mbedtls_ssl_in_hdr_len( const mbedtls_ssl_context *ssl ) +void mbedtls_ssl_write_version( int major, int minor, int transport, + unsigned char ver[2] ); +void mbedtls_ssl_read_version( int *major, int *minor, int transport, + const unsigned char ver[2] ); + +static inline size_t mbedtls_ssl_hdr_len( const mbedtls_ssl_context *ssl ) { -#if !defined(MBEDTLS_SSL_PROTO__BOTH) +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + return( 13 ); +#else ((void) ssl); #endif - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) ) - { - return( 13 ); - } - MBEDTLS_SSL_TRANSPORT_ELSE -#endif /* MBEDTLS_SSL_PROTO_DTLS */ -#if defined(MBEDTLS_SSL_PROTO_TLS) - { - return( 5 ); - } -#endif /* MBEDTLS_SSL_PROTO_TLS */ -} - -static inline size_t mbedtls_ssl_out_hdr_len( const mbedtls_ssl_context *ssl ) -{ - return( (size_t) ( ssl->out_iv - ssl->out_hdr ) ); + return( 5 ); } static inline size_t mbedtls_ssl_hs_hdr_len( const mbedtls_ssl_context *ssl ) { -#if !defined(MBEDTLS_SSL_PROTO__BOTH) +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + return( 12 ); +#else ((void) ssl); #endif - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) ) - return( 12 ); - MBEDTLS_SSL_TRANSPORT_ELSE -#endif -#if defined(MBEDTLS_SSL_PROTO_TLS) - return( 4 ); -#endif + return( 4 ); } #if defined(MBEDTLS_SSL_PROTO_DTLS) void mbedtls_ssl_send_flight_completed( mbedtls_ssl_context *ssl ); void mbedtls_ssl_recv_flight_completed( mbedtls_ssl_context *ssl ); int mbedtls_ssl_resend( mbedtls_ssl_context *ssl ); -int mbedtls_ssl_flight_transmit( mbedtls_ssl_context *ssl ); -#if defined(MBEDTLS_SSL_IMMEDIATE_TRANSMISSION) -void mbedtls_ssl_immediate_flight_done( mbedtls_ssl_context *ssl ); -#endif #endif /* Visible for testing purposes only */ #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) -int mbedtls_ssl_dtls_replay_check( mbedtls_ssl_context const *ssl ); +int mbedtls_ssl_dtls_replay_check( mbedtls_ssl_context *ssl ); void mbedtls_ssl_dtls_replay_update( mbedtls_ssl_context *ssl ); #endif -int mbedtls_ssl_session_copy( mbedtls_ssl_session *dst, - const mbedtls_ssl_session *src ); +/* constant-time buffer comparison */ +static inline int mbedtls_ssl_safer_memcmp( const void *a, const void *b, size_t n ) +{ + size_t i; + volatile const unsigned char *A = (volatile const unsigned char *) a; + volatile const unsigned char *B = (volatile const unsigned char *) b; + volatile unsigned char diff = 0; + + for( i = 0; i < n; i++ ) + { + /* Read volatile data in order before computing diff. + * This avoids IAR compiler warning: + * 'the order of volatile accesses is undefined ..' */ + unsigned char x = A[i], y = B[i]; + diff |= x ^ y; + } + + return( diff ); +} #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ defined(MBEDTLS_SSL_PROTO_TLS1_1) @@ -1228,824 +658,14 @@ int mbedtls_ssl_get_key_exchange_md_ssl_tls( mbedtls_ssl_context *ssl, #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ defined(MBEDTLS_SSL_PROTO_TLS1_2) int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl, - unsigned char *hash, size_t *hashlen, - unsigned char *data, size_t data_len, - mbedtls_md_type_t md_alg ); + unsigned char *output, + unsigned char *data, size_t data_len, + mbedtls_md_type_t md_alg ); #endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \ MBEDTLS_SSL_PROTO_TLS1_2 */ -#if defined(MBEDTLS_SSL_PROTO_TLS) - -/* - * Convert version numbers to/from wire format - * and, for DTLS, to/from TLS equivalent. - * - * For TLS this is the identity. - * For DTLS, use 1's complement (v -> 255 - v, and then map as follows: - * 1.0 <-> 3.2 (DTLS 1.0 is based on TLS 1.1) - * 1.x <-> 3.x+1 for x != 0 (DTLS 1.2 based on TLS 1.2) - */ -MBEDTLS_ALWAYS_INLINE static inline void mbedtls_ssl_write_version( - int major, int minor, int transport, unsigned char ver[2] ) -{ -#if !defined(MBEDTLS_SSL_TRANSPORT__BOTH) - ((void) transport); -#endif - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( transport ) ) - { - if( minor == MBEDTLS_SSL_MINOR_VERSION_2 ) - --minor; /* DTLS 1.0 stored as TLS 1.1 internally */ - - ver[0] = (unsigned char)( 255 - ( major - 2 ) ); - ver[1] = (unsigned char)( 255 - ( minor - 1 ) ); - } - MBEDTLS_SSL_TRANSPORT_ELSE -#endif -#if defined(MBEDTLS_SSL_PROTO_TLS) - { - ver[0] = (unsigned char) major; - ver[1] = (unsigned char) minor; - } -#endif -} - -MBEDTLS_ALWAYS_INLINE static inline void mbedtls_ssl_read_version( - int *major, int *minor, int transport, const unsigned char ver[2] ) -{ -#if !defined(MBEDTLS_SSL_TRANSPORT__BOTH) - ((void) transport); -#endif - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( transport ) ) - { - *major = 255 - ver[0] + 2; - *minor = 255 - ver[1] + 1; - - if( *minor == MBEDTLS_SSL_MINOR_VERSION_1 ) - ++*minor; /* DTLS 1.0 stored as TLS 1.1 internally */ - } - MBEDTLS_SSL_TRANSPORT_ELSE -#endif /* MBEDTLS_SSL_PROTO_DTLS */ -#if defined(MBEDTLS_SSL_PROTO_TLS) - { - *major = ver[0]; - *minor = ver[1]; - } -#endif /* MBEDTLS_SSL_PROTO_TLS */ -} - - -MBEDTLS_ALWAYS_INLINE static inline int mbedtls_ssl_ver_leq( int v0, int v1 ) -{ - return( v0 <= v1 ); -} - -MBEDTLS_ALWAYS_INLINE static inline int mbedtls_ssl_ver_lt( int v0, int v1 ) -{ - return( v0 < v1 ); -} - -MBEDTLS_ALWAYS_INLINE static inline int mbedtls_ssl_ver_geq( int v0, int v1 ) -{ - return( v0 >= v1 ); -} - -MBEDTLS_ALWAYS_INLINE static inline int mbedtls_ssl_ver_gt( int v0, int v1 ) -{ - return( v0 > v1 ); -} - -#else /* MBEDTLS_SSL_PROTO_TLS */ - -/* If only DTLS is enabled, we can match the internal encoding - * with the standard's encoding of versions. */ -static inline void mbedtls_ssl_write_version( int major, int minor, - int transport, - unsigned char ver[2] ) -{ - ((void) transport); - ver[0] = (unsigned char) major; - ver[1] = (unsigned char) minor; -} - -static inline void mbedtls_ssl_read_version( int *major, int *minor, - int transport, - const unsigned char ver[2] ) -{ - ((void) transport); - *major = ver[0]; - *minor = ver[1]; -} - -MBEDTLS_ALWAYS_INLINE static inline int mbedtls_ssl_ver_leq( int v0, int v1 ) -{ - return( v0 >= v1 ); -} - -MBEDTLS_ALWAYS_INLINE static inline int mbedtls_ssl_ver_lt( int v0, int v1 ) -{ - return( v0 > v1 ); -} - -MBEDTLS_ALWAYS_INLINE static inline int mbedtls_ssl_ver_geq( int v0, int v1 ) -{ - return( v0 <= v1 ); -} - -MBEDTLS_ALWAYS_INLINE static inline int mbedtls_ssl_ver_gt( int v0, int v1 ) -{ - return( v0 < v1 ); -} - -#endif /* MBEDTLS_SSL_PROTO_TLS */ - -MBEDTLS_ALWAYS_INLINE static inline size_t mbedtls_ssl_minor_ver_index( - int ver ) -{ - switch( ver ) - { - case MBEDTLS_SSL_MINOR_VERSION_0: - return( 0 ); - case MBEDTLS_SSL_MINOR_VERSION_1: - return( 1 ); - case MBEDTLS_SSL_MINOR_VERSION_2: - return( 2 ); - case MBEDTLS_SSL_MINOR_VERSION_3: - return( 3 ); - } - return( 0 ); -} - #ifdef __cplusplus } #endif -void mbedtls_ssl_transform_init( mbedtls_ssl_transform *transform ); -int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl, - mbedtls_ssl_transform *transform, - mbedtls_record *rec, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ); -int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl, - mbedtls_ssl_transform *transform, - mbedtls_record *rec ); - - -/* - * Accessor functions for optional fields of various structures - */ - -static inline int mbedtls_ssl_handshake_get_resume( - const mbedtls_ssl_handshake_params *handshake ) -{ -#if !defined(MBEDTLS_SSL_NO_SESSION_RESUMPTION) - return( handshake->resume ); -#else - (void) handshake; - return( 0 ); -#endif -} - -static inline int mbedtls_ssl_get_renego_status( - const mbedtls_ssl_context *ssl ) -{ -#if defined(MBEDTLS_SSL_RENEGOTIATION) - return( ssl->renego_status ); -#else - (void) ssl; - return( MBEDTLS_SSL_INITIAL_HANDSHAKE ); -#endif -} - -static inline int mbedtls_ssl_conf_is_renegotiation_enabled( - const mbedtls_ssl_config *conf ) -{ -#if defined(MBEDTLS_SSL_RENEGOTIATION) - return( conf->disable_renegotiation == - MBEDTLS_SSL_RENEGOTIATION_ENABLED ); -#else - (void) conf; - return( 0 ); -#endif -} - -/* - * Getter functions for fields in mbedtls_ssl_config which may - * be fixed at compile time via one of MBEDTLS_SSL_SSL_CONF_XXX. - */ - -#if defined(MBEDTLS_SSL_SRV_C) -#if !defined(MBEDTLS_SSL_CONF_CERT_REQ_CA_LIST) -static inline unsigned int mbedtls_ssl_conf_get_cert_req_ca_list( - mbedtls_ssl_config const *conf ) -{ - return( conf->cert_req_ca_list ); -} -#else /* !MBEDTLS_SSL_CONF_CERT_REQ_CA_LIST */ -static inline unsigned int mbedtls_ssl_conf_get_cert_req_ca_list( - mbedtls_ssl_config const *conf ) -{ - ((void) conf); - return( MBEDTLS_SSL_CONF_CERT_REQ_CA_LIST ); -} -#endif /* MBEDTLS_SSL_CONF_CERT_REQ_CA_LIST */ -#endif /* MBEDTLS_SSL_SRV_C */ - -#if !defined(MBEDTLS_SSL_CONF_ENDPOINT) -static inline unsigned int mbedtls_ssl_conf_get_endpoint( - mbedtls_ssl_config const *conf ) -{ - return( conf->endpoint ); -} -#else /* !MBEDTLS_SSL_CONF_ENDPOINT */ -static inline unsigned int mbedtls_ssl_conf_get_endpoint( - mbedtls_ssl_config const *conf ) -{ - ((void) conf); - return( MBEDTLS_SSL_CONF_ENDPOINT ); -} -#endif /* MBEDTLS_SSL_CONF_ENDPOINT */ - -#if !defined(MBEDTLS_SSL_CONF_TRANSPORT) -static inline unsigned int mbedtls_ssl_conf_get_transport( - mbedtls_ssl_config const *conf ) -{ - return( conf->transport ); -} -#else /* !MBEDTLS_SSL_CONF_TRANSPORT */ -static inline unsigned int mbedtls_ssl_conf_get_transport( - mbedtls_ssl_config const *conf ) -{ - ((void) conf); - return( MBEDTLS_SSL_CONF_TRANSPORT ); -} -#endif /* MBEDTLS_SSL_CONF_TRANSPORT */ - -#if !defined(MBEDTLS_SSL_CONF_READ_TIMEOUT) -static inline uint32_t mbedtls_ssl_conf_get_read_timeout( - mbedtls_ssl_config const *conf ) -{ - return( conf->read_timeout ); -} -#else /* !MBEDTLS_SSL_CONF_READ_TIMEOUT */ -static inline uint32_t mbedtls_ssl_conf_get_read_timeout( - mbedtls_ssl_config const *conf ) -{ - ((void) conf); - return( MBEDTLS_SSL_CONF_READ_TIMEOUT ); -} -#endif /* MBEDTLS_SSL_CONF_READ_TIMEOUT */ - -#if defined(MBEDTLS_SSL_PROTO_DTLS) -#if !defined(MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN) -static inline uint32_t mbedtls_ssl_conf_get_hs_timeout_min( - mbedtls_ssl_config const *conf ) -{ - return( conf->hs_timeout_min ); -} -#else /* !MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN */ -static inline uint32_t mbedtls_ssl_conf_get_hs_timeout_min( - mbedtls_ssl_config const *conf ) -{ - ((void) conf); - return( MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN ); -} -#endif /* MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN */ - -#if !defined(MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX) -static inline uint32_t mbedtls_ssl_conf_get_hs_timeout_max( - mbedtls_ssl_config const *conf ) -{ - return( conf->hs_timeout_max ); -} -#else /* !MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX */ -static inline uint32_t mbedtls_ssl_conf_get_hs_timeout_max( - mbedtls_ssl_config const *conf ) -{ - ((void) conf); - return( MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX ); -} -#endif /* MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX */ -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) -#if !defined(MBEDTLS_SSL_CONF_CID_LEN) -static inline size_t mbedtls_ssl_conf_get_cid_len( - mbedtls_ssl_config const *conf ) -{ - return( conf->cid_len ); -} -#else /* !MBEDTLS_SSL_CONF_CID_LEN */ -static inline size_t mbedtls_ssl_conf_get_cid_len( - mbedtls_ssl_config const *conf ) -{ - ((void) conf); - return( MBEDTLS_SSL_CONF_CID_LEN ); -} -#endif /* MBEDTLS_SSL_CONF_CID_LEN */ - -#if !defined(MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID) -static inline unsigned int mbedtls_ssl_conf_get_ignore_unexpected_cid( - mbedtls_ssl_config const *conf ) -{ - return( conf->ignore_unexpected_cid ); -} -#else /* !MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID */ -static inline unsigned int mbedtls_ssl_conf_get_ignore_unexpected_cid( - mbedtls_ssl_config const *conf ) -{ - ((void) conf); - return( MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID ); -} -#endif /* MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID */ -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - -#if !defined(MBEDTLS_SSL_CONF_ALLOW_LEGACY_RENEGOTIATION) -static inline unsigned int mbedtls_ssl_conf_get_allow_legacy_renegotiation( - mbedtls_ssl_config const *conf ) -{ - return( conf->allow_legacy_renegotiation ); -} -#else /* !MBEDTLS_SSL_CONF_ALLOW_LEGACY_RENEGOTIATION */ -static inline unsigned int mbedtls_ssl_conf_get_allow_legacy_renegotiation( - mbedtls_ssl_config const *conf ) -{ - ((void) conf); - return( MBEDTLS_SSL_CONF_ALLOW_LEGACY_RENEGOTIATION ); -} -#endif /* MBEDTLS_SSL_CONF_ALLOW_LEGACY_RENEGOTIATION */ - -#if !defined(MBEDTLS_SSL_CONF_AUTHMODE) -static inline int mbedtls_ssl_conf_get_authmode( - mbedtls_ssl_config const *conf ) -{ - return( conf->authmode ); -} -#else /* !MBEDTLS_SSL_CONF_AUTHMODE */ -static inline int mbedtls_ssl_conf_get_authmode( - mbedtls_ssl_config const *conf ) -{ - ((void) conf); - return( MBEDTLS_SSL_CONF_AUTHMODE ); -} -#endif /* MBEDTLS_SSL_CONF_AUTHMODE */ - -#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) -#if !defined(MBEDTLS_SSL_CONF_BADMAC_LIMIT) -static inline unsigned int mbedtls_ssl_conf_get_badmac_limit( - mbedtls_ssl_config const *conf ) -{ - return( conf->badmac_limit ); -} -#else /* !MBEDTLS_SSL_CONF_BADMAC_LIMIT */ -static inline unsigned int mbedtls_ssl_conf_get_badmac_limit( - mbedtls_ssl_config const *conf ) -{ - ((void) conf); - return( MBEDTLS_SSL_CONF_BADMAC_LIMIT ); -} -#endif /* MBEDTLS_SSL_CONF_BADMAC_LIMIT */ -#endif /* MBEDTLS_SSL_DTLS_BADMAC_LIMIT */ - -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) -#if !defined(MBEDTLS_SSL_CONF_ANTI_REPLAY) -static inline unsigned int mbedtls_ssl_conf_get_anti_replay( - mbedtls_ssl_config const *conf ) -{ - return( conf->anti_replay ); -} -#else /* !MBEDTLS_SSL_CONF_ANTI_REPLAY */ -static inline unsigned int mbedtls_ssl_conf_get_anti_replay( - mbedtls_ssl_config const *conf ) -{ - ((void) conf); - return( MBEDTLS_SSL_CONF_ANTI_REPLAY ); -} -#endif /* MBEDTLS_SSL_CONF_ANTI_REPLAY */ -#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */ - -#if !defined(MBEDTLS_SSL_CONF_SET_TIMER) -static inline mbedtls_ssl_set_timer_t* mbedtls_ssl_get_set_timer( - mbedtls_ssl_context const *ssl ) -{ - return( ssl->f_set_timer ); -} -#else /* !MBEDTLS_SSL_CONF_SET_TIMER */ - -#define mbedtls_ssl_conf_set_timer_func MBEDTLS_SSL_CONF_SET_TIMER -extern void mbedtls_ssl_conf_set_timer_func( void*, uint32_t, uint32_t ); - -static inline mbedtls_ssl_set_timer_t* mbedtls_ssl_get_set_timer( - mbedtls_ssl_context const *ssl ) -{ - ((void) ssl); - return ((mbedtls_ssl_set_timer_t*) mbedtls_ssl_conf_set_timer_func); -} -#endif /* MBEDTLS_SSL_CONF_SET_TIMER */ - -#if !defined(MBEDTLS_SSL_CONF_GET_TIMER) -static inline mbedtls_ssl_get_timer_t* mbedtls_ssl_get_get_timer( - mbedtls_ssl_context const *ssl ) -{ - return( ssl->f_get_timer ); -} -#else /* !MBEDTLS_SSL_CONF_GET_TIMER */ - -#define mbedtls_ssl_conf_get_timer_func MBEDTLS_SSL_CONF_GET_TIMER -extern int mbedtls_ssl_conf_get_timer_func( void* ); - -static inline mbedtls_ssl_get_timer_t* mbedtls_ssl_get_get_timer( - mbedtls_ssl_context const *ssl ) -{ - ((void) ssl); - return ((mbedtls_ssl_get_timer_t*) mbedtls_ssl_conf_get_timer_func); -} -#endif /* MBEDTLS_SSL_CONF_GET_TIMER */ - -#if !defined(MBEDTLS_SSL_CONF_RECV) -static inline mbedtls_ssl_recv_t* mbedtls_ssl_get_recv( - mbedtls_ssl_context const *ssl ) -{ - return( ssl->f_recv ); -} -#else /* !MBEDTLS_SSL_CONF_RECV */ - -#define mbedtls_ssl_conf_recv_func MBEDTLS_SSL_CONF_RECV -extern int mbedtls_ssl_conf_recv_func( void*, unsigned char*, size_t ); - -static inline mbedtls_ssl_recv_t* mbedtls_ssl_get_recv( - mbedtls_ssl_context const *ssl ) -{ - ((void) ssl); - return ((mbedtls_ssl_recv_t*) mbedtls_ssl_conf_recv_func); -} -#endif /* MBEDTLS_SSL_CONF_RECV */ - -#if !defined(MBEDTLS_SSL_CONF_SEND) -static inline mbedtls_ssl_send_t* mbedtls_ssl_get_send( - mbedtls_ssl_context const *ssl ) -{ - return( ssl->f_send ); -} -#else /* !MBEDTLS_SSL_CONF_SEND */ - -#define mbedtls_ssl_conf_send_func MBEDTLS_SSL_CONF_SEND -extern int mbedtls_ssl_conf_send_func( void*, unsigned char const*, size_t ); - -static inline mbedtls_ssl_send_t* mbedtls_ssl_get_send( - mbedtls_ssl_context const *ssl ) -{ - ((void) ssl); - return ((mbedtls_ssl_send_t*) mbedtls_ssl_conf_send_func); -} -#endif /* MBEDTLS_SSL_CONF_SEND */ - -#if !defined(MBEDTLS_SSL_CONF_RECV_TIMEOUT) -static inline mbedtls_ssl_recv_timeout_t* mbedtls_ssl_get_recv_timeout( - mbedtls_ssl_context const *ssl ) -{ - return( ssl->f_recv_timeout ); -} -#else /* !MBEDTLS_SSL_CONF_RECV_TIMEOUT */ - -#define mbedtls_ssl_conf_recv_timeout_func MBEDTLS_SSL_CONF_RECV_TIMEOUT -extern int mbedtls_ssl_conf_recv_timeout_func( - void*, unsigned char*, size_t, uint32_t ); - -static inline mbedtls_ssl_recv_timeout_t* mbedtls_ssl_get_recv_timeout( - mbedtls_ssl_context const *ssl ) -{ - ((void) ssl); - return ((mbedtls_ssl_recv_timeout_t*) mbedtls_ssl_conf_recv_timeout_func); -} -#endif /* MBEDTLS_SSL_CONF_RECV_TIMEOUT */ - -typedef int mbedtls_frng_t( void*, unsigned char*, size_t ); - -#if !defined(MBEDTLS_SSL_CONF_RNG) -static inline mbedtls_frng_t* mbedtls_ssl_conf_get_frng( - mbedtls_ssl_config const *conf ) -{ - return( conf->f_rng ); -} - -static inline void* mbedtls_ssl_conf_get_prng( mbedtls_ssl_config const *conf ) -{ - return( conf->p_rng ); -} -#else /* !MBEDTLS_SSL_CONF_RNG */ -#define mbedtls_ssl_conf_rng_func MBEDTLS_SSL_CONF_RNG -extern int mbedtls_ssl_conf_rng_func( void*, unsigned char*, size_t ); - -static inline mbedtls_frng_t* mbedtls_ssl_conf_get_frng( - mbedtls_ssl_config const *conf ) -{ - ((void) conf); - return ((mbedtls_frng_t*) mbedtls_ssl_conf_rng_func); -} - -static inline void* mbedtls_ssl_conf_get_prng( mbedtls_ssl_config const *conf ) -{ - ((void) conf); - return( NULL ); -} -#endif /* MBEDTLS_SSL_CONF_RNG */ - -static inline int mbedtls_ssl_conf_get_max_major_ver( - mbedtls_ssl_config const *conf ) -{ -#if !defined(MBEDTLS_SSL_CONF_MAX_MAJOR_VER) - return( conf->max_major_ver ); -#else - ((void) conf); - return( MBEDTLS_SSL_CONF_MAX_MAJOR_VER ); -#endif /* MBEDTLS_SSL_CONF_MAX_MAJOR_VER */ -} - -static inline int mbedtls_ssl_conf_get_min_major_ver( - mbedtls_ssl_config const *conf ) -{ -#if !defined(MBEDTLS_SSL_CONF_MIN_MAJOR_VER) - return( conf->min_major_ver ); -#else /* !MBEDTLS_SSL_CONF_MIN_MAJOR_VER */ - ((void) conf); - return( MBEDTLS_SSL_CONF_MIN_MAJOR_VER ); -#endif /* MBEDTLS_SSL_CONF_MIN_MAJOR_VER */ -} - -static inline int mbedtls_ssl_conf_get_max_minor_ver( - mbedtls_ssl_config const *conf ) -{ -#if !defined(MBEDTLS_SSL_CONF_MAX_MINOR_VER) - return( conf->max_minor_ver ); -#else /* !MBEDTLS_SSL_CONF_MAX_MINOR_VER */ - ((void) conf); - return( MBEDTLS_SSL_CONF_MAX_MINOR_VER ); -#endif /* MBEDTLS_SSL_CONF_MAX_MINOR_VER */ -} - -static inline int mbedtls_ssl_conf_get_min_minor_ver( - mbedtls_ssl_config const *conf ) -{ -#if !defined(MBEDTLS_SSL_CONF_MIN_MINOR_VER) - return( conf->min_minor_ver ); -#else /* !MBEDTLS_SSL_CONF_MIN_MINOR_VER */ - ((void) conf); - return( MBEDTLS_SSL_CONF_MIN_MINOR_VER ); -#endif /* MBEDTLS_SSL_CONF_MIN_MINOR_VER */ -} - -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) -static inline unsigned int mbedtls_ssl_conf_get_ems( - mbedtls_ssl_config const *conf ) -{ -#if !defined(MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET) - return( conf->extended_ms ); -#else - ((void) conf); - return( MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET ); -#endif /* MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET */ -} - -static inline unsigned int mbedtls_ssl_conf_get_ems_enforced( - mbedtls_ssl_config const *conf ) -{ -#if !defined(MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET) - return( conf->enforce_extended_master_secret ); -#else - ((void) conf); - return( MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET ); -#endif /* MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET */ -} -#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ - -/* - * Macros for the traversal of the list of all enabled ciphersuites. - * This is implemented as a plain loop in case we have a runtime - * configurable list of ciphersuites, and as a simple variable - * instantiation in case a single ciphersuite is enabled at - * compile-time. - */ -#if !defined(MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE) - -#define MBEDTLS_SSL_BEGIN_FOR_EACH_CIPHERSUITE( ssl, ver, info ) \ - { \ - int const *__id_ptr; \ - for( __id_ptr=(ssl)->conf->ciphersuite_list[ \ - mbedtls_ssl_minor_ver_index( ver ) ]; \ - *__id_ptr != 0; __id_ptr++ ) \ - { \ - const int __id = *__id_ptr; \ - mbedtls_ssl_ciphersuite_handle_t info; \ - info = mbedtls_ssl_ciphersuite_from_id( __id ); \ - if( info == MBEDTLS_SSL_CIPHERSUITE_INVALID_HANDLE ) \ - continue; - -#define MBEDTLS_SSL_END_FOR_EACH_CIPHERSUITE \ - } \ - } - -#else /* !MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE */ - -#define MBEDTLS_SSL_BEGIN_FOR_EACH_CIPHERSUITE( ssl, ver, info ) \ - do { \ - const mbedtls_ssl_ciphersuite_handle_t info = \ - MBEDTLS_SSL_CIPHERSUITE_UNIQUE_VALID_HANDLE; - -#define MBEDTLS_SSL_END_FOR_EACH_CIPHERSUITE \ - } while( 0 ); - -#endif /* MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE */ - -#if !defined(MBEDTLS_SSL_CONF_SINGLE_EC) - -#define MBEDTLS_SSL_BEGIN_FOR_EACH_SUPPORTED_EC_TLS_ID( TLS_ID_VAR ) \ - { \ - mbedtls_ecp_group_id const *_gid; \ - mbedtls_ecp_curve_info const *_info; \ - for( _gid = ssl->conf->curve_list; \ - *_gid != MBEDTLS_ECP_DP_NONE; _gid++ ) \ - { \ - uint16_t TLS_ID_VAR; \ - _info = mbedtls_ecp_curve_info_from_grp_id( *_gid ) ; \ - if( _info == NULL ) \ - continue; \ - TLS_ID_VAR = _info->tls_id; - -#define MBEDTLS_SSL_END_FOR_EACH_SUPPORTED_EC_TLS_ID \ - } \ - } - -#define MBEDTLS_SSL_BEGIN_FOR_EACH_SUPPORTED_EC_GRP_ID( EC_ID_VAR ) \ - { \ - mbedtls_ecp_group_id const *_gid; \ - for( _gid = ssl->conf->curve_list; \ - *_gid != MBEDTLS_ECP_DP_NONE; _gid++ ) \ - { \ - mbedtls_ecp_group_id EC_ID_VAR = *_gid; \ - -#define MBEDTLS_SSL_END_FOR_EACH_SUPPORTED_EC_GRP_ID \ - } \ - } - -#else /* !MBEDTLS_SSL_CONF_SINGLE_EC */ - -#define MBEDTLS_SSL_BEGIN_FOR_EACH_SUPPORTED_EC_TLS_ID( TLS_ID_VAR ) \ - { \ - uint16_t TLS_ID_VAR = MBEDTLS_SSL_CONF_SINGLE_EC_TLS_ID; \ - ((void) ssl); - -#define MBEDTLS_SSL_END_FOR_EACH_SUPPORTED_EC_TLS_ID \ - } - -#if defined(MBEDTLS_USE_TINYCRYPT) -#define MBEDTLS_SSL_BEGIN_FOR_EACH_SUPPORTED_UECC_GRP_ID( EC_ID_VAR ) \ - { \ - mbedtls_uecc_group_id EC_ID_VAR = MBEDTLS_SSL_CONF_SINGLE_UECC_GRP_ID; \ - ((void) ssl); - -#define MBEDTLS_SSL_END_FOR_EACH_SUPPORTED_UECC_GRP_ID \ - } -#endif /* MBEDTLS_USE_TINYCRYPT */ - -#if defined(MBEDTLS_ECP_C) -#define MBEDTLS_SSL_BEGIN_FOR_EACH_SUPPORTED_EC_GRP_ID( EC_ID_VAR ) \ - { \ - mbedtls_ecp_group_id EC_ID_VAR = MBEDTLS_SSL_CONF_SINGLE_EC_GRP_ID; \ - ((void) ssl); - -#define MBEDTLS_SSL_END_FOR_EACH_SUPPORTED_EC_GRP_ID \ - } -#endif /* MBEDTLS_ECP_C */ - -#endif /* MBEDTLS_SSL_CONF_SINGLE_EC */ - -#if !defined(MBEDTLS_SSL_CONF_SINGLE_SIG_HASH) - -#define MBEDTLS_SSL_BEGIN_FOR_EACH_SIG_HASH( MD_VAR ) \ - { \ - int const *__md; \ - for( __md = ssl->conf->sig_hashes; \ - *__md != MBEDTLS_MD_NONE; __md++ ) \ - { \ - mbedtls_md_type_t MD_VAR = (mbedtls_md_type_t) *__md; \ - - #define MBEDTLS_SSL_END_FOR_EACH_SIG_HASH \ - } \ - } - -#define MBEDTLS_SSL_BEGIN_FOR_EACH_SIG_HASH_TLS( HASH_VAR ) \ - { \ - int const *__md; \ - for( __md = ssl->conf->sig_hashes; \ - *__md != MBEDTLS_MD_NONE; __md++ ) \ - { \ - unsigned char HASH_VAR; \ - HASH_VAR = mbedtls_ssl_hash_from_md_alg( *__md ); - -#define MBEDTLS_SSL_END_FOR_EACH_SIG_HASH_TLS \ - } \ - } - -#else /* !MBEDTLS_SSL_CONF_SINGLE_SIG_HASH */ - -#define MBEDTLS_SSL_BEGIN_FOR_EACH_SIG_HASH( MD_VAR ) \ - { \ - mbedtls_md_type_t MD_VAR = MBEDTLS_SSL_CONF_SINGLE_SIG_HASH_MD_ID; \ - ((void) ssl); - -#define MBEDTLS_SSL_END_FOR_EACH_SIG_HASH \ - } - -#define MBEDTLS_SSL_BEGIN_FOR_EACH_SIG_HASH_TLS( HASH_VAR ) \ - { \ - unsigned char HASH_VAR = MBEDTLS_SSL_CONF_SINGLE_SIG_HASH_TLS_ID; \ - ((void) ssl); - - -#define MBEDTLS_SSL_END_FOR_EACH_SIG_HASH_TLS \ - } - -#endif /* MBEDTLS_SSL_CONF_SINGLE_SIG_HASH */ - -/* This internal function can be used to pend a fatal alert for - * later delivery. - * - * The check for pending alerts must be done by calling - * the function ssl_send_pending_fatal_alert() in ssl_tls.c. - * Currently, it happens only during the handshake loop and after - * calling ssl_get_next_record() in the record processing stack. - * - * This function must not be called multiple times without - * sending the pending fatal alerts in between. - */ -MBEDTLS_ALWAYS_INLINE static inline void mbedtls_ssl_pend_fatal_alert( - mbedtls_ssl_context *ssl, - unsigned char message ) -{ - ssl->pending_fatal_alert_msg = message; -} - -/* - * Getter functions for fields in SSL session. - */ - -static inline int mbedtls_ssl_session_get_compression( - mbedtls_ssl_session const *session ) -{ -#if defined(MBEDTLS_ZLIB_SUPPORT) - return( session->compression ); -#else - ( (void) session ); - return( MBEDTLS_SSL_COMPRESS_NULL ); -#endif -} - -MBEDTLS_ALWAYS_INLINE static inline void mbedtls_ssl_update_checksum( - mbedtls_ssl_context *ssl, - const unsigned char *buf, size_t len ) -{ -#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_1) - mbedtls_md5_update_ret( &ssl->handshake->fin_md5 , buf, len ); - mbedtls_sha1_update_ret( &ssl->handshake->fin_sha1, buf, len ); -#endif -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) -#if defined(MBEDTLS_SHA256_C) - mbedtls_sha256_update_ret( &ssl->handshake->fin_sha256, buf, len ); -#endif -#if defined(MBEDTLS_SHA512_C) - mbedtls_sha512_update_ret( &ssl->handshake->fin_sha512, buf, len ); -#endif -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ -} - -int mbedtls_ssl_calc_verify( int minor_ver, - mbedtls_md_type_t hash, - mbedtls_ssl_context const *ssl, - unsigned char *dst, - size_t *hlen ); - -#define MBEDTLS_SSL_CHK(f) do { if( ( ret = f ) < 0 ) goto cleanup; } while( 0 ) - -#if defined(MBEDTLS_USE_TINYCRYPT) -int mbedtls_ssl_ecdh_read_peerkey( mbedtls_ssl_context *ssl, - unsigned char **p, unsigned char *end ); -#endif /* MBEDTLS_USE_TINYCRYPT */ - - -/* - * Point formats, from RFC 4492's enum ECPointFormat - */ -#define MBEDTLS_SSL_EC_PF_UNCOMPRESSED 0 /**< Uncompressed point format. */ -#define MBEDTLS_SSL_EC_PF_COMPRESSED 1 /**< Compressed point format. */ - -/* - * Some other constants from RFC 4492 - */ -#define MBEDTLS_SSL_EC_TLS_NAMED_CURVE 3 /**< The named_curve of ECCurveType. */ - #endif /* ssl_internal.h */ diff --git a/APP_Framework/Framework/security/mbedtls/ssl_srv.c b/APP_Framework/Framework/security/mbedtls/ssl_srv.c index b89ee2cd4..14690147a 100644 --- a/APP_Framework/Framework/security/mbedtls/ssl_srv.c +++ b/APP_Framework/Framework/security/mbedtls/ssl_srv.c @@ -27,9 +27,9 @@ #if defined(MBEDTLS_SSL_SRV_C) +#if defined(MBEDTLS_PLATFORM_C) #include "platform.h" - -#if !defined(MBEDTLS_PLATFORM_C) +#else #include #define mbedtls_calloc calloc #define mbedtls_free free @@ -38,8 +38,6 @@ #include "debug.h" #include "ssl.h" #include "ssl_internal.h" -#include "platform.h" -#include "platform_util.h" #include @@ -51,12 +49,19 @@ #include "platform_time.h" #endif +#if defined(MBEDTLS_SSL_SESSION_TICKETS) +/* 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; +} +#endif + #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) int mbedtls_ssl_set_client_transport_id( mbedtls_ssl_context *ssl, const unsigned char *info, size_t ilen ) { - if( mbedtls_ssl_conf_get_endpoint( ssl->conf ) != MBEDTLS_SSL_IS_SERVER ) + if( ssl->conf->endpoint != MBEDTLS_SSL_IS_SERVER ) return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); mbedtls_free( ssl->cli_id ); @@ -64,7 +69,6 @@ int mbedtls_ssl_set_client_transport_id( mbedtls_ssl_context *ssl, if( ( ssl->cli_id = mbedtls_calloc( 1, ilen ) ) == NULL ) return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); - /* Not using more secure mbedtls_platform_memcpy as id is public*/ memcpy( ssl->cli_id, info, ilen ); ssl->cli_id_len = ilen; @@ -96,29 +100,28 @@ static int ssl_parse_servername_ext( mbedtls_ssl_context *ssl, if( len < 2 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); } - servername_list_size = mbedtls_platform_get_uint16_be( buf ); - + servername_list_size = ( ( buf[0] << 8 ) | ( buf[1] ) ); if( servername_list_size + 2 != len ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); } p = buf + 2; while( servername_list_size > 2 ) { - hostname_len = mbedtls_platform_get_uint16_be( &p[1] ); + hostname_len = ( ( p[1] << 8 ) | p[2] ); if( hostname_len + 3 > servername_list_size ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); } @@ -129,7 +132,7 @@ static int ssl_parse_servername_ext( mbedtls_ssl_context *ssl, if( ret != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "ssl_sni_wrapper", ret ); - mbedtls_ssl_pend_fatal_alert( ssl, + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, MBEDTLS_SSL_ALERT_MSG_UNRECOGNIZED_NAME ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); } @@ -143,8 +146,8 @@ static int ssl_parse_servername_ext( mbedtls_ssl_context *ssl, if( servername_list_size != 0 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); } @@ -162,12 +165,12 @@ static int ssl_parse_renegotiation_info( mbedtls_ssl_context *ssl, /* Check verify-data in constant-time. The length OTOH is no secret */ if( len != 1 + ssl->verify_data_len || buf[0] != ssl->verify_data_len || - mbedtls_platform_memequal( buf + 1, ssl->peer_verify_data, + mbedtls_ssl_safer_memcmp( buf + 1, ssl->peer_verify_data, ssl->verify_data_len ) != 0 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching renegotiation info" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); } } @@ -177,8 +180,8 @@ static int ssl_parse_renegotiation_info( mbedtls_ssl_context *ssl, if( len != 1 || buf[0] != 0x0 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-zero length renegotiation info" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); } @@ -217,19 +220,17 @@ static int ssl_parse_signature_algorithms_ext( mbedtls_ssl_context *ssl, if ( len < 2 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); } - - sig_alg_list_size = mbedtls_platform_get_uint16_be( buf ); - + sig_alg_list_size = ( ( buf[0] << 8 ) | ( buf[1] ) ); if( sig_alg_list_size + 2 != len || sig_alg_list_size % 2 != 0 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); } @@ -281,52 +282,66 @@ static int ssl_parse_signature_algorithms_ext( mbedtls_ssl_context *ssl, #endif /* MBEDTLS_SSL_PROTO_TLS1_2 && MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ -#if defined(MBEDTLS_ECDH_C) || \ - defined(MBEDTLS_ECDSA_C) || \ - defined(MBEDTLS_USE_TINYCRYPT) || \ +#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) static int ssl_parse_supported_elliptic_curves( mbedtls_ssl_context *ssl, - const unsigned char *buf, size_t len, - unsigned char const **list_start, size_t *list_len ) + const unsigned char *buf, + size_t len ) { - size_t list_size; + size_t list_size, our_size; const unsigned char *p; + const mbedtls_ecp_curve_info *curve_info, **curves; if ( len < 2 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); } - - list_size = mbedtls_platform_get_uint16_be( buf ); + list_size = ( ( buf[0] << 8 ) | ( buf[1] ) ); if( list_size + 2 != len || list_size % 2 != 0 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); } - p = buf + 2; - - /* Remember list for later. */ - *list_start = p; - *list_len = list_size / 2; - - while( list_size > 0 ) + /* Should never happen unless client duplicates the extension */ + if( ssl->handshake->curves != NULL ) { - uint16_t const peer_tls_id = (uint16_t) - mbedtls_platform_get_uint16_be( p ); + 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 ); + } - MBEDTLS_SSL_BEGIN_FOR_EACH_SUPPORTED_EC_TLS_ID( own_tls_id ) - if( own_tls_id == peer_tls_id && - ssl->handshake->curve_tls_id == 0 ) + /* Don't allow our peer to make us allocate too much memory, + * and leave room for a final 0 */ + our_size = list_size / 2 + 1; + if( our_size > MBEDTLS_ECP_DP_MAX ) + our_size = MBEDTLS_ECP_DP_MAX; + + if( ( curves = mbedtls_calloc( our_size, sizeof( *curves ) ) ) == NULL ) + { + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR ); + return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); + } + + ssl->handshake->curves = curves; + + p = buf + 2; + while( list_size > 0 && our_size > 1 ) + { + curve_info = mbedtls_ecp_curve_info_from_tls_id( ( p[0] << 8 ) | p[1] ); + + if( curve_info != NULL ) { - ssl->handshake->curve_tls_id = own_tls_id; + *curves++ = curve_info; + our_size--; } - MBEDTLS_SSL_END_FOR_EACH_SUPPORTED_EC_TLS_ID list_size -= 2; p += 2; @@ -345,8 +360,8 @@ static int ssl_parse_supported_point_formats( mbedtls_ssl_context *ssl, if( len == 0 || (size_t)( buf[0] + 1 ) != len ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); } list_size = buf[0]; @@ -354,10 +369,10 @@ static int ssl_parse_supported_point_formats( mbedtls_ssl_context *ssl, p = buf + 1; while( list_size > 0 ) { - if( p[0] == MBEDTLS_SSL_EC_PF_UNCOMPRESSED || - p[0] == MBEDTLS_SSL_EC_PF_COMPRESSED ) + if( p[0] == MBEDTLS_ECP_PF_UNCOMPRESSED || + p[0] == MBEDTLS_ECP_PF_COMPRESSED ) { -#if defined(MBEDTLS_ECDH_C) +#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) ssl->handshake->ecdh_ctx.point_format = p[0]; #endif #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) @@ -373,7 +388,7 @@ static int ssl_parse_supported_point_formats( mbedtls_ssl_context *ssl, return( 0 ); } -#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || MBEDTLS_USE_TINYCRYPT +#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) @@ -393,8 +408,8 @@ static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl, buf, len ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_one", ret ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); return( ret ); } @@ -413,8 +428,8 @@ static int ssl_parse_max_fragment_length_ext( mbedtls_ssl_context *ssl, if( len != 1 || buf[0] >= MBEDTLS_SSL_MAX_FRAG_LEN_INVALID ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); } @@ -424,79 +439,6 @@ static int ssl_parse_max_fragment_length_ext( mbedtls_ssl_context *ssl, } #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) -static int ssl_parse_cid_ext( mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len ) -{ - size_t peer_cid_len; - - /* CID extension only makes sense in DTLS */ - if( MBEDTLS_SSL_TRANSPORT_IS_TLS( ssl->conf->transport ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - /* - * Quoting draft-ietf-tls-dtls-connection-id-05 - * https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05 - * - * struct { - * opaque cid<0..2^8-1>; - * } ConnectionId; - */ - - if( len < 1 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - peer_cid_len = *buf++; - len--; - - if( len != peer_cid_len ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - /* Ignore CID if the user has disabled its use. */ - if( ssl->negotiate_cid == MBEDTLS_SSL_CID_DISABLED ) - { - /* Leave ssl->handshake->cid_in_use in its default - * value of MBEDTLS_SSL_CID_DISABLED. */ - MBEDTLS_SSL_DEBUG_MSG( 3, ( "Client sent CID extension, but CID disabled" ) ); - return( 0 ); - } - - if( peer_cid_len > MBEDTLS_SSL_CID_OUT_LEN_MAX ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - ssl->handshake->cid_in_use = MBEDTLS_SSL_CID_ENABLED; - ssl->handshake->peer_cid_len = (uint8_t) peer_cid_len; - /* Not using more secure mbedtls_platform_memcpy as peer_cid is is public */ - memcpy( ssl->handshake->peer_cid, buf, peer_cid_len ); - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "Use of CID extension negotiated" ) ); - MBEDTLS_SSL_DEBUG_BUF( 3, "Client CID", buf, peer_cid_len ); - - return( 0 ); -} -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - #if defined(MBEDTLS_SSL_TRUNCATED_HMAC) static int ssl_parse_truncated_hmac_ext( mbedtls_ssl_context *ssl, const unsigned char *buf, @@ -505,8 +447,8 @@ static int ssl_parse_truncated_hmac_ext( mbedtls_ssl_context *ssl, if( len != 0 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); } @@ -527,7 +469,7 @@ static int ssl_parse_encrypt_then_mac_ext( mbedtls_ssl_context *ssl, if( len != 0 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, + 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 ); } @@ -535,7 +477,7 @@ static int ssl_parse_encrypt_then_mac_ext( mbedtls_ssl_context *ssl, ((void) buf); if( ssl->conf->encrypt_then_mac == MBEDTLS_SSL_ETM_ENABLED && - mbedtls_ssl_get_minor_ver( ssl ) != MBEDTLS_SSL_MINOR_VERSION_0 ) + ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_0 ) { ssl->session_negotiate->encrypt_then_mac = MBEDTLS_SSL_ETM_ENABLED; } @@ -552,13 +494,19 @@ static int ssl_parse_extended_ms_ext( mbedtls_ssl_context *ssl, if( len != 0 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); } ((void) buf); + if( ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_ENABLED && + ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_0 ) + { + ssl->handshake->extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED; + } + return( 0 ); } #endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ @@ -618,17 +566,17 @@ static int ssl_parse_session_ticket_ext( mbedtls_ssl_context *ssl, * inform them we're accepting the ticket (RFC 5077 section 3.4) */ session.id_len = ssl->session_negotiate->id_len; - mbedtls_platform_memcpy( &session.id, ssl->session_negotiate->id, session.id_len ); + memcpy( &session.id, ssl->session_negotiate->id, session.id_len ); mbedtls_ssl_session_free( ssl->session_negotiate ); - mbedtls_platform_memcpy( ssl->session_negotiate, &session, sizeof( mbedtls_ssl_session ) ); + memcpy( ssl->session_negotiate, &session, sizeof( mbedtls_ssl_session ) ); /* Zeroize instead of free as we copied the content */ - mbedtls_platform_zeroize( &session, sizeof( mbedtls_ssl_session ) ); + mbedtls_zeroize( &session, sizeof( mbedtls_ssl_session ) ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "session successfully restored from ticket" ) ); - ssl->handshake->resume = MBEDTLS_SSL_FI_FLAG_SET; + ssl->handshake->resume = 1; /* Don't send a new ticket after all, this one is OK */ ssl->handshake->new_session_ticket = 0; @@ -660,17 +608,16 @@ static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl, /* Min length is 2 (list_len) + 1 (name_len) + 1 (name) */ if( len < 4 ) { - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); } - list_len = mbedtls_platform_get_uint16_be ( buf ); - + list_len = ( buf[0] << 8 ) | buf[1]; if( list_len != len - 2 ) { - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); } @@ -686,16 +633,16 @@ static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl, /* Current identifier must fit in list */ if( cur_len > (size_t)( end - theirs ) ) { - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); } /* Empty strings MUST NOT be included */ if( cur_len == 0 ) { - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); } } @@ -711,7 +658,7 @@ static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl, cur_len = *theirs++; if( cur_len == ours_len && - mbedtls_platform_memequal( theirs, *ours, cur_len ) == 0 ) + memcmp( theirs, *ours, cur_len ) == 0 ) { ssl->alpn_chosen = *ours; return( 0 ); @@ -720,8 +667,8 @@ static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl, } /* If we get there, no match was found */ - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_NO_APPLICATION_PROTOCOL ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_NO_APPLICATION_PROTOCOL ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); } #endif /* MBEDTLS_SSL_ALPN */ @@ -734,39 +681,18 @@ static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl, /* * Return 0 if the given key uses one of the acceptable curves, -1 otherwise */ -#if defined(MBEDTLS_ECDSA_C) || defined(MBEDTLS_USE_TINYCRYPT) +#if defined(MBEDTLS_ECDSA_C) static int ssl_check_key_curve( mbedtls_pk_context *pk, - unsigned char const *acceptable_ec_tls_ids, - size_t ec_tls_ids_len ) + const mbedtls_ecp_curve_info **curves ) { - uint16_t tls_id; - -#if defined(MBEDTLS_USE_TINYCRYPT) - ((void) pk); - tls_id = 23; /* TLS ID for Secp256r1. */ -#else - mbedtls_ecp_curve_info const *info; + const mbedtls_ecp_curve_info **crv = curves; mbedtls_ecp_group_id grp_id = mbedtls_pk_ec( *pk )->grp.id; - info = mbedtls_ecp_curve_info_from_grp_id( grp_id ); - if( info == NULL ) - return( -1 ); - - tls_id = info->tls_id; -#endif /* MBEDTLS_USE_TINYCRYPT */ - - if( acceptable_ec_tls_ids == NULL ) - return( -1 ); - - while( ec_tls_ids_len-- != 0 ) + while( *crv != NULL ) { - uint16_t const cur_tls_id = (uint16_t) - mbedtls_platform_get_uint16_be( acceptable_ec_tls_ids ); - - if( cur_tls_id == tls_id ) + if( (*crv)->grp_id == grp_id ) return( 0 ); - - acceptable_ec_tls_ids += 2; + crv++; } return( -1 ); @@ -778,9 +704,7 @@ static int ssl_check_key_curve( mbedtls_pk_context *pk, * return 0 on success and -1 on failure. */ static int ssl_pick_cert( mbedtls_ssl_context *ssl, - mbedtls_ssl_ciphersuite_handle_t ciphersuite_info, - unsigned char const *acceptable_ec_tls_ids, - size_t ec_tls_ids_len ) + const mbedtls_ssl_ciphersuite_t * ciphersuite_info ) { mbedtls_ssl_key_cert *cur, *list, *fallback = NULL; mbedtls_pk_type_t pk_alg = @@ -807,62 +731,14 @@ static int ssl_pick_cert( mbedtls_ssl_context *ssl, for( cur = list; cur != NULL; cur = cur->next ) { - int match = 1; - mbedtls_pk_context *pk; - - /* WARNING: With the current X.509 caching architecture, this MUST - * happen outside of the PK acquire/release block, because it moves - * the cached PK context. In a threading-enabled build, this would - * rightfully fail, but lead to a use-after-free otherwise. */ MBEDTLS_SSL_DEBUG_CRT( 3, "candidate certificate chain, certificate", - cur->cert ); + cur->cert ); -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) - /* ASYNC_PRIVATE may use a NULL entry for the opaque private key, so - * we have to use the public key context to infer the capabilities - * of the key. */ - { - int ret; - ret = mbedtls_x509_crt_pk_acquire( cur->cert, &pk ); - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_x509_crt_pk_acquire", ret ); - return( ret ); - } - } -#else - /* Outside of ASYNC_PRIVATE, use private key context directly - * instead of querying for the public key context from the - * certificate, so save a few bytes of code. */ - pk = cur->key; -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ - - if( ! mbedtls_pk_can_do( pk, pk_alg ) ) + if( ! mbedtls_pk_can_do( cur->key, pk_alg ) ) { MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate mismatch: key type" ) ); - match = 0; - } - -#if defined(MBEDTLS_ECDSA_C) || defined(MBEDTLS_USE_TINYCRYPT) - if( pk_alg == MBEDTLS_PK_ECDSA && - ssl_check_key_curve( pk, - acceptable_ec_tls_ids, - ec_tls_ids_len ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate mismatch: elliptic curve" ) ); - match = 0; - } -#else - ((void) acceptable_ec_tls_ids); - ((void) ec_tls_ids_len); -#endif - -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) - mbedtls_x509_crt_pk_release( cur->cert ); -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ - - if( match == 0 ) continue; + } /* * This avoids sending the client a cert it'll reject based on @@ -880,43 +756,31 @@ static int ssl_pick_cert( mbedtls_ssl_context *ssl, continue; } -#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_1) +#if defined(MBEDTLS_ECDSA_C) + if( pk_alg == MBEDTLS_PK_ECDSA && + ssl_check_key_curve( cur->key, ssl->handshake->curves ) != 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate mismatch: elliptic curve" ) ); + continue; + } +#endif + /* * Try to select a SHA-1 certificate for pre-1.2 clients, but still * present them a SHA-higher cert rather than failing if it's the only * one we got that satisfies the other conditions. */ - if( mbedtls_ssl_ver_lt( mbedtls_ssl_get_minor_ver( ssl ), - MBEDTLS_SSL_MINOR_VERSION_3 ) ) + if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 && + cur->cert->sig_md != MBEDTLS_MD_SHA1 ) { - mbedtls_md_type_t sig_md; + if( fallback == NULL ) + fallback = cur; { - int ret; - mbedtls_x509_crt_frame const *frame; - ret = mbedtls_x509_crt_frame_acquire( cur->cert, &frame ); - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_x509_crt_frame_acquire", ret ); - return( ret ); - } - sig_md = frame->sig_md; - mbedtls_x509_crt_frame_release( cur->cert ); - } - - if( sig_md != MBEDTLS_MD_SHA1 ) - { - if( fallback == NULL ) - fallback = cur; - MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate not preferred: " - "sha-2 with pre-TLS 1.2 client" ) ); - continue; + "sha-2 with pre-TLS 1.2 client" ) ); + continue; } } -#endif /* MBEDTLS_SSL_PROTO_TLS1 || - MBEDTLS_SSL_PROTO_TLS1_1 || - MBEDTLS_SSL_PROTO_SSL3 */ /* If we get there, we got a winner */ break; @@ -942,42 +806,41 @@ static int ssl_pick_cert( mbedtls_ssl_context *ssl, * Check if a given ciphersuite is suitable for use with our config/keys/etc * Sets ciphersuite_info only if the suite matches. */ -static int ssl_ciphersuite_is_match( mbedtls_ssl_context *ssl, - mbedtls_ssl_ciphersuite_handle_t suite_info, - unsigned char const *acceptable_ec_tls_ids, - size_t ec_tls_ids_len ) +static int ssl_ciphersuite_match( mbedtls_ssl_context *ssl, int suite_id, + const mbedtls_ssl_ciphersuite_t **ciphersuite_info ) { + const mbedtls_ssl_ciphersuite_t *suite_info; + #if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) mbedtls_pk_type_t sig_type; #endif - MBEDTLS_SSL_DEBUG_MSG( 3, ( "trying ciphersuite: %s", - mbedtls_ssl_suite_get_name( suite_info ) ) ); + suite_info = mbedtls_ssl_ciphersuite_from_id( suite_id ); + if( suite_info == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } - if( mbedtls_ssl_ver_gt( - mbedtls_ssl_suite_get_min_minor_ver( suite_info ), - mbedtls_ssl_get_minor_ver( ssl ) ) || - mbedtls_ssl_ver_lt( - mbedtls_ssl_suite_get_max_minor_ver( suite_info ), - mbedtls_ssl_get_minor_ver( ssl ) ) ) + MBEDTLS_SSL_DEBUG_MSG( 3, ( "trying ciphersuite: %s", suite_info->name ) ); + + if( suite_info->min_minor_ver > ssl->minor_ver || + suite_info->max_minor_ver < ssl->minor_ver ) { MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: version" ) ); return( 0 ); } #if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) && - ( mbedtls_ssl_suite_get_flags( suite_info ) & - MBEDTLS_CIPHERSUITE_NODTLS ) ) - { + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && + ( suite_info->flags & MBEDTLS_CIPHERSUITE_NODTLS ) ) return( 0 ); - } #endif #if defined(MBEDTLS_ARC4_C) if( ssl->conf->arc4_disabled == MBEDTLS_SSL_ARC4_DISABLED && - mbedtls_ssl_suite_get_cipher( suite_info ) == MBEDTLS_CIPHER_ARC4_128 ) + suite_info->cipher == MBEDTLS_CIPHER_ARC4_128 ) { MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: rc4" ) ); return( 0 ); @@ -985,8 +848,7 @@ static int ssl_ciphersuite_is_match( mbedtls_ssl_context *ssl, #endif #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - if( mbedtls_ssl_suite_get_key_exchange( suite_info ) == - MBEDTLS_KEY_EXCHANGE_ECJPAKE && + if( suite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE && ( ssl->handshake->cli_exts & MBEDTLS_TLS_EXT_ECJPAKE_KKPP_OK ) == 0 ) { MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: ecjpake " @@ -995,10 +857,11 @@ static int ssl_ciphersuite_is_match( mbedtls_ssl_context *ssl, } #endif -#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ - defined(MBEDTLS_USE_TINYCRYPT) + +#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) if( mbedtls_ssl_ciphersuite_uses_ec( suite_info ) && - ssl->handshake->curve_tls_id == 0 ) + ( ssl->handshake->curves == NULL || + ssl->handshake->curves[0] == NULL ) ) { MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: " "no common elliptic curve" ) ); @@ -1023,7 +886,7 @@ static int ssl_ciphersuite_is_match( mbedtls_ssl_context *ssl, defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) /* If the ciphersuite requires signing, check whether * a suitable hash algorithm is present. */ - if( mbedtls_ssl_get_minor_ver( ssl ) == MBEDTLS_SSL_MINOR_VERSION_3 ) + if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) { sig_type = mbedtls_ssl_get_ciphersuite_sig_alg( suite_info ); if( sig_type != MBEDTLS_PK_NONE && @@ -1046,24 +909,19 @@ static int ssl_ciphersuite_is_match( mbedtls_ssl_context *ssl, * - try the next ciphersuite if we don't * This must be done last since we modify the key_cert list. */ - if( ssl_pick_cert( ssl, suite_info, - acceptable_ec_tls_ids, - ec_tls_ids_len ) != 0 ) + if( ssl_pick_cert( ssl, suite_info ) != 0 ) { MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: " "no suitable certificate" ) ); return( 0 ); } -#else - ((void) acceptable_ec_tls_ids); - ((void) ec_tls_ids_len); #endif - return( 1 ); + *ciphersuite_info = suite_info; + return( 0 ); } -#if defined(MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO) && \ - defined(MBEDTLS_SSL_PROTO_TLS) +#if defined(MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO) static int ssl_parse_client_hello_v2( mbedtls_ssl_context *ssl ) { int ret, got_common_suite; @@ -1071,9 +929,8 @@ static int ssl_parse_client_hello_v2( mbedtls_ssl_context *ssl ) size_t n; unsigned int ciph_len, sess_len, chal_len; unsigned char *buf, *p; -#if !defined(MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE) - mbedtls_ssl_ciphersuite_handle_t ciphersuite_info; -#endif + const int *ciphersuites; + const mbedtls_ssl_ciphersuite_t *ciphersuite_info; MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse client hello v2" ) ); @@ -1081,8 +938,8 @@ static int ssl_parse_client_hello_v2( mbedtls_ssl_context *ssl ) if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "client hello v2 illegal for renegotiation" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); } #endif /* MBEDTLS_SSL_RENEGOTIATION */ @@ -1115,7 +972,7 @@ static int ssl_parse_client_hello_v2( mbedtls_ssl_context *ssl ) return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); } - n = mbedtls_platform_get_uint16_be( buf ); + n = ( ( buf[0] << 8 ) | buf[1] ) & 0x7FFF; if( n < 17 || n > 512 ) { @@ -1123,37 +980,24 @@ static int ssl_parse_client_hello_v2( mbedtls_ssl_context *ssl ) return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); } -#if !defined(MBEDTLS_SSL_CONF_FIXED_MAJOR_VER) ssl->major_ver = MBEDTLS_SSL_MAJOR_VERSION_3; -#endif + ssl->minor_ver = ( buf[4] <= ssl->conf->max_minor_ver ) + ? buf[4] : ssl->conf->max_minor_ver; -#if !defined(MBEDTLS_SSL_CONF_FIXED_MINOR_VER) - ssl->minor_ver = - ( buf[4] <= mbedtls_ssl_conf_get_max_minor_ver( ssl->conf ) ) - ? buf[4] : mbedtls_ssl_conf_get_max_minor_ver( ssl->conf ); -#endif - - if( mbedtls_ssl_ver_lt( mbedtls_ssl_get_minor_ver( ssl ), - mbedtls_ssl_conf_get_min_minor_ver( ssl->conf ) ) ) + if( ssl->minor_ver < ssl->conf->min_minor_ver ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "client only supports ssl smaller than minimum" " [%d:%d] < [%d:%d]", - mbedtls_ssl_get_major_ver( ssl ), - mbedtls_ssl_get_minor_ver( ssl ), - mbedtls_ssl_conf_get_min_major_ver( ssl->conf ), - mbedtls_ssl_conf_get_min_minor_ver( ssl->conf ) ) ); + ssl->major_ver, ssl->minor_ver, + ssl->conf->min_major_ver, ssl->conf->min_minor_ver ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION ); return( MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION ); } -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) ssl->handshake->max_major_ver = buf[3]; ssl->handshake->max_minor_ver = buf[4]; -#endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED || - MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ if( ( ret = mbedtls_ssl_fetch_input( ssl, 2 + n ) ) != 0 ) { @@ -1161,7 +1005,7 @@ static int ssl_parse_client_hello_v2( mbedtls_ssl_context *ssl ) return( ret ); } - mbedtls_ssl_update_checksum( ssl, buf + 2, n ); + ssl->handshake->update_checksum( ssl, buf + 2, n ); buf = ssl->in_msg; n = ssl->in_left - 5; @@ -1176,9 +1020,9 @@ static int ssl_parse_client_hello_v2( mbedtls_ssl_context *ssl ) */ MBEDTLS_SSL_DEBUG_BUF( 4, "record contents", buf, n ); - ciph_len = (unsigned int)mbedtls_platform_get_uint16_be( &buf[0] ); - sess_len = (unsigned int)mbedtls_platform_get_uint16_be( &buf[2] ); - chal_len = (unsigned int)mbedtls_platform_get_uint16_be( &buf[4] ); + ciph_len = ( buf[0] << 8 ) | buf[1]; + sess_len = ( buf[2] << 8 ) | buf[3]; + chal_len = ( buf[4] << 8 ) | buf[5]; MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciph_len: %d, sess_len: %d, chal_len: %d", ciph_len, sess_len, chal_len ) ); @@ -1221,17 +1065,11 @@ static int ssl_parse_client_hello_v2( mbedtls_ssl_context *ssl ) ssl->session_negotiate->id_len = sess_len; memset( ssl->session_negotiate->id, 0, sizeof( ssl->session_negotiate->id ) ); - mbedtls_platform_memcpy( ssl->session_negotiate->id, p, ssl->session_negotiate->id_len ); + memcpy( ssl->session_negotiate->id, p, ssl->session_negotiate->id_len ); p += sess_len; - - ssl->handshake->hello_random_set = MBEDTLS_SSL_FI_FLAG_UNSET; memset( ssl->handshake->randbytes, 0, 64 ); - mbedtls_platform_memcpy( ssl->handshake->randbytes + 32 - chal_len, p, chal_len ); - if( mbedtls_platform_memequal( ssl->handshake->randbytes + 32 - chal_len, p, chal_len ) == 0 ) - { - ssl->handshake->hello_random_set = MBEDTLS_SSL_FI_FLAG_SET; - } + memcpy( ssl->handshake->randbytes + 32 - chal_len, p, chal_len ); /* * Check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV @@ -1247,8 +1085,8 @@ static int ssl_parse_client_hello_v2( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_DEBUG_MSG( 1, ( "received RENEGOTIATION SCSV " "during renegotiation" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); } #endif /* MBEDTLS_SSL_RENEGOTIATION */ @@ -1266,14 +1104,12 @@ static int ssl_parse_client_hello_v2( mbedtls_ssl_context *ssl ) { MBEDTLS_SSL_DEBUG_MSG( 3, ( "received FALLBACK_SCSV" ) ); - if( mbedtls_ssl_ver_lt( - mbedtls_ssl_get_minor_ver( ssl ), - mbedtls_ssl_conf_get_max_minor_ver( ssl->conf ) ) ) + if( ssl->minor_ver < ssl->conf->max_minor_ver ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "inapropriate fallback" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_INAPROPRIATE_FALLBACK ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_INAPROPRIATE_FALLBACK ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); } @@ -1284,50 +1120,30 @@ static int ssl_parse_client_hello_v2( mbedtls_ssl_context *ssl ) #endif /* MBEDTLS_SSL_FALLBACK_SCSV */ got_common_suite = 0; + ciphersuites = ssl->conf->ciphersuite_list[ssl->minor_ver]; + ciphersuite_info = NULL; #if defined(MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE) for( j = 0, p = buf + 6; j < ciph_len; j += 3, p += 3 ) - { - MBEDTLS_SSL_BEGIN_FOR_EACH_CIPHERSUITE( ssl, \ - mbedtls_ssl_get_minor_ver( ssl ), \ - cur_info ) - { + for( i = 0; ciphersuites[i] != 0; i++ ) #else - MBEDTLS_SSL_BEGIN_FOR_EACH_CIPHERSUITE( ssl, \ - mbedtls_ssl_get_minor_ver( ssl ), \ - cur_info ) - { + for( i = 0; ciphersuites[i] != 0; i++ ) for( j = 0, p = buf + 6; j < ciph_len; j += 3, p += 3 ) - { #endif - const int ciphersuite_id = - mbedtls_ssl_suite_get_id( cur_info ); - + { if( p[0] != 0 || - p[1] != ( ( ciphersuite_id >> 8 ) & 0xFF ) || - p[2] != ( ( ciphersuite_id ) & 0xFF ) ) - { + p[1] != ( ( ciphersuites[i] >> 8 ) & 0xFF ) || + p[2] != ( ( ciphersuites[i] ) & 0xFF ) ) continue; - } got_common_suite = 1; - if( ssl_ciphersuite_is_match( ssl, cur_info, NULL, 0 ) ) - { -#if !defined(MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE) - ciphersuite_info = cur_info; -#endif - goto have_ciphersuite_v2; - } + if( ( ret = ssl_ciphersuite_match( ssl, ciphersuites[i], + &ciphersuite_info ) ) != 0 ) + return( ret ); -#if defined(MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE) + if( ciphersuite_info != NULL ) + goto have_ciphersuite_v2; } - MBEDTLS_SSL_END_FOR_EACH_CIPHERSUITE - } -#else - } - } - MBEDTLS_SSL_END_FOR_EACH_CIPHERSUITE -#endif if( got_common_suite ) { @@ -1342,38 +1158,31 @@ static int ssl_parse_client_hello_v2( mbedtls_ssl_context *ssl ) } have_ciphersuite_v2: + MBEDTLS_SSL_DEBUG_MSG( 2, ( "selected ciphersuite: %s", ciphersuite_info->name ) ); -#if !defined(MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE) - ssl->session_negotiate->ciphersuite = - mbedtls_ssl_suite_get_id( ciphersuite_info ); - ssl->handshake->ciphersuite_info = ciphersuite_info; -#endif - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "selected ciphersuite: %s", - mbedtls_ssl_get_ciphersuite_name( - mbedtls_ssl_session_get_ciphersuite( ssl->session_negotiate ) ) ) ); + ssl->session_negotiate->ciphersuite = ciphersuites[i]; + ssl->transform_negotiate->ciphersuite_info = ciphersuite_info; /* * SSLv2 Client Hello relevant renegotiation security checks */ if( ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && - mbedtls_ssl_conf_get_allow_legacy_renegotiation( ssl->conf ) == - MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE ) + ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation, breaking off handshake" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); } ssl->in_left = 0; - ssl->state = MBEDTLS_SSL_SERVER_HELLO; + ssl->state++; MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse client hello v2" ) ); return( 0 ); } -#endif /* MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO && MBEDTLS_SSL_PROTO_TLS */ +#endif /* MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO */ /* This function doesn't alert on errors that happen early during ClientHello parsing because they might indicate that the client is @@ -1390,20 +1199,12 @@ static int ssl_parse_client_hello( mbedtls_ssl_context *ssl ) unsigned char *buf, *p, *ext; #if defined(MBEDTLS_SSL_RENEGOTIATION) int renegotiation_info_seen = 0; -#endif -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) - int extended_ms_seen = 0; #endif int handshake_failure = 0; - -#if !defined(MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE) - mbedtls_ssl_ciphersuite_handle_t ciphersuite_info; -#endif + const int *ciphersuites; + const mbedtls_ssl_ciphersuite_t *ciphersuite_info; int major, minor; - unsigned char const *acceptable_ec_tls_ids = NULL; - size_t ec_tls_ids_len = 0; - /* If there is no signature-algorithm extension present, * we need to fall back to the default values for allowed * signature-hash pairs. */ @@ -1423,26 +1224,29 @@ read_record_header: * otherwise read it ourselves manually in order to support SSLv2 * ClientHello, which doesn't use the same record layer format. */ - if( mbedtls_ssl_get_renego_status( ssl ) == MBEDTLS_SSL_INITIAL_HANDSHAKE && - ( ret = mbedtls_ssl_fetch_input( ssl, 5 ) ) != 0 ) +#if defined(MBEDTLS_SSL_RENEGOTIATION) + if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE ) +#endif { - /* No alert on a read error. */ - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret ); - return( ret ); + if( ( ret = mbedtls_ssl_fetch_input( ssl, 5 ) ) != 0 ) + { + /* No alert on a read error. */ + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret ); + return( ret ); + } } buf = ssl->in_hdr; -#if defined(MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO) && \ - defined(MBEDTLS_SSL_PROTO_TLS) - if( MBEDTLS_SSL_TRANSPORT_IS_TLS( ssl->conf->transport ) && - ( buf[0] & 0x80 ) != 0 ) - { - return( ssl_parse_client_hello_v2( ssl ) ); - } +#if defined(MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO) +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_STREAM ) +#endif + if( ( buf[0] & 0x80 ) != 0 ) + return( ssl_parse_client_hello_v2( ssl ) ); #endif - MBEDTLS_SSL_DEBUG_BUF( 4, "record header", buf, mbedtls_ssl_in_hdr_len( ssl ) ); + MBEDTLS_SSL_DEBUG_BUF( 4, "record header", buf, mbedtls_ssl_hdr_len( ssl ) ); /* * SSLv3/TLS Client Hello @@ -1463,13 +1267,12 @@ read_record_header: } MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, message len.: %d", - (int)mbedtls_platform_get_uint16_be( ssl->in_len ) ) ); + ( ssl->in_len[0] << 8 ) | ssl->in_len[1] ) ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, protocol version: [%d:%d]", buf[1], buf[2] ) ); - mbedtls_ssl_read_version( &major, &minor, - mbedtls_ssl_conf_get_transport( ssl->conf ), buf + 1 ); + mbedtls_ssl_read_version( &major, &minor, ssl->conf->transport, buf + 1 ); /* According to RFC 5246 Appendix E.1, the version here is typically * "{03,00}, the lowest version number supported by the client, [or] the @@ -1484,8 +1287,11 @@ read_record_header: /* For DTLS if this is the initial handshake, remember the client sequence * number to use it in our next message (RFC 6347 4.2.1) */ #if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) && - mbedtls_ssl_get_renego_status( ssl ) == MBEDTLS_SSL_INITIAL_HANDSHAKE ) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM +#if defined(MBEDTLS_SSL_RENEGOTIATION) + && ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE +#endif + ) { /* Epoch should be 0 for initial handshakes */ if( ssl->in_ctr[0] != 0 || ssl->in_ctr[1] != 0 ) @@ -1494,7 +1300,7 @@ read_record_header: return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); } - mbedtls_platform_memcpy( ssl->cur_out_ctr + 2, ssl->in_ctr + 2, 6 ); + memcpy( ssl->out_ctr + 2, ssl->in_ctr + 2, 6 ); #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) if( mbedtls_ssl_dtls_replay_check( ssl ) != 0 ) @@ -1511,7 +1317,7 @@ read_record_header: } #endif /* MBEDTLS_SSL_PROTO_DTLS */ - msg_len = mbedtls_platform_get_uint16_be( ssl->in_len ); + msg_len = ( ssl->in_len[0] << 8 ) | ssl->in_len[1]; #if defined(MBEDTLS_SSL_RENEGOTIATION) if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE ) @@ -1522,39 +1328,33 @@ read_record_header: else #endif { - if( msg_len > MBEDTLS_SSL_IN_CONTENT_LEN ) + if( msg_len > MBEDTLS_SSL_MAX_CONTENT_LEN ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); } if( ( ret = mbedtls_ssl_fetch_input( ssl, - mbedtls_ssl_in_hdr_len( ssl ) + msg_len ) ) != 0 ) + mbedtls_ssl_hdr_len( ssl ) + msg_len ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret ); return( ret ); } - /* Done reading this record, get ready for the next one */ + /* Done reading this record, get ready for the next one */ #if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) ) - { - ssl->next_record_offset = msg_len + mbedtls_ssl_in_hdr_len( ssl ); - } - MBEDTLS_SSL_TRANSPORT_ELSE + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + ssl->next_record_offset = msg_len + mbedtls_ssl_hdr_len( ssl ); + else #endif -#if defined(MBEDTLS_SSL_PROTO_TLS) - { ssl->in_left = 0; - } -#endif } buf = ssl->in_msg; MBEDTLS_SSL_DEBUG_BUF( 4, "record contents", buf, msg_len ); - mbedtls_ssl_update_checksum( ssl, buf, msg_len ); + ssl->handshake->update_checksum( ssl, buf, msg_len ); /* * Handshake layer: @@ -1579,19 +1379,18 @@ read_record_header: } MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, handshake len.: %d", - (int)mbedtls_platform_get_uint24_be( &buf[1]) ) ); + ( buf[1] << 16 ) | ( buf[2] << 8 ) | buf[3] ) ); /* We don't support fragmentation of ClientHello (yet?) */ if( buf[1] != 0 || - msg_len != ( mbedtls_ssl_hs_hdr_len( ssl ) + - mbedtls_platform_get_uint16_be( &buf[2]) ) ) + msg_len != mbedtls_ssl_hs_hdr_len( ssl ) + ( ( buf[2] << 8 ) | buf[3] ) ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); } #if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) ) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) { /* * Copy the client's handshake message_seq on initial handshakes, @@ -1601,8 +1400,8 @@ read_record_header: if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS ) { /* This couldn't be done in ssl_prepare_handshake_record() */ - unsigned int cli_msg_seq = (unsigned int) - mbedtls_platform_get_uint16_be( &ssl->in_msg[4] ); + unsigned int cli_msg_seq = ( ssl->in_msg[4] << 8 ) | + ssl->in_msg[5]; if( cli_msg_seq != ssl->handshake->in_msg_seq ) { @@ -1617,9 +1416,8 @@ read_record_header: else #endif { - unsigned int cli_msg_seq = (unsigned int) - mbedtls_platform_get_uint16_be( &ssl->in_msg[4] ); - + unsigned int cli_msg_seq = ( ssl->in_msg[4] << 8 ) | + ssl->in_msg[5]; ssl->handshake->out_msg_seq = cli_msg_seq; ssl->handshake->in_msg_seq = cli_msg_seq + 1; } @@ -1629,7 +1427,7 @@ read_record_header: * fragment_offset == 0 and fragment_length == length */ if( ssl->in_msg[6] != 0 || ssl->in_msg[7] != 0 || ssl->in_msg[8] != 0 || - mbedtls_platform_memequal( ssl->in_msg + 1, ssl->in_msg + 9, 3 ) != 0 ) + memcmp( ssl->in_msg + 1, ssl->in_msg + 9, 3 ) != 0 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "ClientHello fragmentation not supported" ) ); return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); @@ -1657,7 +1455,7 @@ read_record_header: */ /* - * Minimal length (with everything empty and extensions omitted) is + * Minimal length (with everything empty and extensions ommitted) is * 2 + 32 + 1 + 2 + 1 = 38 bytes. Check that first, so that we can * read at least up to session id length without worrying. */ @@ -1672,67 +1470,39 @@ read_record_header: */ MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, version", buf, 2 ); + mbedtls_ssl_read_version( &ssl->major_ver, &ssl->minor_ver, + ssl->conf->transport, buf ); + + ssl->handshake->max_major_ver = ssl->major_ver; + ssl->handshake->max_minor_ver = ssl->minor_ver; + + if( ssl->major_ver < ssl->conf->min_major_ver || + ssl->minor_ver < ssl->conf->min_minor_ver ) { - int minor_ver, major_ver; - mbedtls_ssl_read_version( &major_ver, &minor_ver, - mbedtls_ssl_conf_get_transport( ssl->conf ), - buf ); - -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) - ssl->handshake->max_major_ver = major_ver; - ssl->handshake->max_minor_ver = minor_ver; -#endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED || - MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ - - if( mbedtls_ssl_ver_lt( major_ver, - mbedtls_ssl_conf_get_min_major_ver( ssl->conf ) ) || - mbedtls_ssl_ver_lt( minor_ver, - mbedtls_ssl_conf_get_min_minor_ver( ssl->conf ) ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "client only supports ssl smaller than minimum" + MBEDTLS_SSL_DEBUG_MSG( 1, ( "client only supports ssl smaller than minimum" " [%d:%d] < [%d:%d]", - major_ver, minor_ver, - mbedtls_ssl_conf_get_min_major_ver( ssl->conf ), - mbedtls_ssl_conf_get_min_minor_ver( ssl->conf ) ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION ); - return( MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION ); - } - - if( mbedtls_ssl_ver_gt( - major_ver, - mbedtls_ssl_conf_get_max_major_ver( ssl->conf ) ) ) - { - major_ver = mbedtls_ssl_conf_get_max_major_ver( ssl->conf ); - minor_ver = mbedtls_ssl_conf_get_max_minor_ver( ssl->conf ); - } - else if( mbedtls_ssl_ver_gt( - minor_ver, - mbedtls_ssl_conf_get_max_minor_ver( ssl->conf ) ) ) - { - minor_ver = mbedtls_ssl_conf_get_max_minor_ver( ssl->conf ); - } - -#if !defined(MBEDTLS_SSL_CONF_FIXED_MAJOR_VER) - ssl->major_ver = major_ver; -#endif /* MBEDTLS_SSL_CONF_FIXED_MAJOR_VER */ -#if !defined(MBEDTLS_SSL_CONF_FIXED_MINOR_VER) - ssl->minor_ver = minor_ver; -#endif /* MBEDTLS_SSL_CONF_FIXED_MINOR_VER */ + ssl->major_ver, ssl->minor_ver, + ssl->conf->min_major_ver, ssl->conf->min_minor_ver ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION ); + return( MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION ); } + if( ssl->major_ver > ssl->conf->max_major_ver ) + { + ssl->major_ver = ssl->conf->max_major_ver; + ssl->minor_ver = ssl->conf->max_minor_ver; + } + else if( ssl->minor_ver > ssl->conf->max_minor_ver ) + ssl->minor_ver = ssl->conf->max_minor_ver; + /* * Save client random (inc. Unix time) */ - ssl->handshake->hello_random_set = MBEDTLS_SSL_FI_FLAG_UNSET; MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, random bytes", buf + 2, 32 ); - mbedtls_platform_memcpy( ssl->handshake->randbytes, buf + 2, 32 ); - if( mbedtls_platform_memequal( ssl->handshake->randbytes, buf + 2, 32 ) == 0 ) - { - ssl->handshake->hello_random_set = MBEDTLS_SSL_FI_FLAG_SET; - } + memcpy( ssl->handshake->randbytes, buf + 2, 32 ); + /* * Check the session ID length and save session ID */ @@ -1742,8 +1512,8 @@ read_record_header: sess_len + 34 + 2 > msg_len ) /* 2 for cipherlist length field */ { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); } @@ -1752,7 +1522,6 @@ read_record_header: ssl->session_negotiate->id_len = sess_len; memset( ssl->session_negotiate->id, 0, sizeof( ssl->session_negotiate->id ) ); - /* Not using more secure mbedtls_platform_memcpy as id is public */ memcpy( ssl->session_negotiate->id, buf + 35, ssl->session_negotiate->id_len ); @@ -1760,7 +1529,7 @@ read_record_header: * Check the cookie length and content */ #if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) ) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) { cookie_offset = 35 + sess_len; cookie_len = buf[cookie_offset]; @@ -1768,8 +1537,8 @@ read_record_header: if( cookie_offset + 1 + cookie_len + 2 > msg_len ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); } @@ -1777,8 +1546,11 @@ read_record_header: buf + cookie_offset + 1, cookie_len ); #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) - if( ssl->conf->f_cookie_check != NULL && - mbedtls_ssl_get_renego_status( ssl ) == MBEDTLS_SSL_INITIAL_HANDSHAKE ) + if( ssl->conf->f_cookie_check != NULL +#if defined(MBEDTLS_SSL_RENEGOTIATION) + && ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE +#endif + ) { if( ssl->conf->f_cookie_check( ssl->conf->p_cookie, buf + cookie_offset + 1, cookie_len, @@ -1812,24 +1584,20 @@ read_record_header: */ ciph_offset = cookie_offset + 1 + cookie_len; } - MBEDTLS_SSL_TRANSPORT_ELSE + else #endif /* MBEDTLS_SSL_PROTO_DTLS */ -#if defined(MBEDTLS_SSL_PROTO_TLS) - { ciph_offset = 35 + sess_len; - } -#endif /* MBEDTLS_SSL_PROTO_TLS */ - - ciph_len = mbedtls_platform_get_uint16_be( &buf[ciph_offset + 0] ); + ciph_len = ( buf[ciph_offset + 0] << 8 ) + | ( buf[ciph_offset + 1] ); if( ciph_len < 2 || ciph_len + 2 + ciph_offset + 1 > msg_len || /* 1 for comp. alg. len */ ( ciph_len % 2 ) != 0 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); } @@ -1848,16 +1616,16 @@ read_record_header: comp_len + comp_offset + 1 > msg_len ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); } MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, compression", buf + comp_offset + 1, comp_len ); -#if defined(MBEDTLS_ZLIB_SUPPORT) ssl->session_negotiate->compression = MBEDTLS_SSL_COMPRESS_NULL; +#if defined(MBEDTLS_ZLIB_SUPPORT) for( i = 0; i < comp_len; ++i ) { if( buf[comp_offset + 1 + i] == MBEDTLS_SSL_COMPRESS_DEFLATE ) @@ -1866,18 +1634,17 @@ read_record_header: break; } } +#endif /* See comments in ssl_write_client_hello() */ #if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) ) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) ssl->session_negotiate->compression = MBEDTLS_SSL_COMPRESS_NULL; #endif -#endif /* MBEDTLS_ZLIB_SUPPORT */ /* Do not parse the extensions if the protocol is SSLv3 */ #if defined(MBEDTLS_SSL_PROTO_SSL3) - if( ( mbedtls_ssl_get_major_ver( ssl ) != 3 ) || - ( mbedtls_ssl_get_minor_ver( ssl ) != 0 ) ) + if( ( ssl->major_ver != 3 ) || ( ssl->minor_ver != 0 ) ) { #endif /* @@ -1889,19 +1656,20 @@ read_record_header: if( msg_len < ext_offset + 2 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); } - ext_len = mbedtls_platform_get_uint16_be( &buf[ext_offset + 0] ); + ext_len = ( buf[ext_offset + 0] << 8 ) + | ( buf[ext_offset + 1] ); if( ( ext_len > 0 && ext_len < 4 ) || msg_len != ext_offset + 2 + ext_len ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); } } @@ -1917,18 +1685,18 @@ read_record_header: unsigned int ext_size; if ( ext_len < 4 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); } - ext_id = (unsigned int)mbedtls_platform_get_uint16_be( ext ); - ext_size = (unsigned int)mbedtls_platform_get_uint16_be( &ext[2] ); + ext_id = ( ( ext[0] << 8 ) | ( ext[1] ) ); + ext_size = ( ( ext[2] << 8 ) | ( ext[3] ) ); if( ext_size + 4 > ext_len ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); } switch( ext_id ) @@ -1970,17 +1738,12 @@ read_record_header: #endif /* MBEDTLS_SSL_PROTO_TLS1_2 && MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ -#if defined(MBEDTLS_ECDH_C) || \ - defined(MBEDTLS_ECDSA_C) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) || \ - defined(MBEDTLS_USE_TINYCRYPT) +#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) case MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES: MBEDTLS_SSL_DEBUG_MSG( 3, ( "found supported elliptic curves extension" ) ); - ret = ssl_parse_supported_elliptic_curves( ssl, ext + 4, - ext_size, - &acceptable_ec_tls_ids, - &ec_tls_ids_len ); + ret = ssl_parse_supported_elliptic_curves( ssl, ext + 4, ext_size ); if( ret != 0 ) return( ret ); break; @@ -1994,8 +1757,7 @@ read_record_header: return( ret ); break; #endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || - MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED || - MBEDTLS_USE_TINYCRYPT */ + MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) case MBEDTLS_TLS_EXT_ECJPAKE_KKPP: @@ -2027,16 +1789,6 @@ read_record_header: break; #endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - case MBEDTLS_TLS_EXT_CID: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "found CID extension" ) ); - - ret = ssl_parse_cid_ext( ssl, ext + 4, ext_size ); - if( ret != 0 ) - return( ret ); - break; -#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ - #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) case MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC: MBEDTLS_SSL_DEBUG_MSG( 3, ( "found encrypt then mac extension" ) ); @@ -2054,7 +1806,6 @@ read_record_header: ret = ssl_parse_extended_ms_ext( ssl, ext + 4, ext_size ); if( ret != 0 ) return( ret ); - extended_ms_seen = 1; break; #endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ @@ -2089,8 +1840,8 @@ read_record_header: if( ext_len > 0 && ext_len < 4 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); } } @@ -2106,14 +1857,12 @@ read_record_header: { MBEDTLS_SSL_DEBUG_MSG( 2, ( "received FALLBACK_SCSV" ) ); - if( mbedtls_ssl_ver_lt( - mbedtls_ssl_get_minor_ver( ssl ), - mbedtls_ssl_conf_get_max_minor_ver( ssl->conf ) ) ) + if( ssl->minor_ver < ssl->conf->max_minor_ver ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "inapropriate fallback" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_INAPROPRIATE_FALLBACK ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_INAPROPRIATE_FALLBACK ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); } @@ -2156,8 +1905,8 @@ read_record_header: { MBEDTLS_SSL_DEBUG_MSG( 1, ( "received RENEGOTIATION SCSV " "during renegotiation" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); } #endif @@ -2170,8 +1919,7 @@ read_record_header: * Renegotiation security checks */ if( ssl->secure_renegotiation != MBEDTLS_SSL_SECURE_RENEGOTIATION && - mbedtls_ssl_conf_get_allow_legacy_renegotiation( ssl->conf ) == - MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE ) + ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation, breaking off handshake" ) ); handshake_failure = 1; @@ -2186,8 +1934,7 @@ read_record_header: } else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && - mbedtls_ssl_conf_get_allow_legacy_renegotiation( ssl->conf ) - == MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION ) + ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation not allowed" ) ); handshake_failure = 1; @@ -2201,33 +1948,10 @@ read_record_header: } #endif /* MBEDTLS_SSL_RENEGOTIATION */ - /* - * Check if extended master secret is being enforced - */ -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) - if( mbedtls_ssl_conf_get_ems( ssl->conf ) == - MBEDTLS_SSL_EXTENDED_MS_ENABLED ) - { - if( extended_ms_seen ) - { -#if !defined(MBEDTLS_SSL_EXTENDED_MS_ENFORCED) - ssl->handshake->extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED; -#endif /* !MBEDTLS_SSL_EXTENDED_MS_ENFORCED */ - } - else if( mbedtls_ssl_conf_get_ems_enforced( ssl->conf ) == - MBEDTLS_SSL_EXTENDED_MS_ENFORCE_ENABLED ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "Peer not offering extended master " - "secret, while it is enforced") ); - handshake_failure = 1; - } - } -#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ - if( handshake_failure == 1 ) { - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); } @@ -2237,83 +1961,56 @@ read_record_header: * and certificate from the SNI callback triggered by the SNI extension.) */ got_common_suite = 0; + ciphersuites = ssl->conf->ciphersuite_list[ssl->minor_ver]; + ciphersuite_info = NULL; #if defined(MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE) for( j = 0, p = buf + ciph_offset + 2; j < ciph_len; j += 2, p += 2 ) - { - MBEDTLS_SSL_BEGIN_FOR_EACH_CIPHERSUITE( ssl, \ - mbedtls_ssl_get_minor_ver( ssl ), \ - cur_info ) - { + for( i = 0; ciphersuites[i] != 0; i++ ) #else - MBEDTLS_SSL_BEGIN_FOR_EACH_CIPHERSUITE( ssl, \ - mbedtls_ssl_get_minor_ver( ssl ), \ - cur_info ) - { + for( i = 0; ciphersuites[i] != 0; i++ ) for( j = 0, p = buf + ciph_offset + 2; j < ciph_len; j += 2, p += 2 ) - { #endif - const int ciphersuite_id = - mbedtls_ssl_suite_get_id( cur_info ); - - if( p[0] != ( ( ciphersuite_id >> 8 ) & 0xFF ) || - p[1] != ( ( ciphersuite_id ) & 0xFF ) ) - { + { + if( p[0] != ( ( ciphersuites[i] >> 8 ) & 0xFF ) || + p[1] != ( ( ciphersuites[i] ) & 0xFF ) ) continue; - } got_common_suite = 1; - if( ssl_ciphersuite_is_match( ssl, cur_info, - acceptable_ec_tls_ids, - ec_tls_ids_len ) != 0 ) - { -#if !defined(MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE) - ciphersuite_info = cur_info; -#endif /* MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE */ + if( ( ret = ssl_ciphersuite_match( ssl, ciphersuites[i], + &ciphersuite_info ) ) != 0 ) + return( ret ); + + if( ciphersuite_info != NULL ) goto have_ciphersuite; - } -#if defined(MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE) } - MBEDTLS_SSL_END_FOR_EACH_CIPHERSUITE - } -#else - } - } - MBEDTLS_SSL_END_FOR_EACH_CIPHERSUITE -#endif if( got_common_suite ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "got ciphersuites in common, " "but none of them usable" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE ); } else { MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no ciphersuites in common" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN ); } have_ciphersuite: + MBEDTLS_SSL_DEBUG_MSG( 2, ( "selected ciphersuite: %s", ciphersuite_info->name ) ); -#if !defined(MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE) - ssl->session_negotiate->ciphersuite = - mbedtls_ssl_suite_get_id( ciphersuite_info ); - ssl->handshake->ciphersuite_info = ciphersuite_info; -#endif /* MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE */ + ssl->session_negotiate->ciphersuite = ciphersuites[i]; + ssl->transform_negotiate->ciphersuite_info = ciphersuite_info; - MBEDTLS_SSL_DEBUG_MSG( 2, ( "selected ciphersuite: %s", - mbedtls_ssl_get_ciphersuite_name( - mbedtls_ssl_session_get_ciphersuite( ssl->session_negotiate ) ) ) ); - - ssl->state = MBEDTLS_SSL_SERVER_HELLO; + ssl->state++; #if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) ) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) mbedtls_ssl_recv_flight_completed( ssl ); #endif @@ -2321,10 +2018,9 @@ have_ciphersuite: #if defined(MBEDTLS_DEBUG_C) && \ defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) - if( mbedtls_ssl_get_minor_ver( ssl ) == MBEDTLS_SSL_MINOR_VERSION_3 ) + if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) { - mbedtls_pk_type_t sig_alg = mbedtls_ssl_get_ciphersuite_sig_alg( - mbedtls_ssl_handshake_get_ciphersuite( ssl->handshake ) ); + mbedtls_pk_type_t sig_alg = mbedtls_ssl_get_ciphersuite_sig_alg( ciphersuite_info ); if( sig_alg != MBEDTLS_PK_NONE ) { mbedtls_md_type_t md_alg = mbedtls_ssl_sig_hash_set_find( &ssl->handshake->hash_algs, @@ -2360,7 +2056,9 @@ static void ssl_write_truncated_hmac_ext( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding truncated hmac extension" ) ); - p = mbedtls_platform_put_uint16_be( p, MBEDTLS_TLS_EXT_TRUNCATED_HMAC ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC ) & 0xFF ); + *p++ = 0x00; *p++ = 0x00; @@ -2368,63 +2066,17 @@ static void ssl_write_truncated_hmac_ext( mbedtls_ssl_context *ssl, } #endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) -static void ssl_write_cid_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, - size_t *olen ) -{ - unsigned char *p = buf; - size_t ext_len; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; - - *olen = 0; - - /* Skip writing the extension if we don't want to use it or if - * the client hasn't offered it. */ - if( ssl->handshake->cid_in_use == MBEDTLS_SSL_CID_DISABLED ) - return; - - /* ssl->own_cid_len is at most MBEDTLS_SSL_CID_IN_LEN_MAX - * which is at most 255, so the increment cannot overflow. */ - if( end < p || (size_t)( end - p ) < (unsigned)( ssl->own_cid_len + 5 ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); - return; - } - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding CID extension" ) ); - - /* - * Quoting draft-ietf-tls-dtls-connection-id-05 - * https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05 - * - * struct { - * opaque cid<0..2^8-1>; - * } ConnectionId; - */ - p = mbedtls_platform_put_uint16_be( p, MBEDTLS_TLS_EXT_CID ); - ext_len = (size_t) ssl->own_cid_len + 1; - p = mbedtls_platform_put_uint16_be( p, ext_len ); - *p++ = (uint8_t) ssl->own_cid_len; - /* Not using more secure mbedtls_platform_memcpy as cid is public */ - memcpy( p, ssl->own_cid, ssl->own_cid_len ); - - *olen = ssl->own_cid_len + 5; -} -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) static void ssl_write_encrypt_then_mac_ext( mbedtls_ssl_context *ssl, unsigned char *buf, size_t *olen ) { unsigned char *p = buf; - mbedtls_ssl_ciphersuite_handle_t suite = - MBEDTLS_SSL_CIPHERSUITE_INVALID_HANDLE; + const mbedtls_ssl_ciphersuite_t *suite = NULL; const mbedtls_cipher_info_t *cipher = NULL; if( ssl->session_negotiate->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED || - mbedtls_ssl_get_minor_ver( ssl ) == MBEDTLS_SSL_MINOR_VERSION_0 ) + ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) { *olen = 0; return; @@ -2436,17 +2088,9 @@ static void ssl_write_encrypt_then_mac_ext( mbedtls_ssl_context *ssl, * with Associated Data (AEAD) ciphersuite, it MUST NOT send an * encrypt-then-MAC response extension back to the client." */ - suite = mbedtls_ssl_ciphersuite_from_id( - mbedtls_ssl_session_get_ciphersuite( ssl->session_negotiate ) ); - if( suite == MBEDTLS_SSL_CIPHERSUITE_INVALID_HANDLE ) - { - *olen = 0; - return; - } - - cipher = mbedtls_cipher_info_from_type( - mbedtls_ssl_suite_get_cipher( suite ) ); - if( cipher == NULL || + if( ( suite = mbedtls_ssl_ciphersuite_from_id( + ssl->session_negotiate->ciphersuite ) ) == NULL || + ( cipher = mbedtls_cipher_info_from_type( suite->cipher ) ) == NULL || cipher->mode != MBEDTLS_MODE_CBC ) { *olen = 0; @@ -2455,7 +2099,9 @@ static void ssl_write_encrypt_then_mac_ext( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding encrypt then mac extension" ) ); - p = mbedtls_platform_put_uint16_be( p, MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC ) & 0xFF ); + *p++ = 0x00; *p++ = 0x00; @@ -2470,9 +2116,8 @@ static void ssl_write_extended_ms_ext( mbedtls_ssl_context *ssl, { unsigned char *p = buf; - if( mbedtls_ssl_hs_get_extended_ms( ssl->handshake ) - == MBEDTLS_SSL_EXTENDED_MS_DISABLED || - mbedtls_ssl_get_minor_ver( ssl ) == MBEDTLS_SSL_MINOR_VERSION_0 ) + if( ssl->handshake->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED || + ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) { *olen = 0; return; @@ -2481,7 +2126,8 @@ static void ssl_write_extended_ms_ext( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding extended master secret " "extension" ) ); - p = mbedtls_platform_put_uint16_be( p, MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET ) & 0xFF ); *p++ = 0x00; *p++ = 0x00; @@ -2505,7 +2151,9 @@ static void ssl_write_session_ticket_ext( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding session ticket extension" ) ); - p = mbedtls_platform_put_uint16_be( p, MBEDTLS_TLS_EXT_SESSION_TICKET ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET ) & 0xFF ); + *p++ = 0x00; *p++ = 0x00; @@ -2527,7 +2175,8 @@ static void ssl_write_renegotiation_ext( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, secure renegotiation extension" ) ); - p = mbedtls_platform_put_uint16_be( p, MBEDTLS_TLS_EXT_RENEGOTIATION_INFO ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO ) & 0xFF ); #if defined(MBEDTLS_SSL_RENEGOTIATION) if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE ) @@ -2536,9 +2185,9 @@ static void ssl_write_renegotiation_ext( mbedtls_ssl_context *ssl, *p++ = ( ssl->verify_data_len * 2 + 1 ) & 0xFF; *p++ = ssl->verify_data_len * 2 & 0xFF; - mbedtls_platform_memcpy( p, ssl->peer_verify_data, ssl->verify_data_len ); + memcpy( p, ssl->peer_verify_data, ssl->verify_data_len ); p += ssl->verify_data_len; - mbedtls_platform_memcpy( p, ssl->own_verify_data, ssl->verify_data_len ); + memcpy( p, ssl->own_verify_data, ssl->verify_data_len ); p += ssl->verify_data_len; } else @@ -2567,7 +2216,9 @@ static void ssl_write_max_fragment_length_ext( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, max_fragment_length extension" ) ); - p = mbedtls_platform_put_uint16_be( p, MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH ) & 0xFF ); + *p++ = 0x00; *p++ = 1; @@ -2578,8 +2229,7 @@ static void ssl_write_max_fragment_length_ext( mbedtls_ssl_context *ssl, #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) || \ - defined(MBEDTLS_USE_TINYCRYPT) + defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) static void ssl_write_supported_point_formats_ext( mbedtls_ssl_context *ssl, unsigned char *buf, size_t *olen ) @@ -2596,13 +2246,14 @@ static void ssl_write_supported_point_formats_ext( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, supported_point_formats extension" ) ); - p = mbedtls_platform_put_uint16_be( p, MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS ) & 0xFF ); *p++ = 0x00; *p++ = 2; *p++ = 1; - *p++ = MBEDTLS_SSL_EC_PF_UNCOMPRESSED; + *p++ = MBEDTLS_ECP_PF_UNCOMPRESSED; *olen = 6; } @@ -2615,18 +2266,15 @@ static void ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl, { int ret; unsigned char *p = buf; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; size_t kkpp_len; *olen = 0; /* Skip costly computation if not needed */ - if( mbedtls_ssl_suite_get_key_exchange( - mbedtls_ssl_handshake_get_ciphersuite( ssl->handshake ) ) != + if( ssl->transform_negotiate->ciphersuite_info->key_exchange != MBEDTLS_KEY_EXCHANGE_ECJPAKE ) - { return; - } MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, ecjpake kkpp extension" ) ); @@ -2636,19 +2284,21 @@ static void ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl, return; } - p = mbedtls_platform_put_uint16_be( p, MBEDTLS_TLS_EXT_ECJPAKE_KKPP ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP ) & 0xFF ); ret = mbedtls_ecjpake_write_round_one( &ssl->handshake->ecjpake_ctx, p + 2, end - p - 2, &kkpp_len, - mbedtls_ssl_conf_get_frng( ssl->conf ), - mbedtls_ssl_conf_get_prng( ssl->conf ) ); + ssl->conf->f_rng, ssl->conf->p_rng ); if( ret != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1 , "mbedtls_ecjpake_write_round_one", ret ); return; } - p = mbedtls_platform_put_uint16_be( p, kkpp_len ); + *p++ = (unsigned char)( ( kkpp_len >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( kkpp_len ) & 0xFF ); + *olen = kkpp_len + 4; } #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ @@ -2672,15 +2322,20 @@ static void ssl_write_alpn_ext( mbedtls_ssl_context *ssl, * 6 . 6 protocol name length * 7 . 7+n protocol name */ - (void)mbedtls_platform_put_uint16_be( &buf[0], MBEDTLS_TLS_EXT_ALPN ); + buf[0] = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN >> 8 ) & 0xFF ); + buf[1] = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN ) & 0xFF ); *olen = 7 + strlen( ssl->alpn_chosen ); - (void)mbedtls_platform_put_uint16_be( &buf[2], ( *olen - 4 ) ); - (void)mbedtls_platform_put_uint16_be( &buf[4], ( *olen - 6 ) ); + + buf[2] = (unsigned char)( ( ( *olen - 4 ) >> 8 ) & 0xFF ); + buf[3] = (unsigned char)( ( ( *olen - 4 ) ) & 0xFF ); + + buf[4] = (unsigned char)( ( ( *olen - 6 ) >> 8 ) & 0xFF ); + buf[5] = (unsigned char)( ( ( *olen - 6 ) ) & 0xFF ); buf[6] = (unsigned char)( ( ( *olen - 7 ) ) & 0xFF ); - mbedtls_platform_memcpy( buf + 7, ssl->alpn_chosen, *olen - 7 ); + memcpy( buf + 7, ssl->alpn_chosen, *olen - 7 ); } #endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C */ @@ -2702,9 +2357,8 @@ static int ssl_write_hello_verify_request( mbedtls_ssl_context *ssl ) /* The RFC is not clear on this point, but sending the actual negotiated * version looks like the most interoperable thing to do. */ - mbedtls_ssl_write_version( mbedtls_ssl_get_major_ver( ssl ), - mbedtls_ssl_get_minor_ver( ssl ), - mbedtls_ssl_conf_get_transport( ssl->conf ), p ); + mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver, + ssl->conf->transport, p ); MBEDTLS_SSL_DEBUG_BUF( 3, "server version", p, 2 ); p += 2; @@ -2719,7 +2373,7 @@ static int ssl_write_hello_verify_request( mbedtls_ssl_context *ssl ) cookie_len_byte = p++; if( ( ret = ssl->conf->f_cookie_write( ssl->conf->p_cookie, - &p, ssl->out_buf + MBEDTLS_SSL_OUT_BUFFER_LEN, + &p, ssl->out_buf + MBEDTLS_SSL_BUFFER_LEN, ssl->cli_id, ssl->cli_id_len ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "f_cookie_write", ret ); @@ -2736,27 +2390,12 @@ static int ssl_write_hello_verify_request( mbedtls_ssl_context *ssl ) ssl->state = MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT; - if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 ) + if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 ) { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret ); + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret ); return( ret ); } -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) ) - { -#if defined(MBEDTLS_SSL_IMMEDIATE_TRANSMISSION) - mbedtls_ssl_immediate_flight_done( ssl ); -#else - if( ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flight_transmit", ret ); - return( ret ); - } -#endif - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write hello verify request" ) ); return( 0 ); @@ -2769,14 +2408,13 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl ) mbedtls_time_t t; #endif int ret; - int ciphersuite; size_t olen, ext_len = 0, n; unsigned char *buf, *p; MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write server hello" ) ); #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) && + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && ssl->handshake->verify_cookie_len != 0 ) { MBEDTLS_SSL_DEBUG_MSG( 2, ( "client hello was not authenticated" ) ); @@ -2786,7 +2424,7 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl ) } #endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */ - if( mbedtls_ssl_conf_get_frng( ssl->conf ) == NULL ) + if( ssl->conf->f_rng == NULL ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "no RNG provided") ); return( MBEDTLS_ERR_SSL_NO_RNG ); @@ -2802,9 +2440,8 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl ) buf = ssl->out_msg; p = buf + 4; - mbedtls_ssl_write_version( mbedtls_ssl_get_major_ver( ssl ), - mbedtls_ssl_get_minor_ver( ssl ), - mbedtls_ssl_conf_get_transport( ssl->conf ), p ); + mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver, + ssl->conf->transport, p ); p += 2; MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen version: [%d:%d]", @@ -2812,75 +2449,52 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl ) #if defined(MBEDTLS_HAVE_TIME) t = mbedtls_time( NULL ); - p = mbedtls_platform_put_uint32_be( p, (uint32_t) t ); + *p++ = (unsigned char)( t >> 24 ); + *p++ = (unsigned char)( t >> 16 ); + *p++ = (unsigned char)( t >> 8 ); + *p++ = (unsigned char)( t ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, current time: %lu", t ) ); #else - if( ( ret = mbedtls_ssl_conf_get_frng( ssl->conf ) - ( mbedtls_ssl_conf_get_prng( ssl->conf ), p, 4 ) ) != 0 ) - { + if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p, 4 ) ) != 0 ) return( ret ); - } p += 4; #endif /* MBEDTLS_HAVE_TIME */ - if( ( ret = mbedtls_ssl_conf_get_frng( ssl->conf ) - ( mbedtls_ssl_conf_get_prng( ssl->conf ), p, 28 ) ) != 0 ) - { + if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p, 28 ) ) != 0 ) return( ret ); - } p += 28; - ssl->handshake->hello_random_set = MBEDTLS_SSL_FI_FLAG_UNSET; - mbedtls_platform_memcpy( ssl->handshake->randbytes + 32, buf + 6, 32 ); - if( mbedtls_platform_memequal( ssl->handshake->randbytes + 32, buf + 6, 32 ) == 0 ) - { - ssl->handshake->hello_random_set = MBEDTLS_SSL_FI_FLAG_SET; - } + + memcpy( ssl->handshake->randbytes + 32, buf + 6, 32 ); MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, random bytes", buf + 6, 32 ); -#if !defined(MBEDTLS_SSL_NO_SESSION_CACHE) /* * Resume is 0 by default, see ssl_handshake_init(). * It may be already set to 1 by ssl_parse_session_ticket_ext(). * If not, try looking up session ID in our cache. */ - if( mbedtls_ssl_handshake_get_resume( ssl->handshake ) == MBEDTLS_SSL_FI_FLAG_UNSET && - mbedtls_ssl_get_renego_status( ssl ) == MBEDTLS_SSL_INITIAL_HANDSHAKE && + if( ssl->handshake->resume == 0 && +#if defined(MBEDTLS_SSL_RENEGOTIATION) + ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE && +#endif ssl->session_negotiate->id_len != 0 && ssl->conf->f_get_cache != NULL && ssl->conf->f_get_cache( ssl->conf->p_cache, ssl->session_negotiate ) == 0 ) { MBEDTLS_SSL_DEBUG_MSG( 3, ( "session successfully restored from cache" ) ); - ssl->handshake->resume = MBEDTLS_SSL_FI_FLAG_SET; + ssl->handshake->resume = 1; } -#endif /* !MBEDTLS_SSL_NO_SESSION_CACHE */ -#if !defined(MBEDTLS_SSL_NO_SESSION_RESUMPTION) - if( mbedtls_ssl_handshake_get_resume( ssl->handshake ) == MBEDTLS_SSL_FI_FLAG_SET ) - { - /* - * Resuming a session - */ - n = ssl->session_negotiate->id_len; - ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC; - - if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret ); - return( ret ); - } - } - else -#endif /* !MBEDTLS_SSL_NO_SESSION_RESUMPTION */ + if( ssl->handshake->resume == 0 ) { /* * New session, create a new session id, * unless we're about to issue a session ticket */ - ssl->state = MBEDTLS_SSL_SERVER_CERTIFICATE; + ssl->state++; #if defined(MBEDTLS_HAVE_TIME) ssl->session_negotiate->start = mbedtls_time( NULL ); @@ -2896,11 +2510,23 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl ) #endif /* MBEDTLS_SSL_SESSION_TICKETS */ { ssl->session_negotiate->id_len = n = 32; - if( ( ret = mbedtls_ssl_conf_get_frng( ssl->conf ) - ( mbedtls_ssl_conf_get_prng( ssl->conf ), ssl->session_negotiate->id, n ) ) != 0 ) - { + if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, ssl->session_negotiate->id, + n ) ) != 0 ) return( ret ); - } + } + } + else + { + /* + * Resuming a session + */ + n = ssl->session_negotiate->id_len; + ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC; + + if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret ); + return( ret ); } } @@ -2913,28 +2539,26 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl ) * 44+n . 43+n+m extensions */ *p++ = (unsigned char) ssl->session_negotiate->id_len; - /* Not using more secure mbedtls_platform_memcpy as id is public */ memcpy( p, ssl->session_negotiate->id, ssl->session_negotiate->id_len ); p += ssl->session_negotiate->id_len; MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, session id len.: %d", n ) ); MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, session id", buf + 39, n ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "%s session has been resumed", - mbedtls_ssl_handshake_get_resume( ssl->handshake ) ? "a" : "no" ) ); + ssl->handshake->resume ? "a" : "no" ) ); - ciphersuite = mbedtls_ssl_session_get_ciphersuite( ssl->session_negotiate ); - p = mbedtls_platform_put_uint16_be( p, ciphersuite ); - *p++ = (unsigned char)( - mbedtls_ssl_session_get_compression( ssl->session_negotiate ) ); + *p++ = (unsigned char)( ssl->session_negotiate->ciphersuite >> 8 ); + *p++ = (unsigned char)( ssl->session_negotiate->ciphersuite ); + *p++ = (unsigned char)( ssl->session_negotiate->compression ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %s", - mbedtls_ssl_get_ciphersuite_name( ciphersuite ) ) ); + mbedtls_ssl_get_ciphersuite_name( ssl->session_negotiate->ciphersuite ) ) ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, compress alg.: 0x%02X", - mbedtls_ssl_session_get_compression( ssl->session_negotiate ) ) ); + ssl->session_negotiate->compression ) ); /* Do not write the extensions if the protocol is SSLv3 */ #if defined(MBEDTLS_SSL_PROTO_SSL3) - if( ( mbedtls_ssl_get_major_ver( ssl ) != 3 ) || ( mbedtls_ssl_get_minor_ver( ssl ) != 0 ) ) + if( ( ssl->major_ver != 3 ) || ( ssl->minor_ver != 0 ) ) { #endif @@ -2954,11 +2578,6 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl ) ext_len += olen; #endif -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - ssl_write_cid_ext( ssl, p + 2 + ext_len, &olen ); - ext_len += olen; -#endif - #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) ssl_write_encrypt_then_mac_ext( ssl, p + 2 + ext_len, &olen ); ext_len += olen; @@ -2975,11 +2594,9 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl ) #endif #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) || \ - defined(MBEDTLS_USE_TINYCRYPT) + defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) if ( mbedtls_ssl_ciphersuite_uses_ec( - mbedtls_ssl_ciphersuite_from_id( - mbedtls_ssl_session_get_ciphersuite( ssl->session_negotiate ) ) ) ) + mbedtls_ssl_ciphersuite_from_id( ssl->session_negotiate->ciphersuite ) ) ) { ssl_write_supported_point_formats_ext( ssl, p + 2 + ext_len, &olen ); ext_len += olen; @@ -3000,7 +2617,8 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl ) if( ext_len > 0 ) { - p = mbedtls_platform_put_uint16_be( p, ext_len ); + *p++ = (unsigned char)( ( ext_len >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( ext_len ) & 0xFF ); p += ext_len; } @@ -3012,56 +2630,69 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl ) ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; ssl->out_msg[0] = MBEDTLS_SSL_HS_SERVER_HELLO; - ret = mbedtls_ssl_write_handshake_msg( ssl ); + ret = mbedtls_ssl_write_record( ssl ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write server hello" ) ); return( ret ); } -#if !defined(MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED) +#if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)&& \ + !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) static int ssl_write_certificate_request( mbedtls_ssl_context *ssl ) { - mbedtls_ssl_ciphersuite_handle_t ciphersuite_info = - mbedtls_ssl_handshake_get_ciphersuite( ssl->handshake ); + const mbedtls_ssl_ciphersuite_t *ciphersuite_info = + ssl->transform_negotiate->ciphersuite_info; MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate request" ) ); - if( !mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) ) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) { MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate request" ) ); - ssl->state = MBEDTLS_SSL_SERVER_HELLO_DONE; + ssl->state++; return( 0 ); } MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); } -#else /* !MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED */ +#else static int ssl_write_certificate_request( mbedtls_ssl_context *ssl ) { int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; - mbedtls_ssl_ciphersuite_handle_t ciphersuite_info = - mbedtls_ssl_handshake_get_ciphersuite( ssl->handshake ); + const mbedtls_ssl_ciphersuite_t *ciphersuite_info = + ssl->transform_negotiate->ciphersuite_info; size_t dn_size, total_dn_size; /* excluding length bytes */ size_t ct_len, sa_len; /* including length bytes */ unsigned char *buf, *p; - const unsigned char * const end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; + const unsigned char * const end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; const mbedtls_x509_crt *crt; int authmode; MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate request" ) ); - ssl->state = MBEDTLS_SSL_SERVER_HELLO_DONE; + ssl->state++; #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) if( ssl->handshake->sni_authmode != MBEDTLS_SSL_VERIFY_UNSET ) authmode = ssl->handshake->sni_authmode; else #endif - authmode = mbedtls_ssl_conf_get_authmode( ssl->conf ); + authmode = ssl->conf->authmode; - if( !mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) || + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE || authmode == MBEDTLS_SSL_VERIFY_NONE ) { MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate request" ) ); @@ -3094,7 +2725,7 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl ) #if defined(MBEDTLS_RSA_C) p[1 + ct_len++] = MBEDTLS_SSL_CERT_TYPE_RSA_SIGN; #endif -#if defined(MBEDTLS_ECDSA_C) || defined(MBEDTLS_USE_TINYCRYPT) +#if defined(MBEDTLS_ECDSA_C) p[1 + ct_len++] = MBEDTLS_SSL_CERT_TYPE_ECDSA_SIGN; #endif @@ -3116,33 +2747,32 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl ) * enum { (255) } HashAlgorithm; * enum { (255) } SignatureAlgorithm; */ - if( mbedtls_ssl_get_minor_ver( ssl ) == MBEDTLS_SSL_MINOR_VERSION_3 ) + if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) { + const int *cur; + /* * Supported signature algorithms */ - MBEDTLS_SSL_BEGIN_FOR_EACH_SIG_HASH_TLS( hash ) - if( 0 -#if defined(MBEDTLS_SHA512_C) - || hash == MBEDTLS_SSL_HASH_SHA384 -#endif -#if defined(MBEDTLS_SHA256_C) - || hash == MBEDTLS_SSL_HASH_SHA256 -#endif - ) + for( cur = ssl->conf->sig_hashes; *cur != MBEDTLS_MD_NONE; cur++ ) { + unsigned char hash = mbedtls_ssl_hash_from_md_alg( *cur ); + + if( MBEDTLS_SSL_HASH_NONE == hash || mbedtls_ssl_set_calc_verify_md( ssl, hash ) ) + continue; + #if defined(MBEDTLS_RSA_C) p[2 + sa_len++] = hash; p[2 + sa_len++] = MBEDTLS_SSL_SIG_RSA; #endif -#if defined(MBEDTLS_ECDSA_C) || defined(MBEDTLS_USE_TINYCRYPT) +#if defined(MBEDTLS_ECDSA_C) p[2 + sa_len++] = hash; p[2 + sa_len++] = MBEDTLS_SSL_SIG_ECDSA; #endif } - MBEDTLS_SSL_END_FOR_EACH_SIG_HASH_TLS - (void)mbedtls_platform_put_uint16_be( p, sa_len ); + p[0] = (unsigned char)( sa_len >> 8 ); + p[1] = (unsigned char)( sa_len ); sa_len += 2; p += sa_len; } @@ -3156,8 +2786,7 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl ) total_dn_size = 0; - if( mbedtls_ssl_conf_get_cert_req_ca_list( ssl->conf ) - == MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED ) + if( ssl->conf->cert_req_ca_list == MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED ) { #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) if( ssl->handshake->sni_ca_chain != NULL ) @@ -3166,37 +2795,26 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl ) #endif crt = ssl->conf->ca_chain; - while( crt != NULL && crt->raw.p != NULL ) + while( crt != NULL && crt->version != 0 ) { - mbedtls_x509_crt_frame const *frame; - ret = mbedtls_x509_crt_frame_acquire( crt, &frame ); - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_x509_crt_frame_acquire", ret ); - return( ret ); - } - - dn_size = frame->subject_raw.len; + dn_size = crt->subject_raw.len; if( end < p || (size_t)( end - p ) < dn_size || (size_t)( end - p ) < 2 + dn_size ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "skipping CAs: buffer too short" ) ); - mbedtls_x509_crt_frame_release( crt ); break; } - p = mbedtls_platform_put_uint16_be( p, dn_size ); - mbedtls_platform_memcpy( p, frame->subject_raw.p, dn_size ); + *p++ = (unsigned char)( dn_size >> 8 ); + *p++ = (unsigned char)( dn_size ); + memcpy( p, crt->subject_raw.p, dn_size ); p += dn_size; MBEDTLS_SSL_DEBUG_BUF( 3, "requested DN", p - dn_size, dn_size ); total_dn_size += 2 + dn_size; - - mbedtls_x509_crt_frame_release( crt ); - crt = crt->next; } } @@ -3204,39 +2822,24 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl ) ssl->out_msglen = p - buf; ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; ssl->out_msg[0] = MBEDTLS_SSL_HS_CERTIFICATE_REQUEST; - (void)mbedtls_platform_put_uint16_be( &ssl->out_msg[4 + ct_len + sa_len], - total_dn_size ); + ssl->out_msg[4 + ct_len + sa_len] = (unsigned char)( total_dn_size >> 8 ); + ssl->out_msg[5 + ct_len + sa_len] = (unsigned char)( total_dn_size ); - ret = mbedtls_ssl_write_handshake_msg( ssl ); + ret = mbedtls_ssl_write_record( ssl ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write certificate request" ) ); return( ret ); } -#endif /* MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED */ +#endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED && + !MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED && + !MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED && + !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED && + !MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED && + !MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ #if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) - -#if defined(MBEDTLS_USE_TINYCRYPT) -static int ssl_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl ) -{ - mbedtls_uecc_keypair *own_key = - mbedtls_pk_uecc( *mbedtls_ssl_own_key( ssl ) ); - - if( ! mbedtls_pk_can_do( mbedtls_ssl_own_key( ssl ), MBEDTLS_PK_ECKEY ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "server key not ECDH capable" ) ); - return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH ); - } - - mbedtls_platform_memcpy( ssl->handshake->ecdh_privkey, - own_key->private_key, - sizeof( ssl->handshake->ecdh_privkey ) ); - - return( 0 ); -} -#else /* MBEDTLS_USE_TINYCRYPT */ static int ssl_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl ) { int ret; @@ -3257,61 +2860,57 @@ static int ssl_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl ) return( 0 ); } -#endif /* MBEDTLS_USE_TINYCRYPT */ #endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) && \ - defined(MBEDTLS_SSL_ASYNC_PRIVATE) -static int ssl_resume_server_key_exchange( mbedtls_ssl_context *ssl, - size_t *signature_len ) +static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl ) { - /* Append the signature to ssl->out_msg, leaving 2 bytes for the - * signature length which will be added in ssl_write_server_key_exchange - * after the call to ssl_prepare_server_key_exchange. - * ssl_write_server_key_exchange also takes care of incrementing - * ssl->out_msglen. */ - unsigned char *sig_start = ssl->out_msg + ssl->out_msglen + 2; - size_t sig_max_len = ( ssl->out_buf + MBEDTLS_SSL_OUT_CONTENT_LEN - - sig_start ); - int ret = ssl->conf->f_async_resume( ssl, - sig_start, signature_len, sig_max_len ); - if( ret != MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS ) - { - ssl->handshake->async_in_progress = 0; - mbedtls_ssl_set_async_operation_data( ssl, NULL ); - } - MBEDTLS_SSL_DEBUG_RET( 2, "ssl_resume_server_key_exchange", ret ); - return( ret ); -} -#endif /* defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) && - defined(MBEDTLS_SSL_ASYNC_PRIVATE) */ - -/* Prepare the ServerKeyExchange message, up to and including - * calculating the signature if any, but excluding formatting the - * signature and sending the message. */ -static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl, - size_t *signature_len ) -{ - mbedtls_ssl_ciphersuite_handle_t ciphersuite_info = - mbedtls_ssl_handshake_get_ciphersuite( ssl->handshake ); + int ret; + size_t n = 0; + const mbedtls_ssl_ciphersuite_t *ciphersuite_info = + ssl->transform_negotiate->ciphersuite_info; #if defined(MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED) + unsigned char *p = ssl->out_msg + 4; + size_t len = 0; #if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) - unsigned char *dig_signed = NULL; + unsigned char *dig_signed = p; + size_t dig_signed_len = 0; #endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */ #endif /* MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED */ - (void) ciphersuite_info; /* unused in some configurations */ -#if !defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) - (void) signature_len; -#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */ - - ssl->out_msglen = 4; /* header (type:1, length:3) to be written later */ + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write server key exchange" ) ); /* * - * Part 1: Provide key exchange parameters for chosen ciphersuite. + * Part 1: Extract static ECDH parameters and abort + * if ServerKeyExchange not needed. + * + */ + + /* For suites involving ECDH, extract DH parameters + * from certificate at this point. */ +#if defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED) + if( mbedtls_ssl_ciphersuite_uses_ecdh( ciphersuite_info ) ) + { + ssl_get_ecdh_params_from_cert( ssl ); + } +#endif /* MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED */ + + /* Key exchanges not involving ephemeral keys don't use + * ServerKeyExchange, so end here. */ +#if defined(MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED) + if( mbedtls_ssl_ciphersuite_no_pfs( ciphersuite_info ) ) + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write server key exchange" ) ); + ssl->state++; + return( 0 ); + } +#endif /* MBEDTLS_KEY_EXCHANGE__NON_PFS__ENABLED */ + + /* + * + * Part 2: Provide key exchange parameters for chosen ciphersuite. * */ @@ -3319,25 +2918,20 @@ static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl, * - ECJPAKE key exchanges */ #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) { - int ret; - size_t len = 0; + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; - ret = mbedtls_ecjpake_write_round_two( - &ssl->handshake->ecjpake_ctx, - ssl->out_msg + ssl->out_msglen, - MBEDTLS_SSL_OUT_CONTENT_LEN - ssl->out_msglen, &len, - mbedtls_ssl_conf_get_frng( ssl->conf ), - mbedtls_ssl_conf_get_prng( ssl->conf ) ); + ret = mbedtls_ecjpake_write_round_two( &ssl->handshake->ecjpake_ctx, + p, end - p, &len, ssl->conf->f_rng, ssl->conf->p_rng ); if( ret != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_write_round_two", ret ); return( ret ); } - ssl->out_msglen += len; + p += len; + n += len; } #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ @@ -3348,13 +2942,13 @@ static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl, **/ #if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \ defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) - if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) == - MBEDTLS_KEY_EXCHANGE_DHE_PSK || - mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) == - MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ) { - ssl->out_msg[ssl->out_msglen++] = 0x00; - ssl->out_msg[ssl->out_msglen++] = 0x00; + *(p++) = 0x00; + *(p++) = 0x00; + + n += 2; } #endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED || MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ @@ -3365,9 +2959,6 @@ static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl, #if defined(MBEDTLS_KEY_EXCHANGE__SOME__DHE_ENABLED) if( mbedtls_ssl_ciphersuite_uses_dhe( ciphersuite_info ) ) { - int ret; - size_t len = 0; - if( ssl->conf->dhm_P.p == NULL || ssl->conf->dhm_G.p == NULL ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "no DH parameters set" ) ); @@ -3391,22 +2982,21 @@ static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl, return( ret ); } - if( ( ret = mbedtls_dhm_make_params( - &ssl->handshake->dhm_ctx, - (int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ), - ssl->out_msg + ssl->out_msglen, &len, - mbedtls_ssl_conf_get_frng( ssl->conf ), - mbedtls_ssl_conf_get_prng( ssl->conf ) ) ) != 0 ) + if( ( ret = mbedtls_dhm_make_params( &ssl->handshake->dhm_ctx, + (int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ), + p, &len, ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_make_params", ret ); return( ret ); } #if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) - dig_signed = ssl->out_msg + ssl->out_msglen; + dig_signed = p; + dig_signed_len = len; #endif - ssl->out_msglen += len; + p += len; + n += len; MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: X ", &ssl->handshake->dhm_ctx.X ); MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: P ", &ssl->handshake->dhm_ctx.P ); @@ -3429,96 +3019,66 @@ static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl, * ECPoint public; * } ServerECDHParams; */ + const mbedtls_ecp_curve_info **curve = NULL; + const mbedtls_ecp_group_id *gid; -#if defined(MBEDTLS_USE_TINYCRYPT) + /* Match our preference list against the offered curves */ + for( gid = ssl->conf->curve_list; *gid != MBEDTLS_ECP_DP_NONE; gid++ ) + for( curve = ssl->handshake->curves; *curve != NULL; curve++ ) + if( (*curve)->grp_id == *gid ) + goto curve_matching_done; + +curve_matching_done: + if( curve == NULL || *curve == NULL ) { - int ret = UECC_FAULT_DETECTED; - static const unsigned char ecdh_param_hdr[] = { - MBEDTLS_SSL_EC_TLS_NAMED_CURVE, - 0 /* high bits of secp256r1 TLS ID */, - 23 /* low bits of secp256r1 TLS ID */, - 2 * NUM_ECC_BYTES + 1, - 0x04 /* Uncompressed */ - }; + MBEDTLS_SSL_DEBUG_MSG( 1, ( "no matching curve for ECDHE" ) ); + return( MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN ); + } + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "ECDHE curve: %s", (*curve)->name ) ); + + if( ( ret = mbedtls_ecp_group_load( &ssl->handshake->ecdh_ctx.grp, + (*curve)->grp_id ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecp_group_load", ret ); + return( ret ); + } + + if( ( ret = mbedtls_ecdh_make_params( &ssl->handshake->ecdh_ctx, &len, + p, MBEDTLS_SSL_MAX_CONTENT_LEN - n, + ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_make_params", ret ); + return( ret ); + } #if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) - dig_signed = ssl->out_msg + ssl->out_msglen; + dig_signed = p; + dig_signed_len = len; #endif - mbedtls_platform_memcpy( ssl->out_msg + ssl->out_msglen, - ecdh_param_hdr, sizeof( ecdh_param_hdr ) ); - ssl->out_msglen += sizeof( ecdh_param_hdr ); + p += len; + n += len; - ret = uECC_make_key( &ssl->out_msg[ ssl->out_msglen ], - ssl->handshake->ecdh_privkey ); - if( ret == UECC_FAULT_DETECTED ) - return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); - if( ret != UECC_SUCCESS ) - return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); - - ssl->out_msglen += 2*NUM_ECC_BYTES; - } -#else /* MBEDTLS_USE_TINYCRYPT */ - { - const mbedtls_ecp_curve_info *curve = - mbedtls_ecp_curve_info_from_tls_id( ssl->handshake->curve_tls_id ); - int ret; - size_t len = 0; - - if( curve == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "no matching curve for ECDHE" ) ); - return( MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN ); - } - MBEDTLS_SSL_DEBUG_MSG( 2, ( "ECDHE curve: %s", curve->name ) ); - - if( ( ret = mbedtls_ecdh_setup( &ssl->handshake->ecdh_ctx, - curve->grp_id ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecp_group_load", ret ); - return( ret ); - } - - if( ( ret = mbedtls_ecdh_make_params( - &ssl->handshake->ecdh_ctx, &len, - ssl->out_msg + ssl->out_msglen, - MBEDTLS_SSL_OUT_CONTENT_LEN - ssl->out_msglen, - mbedtls_ssl_conf_get_frng( ssl->conf ), - mbedtls_ssl_conf_get_prng( ssl->conf ) ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_make_params", ret ); - return( ret ); - } - -#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) - dig_signed = ssl->out_msg + ssl->out_msglen; -#endif - - ssl->out_msglen += len; - - MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx, - MBEDTLS_DEBUG_ECDH_Q ); - } -#endif /* MBEDTLS_USE_TINYCRYPT */ + MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Q ", &ssl->handshake->ecdh_ctx.Q ); } #endif /* MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED */ /* * - * Part 2: For key exchanges involving the server signing the + * Part 3: For key exchanges involving the server signing the * exchange parameters, compute and add the signature here. * */ #if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) if( mbedtls_ssl_ciphersuite_uses_server_signature( ciphersuite_info ) ) { - size_t dig_signed_len = ssl->out_msg + ssl->out_msglen - dig_signed; - size_t hashlen = 0; - unsigned char hash[MBEDTLS_MD_MAX_SIZE]; - int ret; + size_t signature_len = 0; + unsigned int hashlen = 0; + unsigned char hash[64]; /* - * 2.1: Choose hash algorithm: + * 3.1: Choose hash algorithm: * A: For TLS 1.2, obey signature-hash-algorithm extension * to choose appropriate hash. * B: For SSL3, TLS1.0, TLS1.1 and ECDHE_ECDSA, use SHA1 @@ -3531,7 +3091,7 @@ static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl, #if defined(MBEDTLS_SSL_PROTO_TLS1_2) mbedtls_pk_type_t sig_alg = mbedtls_ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info ); - if( mbedtls_ssl_get_minor_ver( ssl ) == MBEDTLS_SSL_MINOR_VERSION_3 ) + if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) { /* A: For TLS 1.2, obey signature-hash-algorithm extension * (RFC 5246, Sec. 7.4.1.4.1). */ @@ -3549,8 +3109,7 @@ static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl, #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ defined(MBEDTLS_SSL_PROTO_TLS1_1) - if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA ) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA ) { /* B: Default hash SHA1 */ md_alg = MBEDTLS_MD_SHA1; @@ -3566,7 +3125,7 @@ static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_MSG( 3, ( "pick hash algorithm %d for signing", md_alg ) ); /* - * 2.2: Compute the hash to be signed + * 3.2: Compute the hash to be signed */ #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ defined(MBEDTLS_SSL_PROTO_TLS1_1) @@ -3586,7 +3145,9 @@ static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl, defined(MBEDTLS_SSL_PROTO_TLS1_2) if( md_alg != MBEDTLS_MD_NONE ) { - ret = mbedtls_ssl_get_key_exchange_md_tls1_2( ssl, hash, &hashlen, + /* Info from md_alg will be used instead */ + hashlen = 0; + ret = mbedtls_ssl_get_key_exchange_md_tls1_2( ssl, hash, dig_signed, dig_signed_len, md_alg ); @@ -3601,13 +3162,20 @@ static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl, return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); } - MBEDTLS_SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen ); + MBEDTLS_SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen != 0 ? hashlen : + (unsigned int) ( mbedtls_md_get_size( mbedtls_md_info_from_type( md_alg ) ) ) ); /* - * 2.3: Compute and add the signature + * 3.3: Compute and add the signature */ + if( mbedtls_ssl_own_key( ssl ) == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no private key" ) ); + return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED ); + } + #if defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( mbedtls_ssl_get_minor_ver( ssl ) == MBEDTLS_SSL_MINOR_VERSION_3 ) + if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) { /* * For TLS 1.2, we need to specify signature and hash algorithm @@ -3625,162 +3193,46 @@ static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl, * */ - ssl->out_msg[ssl->out_msglen++] = - mbedtls_ssl_hash_from_md_alg( md_alg ); - ssl->out_msg[ssl->out_msglen++] = - mbedtls_ssl_sig_from_pk_alg( sig_alg ); + *(p++) = mbedtls_ssl_hash_from_md_alg( md_alg ); + *(p++) = mbedtls_ssl_sig_from_pk_alg( sig_alg ); + + n += 2; } #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) - if( ssl->conf->f_async_sign_start != NULL ) - { - ret = ssl->conf->f_async_sign_start( ssl, - mbedtls_ssl_own_cert( ssl ), - md_alg, hash, hashlen ); - switch( ret ) - { - case MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH: - /* act as if f_async_sign was null */ - break; - case 0: - ssl->handshake->async_in_progress = 1; - return( ssl_resume_server_key_exchange( ssl, signature_len ) ); - case MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS: - ssl->handshake->async_in_progress = 1; - return( MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS ); - default: - MBEDTLS_SSL_DEBUG_RET( 1, "f_async_sign_start", ret ); - return( ret ); - } - } -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ - - if( mbedtls_ssl_own_key( ssl ) == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no private key" ) ); - return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED ); - } - - /* Append the signature to ssl->out_msg, leaving 2 bytes for the - * signature length which will be added in ssl_write_server_key_exchange - * after the call to ssl_prepare_server_key_exchange. - * ssl_write_server_key_exchange also takes care of incrementing - * ssl->out_msglen. */ - if( ( ret = mbedtls_pk_sign( mbedtls_ssl_own_key( ssl ), - md_alg, hash, hashlen, - ssl->out_msg + ssl->out_msglen + 2, - signature_len, - mbedtls_ssl_conf_get_frng( ssl->conf ), - mbedtls_ssl_conf_get_prng( ssl->conf ) ) ) != 0 ) + if( ( ret = mbedtls_pk_sign( mbedtls_ssl_own_key( ssl ), md_alg, hash, hashlen, + p + 2 , &signature_len, ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_sign", ret ); return( ret ); } - } -#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */ - return( 0 ); -} -/* Prepare the ServerKeyExchange message and send it. For ciphersuites - * that do not include a ServerKeyExchange message, do nothing. Either - * way, if successful, move on to the next step in the SSL state - * machine. */ -static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl ) -{ - int ret; - size_t signature_len = 0; -#if defined(MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED) - mbedtls_ssl_ciphersuite_handle_t ciphersuite_info = - mbedtls_ssl_handshake_get_ciphersuite( ssl->handshake ); -#endif /* MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED */ + *(p++) = (unsigned char)( signature_len >> 8 ); + *(p++) = (unsigned char)( signature_len ); + n += 2; - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write server key exchange" ) ); + MBEDTLS_SSL_DEBUG_BUF( 3, "my signature", p, signature_len ); -#if defined(MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED) - /* Extract static ECDH parameters and abort if ServerKeyExchange - * is not needed. */ - if( mbedtls_ssl_ciphersuite_no_pfs( ciphersuite_info ) ) - { - /* For suites involving ECDH, extract DH parameters - * from certificate at this point. */ -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED) - if( mbedtls_ssl_ciphersuite_uses_ecdh( ciphersuite_info ) ) - { - ssl_get_ecdh_params_from_cert( ssl ); - } -#endif /* MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED */ - - /* Key exchanges not involving ephemeral keys don't use - * ServerKeyExchange, so end here. */ - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write server key exchange" ) ); - ssl->state = MBEDTLS_SSL_CERTIFICATE_REQUEST; - return( 0 ); - } -#endif /* MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) && \ - defined(MBEDTLS_SSL_ASYNC_PRIVATE) - /* If we have already prepared the message and there is an ongoing - * signature operation, resume signing. */ - if( ssl->handshake->async_in_progress != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "resuming signature operation" ) ); - ret = ssl_resume_server_key_exchange( ssl, &signature_len ); - } - else -#endif /* defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) && - defined(MBEDTLS_SSL_ASYNC_PRIVATE) */ - { - /* ServerKeyExchange is needed. Prepare the message. */ - ret = ssl_prepare_server_key_exchange( ssl, &signature_len ); - } - - if( ret != 0 ) - { - /* If we're starting to write a new message, set ssl->out_msglen - * to 0. But if we're resuming after an asynchronous message, - * out_msglen is the amount of data written so far and mst be - * preserved. */ - if( ret == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS ) - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write server key exchange (pending)" ) ); - else - ssl->out_msglen = 0; - return( ret ); - } - - /* If there is a signature, write its length. - * ssl_prepare_server_key_exchange already wrote the signature - * itself at its proper place in the output buffer. */ -#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) - if( signature_len != 0 ) - { - (void)mbedtls_platform_put_uint16_be( &ssl->out_msg[ssl->out_msglen], - signature_len ); - ssl->out_msglen += 2; - - MBEDTLS_SSL_DEBUG_BUF( 3, "my signature", - ssl->out_msg + ssl->out_msglen, - signature_len ); - - /* Skip over the already-written signature */ - ssl->out_msglen += signature_len; + n += signature_len; } #endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */ - /* Add header and send. */ + /* Done with actual work; add header and send. */ + + ssl->out_msglen = 4 + n; ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; ssl->out_msg[0] = MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE; - ssl->state = MBEDTLS_SSL_CERTIFICATE_REQUEST; + ssl->state++; - if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 ) + if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 ) { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret ); + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret ); return( ret ); } MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write server key exchange" ) ); + return( 0 ); } @@ -3794,34 +3246,19 @@ static int ssl_write_server_hello_done( mbedtls_ssl_context *ssl ) ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; ssl->out_msg[0] = MBEDTLS_SSL_HS_SERVER_HELLO_DONE; - ssl->state = MBEDTLS_SSL_CLIENT_CERTIFICATE; + ssl->state++; #if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) ) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) mbedtls_ssl_send_flight_completed( ssl ); #endif - if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 ) + if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 ) { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret ); + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret ); return( ret ); } -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) ) - { -#if defined(MBEDTLS_SSL_IMMEDIATE_TRANSMISSION) - mbedtls_ssl_immediate_flight_done( ssl ); -#else - if( ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flight_transmit", ret ); - return( ret ); - } -#endif - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write server hello done" ) ); return( 0 ); @@ -3844,7 +3281,7 @@ static int ssl_parse_client_dh_public( mbedtls_ssl_context *ssl, unsigned char * return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); } - n = mbedtls_platform_get_uint16_be ( *p ); + n = ( (*p)[0] << 8 ) | (*p)[1]; *p += 2; if( *p + n > end ) @@ -3870,63 +3307,37 @@ static int ssl_parse_client_dh_public( mbedtls_ssl_context *ssl, unsigned char * #if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) - -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) -static int ssl_resume_decrypt_pms( mbedtls_ssl_context *ssl, - unsigned char *peer_pms, - size_t *peer_pmslen, - size_t peer_pmssize ) -{ - int ret = ssl->conf->f_async_resume( ssl, - peer_pms, peer_pmslen, peer_pmssize ); - if( ret != MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS ) - { - ssl->handshake->async_in_progress = 0; - mbedtls_ssl_set_async_operation_data( ssl, NULL ); - } - MBEDTLS_SSL_DEBUG_RET( 2, "ssl_decrypt_encrypted_pms", ret ); - return( ret ); -} -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ - -static int ssl_decrypt_encrypted_pms( mbedtls_ssl_context *ssl, - const unsigned char *p, - const unsigned char *end, - unsigned char *peer_pms, - size_t *peer_pmslen, - size_t peer_pmssize ) +static int ssl_parse_encrypted_pms( mbedtls_ssl_context *ssl, + const unsigned char *p, + const unsigned char *end, + size_t pms_offset ) { int ret; - size_t len = (size_t)( end - p ); /* Cast is safe because p <= end. */ - mbedtls_pk_context *private_key = mbedtls_ssl_own_key( ssl ); + size_t len = mbedtls_pk_get_len( mbedtls_ssl_own_key( ssl ) ); + unsigned char *pms = ssl->handshake->premaster + pms_offset; + unsigned char ver[2]; + unsigned char fake_pms[48], peer_pms[48]; + unsigned char mask; + size_t i, peer_pmslen; + unsigned int diff; -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) - /* If we have already started decoding the message and there is an ongoing - * decryption operation, resume signing. */ - if( ssl->handshake->async_in_progress != 0 ) + if( ! mbedtls_pk_can_do( mbedtls_ssl_own_key( ssl ), MBEDTLS_PK_RSA ) ) { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "resuming decryption operation" ) ); - return( ssl_resume_decrypt_pms( ssl, - peer_pms, peer_pmslen, peer_pmssize ) ); + MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no RSA private key" ) ); + return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED ); } -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ /* - * Prepare to decrypt the premaster using own private RSA key + * Decrypt the premaster using own private RSA key */ #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ defined(MBEDTLS_SSL_PROTO_TLS1_2) -#if defined(MBEDTLS_SSL_PROTO_SSL3) - if( mbedtls_ssl_get_minor_ver( ssl ) != MBEDTLS_SSL_MINOR_VERSION_0 ) -#endif /* MBEDTLS_SSL_PROTO_SSL3 */ + if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_0 ) { - if( len < 2 ) - { + if ( p + 2 > end ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); } - len -= 2; - if( *p++ != ( ( len >> 8 ) & 0xFF ) || *p++ != ( ( len ) & 0xFF ) ) { @@ -3936,123 +3347,36 @@ static int ssl_decrypt_encrypted_pms( mbedtls_ssl_context *ssl, } #endif - /* - * Decrypt the premaster secret - */ -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) - if( ssl->conf->f_async_decrypt_start != NULL ) + if( p + len != end ) { - ret = ssl->conf->f_async_decrypt_start( ssl, - mbedtls_ssl_own_cert( ssl ), - p, len ); - switch( ret ) - { - case MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH: - /* act as if f_async_decrypt_start was null */ - break; - case 0: - ssl->handshake->async_in_progress = 1; - return( ssl_resume_decrypt_pms( ssl, - peer_pms, - peer_pmslen, - peer_pmssize ) ); - case MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS: - ssl->handshake->async_in_progress = 1; - return( MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS ); - default: - MBEDTLS_SSL_DEBUG_RET( 1, "f_async_decrypt_start", ret ); - return( ret ); - } + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); } -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ - - if( ! mbedtls_pk_can_do( private_key, MBEDTLS_PK_RSA ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no RSA private key" ) ); - return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED ); - } - - ret = mbedtls_pk_decrypt( private_key, p, len, - peer_pms, peer_pmslen, peer_pmssize, - mbedtls_ssl_conf_get_frng( ssl->conf ), - mbedtls_ssl_conf_get_prng( ssl->conf ) ); - return( ret ); -} - -static int ssl_parse_encrypted_pms( mbedtls_ssl_context *ssl, - const unsigned char *p, - const unsigned char *end, - size_t pms_offset ) -{ - int ret; - unsigned char *pms = ssl->handshake->premaster + pms_offset; - unsigned char ver[2]; - unsigned char fake_pms[48], peer_pms[48]; - unsigned char mask; - size_t i, peer_pmslen; - unsigned int diff; - volatile unsigned int pmscounter = 0; - - /* In case of a failure in decryption, the decryption may write less than - * 2 bytes of output, but we always read the first two bytes. It doesn't - * matter in the end because diff will be nonzero in that case due to - * peer_pmslen being less than 48, and we only care whether diff is 0. - * But do initialize peer_pms for robustness anyway. This also makes - * memory analyzers happy (don't access uninitialized memory, even - * if it's an unsigned char). */ - peer_pms[0] = peer_pms[1] = ~0; - - ret = ssl_decrypt_encrypted_pms( ssl, p, end, - peer_pms, - &peer_pmslen, - sizeof( peer_pms ) ); - -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) - if ( ret == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS ) - return( ret ); -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ mbedtls_ssl_write_version( ssl->handshake->max_major_ver, - ssl->handshake->max_minor_ver, - mbedtls_ssl_conf_get_transport( ssl->conf ), ver ); - - /* Avoid data-dependent branches while checking for invalid - * padding, to protect against timing-based Bleichenbacher-type - * attacks. */ - diff = (unsigned int) ret; - diff |= peer_pmslen ^ 48; - diff |= peer_pms[0] ^ ver[0]; - diff |= peer_pms[1] ^ ver[1]; - - /* mask = diff ? 0xff : 0x00 using bit operations to avoid branches */ - /* MSVC has a warning about unary minus on unsigned, but this is - * well-defined and precisely what we want to do here */ -#if defined(_MSC_VER) -#pragma warning( push ) -#pragma warning( disable : 4146 ) -#endif - mask = - ( ( diff | - diff ) >> ( sizeof( unsigned int ) * 8 - 1 ) ); -#if defined(_MSC_VER) -#pragma warning( pop ) -#endif + ssl->handshake->max_minor_ver, + ssl->conf->transport, ver ); /* * Protection against Bleichenbacher's attack: invalid PKCS#1 v1.5 padding * must not cause the connection to end immediately; instead, send a * bad_record_mac later in the handshake. - * To protect against timing-based variants of the attack, we must - * not have any branch that depends on whether the decryption was - * successful. In particular, always generate the fake premaster secret, - * regardless of whether it will ultimately influence the output or not. + * Also, avoid data-dependant branches here to protect against + * timing-based variants. */ - ret = mbedtls_ssl_conf_get_frng( ssl->conf ) - ( mbedtls_ssl_conf_get_prng( ssl->conf ), fake_pms, sizeof( fake_pms ) ); + ret = ssl->conf->f_rng( ssl->conf->p_rng, fake_pms, sizeof( fake_pms ) ); if( ret != 0 ) - { - /* It's ok to abort on an RNG failure, since this does not reveal - * anything about the RSA decryption. */ return( ret ); - } + + ret = mbedtls_pk_decrypt( mbedtls_ssl_own_key( ssl ), p, len, + peer_pms, &peer_pmslen, + sizeof( peer_pms ), + ssl->conf->f_rng, ssl->conf->p_rng ); + + diff = (unsigned int) ret; + diff |= peer_pmslen ^ 48; + diff |= peer_pms[0] ^ ver[0]; + diff |= peer_pms[1] ^ ver[1]; #if defined(MBEDTLS_SSL_DEBUG_ALL) if( diff != 0 ) @@ -4067,22 +3391,20 @@ static int ssl_parse_encrypted_pms( mbedtls_ssl_context *ssl, } ssl->handshake->pmslen = 48; - /* Set pms to either the true or the fake PMS, without - * data-dependent branches. */ - for( i = 0; i < ssl->handshake->pmslen; i++ ) - { - pms[i] = ( mask & fake_pms[i] ) | ( (~mask) & peer_pms[i] ); - pmscounter++; - } + /* mask = diff ? 0xff : 0x00 using bit operations to avoid branches */ + /* MSVC has a warning about unary minus on unsigned, but this is + * well-defined and precisely what we want to do here */ +#if defined(_MSC_VER) +#pragma warning( push ) +#pragma warning( disable : 4146 ) +#endif + mask = - ( ( diff | - diff ) >> ( sizeof( unsigned int ) * 8 - 1 ) ); +#if defined(_MSC_VER) +#pragma warning( pop ) +#endif - if( pmscounter == ssl->handshake->pmslen ) - { - mbedtls_platform_random_delay(); - if( pmscounter == ssl->handshake->pmslen ) - { - ssl->handshake->premaster_generated = MBEDTLS_SSL_FI_FLAG_SET; - } - } + for( i = 0; i < ssl->handshake->pmslen; i++ ) + pms[i] = ( mask & fake_pms[i] ) | ( (~mask) & peer_pms[i] ); return( 0 ); } @@ -4113,7 +3435,7 @@ static int ssl_parse_client_psk_identity( mbedtls_ssl_context *ssl, unsigned cha return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); } - n = mbedtls_platform_get_uint16_be( *p ); + n = ( (*p)[0] << 8 ) | (*p)[1]; *p += 2; if( n < 1 || n > 65535 || n > (size_t) ( end - *p ) ) @@ -4132,7 +3454,7 @@ static int ssl_parse_client_psk_identity( mbedtls_ssl_context *ssl, unsigned cha /* Identity is not a big secret since clients send it in the clear, * but treat it carefully anyway, just in case */ if( n != ssl->conf->psk_identity_len || - mbedtls_platform_memequal( ssl->conf->psk_identity, *p, n ) != 0 ) + mbedtls_ssl_safer_memcmp( ssl->conf->psk_identity, *p, n ) != 0 ) { ret = MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY; } @@ -4141,8 +3463,8 @@ static int ssl_parse_client_psk_identity( mbedtls_ssl_context *ssl, unsigned cha if( ret == MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY ) { MBEDTLS_SSL_DEBUG_BUF( 3, "Unknown PSK identity", *p, n ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_UNKNOWN_PSK_IDENTITY ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_UNKNOWN_PSK_IDENTITY ); return( MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY ); } @@ -4152,91 +3474,39 @@ static int ssl_parse_client_psk_identity( mbedtls_ssl_context *ssl, unsigned cha } #endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ -/* - * - * STATE HANDLING: Client Key Exchange - * - */ - -/* - * Overview - */ - -/* Main entry point; orchestrates the other functions. */ -static int ssl_process_in_client_key_exchange( mbedtls_ssl_context *ssl ); - -static int ssl_in_client_key_exchange_parse( mbedtls_ssl_context *ssl, - unsigned char *buf, - size_t buflen ); -/* Update the handshake state */ -static int ssl_in_client_key_exchange_postprocess( mbedtls_ssl_context *ssl ); - -/* - * Implementation - */ - -static int ssl_process_in_client_key_exchange( mbedtls_ssl_context *ssl ) +static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl ) { int ret; - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> process client key exchange" ) ); + const mbedtls_ssl_ciphersuite_t *ciphersuite_info; + unsigned char *p, *end; - /* The ClientKeyExchange message is never skipped. */ + ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; - /* Reading step */ - if( ( ret = mbedtls_ssl_read_record( ssl, - 1 /* update checksum */ ) ) != 0 ) + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse client key exchange" ) ); + + if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); return( ret ); } - if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE || - ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_KEY_EXCHANGE ) + p = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ); + end = ssl->in_msg + ssl->in_hslen; + + if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); - ret = MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; - goto cleanup; + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); } - MBEDTLS_SSL_CHK( ssl_in_client_key_exchange_parse( ssl, ssl->in_msg, - ssl->in_hslen ) ); - - /* Update state */ - MBEDTLS_SSL_CHK( ssl_in_client_key_exchange_postprocess( ssl ) ); - -cleanup: - -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) - if ( ret == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS ) - ssl->keep_current_message = 1; -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= process client key exchange" ) ); - return( ret ); -} - -/* Warning: Despite accepting a length argument, this function is currently - * still lacking some bounds checks and assumes that `buf` has length - * `MBEDTLS_SSL_IN_CONTENT_LEN`. Eventually, it should be rewritten to work - * with any buffer + length pair, returning MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL - * on insufficient parsing space. */ -static int ssl_in_client_key_exchange_parse( mbedtls_ssl_context *ssl, - unsigned char *buf, - size_t buflen ) -{ - int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; - mbedtls_ssl_ciphersuite_handle_t ciphersuite_info = - mbedtls_ssl_handshake_get_ciphersuite( ssl->handshake ); - unsigned char *p, *end; - - p = buf + mbedtls_ssl_hs_hdr_len( ssl ); - end = buf + buflen; + if( ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_KEY_EXCHANGE ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); + } #if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) - if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_DHE_RSA ) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA ) { if( ( ret = ssl_parse_client_dh_public( ssl, &p, end ) ) != 0 ) { @@ -4249,37 +3519,29 @@ static int ssl_in_client_key_exchange_parse( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange" ) ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); } + + if( ( ret = mbedtls_dhm_calc_secret( &ssl->handshake->dhm_ctx, + ssl->handshake->premaster, + MBEDTLS_PREMASTER_SIZE, + &ssl->handshake->pmslen, + ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_calc_secret", ret ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS ); + } + + MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->handshake->dhm_ctx.K ); } else #endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */ -#if defined(MBEDTLS_USE_TINYCRYPT) - if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA || - mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA || - mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_ECDH_RSA || - mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA ) - { - if( ( ret = mbedtls_ssl_ecdh_read_peerkey( ssl, &p, end ) ) != 0 ) - return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); - } - else -#endif -#if defined(MBEDTLS_ECDH_C) && \ - ( defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) ) - if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA || - mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA || - mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_ECDH_RSA || - mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA ) +#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_RSA || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA ) { if( ( ret = mbedtls_ecdh_read_public( &ssl->handshake->ecdh_ctx, p, end - p) ) != 0 ) @@ -4288,8 +3550,19 @@ static int ssl_in_client_key_exchange_parse( mbedtls_ssl_context *ssl, return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP ); } - MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx, - MBEDTLS_DEBUG_ECDH_QP ); + MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Qp ", &ssl->handshake->ecdh_ctx.Qp ); + + if( ( ret = mbedtls_ecdh_calc_secret( &ssl->handshake->ecdh_ctx, + &ssl->handshake->pmslen, + ssl->handshake->premaster, + MBEDTLS_MPI_MAX_SIZE, + ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_calc_secret", ret ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS ); + } + + MBEDTLS_SSL_DEBUG_MPI( 3, "ECDH: z ", &ssl->handshake->ecdh_ctx.z ); } else #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || @@ -4297,8 +3570,7 @@ static int ssl_in_client_key_exchange_parse( mbedtls_ssl_context *ssl, MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED || MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ #if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) - if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_PSK ) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ) { if( ( ret = ssl_parse_client_psk_identity( ssl, &p, end ) ) != 0 ) { @@ -4311,26 +3583,19 @@ static int ssl_in_client_key_exchange_parse( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange" ) ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); } + + if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl, + ciphersuite_info->key_exchange ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_psk_derive_premaster", ret ); + return( ret ); + } } else #endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */ #if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) - if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_RSA_PSK ) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ) { -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) - if ( ssl->handshake->async_in_progress != 0 ) - { - /* There is an asynchronous operation in progress to - * decrypt the encrypted premaster secret, so skip - * directly to resuming this operation. */ - MBEDTLS_SSL_DEBUG_MSG( 3, ( "PSK identity already parsed" ) ); - /* Update p to skip the PSK identity. ssl_parse_encrypted_pms - * won't actually use it, but maintain p anyway for robustness. */ - p += ssl->conf->psk_identity_len + 2; - } - else -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ if( ( ret = ssl_parse_client_psk_identity( ssl, &p, end ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_client_psk_identity" ), ret ); @@ -4342,12 +3607,18 @@ static int ssl_in_client_key_exchange_parse( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_encrypted_pms" ), ret ); return( ret ); } + + if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl, + ciphersuite_info->key_exchange ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_psk_derive_premaster", ret ); + return( ret ); + } } else #endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ #if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) - if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_DHE_PSK ) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ) { if( ( ret = ssl_parse_client_psk_identity( ssl, &p, end ) ) != 0 ) { @@ -4365,12 +3636,18 @@ static int ssl_in_client_key_exchange_parse( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange" ) ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); } + + if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl, + ciphersuite_info->key_exchange ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_psk_derive_premaster", ret ); + return( ret ); + } } else #endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) - if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ) { if( ( ret = ssl_parse_client_psk_identity( ssl, &p, end ) ) != 0 ) { @@ -4378,10 +3655,6 @@ static int ssl_in_client_key_exchange_parse( mbedtls_ssl_context *ssl, return( ret ); } -#if defined(MBEDTLS_USE_TINYCRYPT) - if( mbedtls_ssl_ecdh_read_peerkey( ssl, &p, end ) != 0 ) - return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); -#else /* MBEDTLS_USE_TINYCRYPT */ if( ( ret = mbedtls_ecdh_read_public( &ssl->handshake->ecdh_ctx, p, end - p ) ) != 0 ) { @@ -4390,13 +3663,18 @@ static int ssl_in_client_key_exchange_parse( mbedtls_ssl_context *ssl, } MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Qp ", &ssl->handshake->ecdh_ctx.Qp ); -#endif /* MBEDTLS_USE_TINYCRYPT */ + + if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl, + ciphersuite_info->key_exchange ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_psk_derive_premaster", ret ); + return( ret ); + } } else #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ #if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) - if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_RSA ) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA ) { if( ( ret = ssl_parse_encrypted_pms( ssl, p, end, 0 ) ) != 0 ) { @@ -4407,8 +3685,7 @@ static int ssl_in_client_key_exchange_parse( mbedtls_ssl_context *ssl, else #endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */ #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) { ret = mbedtls_ecjpake_read_round_two( &ssl->handshake->ecjpake_ctx, p, end - p ); @@ -4417,6 +3694,15 @@ static int ssl_in_client_key_exchange_parse( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_two", ret ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); } + + ret = mbedtls_ecjpake_derive_secret( &ssl->handshake->ecjpake_ctx, + ssl->handshake->premaster, 32, &ssl->handshake->pmslen, + ssl->conf->f_rng, ssl->conf->p_rng ); + if( ret != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_derive_secret", ret ); + return( ret ); + } } else #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ @@ -4424,19 +3710,6 @@ static int ssl_in_client_key_exchange_parse( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); } - return( ret ); -} - -/* Update the handshake state */ -static int ssl_in_client_key_exchange_postprocess( mbedtls_ssl_context *ssl ) -{ - int ret; - - if( ( ret = mbedtls_ssl_build_pms( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_build_pms", ret ); - return( ret ); - } if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 ) { @@ -4444,33 +3717,44 @@ static int ssl_in_client_key_exchange_postprocess( mbedtls_ssl_context *ssl ) return( ret ); } - ssl->state = MBEDTLS_SSL_CERTIFICATE_VERIFY; + ssl->state++; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse client key exchange" ) ); + return( 0 ); } -#if !defined(MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED) +#if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)&& \ + !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl ) { - mbedtls_ssl_ciphersuite_handle_t ciphersuite_info = - mbedtls_ssl_handshake_get_ciphersuite( ssl->handshake ); + const mbedtls_ssl_ciphersuite_t *ciphersuite_info = + ssl->transform_negotiate->ciphersuite_info; MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate verify" ) ); - if( !mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) ) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) { MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate verify" ) ); - ssl->state = MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC; + ssl->state++; return( 0 ); } MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); } -#else /* !MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED */ +#else static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl ) { - volatile int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; - volatile int ret_fi = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; + int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; size_t i, sig_len; unsigned char hash[48]; unsigned char *hash_start = hash; @@ -4479,64 +3763,50 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl ) mbedtls_pk_type_t pk_alg; #endif mbedtls_md_type_t md_alg; - mbedtls_ssl_ciphersuite_handle_t ciphersuite_info = - mbedtls_ssl_handshake_get_ciphersuite( ssl->handshake ); - mbedtls_pk_context *peer_pk = NULL; + const mbedtls_ssl_ciphersuite_t *ciphersuite_info = + ssl->transform_negotiate->ciphersuite_info; MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate verify" ) ); - if( !mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) ) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE || + ssl->session_negotiate->peer_cert == NULL ) { MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate verify" ) ); - ssl->state = MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC; - return( 0 ); - } - - /* Skip if we haven't received a certificate from the client. - * If MBEDTLS_SSL_KEEP_PEER_CERTIFICATE is set, this can be - * inferred from the setting of mbedtls_ssl_session::peer_cert. - * If MBEDTLS_SSL_KEEP_PEER_CERTIFICATE is not set, it is tracked in a - * specific variable. */ -#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - if( ssl->handshake->got_peer_pubkey ) - peer_pk = &ssl->handshake->peer_pubkey; -#else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - if( ssl->session_negotiate->peer_cert != NULL ) - { - ret = mbedtls_x509_crt_pk_acquire( ssl->session_negotiate->peer_cert, - &peer_pk ); - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_x509_crt_pk_acquire", ret ); - return( ret ); - } - } -#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - - if( peer_pk == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate verify" ) ); - ssl->state = MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC; + ssl->state++; return( 0 ); } /* Read the message without adding it to the checksum */ - ret = mbedtls_ssl_read_record( ssl, 0 /* no checksum update */ ); + do { + + if( ( ret = mbedtls_ssl_read_record_layer( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ssl_read_record_layer" ), ret ); + return( ret ); + } + + ret = mbedtls_ssl_handle_message_type( ssl ); + + } while( MBEDTLS_ERR_SSL_NON_FATAL == ret ); + if( 0 != ret ) { - MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ssl_read_record" ), ret ); - goto exit; + MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ssl_handle_message_type" ), ret ); + return( ret ); } - ssl->state = MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC; + ssl->state++; /* Process the message contents */ if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE || ssl->in_msg[0] != MBEDTLS_SSL_HS_CERTIFICATE_VERIFY ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate verify message" ) ); - ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY; - goto exit; + return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY ); } i = mbedtls_ssl_hs_hdr_len( ssl ); @@ -4549,13 +3819,14 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl ) */ #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ defined(MBEDTLS_SSL_PROTO_TLS1_1) - if( mbedtls_ssl_get_minor_ver( ssl ) != MBEDTLS_SSL_MINOR_VERSION_3 ) + if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 ) { md_alg = MBEDTLS_MD_NONE; hashlen = 36; /* For ECDSA, use SHA-1, not MD-5 + SHA-1 */ - if( mbedtls_pk_can_do( peer_pk, MBEDTLS_PK_ECDSA ) ) + if( mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk, + MBEDTLS_PK_ECDSA ) ) { hash_start += 16; hashlen -= 16; @@ -4566,13 +3837,12 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl ) #endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 */ #if defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( mbedtls_ssl_get_minor_ver( ssl ) == MBEDTLS_SSL_MINOR_VERSION_3 ) + if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) { if( i + 2 > ssl->in_hslen ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate verify message" ) ); - ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY; - goto exit; + return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY ); } /* @@ -4580,21 +3850,18 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl ) */ md_alg = mbedtls_ssl_md_alg_from_hash( ssl->in_msg[i] ); - if( -#if defined(MBEDTLS_SHA512_C) - md_alg != MBEDTLS_MD_SHA384 && -#endif -#if defined(MBEDTLS_SHA256_C) - md_alg != MBEDTLS_MD_SHA256 && -#endif - 1 ) + if( md_alg == MBEDTLS_MD_NONE || mbedtls_ssl_set_calc_verify_md( ssl, ssl->in_msg[i] ) ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "peer not adhering to requested sig_alg" " for verify message" ) ); - ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY; - goto exit; + return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY ); } +#if !defined(MBEDTLS_MD_SHA1) + if( MBEDTLS_MD_SHA1 == md_alg ) + hash_start += 16; +#endif + /* Info from md_alg will be used instead */ hashlen = 0; @@ -4608,18 +3875,16 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "peer not adhering to requested sig_alg" " for verify message" ) ); - ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY; - goto exit; + return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY ); } /* * Check the certificate's key type matches the signature alg */ - if( !mbedtls_pk_can_do( peer_pk, pk_alg ) ) + if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk, pk_alg ) ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "sig_alg doesn't match cert key" ) ); - ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY; - goto exit; + return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY ); } i++; @@ -4634,64 +3899,41 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl ) if( i + 2 > ssl->in_hslen ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate verify message" ) ); - ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY; - goto exit; + return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY ); } - sig_len = mbedtls_platform_get_uint16_be( &ssl->in_msg[i] ); + sig_len = ( ssl->in_msg[i] << 8 ) | ssl->in_msg[i+1]; i += 2; if( i + sig_len != ssl->in_hslen ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate verify message" ) ); - ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY; - goto exit; + return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY ); } /* Calculate hash and verify signature */ + ssl->handshake->calc_verify( ssl, hash ); + + if( ( ret = mbedtls_pk_verify( &ssl->session_negotiate->peer_cert->pk, + md_alg, hash_start, hashlen, + ssl->in_msg + i, sig_len ) ) != 0 ) { - size_t dummy_hlen; - mbedtls_ssl_calc_verify( - mbedtls_ssl_get_minor_ver( ssl ), - md_alg, ssl, hash, &dummy_hlen ); + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_verify", ret ); + return( ret ); } - ret = mbedtls_pk_verify( peer_pk, - md_alg, hash_start, hashlen, - ssl->in_msg + i, sig_len ); + mbedtls_ssl_update_handshake_status( ssl ); - if( ret == 0 ) - { - mbedtls_platform_random_delay(); - - ret_fi = mbedtls_pk_verify( peer_pk, - md_alg, hash_start, hashlen, - ssl->in_msg + i, sig_len ); - if( ret == 0 && ret_fi == 0 ) - { - mbedtls_ssl_update_handshake_status( ssl ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse certificate verify" ) ); - goto exit; - } - else - { - ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; - } - - } - - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_verify", ret ); - -exit: - -#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - mbedtls_x509_crt_pk_release( ssl->session_negotiate->peer_cert ); -#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse certificate verify" ) ); return( ret ); } -#endif /* MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED */ +#endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED && + !MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED && + !MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED && + !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED && + !MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED && + !MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ #if defined(MBEDTLS_SSL_SESSION_TICKETS) static int ssl_write_new_session_ticket( mbedtls_ssl_context *ssl ) @@ -4719,15 +3961,21 @@ static int ssl_write_new_session_ticket( mbedtls_ssl_context *ssl ) if( ( ret = ssl->conf->f_ticket_write( ssl->conf->p_ticket, ssl->session_negotiate, ssl->out_msg + 10, - ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN, + ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN, &tlen, &lifetime ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_ticket_write", ret ); tlen = 0; } - (void)mbedtls_platform_put_uint32_be( &ssl->out_msg[4], lifetime ); - (void)mbedtls_platform_put_uint16_be( &ssl->out_msg[8], tlen ); + ssl->out_msg[4] = ( lifetime >> 24 ) & 0xFF; + ssl->out_msg[5] = ( lifetime >> 16 ) & 0xFF; + ssl->out_msg[6] = ( lifetime >> 8 ) & 0xFF; + ssl->out_msg[7] = ( lifetime ) & 0xFF; + + ssl->out_msg[8] = (unsigned char)( ( tlen >> 8 ) & 0xFF ); + ssl->out_msg[9] = (unsigned char)( ( tlen ) & 0xFF ); + ssl->out_msglen = 10 + tlen; /* @@ -4736,9 +3984,9 @@ static int ssl_write_new_session_ticket( mbedtls_ssl_context *ssl ) */ ssl->handshake->new_session_ticket = 0; - if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 ) + if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 ) { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret ); + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret ); return( ret ); } @@ -4753,7 +4001,7 @@ static int ssl_write_new_session_ticket( mbedtls_ssl_context *ssl ) */ int mbedtls_ssl_handshake_server_step( mbedtls_ssl_context *ssl ) { - int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; + int ret = 0; if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER || ssl->handshake == NULL ) return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); @@ -4764,13 +4012,13 @@ int mbedtls_ssl_handshake_server_step( mbedtls_ssl_context *ssl ) return( ret ); #if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) && + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING ) { - if( ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 ) + if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 ) return( ret ); } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ +#endif switch( ssl->state ) { @@ -4829,7 +4077,7 @@ int mbedtls_ssl_handshake_server_step( mbedtls_ssl_context *ssl ) break; case MBEDTLS_SSL_CLIENT_KEY_EXCHANGE: - ret = ssl_process_in_client_key_exchange( ssl ); + ret = ssl_parse_client_key_exchange( ssl ); break; case MBEDTLS_SSL_CERTIFICATE_VERIFY: @@ -4868,10 +4116,9 @@ int mbedtls_ssl_handshake_server_step( mbedtls_ssl_context *ssl ) break; case MBEDTLS_SSL_HANDSHAKE_WRAPUP: - ret = mbedtls_ssl_handshake_wrapup( ssl ); + mbedtls_ssl_handshake_wrapup( ssl ); break; - case MBEDTLS_SSL_INVALID: default: MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid state %d", ssl->state ) ); return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); diff --git a/APP_Framework/Framework/security/mbedtls/ssl_ticket.c b/APP_Framework/Framework/security/mbedtls/ssl_ticket.c new file mode 100644 index 000000000..253c24a58 --- /dev/null +++ b/APP_Framework/Framework/security/mbedtls/ssl_ticket.c @@ -0,0 +1,489 @@ +/* + * TLS server tickets callbacks implementation + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_SSL_TICKET_C) + +#if defined(MBEDTLS_PLATFORM_C) +#include "platform.h" +#else +#include +#define mbedtls_calloc calloc +#define mbedtls_free free +#endif + +#include "ssl_ticket.h" + +#include + +/* 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; +} + +/* + * Initialze context + */ +void mbedtls_ssl_ticket_init( mbedtls_ssl_ticket_context *ctx ) +{ + memset( ctx, 0, sizeof( mbedtls_ssl_ticket_context ) ); + +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_init( &ctx->mutex ); +#endif +} + +#define MAX_KEY_BYTES 32 /* 256 bits */ + +/* + * Generate/update a key + */ +static int ssl_ticket_gen_key( mbedtls_ssl_ticket_context *ctx, + unsigned char index ) +{ + int ret; + unsigned char buf[MAX_KEY_BYTES]; + mbedtls_ssl_ticket_key *key = ctx->keys + index; + +#if defined(MBEDTLS_HAVE_TIME) + key->generation_time = (uint32_t) mbedtls_time( NULL ); +#endif + + if( ( ret = ctx->f_rng( ctx->p_rng, key->name, sizeof( key->name ) ) ) != 0 ) + return( ret ); + + if( ( ret = ctx->f_rng( ctx->p_rng, buf, sizeof( buf ) ) ) != 0 ) + return( ret ); + + /* With GCM and CCM, same context can encrypt & decrypt */ + ret = mbedtls_cipher_setkey( &key->ctx, buf, + mbedtls_cipher_get_key_bitlen( &key->ctx ), + MBEDTLS_ENCRYPT ); + + mbedtls_zeroize( buf, sizeof( buf ) ); + + return( ret ); +} + +/* + * Rotate/generate keys if necessary + */ +static int ssl_ticket_update_keys( mbedtls_ssl_ticket_context *ctx ) +{ +#if !defined(MBEDTLS_HAVE_TIME) + ((void) ctx); +#else + if( ctx->ticket_lifetime != 0 ) + { + uint32_t current_time = (uint32_t) mbedtls_time( NULL ); + uint32_t key_time = ctx->keys[ctx->active].generation_time; + + if( current_time >= key_time && + current_time - key_time < ctx->ticket_lifetime ) + { + return( 0 ); + } + + ctx->active = 1 - ctx->active; + + return( ssl_ticket_gen_key( ctx, ctx->active ) ); + } + else +#endif /* MBEDTLS_HAVE_TIME */ + return( 0 ); +} + +/* + * Setup context for actual use + */ +int mbedtls_ssl_ticket_setup( mbedtls_ssl_ticket_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, + mbedtls_cipher_type_t cipher, + uint32_t lifetime ) +{ + int ret; + const mbedtls_cipher_info_t *cipher_info; + + ctx->f_rng = f_rng; + ctx->p_rng = p_rng; + + ctx->ticket_lifetime = lifetime; + + cipher_info = mbedtls_cipher_info_from_type( cipher); + if( cipher_info == NULL ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + + if( cipher_info->mode != MBEDTLS_MODE_GCM && + cipher_info->mode != MBEDTLS_MODE_CCM ) + { + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + } + + if( cipher_info->key_bitlen > 8 * MAX_KEY_BYTES ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + + if( ( ret = mbedtls_cipher_setup( &ctx->keys[0].ctx, cipher_info ) ) != 0 || + ( ret = mbedtls_cipher_setup( &ctx->keys[1].ctx, cipher_info ) ) != 0 ) + { + return( ret ); + } + + if( ( ret = ssl_ticket_gen_key( ctx, 0 ) ) != 0 || + ( ret = ssl_ticket_gen_key( ctx, 1 ) ) != 0 ) + { + return( ret ); + } + + return( 0 ); +} + +/* + * Serialize a session in the following format: + * 0 . n-1 session structure, n = sizeof(mbedtls_ssl_session) + * n . n+2 peer_cert length = m (0 if no certificate) + * n+3 . n+2+m peer cert ASN.1 + */ +static int ssl_save_session( const mbedtls_ssl_session *session, + unsigned char *buf, size_t buf_len, + size_t *olen ) +{ + unsigned char *p = buf; + size_t left = buf_len; +#if defined(MBEDTLS_X509_CRT_PARSE_C) + size_t cert_len; +#endif /* MBEDTLS_X509_CRT_PARSE_C */ + + if( left < sizeof( mbedtls_ssl_session ) ) + return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); + + memcpy( p, session, sizeof( mbedtls_ssl_session ) ); + p += sizeof( mbedtls_ssl_session ); + left -= sizeof( mbedtls_ssl_session ); + +#if defined(MBEDTLS_X509_CRT_PARSE_C) + if( session->peer_cert == NULL ) + cert_len = 0; + else + cert_len = session->peer_cert->raw.len; + + if( left < 3 + cert_len ) + return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); + + *p++ = (unsigned char)( ( cert_len >> 16 ) & 0xFF ); + *p++ = (unsigned char)( ( cert_len >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( cert_len ) & 0xFF ); + + if( session->peer_cert != NULL ) + memcpy( p, session->peer_cert->raw.p, cert_len ); + + p += cert_len; +#endif /* MBEDTLS_X509_CRT_PARSE_C */ + + *olen = p - buf; + + return( 0 ); +} + +/* + * Unserialise session, see ssl_save_session() + */ +static int ssl_load_session( mbedtls_ssl_session *session, + const unsigned char *buf, size_t len ) +{ + const unsigned char *p = buf; + const unsigned char * const end = buf + len; +#if defined(MBEDTLS_X509_CRT_PARSE_C) + size_t cert_len; +#endif /* MBEDTLS_X509_CRT_PARSE_C */ + + if( sizeof( mbedtls_ssl_session ) > (size_t)( end - p ) ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + + memcpy( session, p, sizeof( mbedtls_ssl_session ) ); + p += sizeof( mbedtls_ssl_session ); + +#if defined(MBEDTLS_X509_CRT_PARSE_C) + if( 3 > (size_t)( end - p ) ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + + cert_len = ( p[0] << 16 ) | ( p[1] << 8 ) | p[2]; + p += 3; + + if( cert_len == 0 ) + { + session->peer_cert = NULL; + } + else + { + int ret; + + if( cert_len > (size_t)( end - p ) ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + + session->peer_cert = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt ) ); + + if( session->peer_cert == NULL ) + return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); + + mbedtls_x509_crt_init( session->peer_cert ); + + if( ( ret = mbedtls_x509_crt_parse_der( session->peer_cert, + p, cert_len ) ) != 0 ) + { + mbedtls_x509_crt_free( session->peer_cert ); + mbedtls_free( session->peer_cert ); + session->peer_cert = NULL; + return( ret ); + } + + p += cert_len; + } +#endif /* MBEDTLS_X509_CRT_PARSE_C */ + + if( p != end ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + + return( 0 ); +} + +/* + * Create session ticket, with the following structure: + * + * struct { + * opaque key_name[4]; + * opaque iv[12]; + * opaque encrypted_state<0..2^16-1>; + * opaque tag[16]; + * } ticket; + * + * The key_name, iv, and length of encrypted_state are the additional + * authenticated data. + */ +int mbedtls_ssl_ticket_write( void *p_ticket, + const mbedtls_ssl_session *session, + unsigned char *start, + const unsigned char *end, + size_t *tlen, + uint32_t *ticket_lifetime ) +{ + int ret; + mbedtls_ssl_ticket_context *ctx = p_ticket; + mbedtls_ssl_ticket_key *key; + unsigned char *key_name = start; + unsigned char *iv = start + 4; + unsigned char *state_len_bytes = iv + 12; + unsigned char *state = state_len_bytes + 2; + unsigned char *tag; + size_t clear_len, ciph_len; + + *tlen = 0; + + if( ctx == NULL || ctx->f_rng == NULL ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + + /* We need at least 4 bytes for key_name, 12 for IV, 2 for len 16 for tag, + * in addition to session itself, that will be checked when writing it. */ + if( end - start < 4 + 12 + 2 + 16 ) + return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); + +#if defined(MBEDTLS_THREADING_C) + if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) + return( ret ); +#endif + + if( ( ret = ssl_ticket_update_keys( ctx ) ) != 0 ) + goto cleanup; + + key = &ctx->keys[ctx->active]; + + *ticket_lifetime = ctx->ticket_lifetime; + + memcpy( key_name, key->name, 4 ); + + if( ( ret = ctx->f_rng( ctx->p_rng, iv, 12 ) ) != 0 ) + goto cleanup; + + /* Dump session state */ + if( ( ret = ssl_save_session( session, + state, end - state, &clear_len ) ) != 0 || + (unsigned long) clear_len > 65535 ) + { + goto cleanup; + } + state_len_bytes[0] = ( clear_len >> 8 ) & 0xff; + state_len_bytes[1] = ( clear_len ) & 0xff; + + /* Encrypt and authenticate */ + tag = state + clear_len; + if( ( ret = mbedtls_cipher_auth_encrypt( &key->ctx, + iv, 12, key_name, 4 + 12 + 2, + state, clear_len, state, &ciph_len, tag, 16 ) ) != 0 ) + { + goto cleanup; + } + if( ciph_len != clear_len ) + { + ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR; + goto cleanup; + } + + *tlen = 4 + 12 + 2 + 16 + ciph_len; + +cleanup: +#if defined(MBEDTLS_THREADING_C) + if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) + return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); +#endif + + return( ret ); +} + +/* + * Select key based on name + */ +static mbedtls_ssl_ticket_key *ssl_ticket_select_key( + mbedtls_ssl_ticket_context *ctx, + const unsigned char name[4] ) +{ + unsigned char i; + + for( i = 0; i < sizeof( ctx->keys ) / sizeof( *ctx->keys ); i++ ) + if( memcmp( name, ctx->keys[i].name, 4 ) == 0 ) + return( &ctx->keys[i] ); + + return( NULL ); +} + +/* + * Load session ticket (see mbedtls_ssl_ticket_write for structure) + */ +int mbedtls_ssl_ticket_parse( void *p_ticket, + mbedtls_ssl_session *session, + unsigned char *buf, + size_t len ) +{ + int ret; + mbedtls_ssl_ticket_context *ctx = p_ticket; + mbedtls_ssl_ticket_key *key; + unsigned char *key_name = buf; + unsigned char *iv = buf + 4; + unsigned char *enc_len_p = iv + 12; + unsigned char *ticket = enc_len_p + 2; + unsigned char *tag; + size_t enc_len, clear_len; + + if( ctx == NULL || ctx->f_rng == NULL ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + + /* See mbedtls_ssl_ticket_write() */ + if( len < 4 + 12 + 2 + 16 ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + +#if defined(MBEDTLS_THREADING_C) + if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) + return( ret ); +#endif + + if( ( ret = ssl_ticket_update_keys( ctx ) ) != 0 ) + goto cleanup; + + enc_len = ( enc_len_p[0] << 8 ) | enc_len_p[1]; + tag = ticket + enc_len; + + if( len != 4 + 12 + 2 + enc_len + 16 ) + { + ret = MBEDTLS_ERR_SSL_BAD_INPUT_DATA; + goto cleanup; + } + + /* Select key */ + if( ( key = ssl_ticket_select_key( ctx, key_name ) ) == NULL ) + { + /* We can't know for sure but this is a likely option unless we're + * under attack - this is only informative anyway */ + ret = MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED; + goto cleanup; + } + + /* Decrypt and authenticate */ + if( ( ret = mbedtls_cipher_auth_decrypt( &key->ctx, iv, 12, + key_name, 4 + 12 + 2, ticket, enc_len, + ticket, &clear_len, tag, 16 ) ) != 0 ) + { + if( ret == MBEDTLS_ERR_CIPHER_AUTH_FAILED ) + ret = MBEDTLS_ERR_SSL_INVALID_MAC; + + goto cleanup; + } + if( clear_len != enc_len ) + { + ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR; + goto cleanup; + } + + /* Actually load session */ + if( ( ret = ssl_load_session( session, ticket, clear_len ) ) != 0 ) + goto cleanup; + +#if defined(MBEDTLS_HAVE_TIME) + { + /* Check for expiration */ + mbedtls_time_t current_time = mbedtls_time( NULL ); + + if( current_time < session->start || + (uint32_t)( current_time - session->start ) > ctx->ticket_lifetime ) + { + ret = MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED; + goto cleanup; + } + } +#endif + +cleanup: +#if defined(MBEDTLS_THREADING_C) + if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) + return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); +#endif + + return( ret ); +} + +/* + * Free context + */ +void mbedtls_ssl_ticket_free( mbedtls_ssl_ticket_context *ctx ) +{ + mbedtls_cipher_free( &ctx->keys[0].ctx ); + mbedtls_cipher_free( &ctx->keys[1].ctx ); + +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_free( &ctx->mutex ); +#endif + + mbedtls_zeroize( ctx, sizeof( mbedtls_ssl_ticket_context ) ); +} + +#endif /* MBEDTLS_SSL_TICKET_C */ diff --git a/APP_Framework/Framework/security/mbedtls/ssl_ticket.h b/APP_Framework/Framework/security/mbedtls/ssl_ticket.h index bb6cfe321..ff7eccbb8 100644 --- a/APP_Framework/Framework/security/mbedtls/ssl_ticket.h +++ b/APP_Framework/Framework/security/mbedtls/ssl_ticket.h @@ -50,7 +50,7 @@ extern "C" { /** * \brief Information for session ticket protection */ -typedef struct mbedtls_ssl_ticket_key +typedef struct { unsigned char name[4]; /*!< random key identifier */ uint32_t generation_time; /*!< key generation timestamp (seconds) */ @@ -61,17 +61,17 @@ mbedtls_ssl_ticket_key; /** * \brief Context for session ticket handling functions */ -typedef struct mbedtls_ssl_ticket_context +typedef struct { + mbedtls_ssl_ticket_key keys[2]; /*!< ticket protection keys */ unsigned char active; /*!< index of the currently active key */ + uint32_t ticket_lifetime; /*!< lifetime of tickets in seconds */ /** Callback for getting (pseudo-)random numbers */ int (*f_rng)(void *, unsigned char *, size_t); void *p_rng; /*!< context for the RNG function */ - mbedtls_ssl_ticket_key keys[2]; /*!< ticket protection keys */ - #if defined(MBEDTLS_THREADING_C) mbedtls_threading_mutex_t mutex; #endif @@ -117,14 +117,14 @@ int mbedtls_ssl_ticket_setup( mbedtls_ssl_ticket_context *ctx, /** * \brief Implementation of the ticket write callback * - * \note See \c mbedtls_ssl_ticket_write_t for description + * \note See \c mbedlts_ssl_ticket_write_t for description */ mbedtls_ssl_ticket_write_t mbedtls_ssl_ticket_write; /** * \brief Implementation of the ticket parse callback * - * \note See \c mbedtls_ssl_ticket_parse_t for description + * \note See \c mbedlts_ssl_ticket_parse_t for description */ mbedtls_ssl_ticket_parse_t mbedtls_ssl_ticket_parse; diff --git a/APP_Framework/Framework/security/mbedtls/ssl_tls.c b/APP_Framework/Framework/security/mbedtls/ssl_tls.c index 1453b12f9..8c630b800 100644 --- a/APP_Framework/Framework/security/mbedtls/ssl_tls.c +++ b/APP_Framework/Framework/security/mbedtls/ssl_tls.c @@ -35,8 +35,6 @@ #if defined(MBEDTLS_SSL_TLS_C) -#include - #if defined(MBEDTLS_PLATFORM_C) #include "platform.h" #else @@ -48,9 +46,6 @@ #include "debug.h" #include "ssl.h" #include "ssl_internal.h" -#include "platform_util.h" -#include "version.h" -#include "platform.h" #include @@ -58,143 +53,21 @@ #include "oid.h" #endif -#define PROPER_HS_FRAGMENT 0x75 - -#if defined(MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS) -static int mbedtls_ssl_switch_key( mbedtls_ssl_transform *transform, - const mbedtls_operation_t operation ) -{ - unsigned char * key; - int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; - volatile int flow_ctrl = 0; -#if defined(MBEDTLS_VALIDATE_SSL_KEYS_INTEGRITY) - uint32_t hash; -#endif - if( operation == MBEDTLS_ENCRYPT ) - { - flow_ctrl++; - key = transform->key_enc; -#if defined(MBEDTLS_VALIDATE_SSL_KEYS_INTEGRITY) - hash = transform->key_enc_hash; -#endif - } - else if ( operation == MBEDTLS_DECRYPT ) - { - flow_ctrl++; - key = transform->key_dec; -#if defined(MBEDTLS_VALIDATE_SSL_KEYS_INTEGRITY) - hash = transform->key_dec_hash; -#endif - } - else - { - return ( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } -#if defined(MBEDTLS_VALIDATE_SSL_KEYS_INTEGRITY) - /* Check hash */ - if( hash != mbedtls_hash( key, transform->key_bitlen >> 3 ) ) - { - return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); - } - else - { - flow_ctrl++; - } -#else - flow_ctrl++; -#endif - if( operation != transform->cipher_ctx.operation ) - { - if( ( ret = mbedtls_cipher_setkey( &transform->cipher_ctx, - key, - transform->key_bitlen, - operation ) ) != 0 ) - { - return( ret ); - } - } - if( flow_ctrl == 2 ) - { - return( 0 ); - } - return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); +/* 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; } -#endif - -#if defined(MBEDTLS_USE_TINYCRYPT) -static int uecc_rng_wrapper( uint8_t *dest, unsigned int size ) -{ - int ret; - ret = mbedtls_ssl_conf_rng_func( NULL, dest, size ); - if( ret == 0 ) - return( (int) size ); - - return( 0 ); -} - -int mbedtls_ssl_ecdh_read_peerkey( mbedtls_ssl_context *ssl, - unsigned char **p, unsigned char *end ) -{ - size_t const secp256r1_uncompressed_point_length = - 1 /* length */ + 1 /* length */ + 2 * NUM_ECC_BYTES /* data */; - - if( (size_t)( end - *p ) < secp256r1_uncompressed_point_length ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "Bad ECDH peer pubkey (too short)" ) ); - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - } - - if( (*p)[0] != 2 * NUM_ECC_BYTES + 1 || - (*p)[1] != 0x04 ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "Unexpected ECDH peer pubkey header - expected { %#02x, %#02x }, got { %#02x, %#02x }", - 2 * NUM_ECC_BYTES + 1, - 0x04, - (unsigned) (*p)[0], - (unsigned) (*p)[1] ) ); - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - } - - if( mbedtls_platform_memcpy( ssl->handshake->ecdh_peerkey, *p + 2, 2 * NUM_ECC_BYTES ) != - ssl->handshake->ecdh_peerkey ) - { - return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); - } - - *p += secp256r1_uncompressed_point_length; - return( 0 ); -} -#endif /* MBEDTLS_USE_TINYCRYPT */ - -static void ssl_reset_in_out_pointers( mbedtls_ssl_context *ssl ); -static uint32_t ssl_get_hs_total_len( mbedtls_ssl_context const *ssl ); /* Length of the "epoch" field in the record header */ static inline size_t ssl_ep_len( const mbedtls_ssl_context *ssl ) { -#if !defined(MBEDTLS_SSL_TRANSPORT__BOTH) +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + return( 2 ); +#else ((void) ssl); #endif - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) ) - return( 2 ); - MBEDTLS_SSL_TRANSPORT_ELSE -#endif -#if defined(MBEDTLS_SSL_PROTO_TLS) return( 0 ); -#endif -} - -static void ssl_send_pending_fatal_alert( mbedtls_ssl_context *ssl ) -{ - if( ssl->pending_fatal_alert_msg == MBEDTLS_SSL_ALERT_MSG_NONE ) - return; - - mbedtls_ssl_send_alert_message( ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - ssl->pending_fatal_alert_msg ); - ssl->pending_fatal_alert_msg = MBEDTLS_SSL_ALERT_MSG_NONE; } /* @@ -203,13 +76,11 @@ static void ssl_send_pending_fatal_alert( mbedtls_ssl_context *ssl ) */ static void ssl_set_timer( mbedtls_ssl_context *ssl, uint32_t millisecs ) { - if( mbedtls_ssl_get_set_timer( ssl ) == NULL ) + if( ssl->f_set_timer == NULL ) return; MBEDTLS_SSL_DEBUG_MSG( 3, ( "set_timer to %d ms", (int) millisecs ) ); - mbedtls_ssl_get_set_timer( ssl )( ssl->p_timer, - millisecs / 4, - millisecs ); + ssl->f_set_timer( ssl->p_timer, millisecs / 4, millisecs ); } /* @@ -217,10 +88,10 @@ static void ssl_set_timer( mbedtls_ssl_context *ssl, uint32_t millisecs ) */ static int ssl_check_timer( mbedtls_ssl_context *ssl ) { - if( mbedtls_ssl_get_get_timer( ssl ) == NULL ) + if( ssl->f_get_timer == NULL ) return( 0 ); - if( mbedtls_ssl_get_get_timer( ssl )( ssl->p_timer ) == 2 ) + if( ssl->f_get_timer( ssl->p_timer ) == 2 ) { MBEDTLS_SSL_DEBUG_MSG( 3, ( "timer expired" ) ); return( -1 ); @@ -229,286 +100,7 @@ static int ssl_check_timer( mbedtls_ssl_context *ssl ) return( 0 ); } -static void ssl_update_out_pointers( mbedtls_ssl_context *ssl, - mbedtls_ssl_transform *transform ); -static void ssl_update_in_pointers( mbedtls_ssl_context *ssl ); - -#if defined(MBEDTLS_SSL_RECORD_CHECKING) -static int ssl_parse_record_header( mbedtls_ssl_context const *ssl, - unsigned char *buf, - size_t len, - mbedtls_record *rec ); - -int mbedtls_ssl_check_record( mbedtls_ssl_context const *ssl, - unsigned char *buf, - size_t buflen ) -{ - int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; - mbedtls_record rec; - MBEDTLS_SSL_DEBUG_MSG( 1, ( "=> mbedtls_ssl_check_record" ) ); - MBEDTLS_SSL_DEBUG_BUF( 3, "record buffer", buf, buflen ); - - /* We don't support record checking in TLS because - * (a) there doesn't seem to be a usecase for it, and - * (b) In SSLv3 and TLS 1.0, CBC record decryption has state - * and we'd need to backup the transform here. - */ -#if defined(MBEDTLS_SSL_PROTO_TLS) - if( MBEDTLS_SSL_TRANSPORT_IS_TLS( ssl->conf->transport ) ) - { - ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; - goto exit; - } - MBEDTLS_SSL_TRANSPORT_ELSE -#endif /* MBEDTLS_SSL_PROTO_TLS */ #if defined(MBEDTLS_SSL_PROTO_DTLS) - { - ret = ssl_parse_record_header( ssl, buf, buflen, &rec ); - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 3, "ssl_parse_record_header", ret ); - goto exit; - } - - if( ssl->transform_in != NULL ) - { - ret = mbedtls_ssl_decrypt_buf( ssl, ssl->transform_in, &rec ); - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 3, "mbedtls_ssl_decrypt_buf", ret ); - goto exit; - } - } - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - -exit: - /* On success, we have decrypted the buffer in-place, so make - * sure we don't leak any plaintext data. */ - mbedtls_platform_zeroize( buf, buflen ); - - /* For the purpose of this API, treat messages with unexpected CID - * as well as such from future epochs as unexpected. */ - if( ret == MBEDTLS_ERR_SSL_UNEXPECTED_CID || - ret == MBEDTLS_ERR_SSL_EARLY_MESSAGE ) - { - ret = MBEDTLS_ERR_SSL_UNEXPECTED_RECORD; - } - - MBEDTLS_SSL_DEBUG_MSG( 1, ( "<= mbedtls_ssl_check_record" ) ); - return( ret ); -} -#endif /* MBEDTLS_SSL_RECORD_CHECKING */ - -#define SSL_DONT_FORCE_FLUSH 0 -#define SSL_FORCE_FLUSH 1 - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) -/* Top-level Connection ID API */ - -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \ - !defined(MBEDTLS_SSL_CONF_CID_LEN) && \ - !defined(MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID) -int mbedtls_ssl_conf_cid( mbedtls_ssl_config *conf, - size_t len, - int ignore_other_cid ) -{ - if( len > MBEDTLS_SSL_CID_IN_LEN_MAX ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - if( ignore_other_cid != MBEDTLS_SSL_UNEXPECTED_CID_FAIL && - ignore_other_cid != MBEDTLS_SSL_UNEXPECTED_CID_IGNORE ) - { - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - } - - conf->ignore_unexpected_cid = ignore_other_cid; - conf->cid_len = len; - return( 0 ); -} -#else /* MBEDTLS_SSL_DTLS_CONNECTION_ID && - !MBEDTLS_SSL_CONF_CID_LEN && - !MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID */ - -#if MBEDTLS_SSL_CONF_CID_LEN > MBEDTLS_SSL_CID_IN_LEN_MAX -#error "Invalid hardcoded value for MBEDTLS_SSL_CONF_CID_LEN" -#endif -#if MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID != MBEDTLS_SSL_UNEXPECTED_CID_IGNORE && \ - MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID != MBEDTLS_SSL_UNEXPECTED_CID_FAIL -#error "Invalid hardcoded value for MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID" -#endif - -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID && - !MBEDTLS_SSL_CONF_CID_LEN && - !MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID */ - -int mbedtls_ssl_set_cid( mbedtls_ssl_context *ssl, - int enable, - unsigned char const *own_cid, - size_t own_cid_len ) -{ - if( MBEDTLS_SSL_TRANSPORT_IS_TLS( ssl->conf->transport ) ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - ssl->negotiate_cid = enable; - if( enable == MBEDTLS_SSL_CID_DISABLED ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "Disable use of CID extension." ) ); - return( 0 ); - } - MBEDTLS_SSL_DEBUG_MSG( 3, ( "Enable use of CID extension." ) ); - MBEDTLS_SSL_DEBUG_BUF( 3, "Own CID", own_cid, own_cid_len ); - - if( own_cid_len != mbedtls_ssl_conf_get_cid_len( ssl->conf ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "CID length %u does not match CID length %u in config", - (unsigned) own_cid_len, - (unsigned) mbedtls_ssl_conf_get_cid_len( ssl->conf ) ) ); - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - } - - /* Not using more secure mbedtls_platform_memcpy as cid is public */ - memcpy( ssl->own_cid, own_cid, own_cid_len ); - /* Truncation is not an issue here because - * MBEDTLS_SSL_CID_IN_LEN_MAX at most 255. */ - ssl->own_cid_len = (uint8_t) own_cid_len; - - return( 0 ); -} - -int mbedtls_ssl_get_peer_cid( mbedtls_ssl_context *ssl, - int *enabled, - unsigned char peer_cid[ MBEDTLS_SSL_CID_OUT_LEN_MAX ], - size_t *peer_cid_len ) -{ - *enabled = MBEDTLS_SSL_CID_DISABLED; - - if( MBEDTLS_SSL_TRANSPORT_IS_TLS( ssl->conf->transport ) || - ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) - { - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - } - - /* We report MBEDTLS_SSL_CID_DISABLED in case the CID extensions - * were used, but client and server requested the empty CID. - * This is indistinguishable from not using the CID extension - * in the first place. */ - if( ssl->transform_in->in_cid_len == 0 && - ssl->transform_in->out_cid_len == 0 ) - { - return( 0 ); - } - - if( peer_cid_len != NULL ) - { - *peer_cid_len = ssl->transform_in->out_cid_len; - if( peer_cid != NULL ) - { - /* Not using more secure mbedtls_platform_memcpy as cid is public */ - memcpy( peer_cid, ssl->transform_in->out_cid, - ssl->transform_in->out_cid_len ); - } - } - - *enabled = MBEDTLS_SSL_CID_ENABLED; - - return( 0 ); -} -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - -/* Forward declarations for functions related to message buffering. */ -static void ssl_buffering_free( mbedtls_ssl_context *ssl ); -static void ssl_buffering_free_slot( mbedtls_ssl_context *ssl, - uint8_t slot ); -static void ssl_free_buffered_record( mbedtls_ssl_context *ssl ); -static int ssl_load_buffered_message( mbedtls_ssl_context *ssl ); -static int ssl_load_buffered_record( mbedtls_ssl_context *ssl ); -static int ssl_buffer_message( mbedtls_ssl_context *ssl ); -static int ssl_buffer_future_record( mbedtls_ssl_context *ssl, - mbedtls_record const *rec ); -static int ssl_next_record_is_in_datagram( mbedtls_ssl_context *ssl ); - -static size_t ssl_get_current_mtu( const mbedtls_ssl_context *ssl ); -static size_t ssl_get_maximum_datagram_size( mbedtls_ssl_context const *ssl ) -{ - size_t mtu = ssl_get_current_mtu( ssl ); -#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) - size_t out_buf_len = ssl->out_buf_len; -#else - size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN; -#endif - - if( mtu != 0 && mtu < out_buf_len ) - return( mtu ); - - return( out_buf_len ); -} - -static int ssl_get_remaining_space_in_datagram( mbedtls_ssl_context const *ssl ) -{ - size_t const bytes_written = ssl->out_left; - size_t const mtu = ssl_get_maximum_datagram_size( ssl ); - - /* Double-check that the write-index hasn't gone - * past what we can transmit in a single datagram. */ - if( bytes_written > mtu ) - { - /* Should never happen... */ - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - return( (int) ( mtu - bytes_written ) ); -} - -static int ssl_get_remaining_payload_in_datagram( mbedtls_ssl_context const *ssl ) -{ - int ret; - size_t remaining, expansion; - size_t max_len = MBEDTLS_SSL_OUT_CONTENT_LEN; - -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) - const size_t mfl = mbedtls_ssl_get_output_max_frag_len( ssl ); - - if( max_len > mfl ) - max_len = mfl; - - /* By the standard (RFC 6066 Sect. 4), the MFL extension - * only limits the maximum record payload size, so in theory - * we would be allowed to pack multiple records of payload size - * MFL into a single datagram. However, this would mean that there's - * no way to explicitly communicate MTU restrictions to the peer. - * - * The following reduction of max_len makes sure that we never - * write datagrams larger than MFL + Record Expansion Overhead. - */ - if( max_len <= ssl->out_left ) - return( 0 ); - - max_len -= ssl->out_left; -#endif - - ret = ssl_get_remaining_space_in_datagram( ssl ); - if( ret < 0 ) - return( ret ); - remaining = (size_t) ret; - - ret = mbedtls_ssl_get_record_expansion( ssl ); - if( ret < 0 ) - return( ret ); - expansion = (size_t) ret; - - if( remaining <= expansion ) - return( 0 ); - - remaining -= expansion; - if( remaining >= max_len ) - remaining = max_len; - - return( (int) remaining ); -} - /* * Double the retransmit timeout value, within the allowed range, * returning -1 if the maximum value has already been reached. @@ -517,32 +109,16 @@ static int ssl_double_retransmit_timeout( mbedtls_ssl_context *ssl ) { uint32_t new_timeout; - if( ssl->handshake->retransmit_timeout >= - mbedtls_ssl_conf_get_hs_timeout_max( ssl->conf ) ) - { + if( ssl->handshake->retransmit_timeout >= ssl->conf->hs_timeout_max ) return( -1 ); - } - - /* Implement the final paragraph of RFC 6347 section 4.1.1.1 - * in the following way: after the initial transmission and a first - * retransmission, back off to a temporary estimated MTU of 508 bytes. - * This value is guaranteed to be deliverable (if not guaranteed to be - * delivered) of any compliant IPv4 (and IPv6) network, and should work - * on most non-IP stacks too. */ - if( ssl->handshake->retransmit_timeout != - mbedtls_ssl_conf_get_hs_timeout_min( ssl->conf ) ) - { - ssl->handshake->mtu = 508; - MBEDTLS_SSL_DEBUG_MSG( 2, ( "mtu autoreduction to %d bytes", ssl->handshake->mtu ) ); - } new_timeout = 2 * ssl->handshake->retransmit_timeout; /* Avoid arithmetic overflow and range overflow */ if( new_timeout < ssl->handshake->retransmit_timeout || - new_timeout > mbedtls_ssl_conf_get_hs_timeout_max( ssl->conf ) ) + new_timeout > ssl->conf->hs_timeout_max ) { - new_timeout = mbedtls_ssl_conf_get_hs_timeout_max( ssl->conf ); + new_timeout = ssl->conf->hs_timeout_max; } ssl->handshake->retransmit_timeout = new_timeout; @@ -554,7 +130,7 @@ static int ssl_double_retransmit_timeout( mbedtls_ssl_context *ssl ) static void ssl_reset_retransmit_timeout( mbedtls_ssl_context *ssl ) { - ssl->handshake->retransmit_timeout = mbedtls_ssl_conf_get_hs_timeout_min( ssl->conf ); + ssl->handshake->retransmit_timeout = ssl->conf->hs_timeout_min; MBEDTLS_SSL_DEBUG_MSG( 3, ( "update timeout value to %d millisecs", ssl->handshake->retransmit_timeout ) ); } @@ -569,35 +145,23 @@ static void ssl_reset_retransmit_timeout( mbedtls_ssl_context *ssl ) * } MaxFragmentLength; * and we add 0 -> extension unused */ -static unsigned int ssl_mfl_code_to_length( int mfl ) +static unsigned int mfl_code_to_length[MBEDTLS_SSL_MAX_FRAG_LEN_INVALID] = { - switch( mfl ) - { - case MBEDTLS_SSL_MAX_FRAG_LEN_NONE: - return( MBEDTLS_TLS_EXT_ADV_CONTENT_LEN ); - case MBEDTLS_SSL_MAX_FRAG_LEN_512: - return 512; - case MBEDTLS_SSL_MAX_FRAG_LEN_1024: - return 1024; - case MBEDTLS_SSL_MAX_FRAG_LEN_2048: - return 2048; - case MBEDTLS_SSL_MAX_FRAG_LEN_4096: - return 4096; - default: - return( MBEDTLS_TLS_EXT_ADV_CONTENT_LEN ); - } -} + MBEDTLS_SSL_MAX_CONTENT_LEN, /* MBEDTLS_SSL_MAX_FRAG_LEN_NONE */ + 512, /* MBEDTLS_SSL_MAX_FRAG_LEN_512 */ + 1024, /* MBEDTLS_SSL_MAX_FRAG_LEN_1024 */ + 2048, /* MBEDTLS_SSL_MAX_FRAG_LEN_2048 */ + 4096, /* MBEDTLS_SSL_MAX_FRAG_LEN_4096 */ +}; #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ -int mbedtls_ssl_session_copy( mbedtls_ssl_session *dst, - const mbedtls_ssl_session *src ) +#if defined(MBEDTLS_SSL_CLI_C) +static int ssl_session_copy( mbedtls_ssl_session *dst, const mbedtls_ssl_session *src ) { mbedtls_ssl_session_free( dst ); - mbedtls_platform_memcpy( dst, src, sizeof( mbedtls_ssl_session ) ); + memcpy( dst, src, sizeof( mbedtls_ssl_session ) ); #if defined(MBEDTLS_X509_CRT_PARSE_C) - -#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) if( src->peer_cert != NULL ) { int ret; @@ -616,21 +180,6 @@ int mbedtls_ssl_session_copy( mbedtls_ssl_session *dst, return( ret ); } } -#elif defined(MBEDTLS_SSL_RENEGOTIATION) - if( src->peer_cert_digest != NULL ) - { - dst->peer_cert_digest = - mbedtls_calloc( 1, src->peer_cert_digest_len ); - if( dst->peer_cert_digest == NULL ) - return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); - - mbedtls_platform_memcpy( dst->peer_cert_digest, src->peer_cert_digest, - src->peer_cert_digest_len ); - dst->peer_cert_digest_type = src->peer_cert_digest_type; - dst->peer_cert_digest_len = src->peer_cert_digest_len; - } -#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE && MBEDTLS_SSL_RENEGOTIATION */ - #endif /* MBEDTLS_X509_CRT_PARSE_C */ #if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C) @@ -640,101 +189,13 @@ int mbedtls_ssl_session_copy( mbedtls_ssl_session *dst, if( dst->ticket == NULL ) return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); - mbedtls_platform_memcpy( dst->ticket, src->ticket, src->ticket_len ); + memcpy( dst->ticket, src->ticket, src->ticket_len ); } #endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */ return( 0 ); } - -#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) -static int resize_buffer( unsigned char **buffer, size_t len_new, size_t *len_old ) -{ - unsigned char* resized_buffer = mbedtls_calloc( 1, len_new ); - if( resized_buffer == NULL ) - return -1; - - /* We want to copy len_new bytes when downsizing the buffer, and - * len_old bytes when upsizing, so we choose the smaller of two sizes, - * to fit one buffer into another. Size checks, ensuring that no data is - * lost, are done outside of this function. */ - memcpy( resized_buffer, *buffer, - ( len_new < *len_old ) ? len_new : *len_old ); - mbedtls_platform_zeroize( *buffer, *len_old ); - mbedtls_free( *buffer ); - - *buffer = resized_buffer; - *len_old = len_new; - - return 0; -} - -#define BUFFER_UPSIZING 0 -#define BUFFER_DOWNSIZING 1 -static void handle_buffer_resizing( mbedtls_ssl_context *ssl, int downsizing, - uint32_t in_buf_new_len, - uint32_t out_buf_new_len ) -{ - int modified = 0; - size_t written_in = 0, len_offset_in = 0; - size_t written_out = 0, iv_offset_out = 0, len_offset_out = 0; - if( ssl->in_buf != NULL ) - { - written_in = ssl->in_msg - ssl->in_buf; - len_offset_in = ssl->in_len - ssl->in_buf; - if( ( downsizing && ssl->in_buf_len > in_buf_new_len && ssl->in_left < in_buf_new_len ) || - ( !downsizing && ssl->in_buf_len < in_buf_new_len ) ) - { - if( resize_buffer( &ssl->in_buf, in_buf_new_len, &ssl->in_buf_len ) != 0 ) - { - /* No need to return an error here; The buffer will remain as - * is with no negative impact on the flow. */ - MBEDTLS_SSL_DEBUG_MSG( 1, ( "input buffer resizing failed - out of memory" ) ); - } - else - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Reallocating in_buf to %d", in_buf_new_len ) ); - modified = 1; - } - } - } - - if( ssl->out_buf != NULL ) - { - written_out = ssl->out_msg - ssl->out_buf; - iv_offset_out = ssl->out_iv - ssl->out_buf; - len_offset_out = ssl->out_len - ssl->out_buf; - if( ( downsizing && ssl->out_buf_len > out_buf_new_len && ssl->out_left < out_buf_new_len ) || - ( !downsizing && ssl->out_buf_len < out_buf_new_len ) ) - { - if( resize_buffer( &ssl->out_buf, out_buf_new_len, &ssl->out_buf_len ) != 0 ) - { - /* No need to return an error here; The buffer will remain as - * is with no negative impact on the flow. */ - MBEDTLS_SSL_DEBUG_MSG( 1, ( "output buffer resizing failed - out of memory" ) ); - } - else - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Reallocating out_buf to %d", out_buf_new_len ) ); - modified = 1; - } - } - } - if( modified ) - { - /* Update pointers here to avoid doing it twice. */ - ssl_reset_in_out_pointers( ssl ); - /* Fields below might not be properly updated with record - * splitting or with CID, so they are manually updated here. */ - ssl->out_msg = ssl->out_buf + written_out; - ssl->out_len = ssl->out_buf + len_offset_out; - ssl->out_iv = ssl->out_buf + iv_offset_out; - - ssl->in_msg = ssl->in_buf + written_in; - ssl->in_len = ssl->in_buf + len_offset_in; - } -} -#endif /* MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH */ +#endif /* MBEDTLS_SSL_CLI_C */ #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) int (*mbedtls_ssl_hw_record_init)( mbedtls_ssl_context *ssl, @@ -755,7 +216,7 @@ int (*mbedtls_ssl_hw_record_finish)( mbedtls_ssl_context *ssl ) = NULL; * Key material generation */ #if defined(MBEDTLS_SSL_PROTO_SSL3) -MBEDTLS_NO_INLINE static int ssl3_prf( const unsigned char *secret, size_t slen, +static int ssl3_prf( const unsigned char *secret, size_t slen, const char *label, const unsigned char *random, size_t rlen, unsigned char *dstbuf, size_t dlen ) @@ -781,7 +242,7 @@ MBEDTLS_NO_INLINE static int ssl3_prf( const unsigned char *secret, size_t slen, */ for( i = 0; i < dlen / 16; i++ ) { - mbedtls_platform_memset( padding, (unsigned char) ('A' + i), 1 + i ); + memset( padding, (unsigned char) ('A' + i), 1 + i ); if( ( ret = mbedtls_sha1_starts_ret( &sha1 ) ) != 0 ) goto exit; @@ -808,15 +269,15 @@ exit: mbedtls_md5_free( &md5 ); mbedtls_sha1_free( &sha1 ); - mbedtls_platform_zeroize( padding, sizeof( padding ) ); - mbedtls_platform_zeroize( sha1sum, sizeof( sha1sum ) ); + mbedtls_zeroize( padding, sizeof( padding ) ); + mbedtls_zeroize( sha1sum, sizeof( sha1sum ) ); return( ret ); } #endif /* MBEDTLS_SSL_PROTO_SSL3 */ #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) -MBEDTLS_NO_INLINE static int tls1_prf( const unsigned char *secret, size_t slen, +static int tls1_prf( const unsigned char *secret, size_t slen, const char *label, const unsigned char *random, size_t rlen, unsigned char *dstbuf, size_t dlen ) @@ -826,7 +287,7 @@ MBEDTLS_NO_INLINE static int tls1_prf( const unsigned char *secret, size_t slen, const unsigned char *S1, *S2; unsigned char tmp[128]; unsigned char h_i[20]; - mbedtls_md_handle_t md_info; + const mbedtls_md_info_t *md_info; mbedtls_md_context_t md_ctx; int ret; @@ -840,18 +301,15 @@ MBEDTLS_NO_INLINE static int tls1_prf( const unsigned char *secret, size_t slen, S2 = secret + slen - hs; nb = strlen( label ); - mbedtls_platform_memcpy( tmp + 20, label, nb ); - mbedtls_platform_memcpy( tmp + 20 + nb, random, rlen ); + memcpy( tmp + 20, label, nb ); + memcpy( tmp + 20 + nb, random, rlen ); nb += rlen; /* * First compute P_md5(secret,label+random)[0..dlen] */ - if( ( md_info = mbedtls_md_info_from_type( MBEDTLS_MD_MD5 ) ) == - MBEDTLS_MD_INVALID_HANDLE ) - { + if( ( md_info = mbedtls_md_info_from_type( MBEDTLS_MD_MD5 ) ) == NULL ) return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 1 ) ) != 0 ) return( ret ); @@ -881,11 +339,8 @@ MBEDTLS_NO_INLINE static int tls1_prf( const unsigned char *secret, size_t slen, /* * XOR out with P_sha1(secret,label+random)[0..dlen] */ - if( ( md_info = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 ) ) == - MBEDTLS_MD_INVALID_HANDLE ) - { + if( ( md_info = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 ) ) == NULL ) return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 1 ) ) != 0 ) return( ret ); @@ -912,20 +367,15 @@ MBEDTLS_NO_INLINE static int tls1_prf( const unsigned char *secret, size_t slen, mbedtls_md_free( &md_ctx ); - mbedtls_platform_zeroize( tmp, sizeof( tmp ) ); - mbedtls_platform_zeroize( h_i, sizeof( h_i ) ); + mbedtls_zeroize( tmp, sizeof( tmp ) ); + mbedtls_zeroize( h_i, sizeof( h_i ) ); return( 0 ); } #endif /* MBEDTLS_SSL_PROTO_TLS1) || MBEDTLS_SSL_PROTO_TLS1_1 */ #if defined(MBEDTLS_SSL_PROTO_TLS1_2) -#if !( defined(MBEDTLS_SHA256_C) && defined(MBEDTLS_SHA512_C) ) -MBEDTLS_ALWAYS_INLINE static inline -#else -static -#endif -int tls_prf_generic( mbedtls_md_type_t md_type, +static int tls_prf_generic( mbedtls_md_type_t md_type, const unsigned char *secret, size_t slen, const char *label, const unsigned char *random, size_t rlen, @@ -933,19 +383,16 @@ int tls_prf_generic( mbedtls_md_type_t md_type, { size_t nb; size_t i, j, k, md_len; - unsigned char tmp[128] = {0}; - unsigned char h_i[MBEDTLS_MD_MAX_SIZE] = {0}; - mbedtls_md_handle_t md_info; + unsigned char tmp[128]; + unsigned char h_i[MBEDTLS_MD_MAX_SIZE]; + const mbedtls_md_info_t *md_info; mbedtls_md_context_t md_ctx; int ret; mbedtls_md_init( &md_ctx ); - if( ( md_info = mbedtls_md_info_from_type( md_type ) ) == - MBEDTLS_MD_INVALID_HANDLE ) - { + if( ( md_info = mbedtls_md_info_from_type( md_type ) ) == NULL ) return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } md_len = mbedtls_md_get_size( md_info ); @@ -953,8 +400,8 @@ int tls_prf_generic( mbedtls_md_type_t md_type, return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); nb = strlen( label ); - (void)mbedtls_platform_memcpy( tmp + md_len, label, nb ); - (void)mbedtls_platform_memcpy( tmp + md_len + nb, random, rlen ); + memcpy( tmp + md_len, label, nb ); + memcpy( tmp + md_len + nb, random, rlen ); nb += rlen; /* @@ -963,28 +410,19 @@ int tls_prf_generic( mbedtls_md_type_t md_type, if ( ( ret = mbedtls_md_setup( &md_ctx, md_info, 1 ) ) != 0 ) return( ret ); - if ( ( ret = mbedtls_md_hmac_starts( &md_ctx, secret, slen ) ) != 0 ) - return( ret ); - if ( ( ret = mbedtls_md_hmac_update( &md_ctx, tmp + md_len, nb ) ) != 0 ) - return( ret ); - if ( ( ret = mbedtls_md_hmac_finish( &md_ctx, tmp ) ) != 0 ) - return( ret ); + mbedtls_md_hmac_starts( &md_ctx, secret, slen ); + mbedtls_md_hmac_update( &md_ctx, tmp + md_len, nb ); + mbedtls_md_hmac_finish( &md_ctx, tmp ); for( i = 0; i < dlen; i += md_len ) { - if ( ( ret = mbedtls_md_hmac_reset ( &md_ctx ) ) != 0 ) - return( ret ); - if ( ( ret = mbedtls_md_hmac_update( &md_ctx, tmp, md_len + nb ) ) != 0 ) - return( ret ); - if ( ( ret = mbedtls_md_hmac_finish( &md_ctx, h_i ) ) != 0 ) - return( ret ); + mbedtls_md_hmac_reset ( &md_ctx ); + mbedtls_md_hmac_update( &md_ctx, tmp, md_len + nb ); + mbedtls_md_hmac_finish( &md_ctx, h_i ); - if ( ( ret = mbedtls_md_hmac_reset ( &md_ctx ) ) != 0 ) - return( ret ); - if ( ( ret = mbedtls_md_hmac_update( &md_ctx, tmp, md_len ) ) != 0 ) - return( ret ); - if ( ( ret = mbedtls_md_hmac_finish( &md_ctx, tmp ) ) != 0 ) - return( ret ); + mbedtls_md_hmac_reset ( &md_ctx ); + mbedtls_md_hmac_update( &md_ctx, tmp, md_len ); + mbedtls_md_hmac_finish( &md_ctx, tmp ); k = ( i + md_len > dlen ) ? dlen % md_len : md_len; @@ -994,15 +432,14 @@ int tls_prf_generic( mbedtls_md_type_t md_type, mbedtls_md_free( &md_ctx ); - (void)mbedtls_platform_zeroize( tmp, sizeof( tmp ) ); - (void)mbedtls_platform_zeroize( h_i, sizeof( h_i ) ); + mbedtls_zeroize( tmp, sizeof( tmp ) ); + mbedtls_zeroize( h_i, sizeof( h_i ) ); return( 0 ); } #if defined(MBEDTLS_SHA256_C) -MBEDTLS_NO_INLINE static int tls_prf_sha256( - const unsigned char *secret, size_t slen, +static int tls_prf_sha256( const unsigned char *secret, size_t slen, const char *label, const unsigned char *random, size_t rlen, unsigned char *dstbuf, size_t dlen ) @@ -1013,8 +450,7 @@ MBEDTLS_NO_INLINE static int tls_prf_sha256( #endif /* MBEDTLS_SHA256_C */ #if defined(MBEDTLS_SHA512_C) -MBEDTLS_NO_INLINE static int tls_prf_sha384( - const unsigned char *secret, size_t slen, +static int tls_prf_sha384( const unsigned char *secret, size_t slen, const char *label, const unsigned char *random, size_t rlen, unsigned char *dstbuf, size_t dlen ) @@ -1025,402 +461,41 @@ MBEDTLS_NO_INLINE static int tls_prf_sha384( #endif /* MBEDTLS_SHA512_C */ #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ -/* - * Call the appropriate PRF function - */ -MBEDTLS_ALWAYS_INLINE static inline int ssl_prf( int minor_ver, - mbedtls_md_type_t hash, - const unsigned char *secret, size_t slen, - const char *label, - const unsigned char *random, size_t rlen, - unsigned char *dstbuf, size_t dlen ) -{ -#if !defined(MBEDTLS_SSL_PROTO_TLS1_2) || !defined(MBEDTLS_SHA512_C) - (void) hash; +static void ssl_update_checksum_start( mbedtls_ssl_context *, const unsigned char *, size_t ); + +#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ + defined(MBEDTLS_SSL_PROTO_TLS1_1) +static void ssl_update_checksum_md5sha1( mbedtls_ssl_context *, const unsigned char *, size_t ); #endif #if defined(MBEDTLS_SSL_PROTO_SSL3) - if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) - return( ssl3_prf( secret, slen, label, random, rlen, dstbuf, dlen ) ); - else +static void ssl_calc_verify_ssl( mbedtls_ssl_context *, unsigned char * ); +static void ssl_calc_finished_ssl( mbedtls_ssl_context *, unsigned char *, int ); #endif -#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) - if( mbedtls_ssl_ver_lt( minor_ver, MBEDTLS_SSL_MINOR_VERSION_3 ) ) - return( tls1_prf( secret, slen, label, random, rlen, dstbuf, dlen ) ); - else -#endif -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) -#if defined(MBEDTLS_SHA512_C) - if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 && - hash == MBEDTLS_MD_SHA384 ) - { - return( tls_prf_sha384( secret, slen, label, random, rlen, - dstbuf, dlen ) ); - } - else -#endif -#if defined(MBEDTLS_SHA256_C) - if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) - { - return( tls_prf_sha256( secret, slen, label, random, rlen, - dstbuf, dlen ) ); - } -#endif -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); -} - -#if defined(MBEDTLS_SSL_PROTO_SSL3) -MBEDTLS_NO_INLINE static void ssl_calc_finished_ssl( - mbedtls_ssl_context *ssl, unsigned char *buf, int from ) -{ - const char *sender; - mbedtls_md5_context md5; - mbedtls_sha1_context sha1; - - unsigned char padbuf[48]; - unsigned char md5sum[16]; - unsigned char sha1sum[20]; - - mbedtls_ssl_session *session = ssl->session_negotiate; - if( !session ) - session = ssl->session; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc finished ssl" ) ); - - mbedtls_md5_init( &md5 ); - mbedtls_sha1_init( &sha1 ); - - mbedtls_md5_clone( &md5, &ssl->handshake->fin_md5 ); - mbedtls_sha1_clone( &sha1, &ssl->handshake->fin_sha1 ); - - /* - * SSLv3: - * hash = - * MD5( master + pad2 + - * MD5( handshake + sender + master + pad1 ) ) - * + SHA1( master + pad2 + - * SHA1( handshake + sender + master + pad1 ) ) - */ - -#if !defined(MBEDTLS_MD5_ALT) - MBEDTLS_SSL_DEBUG_BUF( 4, "finished md5 state", (unsigned char *) - md5.state, sizeof( md5.state ) ); -#endif - -#if !defined(MBEDTLS_SHA1_ALT) - MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha1 state", (unsigned char *) - sha1.state, sizeof( sha1.state ) ); -#endif - - sender = ( from == MBEDTLS_SSL_IS_CLIENT ) ? "CLNT" - : "SRVR"; - - mbedtls_platform_memset( padbuf, 0x36, 48 ); - - mbedtls_md5_update_ret( &md5, (const unsigned char *) sender, 4 ); - mbedtls_md5_update_ret( &md5, session->master, 48 ); - mbedtls_md5_update_ret( &md5, padbuf, 48 ); - mbedtls_md5_finish_ret( &md5, md5sum ); - - mbedtls_sha1_update_ret( &sha1, (const unsigned char *) sender, 4 ); - mbedtls_sha1_update_ret( &sha1, session->master, 48 ); - mbedtls_sha1_update_ret( &sha1, padbuf, 40 ); - mbedtls_sha1_finish_ret( &sha1, sha1sum ); - - mbedtls_platform_memset( padbuf, 0x5C, 48 ); - - mbedtls_md5_starts_ret( &md5 ); - mbedtls_md5_update_ret( &md5, session->master, 48 ); - mbedtls_md5_update_ret( &md5, padbuf, 48 ); - mbedtls_md5_update_ret( &md5, md5sum, 16 ); - mbedtls_md5_finish_ret( &md5, buf ); - - mbedtls_sha1_starts_ret( &sha1 ); - mbedtls_sha1_update_ret( &sha1, session->master, 48 ); - mbedtls_sha1_update_ret( &sha1, padbuf , 40 ); - mbedtls_sha1_update_ret( &sha1, sha1sum, 20 ); - mbedtls_sha1_finish_ret( &sha1, buf + 16 ); - - MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, 36 ); - - mbedtls_md5_free( &md5 ); - mbedtls_sha1_free( &sha1 ); - - mbedtls_platform_zeroize( padbuf, sizeof( padbuf ) ); - mbedtls_platform_zeroize( md5sum, sizeof( md5sum ) ); - mbedtls_platform_zeroize( sha1sum, sizeof( sha1sum ) ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc finished" ) ); -} -#endif /* MBEDTLS_SSL_PROTO_SSL3 */ #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) -MBEDTLS_NO_INLINE static void ssl_calc_finished_tls( - mbedtls_ssl_context *ssl, unsigned char *buf, int from ) -{ - int len = 12; - const char *sender; - mbedtls_md5_context md5; - mbedtls_sha1_context sha1; - unsigned char padbuf[36]; - - mbedtls_ssl_session *session = ssl->session_negotiate; - if( !session ) - session = ssl->session; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc finished tls" ) ); - - mbedtls_md5_init( &md5 ); - mbedtls_sha1_init( &sha1 ); - - mbedtls_md5_clone( &md5, &ssl->handshake->fin_md5 ); - mbedtls_sha1_clone( &sha1, &ssl->handshake->fin_sha1 ); - - /* - * TLSv1: - * hash = PRF( master, finished_label, - * MD5( handshake ) + SHA1( handshake ) )[0..11] - */ - -#if !defined(MBEDTLS_MD5_ALT) - MBEDTLS_SSL_DEBUG_BUF( 4, "finished md5 state", (unsigned char *) - md5.state, sizeof( md5.state ) ); +static void ssl_calc_verify_tls( mbedtls_ssl_context *, unsigned char * ); +static void ssl_calc_finished_tls( mbedtls_ssl_context *, unsigned char *, int ); #endif -#if !defined(MBEDTLS_SHA1_ALT) - MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha1 state", (unsigned char *) - sha1.state, sizeof( sha1.state ) ); -#endif - - sender = ( from == MBEDTLS_SSL_IS_CLIENT ) - ? "client finished" - : "server finished"; - - mbedtls_md5_finish_ret( &md5, padbuf ); - mbedtls_sha1_finish_ret( &sha1, padbuf + 16 ); - - ssl_prf( mbedtls_ssl_get_minor_ver( ssl ), - mbedtls_ssl_suite_get_mac( - mbedtls_ssl_ciphersuite_from_id( - mbedtls_ssl_session_get_ciphersuite( session ) ) ), - session->master, 48, sender, - padbuf, 36, buf, len ); - - MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, len ); - - mbedtls_md5_free( &md5 ); - mbedtls_sha1_free( &sha1 ); - - mbedtls_platform_zeroize( padbuf, sizeof( padbuf ) ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc finished" ) ); -} -#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 */ - #if defined(MBEDTLS_SSL_PROTO_TLS1_2) #if defined(MBEDTLS_SHA256_C) -MBEDTLS_NO_INLINE static void ssl_calc_finished_tls_sha256( - mbedtls_ssl_context *ssl, unsigned char *buf, int from ) -{ - int len = 12; - const char *sender; - mbedtls_sha256_context sha256; - unsigned char padbuf[32]; - - mbedtls_ssl_session *session = ssl->session_negotiate; - if( !session ) - session = ssl->session; - - mbedtls_sha256_init( &sha256 ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc finished tls sha256" ) ); - - mbedtls_sha256_clone( &sha256, &ssl->handshake->fin_sha256 ); - - /* - * TLSv1.2: - * hash = PRF( master, finished_label, - * Hash( handshake ) )[0.11] - */ - -#if !defined(MBEDTLS_SHA256_ALT) - MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha2 state", (unsigned char *) - sha256.state, sizeof( sha256.state ) ); +static void ssl_update_checksum_sha256( mbedtls_ssl_context *, const unsigned char *, size_t ); +static void ssl_calc_verify_tls_sha256( mbedtls_ssl_context *,unsigned char * ); +static void ssl_calc_finished_tls_sha256( mbedtls_ssl_context *,unsigned char *, int ); #endif - sender = ( from == MBEDTLS_SSL_IS_CLIENT ) - ? "client finished" - : "server finished"; - - mbedtls_sha256_finish_ret( &sha256, padbuf ); - - ssl_prf( mbedtls_ssl_get_minor_ver( ssl ), - mbedtls_ssl_suite_get_mac( - mbedtls_ssl_ciphersuite_from_id( - mbedtls_ssl_session_get_ciphersuite( session ) ) ), - session->master, 48, sender, - padbuf, 32, buf, len ); - - MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, len ); - - mbedtls_sha256_free( &sha256 ); - - mbedtls_platform_zeroize( padbuf, sizeof( padbuf ) ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc finished" ) ); -} -#endif /* MBEDTLS_SHA256_C */ - #if defined(MBEDTLS_SHA512_C) -MBEDTLS_NO_INLINE static void ssl_calc_finished_tls_sha384( - mbedtls_ssl_context *ssl, unsigned char *buf, int from ) -{ - int len = 12; - const char *sender; - mbedtls_sha512_context sha512; - unsigned char padbuf[48]; - - mbedtls_ssl_session *session = ssl->session_negotiate; - if( !session ) - session = ssl->session; - - mbedtls_sha512_init( &sha512 ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc finished tls sha384" ) ); - - mbedtls_sha512_clone( &sha512, &ssl->handshake->fin_sha512 ); - - /* - * TLSv1.2: - * hash = PRF( master, finished_label, - * Hash( handshake ) )[0.11] - */ - -#if !defined(MBEDTLS_SHA512_ALT) - MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha512 state", (unsigned char *) - sha512.state, sizeof( sha512.state ) ); -#endif - - sender = ( from == MBEDTLS_SSL_IS_CLIENT ) - ? "client finished" - : "server finished"; - - mbedtls_sha512_finish_ret( &sha512, padbuf ); - - ssl_prf( mbedtls_ssl_get_minor_ver( ssl ), - mbedtls_ssl_suite_get_mac( - mbedtls_ssl_ciphersuite_from_id( - mbedtls_ssl_session_get_ciphersuite( session ) ) ), - session->master, 48, sender, - padbuf, 48, buf, len ); - - MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, len ); - - mbedtls_sha512_free( &sha512 ); - - mbedtls_platform_zeroize( padbuf, sizeof( padbuf ) ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc finished" ) ); -} -#endif /* MBEDTLS_SHA512_C */ -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - -MBEDTLS_ALWAYS_INLINE static inline int ssl_calc_finished( - int minor_ver, - mbedtls_md_type_t hash, - mbedtls_ssl_context *ssl, - unsigned char *buf, - int from ) -{ -#if !defined(MBEDTLS_SSL_PROTO_TLS1_2) || !defined(MBEDTLS_SHA512_C) - (void) hash; -#endif - -#if defined(MBEDTLS_SSL_PROTO_SSL3) - if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) - ssl_calc_finished_ssl( ssl, buf, from ); - else -#endif -#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) - if( mbedtls_ssl_ver_lt( minor_ver, MBEDTLS_SSL_MINOR_VERSION_3 ) ) - ssl_calc_finished_tls( ssl, buf, from ); - else -#endif -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) -#if defined(MBEDTLS_SHA512_C) - if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 && - hash == MBEDTLS_MD_SHA384 ) - { - ssl_calc_finished_tls_sha384( ssl, buf, from ); - } - else -#endif -#if defined(MBEDTLS_SHA256_C) - if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) - ssl_calc_finished_tls_sha256( ssl, buf, from ); - else +static void ssl_update_checksum_sha384( mbedtls_ssl_context *, const unsigned char *, size_t ); +static void ssl_calc_verify_tls_sha384( mbedtls_ssl_context *, unsigned char * ); +static void ssl_calc_finished_tls_sha384( mbedtls_ssl_context *, unsigned char *, int ); #endif #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - return( 0 ); -} - -/* - * Populate a transform structure with session keys and all the other - * necessary information. - * - * Parameters: - * - [in/out]: transform: structure to populate - * [in] must be just initialised with mbedtls_ssl_transform_init() - * [out] fully populated, ready for use by mbedtls_ssl_{en,de}crypt_buf() - * - [in] ciphersuite - * - [in] master - * - [in] encrypt_then_mac - * - [in] trunc_hmac - * - [in] compression - * - [in] tls_prf: pointer to PRF to use for key derivation - * - [in] randbytes: buffer holding ServerHello.random + ClientHello.random - * - [in] minor_ver: SSL/TLS minor version - * - [in] endpoint: client or server - * - [in] ssl: optionally used for: - * - MBEDTLS_SSL_HW_RECORD_ACCEL: whole context - * - MBEDTLS_SSL_EXPORT_KEYS: ssl->conf->{f,p}_export_keys - * - MBEDTLS_DEBUG_C: ssl->conf->{f,p}_dbg - */ -/* Force compilers to inline this function if it's used only - * from one place, because at least ARMC5 doesn't do that - * automatically. */ -#if !defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION) -MBEDTLS_ALWAYS_INLINE static inline -#else -static -#endif /* MBEDTLS_SSL_CONTEXT_SERIALIZATION */ -int ssl_populate_transform( mbedtls_ssl_transform *transform, - int ciphersuite, - const unsigned char master[48], -#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC) -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) - int encrypt_then_mac, -#endif -#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) - int trunc_hmac, -#endif -#endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */ -#if defined(MBEDTLS_ZLIB_SUPPORT) - int compression, -#endif - const unsigned char randbytes[64], - int minor_ver, - unsigned endpoint, -#if !defined(MBEDTLS_SSL_HW_RECORD_ACCEL) - const -#endif - mbedtls_ssl_context *ssl ) +int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl ) { int ret = 0; + unsigned char tmp[64]; unsigned char keyblk[256]; unsigned char *key1; unsigned char *key2; @@ -1428,95 +503,172 @@ int ssl_populate_transform( mbedtls_ssl_transform *transform, unsigned char *mac_dec; size_t mac_key_len; size_t iv_copy_len; - unsigned keylen; - mbedtls_ssl_ciphersuite_handle_t ciphersuite_info; const mbedtls_cipher_info_t *cipher_info; - mbedtls_md_handle_t md_info; + const mbedtls_md_info_t *md_info; -#if !defined(MBEDTLS_SSL_HW_RECORD_ACCEL) && \ - !defined(MBEDTLS_SSL_EXPORT_KEYS) && \ - !defined(MBEDTLS_DEBUG_C) && \ - !defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - ssl = NULL; /* make sure we don't use it except for those cases */ - (void) ssl; -#endif + mbedtls_ssl_session *session = ssl->session_negotiate; + mbedtls_ssl_transform *transform = ssl->transform_negotiate; + mbedtls_ssl_handshake_params *handshake = ssl->handshake; - /* - * Some data just needs copying into the structure - */ -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) && \ - defined(MBEDTLS_SSL_SOME_MODES_USE_MAC) - transform->encrypt_then_mac = encrypt_then_mac; -#endif + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> derive keys" ) ); -#if !defined(MBEDTLS_SSL_CONF_FIXED_MINOR_VER) - transform->minor_ver = minor_ver; -#else - ((void) minor_ver); -#endif /* !MBEDTLS_SSL_CONF_FIXED_MINOR_VER */ - -#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION) - mbedtls_platform_memcpy( transform->randbytes, randbytes, sizeof( transform->randbytes ) ); -#endif - - /* - * Get various info structures - */ - ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( ciphersuite ); - if( ciphersuite_info == MBEDTLS_SSL_CIPHERSUITE_INVALID_HANDLE ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "ciphersuite info for %d not found", - ciphersuite ) ); - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - } - - cipher_info = mbedtls_cipher_info_from_type( - mbedtls_ssl_suite_get_cipher( ciphersuite_info ) ); + cipher_info = mbedtls_cipher_info_from_type( transform->ciphersuite_info->cipher ); if( cipher_info == NULL ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "cipher info for %d not found", - mbedtls_ssl_suite_get_cipher( ciphersuite_info ) ) ); + transform->ciphersuite_info->cipher ) ); return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); } - md_info = mbedtls_md_info_from_type( - mbedtls_ssl_suite_get_mac( ciphersuite_info ) ); - if( md_info == MBEDTLS_MD_INVALID_HANDLE ) + md_info = mbedtls_md_info_from_type( transform->ciphersuite_info->mac ); + if( md_info == NULL ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "mbedtls_md info for %d not found", - mbedtls_ssl_suite_get_mac( ciphersuite_info ) ) ); + transform->ciphersuite_info->mac ) ); return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); } -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - /* Copy own and peer's CID if the use of the CID - * extension has been negotiated. */ - if( ssl->handshake->cid_in_use == MBEDTLS_SSL_CID_ENABLED ) + /* + * Set appropriate PRF function and other SSL / TLS / TLS1.2 functions + */ +#if defined(MBEDTLS_SSL_PROTO_SSL3) + if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "Copy CIDs into SSL transform" ) ); - - transform->in_cid_len = ssl->own_cid_len; - /* Not using more secure mbedtls_platform_memcpy as cid is public */ - memcpy( transform->in_cid, ssl->own_cid, ssl->own_cid_len ); - MBEDTLS_SSL_DEBUG_BUF( 3, "Incoming CID", transform->in_cid, - transform->in_cid_len ); - - transform->out_cid_len = ssl->handshake->peer_cid_len; - /* Not using more secure mbedtls_platform_memcpy as cid is public */ - memcpy( transform->out_cid, ssl->handshake->peer_cid, - ssl->handshake->peer_cid_len ); - MBEDTLS_SSL_DEBUG_BUF( 3, "Outgoing CID", transform->out_cid, - transform->out_cid_len ); + handshake->tls_prf = ssl3_prf; + handshake->calc_verify = ssl_calc_verify_ssl; + handshake->calc_finished = ssl_calc_finished_ssl; + } + else +#endif +#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) + if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 ) + { + handshake->tls_prf = tls1_prf; + handshake->calc_verify = ssl_calc_verify_tls; + handshake->calc_finished = ssl_calc_finished_tls; + } + else +#endif +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) +#if defined(MBEDTLS_SHA512_C) + if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 && + transform->ciphersuite_info->mac == MBEDTLS_MD_SHA384 ) + { + handshake->tls_prf = tls_prf_sha384; + handshake->calc_verify = ssl_calc_verify_tls_sha384; + handshake->calc_finished = ssl_calc_finished_tls_sha384; + } + else +#endif +#if defined(MBEDTLS_SHA256_C) + if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) + { + handshake->tls_prf = tls_prf_sha256; + handshake->calc_verify = ssl_calc_verify_tls_sha256; + handshake->calc_finished = ssl_calc_finished_tls_sha256; + } + else +#endif +#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); } -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ /* - * Compute key block using the PRF + * SSLv3: + * master = + * MD5( premaster + SHA1( 'A' + premaster + randbytes ) ) + + * MD5( premaster + SHA1( 'BB' + premaster + randbytes ) ) + + * MD5( premaster + SHA1( 'CCC' + premaster + randbytes ) ) + * + * TLSv1+: + * master = PRF( premaster, "master secret", randbytes )[0..47] */ - ret = ssl_prf( minor_ver, - mbedtls_ssl_suite_get_mac( ciphersuite_info ), - master, 48, "key expansion", randbytes, 64, - keyblk, 256 ); + if( handshake->resume == 0 ) + { + MBEDTLS_SSL_DEBUG_BUF( 3, "premaster secret", handshake->premaster, + handshake->pmslen ); + +#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) + if( ssl->handshake->extended_ms == MBEDTLS_SSL_EXTENDED_MS_ENABLED ) + { + unsigned char session_hash[48]; + size_t hash_len; + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "using extended master secret" ) ); + + ssl->handshake->calc_verify( ssl, session_hash ); + +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) + if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) + { +#if defined(MBEDTLS_SHA512_C) + if( ssl->transform_negotiate->ciphersuite_info->mac == + MBEDTLS_MD_SHA384 ) + { + hash_len = 48; + } + else +#endif + hash_len = 32; + } + else +#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ + hash_len = 36; + + MBEDTLS_SSL_DEBUG_BUF( 3, "session hash", session_hash, hash_len ); + + ret = handshake->tls_prf( handshake->premaster, handshake->pmslen, + "extended master secret", + session_hash, hash_len, + session->master, 48 ); + if( ret != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "prf", ret ); + return( ret ); + } + + } + else +#endif + ret = handshake->tls_prf( handshake->premaster, handshake->pmslen, + "master secret", + handshake->randbytes, 64, + session->master, 48 ); + if( ret != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "prf", ret ); + return( ret ); + } + + mbedtls_zeroize( handshake->premaster, sizeof(handshake->premaster) ); + } + else + MBEDTLS_SSL_DEBUG_MSG( 3, ( "no premaster (session resumed)" ) ); + + /* + * Swap the client and server random values. + */ + memcpy( tmp, handshake->randbytes, 64 ); + memcpy( handshake->randbytes, tmp + 32, 32 ); + memcpy( handshake->randbytes + 32, tmp, 32 ); + mbedtls_zeroize( tmp, sizeof( tmp ) ); + + /* + * SSLv3: + * key block = + * MD5( master + SHA1( 'A' + master + randbytes ) ) + + * MD5( master + SHA1( 'BB' + master + randbytes ) ) + + * MD5( master + SHA1( 'CCC' + master + randbytes ) ) + + * MD5( master + SHA1( 'DDDD' + master + randbytes ) ) + + * ... + * + * TLSv1: + * key block = PRF( master, "key expansion", randbytes ) + */ + ret = handshake->tls_prf( session->master, 48, "key expansion", + handshake->randbytes, 64, keyblk, 256 ); if( ret != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "prf", ret ); @@ -1524,44 +676,34 @@ int ssl_populate_transform( mbedtls_ssl_transform *transform, } MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite = %s", - mbedtls_ssl_get_ciphersuite_name( ciphersuite ) ) ); - MBEDTLS_SSL_DEBUG_BUF( 3, "master secret", master, 48 ); - MBEDTLS_SSL_DEBUG_BUF( 4, "random bytes", randbytes, 64 ); + mbedtls_ssl_get_ciphersuite_name( session->ciphersuite ) ) ); + MBEDTLS_SSL_DEBUG_BUF( 3, "master secret", session->master, 48 ); + MBEDTLS_SSL_DEBUG_BUF( 4, "random bytes", handshake->randbytes, 64 ); MBEDTLS_SSL_DEBUG_BUF( 4, "key block", keyblk, 256 ); + mbedtls_zeroize( handshake->randbytes, sizeof( handshake->randbytes ) ); + /* * Determine the appropriate key, IV and MAC length. */ - keylen = cipher_info->key_bitlen / 8; + transform->keylen = cipher_info->key_bitlen / 8; -#if defined(MBEDTLS_GCM_C) || \ - defined(MBEDTLS_CCM_C) || \ - defined(MBEDTLS_CHACHAPOLY_C) if( cipher_info->mode == MBEDTLS_MODE_GCM || - cipher_info->mode == MBEDTLS_MODE_CCM || - cipher_info->mode == MBEDTLS_MODE_CHACHAPOLY ) + cipher_info->mode == MBEDTLS_MODE_CCM ) { transform->maclen = 0; mac_key_len = 0; - transform->taglen = mbedtls_ssl_suite_get_flags( ciphersuite_info ) & - MBEDTLS_CIPHERSUITE_SHORT_TAG ? 8 : 16; - /* All modes haves 96-bit IVs; - * GCM and CCM has 4 implicit and 8 explicit bytes - * ChachaPoly has all 12 bytes implicit - */ transform->ivlen = 12; - if( cipher_info->mode == MBEDTLS_MODE_CHACHAPOLY ) - transform->fixed_ivlen = 12; - else - transform->fixed_ivlen = 4; + transform->fixed_ivlen = 4; + + /* Minimum length is expicit IV + tag */ + transform->minlen = transform->ivlen - transform->fixed_ivlen + + ( transform->ciphersuite_info->flags & + MBEDTLS_CIPHERSUITE_SHORT_TAG ? 8 : 16 ); } else -#endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C || MBEDTLS_CHACHAPOLY_C */ -#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC) - if( cipher_info->mode == MBEDTLS_MODE_STREAM || - cipher_info->mode == MBEDTLS_MODE_CBC ) { /* Initialize HMAC contexts */ if( ( ret = mbedtls_md_setup( &transform->md_ctx_enc, md_info, 1 ) ) != 0 || @@ -1581,7 +723,7 @@ int ssl_populate_transform( mbedtls_ssl_transform *transform, * (rfc 6066 page 13 or rfc 2104 section 4), * so we only need to adjust the length here. */ - if( trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_ENABLED ) + if( session->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_ENABLED ) { transform->maclen = MBEDTLS_SSL_TRUNCATED_HMAC_LEN; @@ -1596,27 +738,65 @@ int ssl_populate_transform( mbedtls_ssl_transform *transform, /* IV length */ transform->ivlen = cipher_info->iv_size; - } - else -#endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */ - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + + /* Minimum length */ + if( cipher_info->mode == MBEDTLS_MODE_STREAM ) + transform->minlen = transform->maclen; + else + { + /* + * GenericBlockCipher: + * 1. if EtM is in use: one block plus MAC + * otherwise: * first multiple of blocklen greater than maclen + * 2. IV except for SSL3 and TLS 1.0 + */ +#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) + if( session->encrypt_then_mac == MBEDTLS_SSL_ETM_ENABLED ) + { + transform->minlen = transform->maclen + + cipher_info->block_size; + } + else +#endif + { + transform->minlen = transform->maclen + + cipher_info->block_size + - transform->maclen % cipher_info->block_size; + } + +#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) + if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 || + ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_1 ) + ; /* No need to adjust minlen */ + else +#endif +#if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2) + if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_2 || + ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) + { + transform->minlen += transform->ivlen; + } + else +#endif + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } + } } - MBEDTLS_SSL_DEBUG_MSG( 3, ( "keylen: %u, ivlen: %u, maclen: %u", - (unsigned) keylen, - (unsigned) transform->ivlen, - (unsigned) transform->maclen ) ); + MBEDTLS_SSL_DEBUG_MSG( 3, ( "keylen: %d, minlen: %d, ivlen: %d, maclen: %d", + transform->keylen, transform->minlen, transform->ivlen, + transform->maclen ) ); /* * Finally setup the cipher contexts, IVs and MAC secrets. */ #if defined(MBEDTLS_SSL_CLI_C) - if( endpoint == MBEDTLS_SSL_IS_CLIENT ) + if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) { key1 = keyblk + mac_key_len * 2; - key2 = keyblk + mac_key_len * 2 + keylen; + key2 = keyblk + mac_key_len * 2 + transform->keylen; mac_enc = keyblk; mac_dec = keyblk + mac_key_len; @@ -1626,16 +806,16 @@ int ssl_populate_transform( mbedtls_ssl_transform *transform, */ iv_copy_len = ( transform->fixed_ivlen ) ? transform->fixed_ivlen : transform->ivlen; - mbedtls_platform_memcpy( transform->iv_enc, key2 + keylen, iv_copy_len ); - mbedtls_platform_memcpy( transform->iv_dec, key2 + keylen + iv_copy_len, + memcpy( transform->iv_enc, key2 + transform->keylen, iv_copy_len ); + memcpy( transform->iv_dec, key2 + transform->keylen + iv_copy_len, iv_copy_len ); } else #endif /* MBEDTLS_SSL_CLI_C */ #if defined(MBEDTLS_SSL_SRV_C) - if( endpoint == MBEDTLS_SSL_IS_SERVER ) + if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) { - key1 = keyblk + mac_key_len * 2 + keylen; + key1 = keyblk + mac_key_len * 2 + transform->keylen; key2 = keyblk + mac_key_len * 2; mac_enc = keyblk + mac_key_len; @@ -1646,8 +826,8 @@ int ssl_populate_transform( mbedtls_ssl_transform *transform, */ iv_copy_len = ( transform->fixed_ivlen ) ? transform->fixed_ivlen : transform->ivlen; - mbedtls_platform_memcpy( transform->iv_dec, key1 + keylen, iv_copy_len ); - mbedtls_platform_memcpy( transform->iv_enc, key1 + keylen + iv_copy_len, + memcpy( transform->iv_dec, key1 + transform->keylen, iv_copy_len ); + memcpy( transform->iv_enc, key1 + transform->keylen + iv_copy_len, iv_copy_len ); } else @@ -1657,24 +837,23 @@ int ssl_populate_transform( mbedtls_ssl_transform *transform, return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); } -#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC) #if defined(MBEDTLS_SSL_PROTO_SSL3) - if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) + if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) { - if( mac_key_len > sizeof( transform->mac_enc ) ) + if( mac_key_len > sizeof transform->mac_enc ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); } - mbedtls_platform_memcpy( transform->mac_enc, mac_enc, mac_key_len ); - mbedtls_platform_memcpy( transform->mac_dec, mac_dec, mac_key_len ); + memcpy( transform->mac_enc, mac_enc, mac_key_len ); + memcpy( transform->mac_dec, mac_dec, mac_key_len ); } else #endif /* MBEDTLS_SSL_PROTO_SSL3 */ #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( mbedtls_ssl_ver_geq( minor_ver, MBEDTLS_SSL_MINOR_VERSION_1 ) ) + if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 ) { /* For HMAC-based ciphersuites, initialize the HMAC transforms. For AEAD-based ciphersuites, there is nothing to do here. */ @@ -1690,14 +869,15 @@ int ssl_populate_transform( mbedtls_ssl_transform *transform, MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); } -#endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */ #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) if( mbedtls_ssl_hw_record_init != NULL ) { + int ret = 0; + MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_init()" ) ); - if( ( ret = mbedtls_ssl_hw_record_init( ssl, key1, key2, keylen, + if( ( ret = mbedtls_ssl_hw_record_init( ssl, key1, key2, transform->keylen, transform->iv_enc, transform->iv_dec, iv_copy_len, mac_enc, mac_dec, @@ -1707,45 +887,18 @@ int ssl_populate_transform( mbedtls_ssl_transform *transform, return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); } } -#else - ((void) mac_dec); - ((void) mac_enc); #endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */ #if defined(MBEDTLS_SSL_EXPORT_KEYS) if( ssl->conf->f_export_keys != NULL ) { ssl->conf->f_export_keys( ssl->conf->p_export_keys, - master, keyblk, - mac_key_len, keylen, + session->master, keyblk, + mac_key_len, transform->keylen, iv_copy_len ); } #endif -#if defined(MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS) - if( ( ret = mbedtls_cipher_setup( &transform->cipher_ctx, - cipher_info ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setup", ret ); - return( ret ); - } - transform->key_enc = mbedtls_calloc( 1, cipher_info->key_bitlen >> 3 ); - transform->key_dec = mbedtls_calloc( 1, cipher_info->key_bitlen >> 3 ); - if( transform->key_enc == NULL || transform->key_dec == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "Failed to allocate cipher keys" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - memcpy( transform->key_enc, key1, cipher_info->key_bitlen >> 3 ); - memcpy( transform->key_dec, key2, cipher_info->key_bitlen >> 3 ); - - transform->key_bitlen = cipher_info->key_bitlen; -#if defined(MBEDTLS_VALIDATE_SSL_KEYS_INTEGRITY) - transform->key_enc_hash = mbedtls_hash( transform->key_enc, transform->key_bitlen >> 3 ); - transform->key_dec_hash = mbedtls_hash( transform->key_dec, transform->key_bitlen >> 3 ); -#endif - -#else if( ( ret = mbedtls_cipher_setup( &transform->cipher_ctx_enc, cipher_info ) ) != 0 ) { @@ -1775,18 +928,10 @@ int ssl_populate_transform( mbedtls_ssl_transform *transform, MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setkey", ret ); return( ret ); } -#endif + #if defined(MBEDTLS_CIPHER_MODE_CBC) if( cipher_info->mode == MBEDTLS_MODE_CBC ) { -#if defined(MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS) - if( ( ret = mbedtls_cipher_set_padding_mode( &transform->cipher_ctx, - MBEDTLS_PADDING_NONE ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_set_padding_mode", ret ); - return( ret ); - } -#else if( ( ret = mbedtls_cipher_set_padding_mode( &transform->cipher_ctx_enc, MBEDTLS_PADDING_NONE ) ) != 0 ) { @@ -1800,20 +945,32 @@ int ssl_populate_transform( mbedtls_ssl_transform *transform, MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_set_padding_mode", ret ); return( ret ); } -#endif } #endif /* MBEDTLS_CIPHER_MODE_CBC */ - mbedtls_platform_zeroize( keyblk, sizeof( keyblk ) ); + mbedtls_zeroize( keyblk, sizeof( keyblk ) ); - /* Initialize Zlib contexts */ #if defined(MBEDTLS_ZLIB_SUPPORT) - if( compression == MBEDTLS_SSL_COMPRESS_DEFLATE ) + // Initialize compression + // + if( session->compression == MBEDTLS_SSL_COMPRESS_DEFLATE ) { + if( ssl->compress_buf == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 3, ( "Allocating compression buffer" ) ); + ssl->compress_buf = mbedtls_calloc( 1, MBEDTLS_SSL_BUFFER_LEN ); + if( ssl->compress_buf == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed", + MBEDTLS_SSL_BUFFER_LEN ) ); + return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); + } + } + MBEDTLS_SSL_DEBUG_MSG( 3, ( "Initializing zlib states" ) ); - mbedtls_platform_memset( &transform->ctx_deflate, 0, sizeof( transform->ctx_deflate ) ); - mbedtls_platform_memset( &transform->ctx_inflate, 0, sizeof( transform->ctx_inflate ) ); + memset( &transform->ctx_deflate, 0, sizeof( transform->ctx_deflate ) ); + memset( &transform->ctx_inflate, 0, sizeof( transform->ctx_inflate ) ); if( deflateInit( &transform->ctx_deflate, Z_DEFAULT_COMPRESSION ) != Z_OK || @@ -1825,13 +982,13 @@ int ssl_populate_transform( mbedtls_ssl_transform *transform, } #endif /* MBEDTLS_ZLIB_SUPPORT */ + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= derive keys" ) ); + return( 0 ); } #if defined(MBEDTLS_SSL_PROTO_SSL3) -static inline void ssl_calc_verify_ssl( const mbedtls_ssl_context *ssl, - unsigned char hash[36], - size_t *hlen ) +void ssl_calc_verify_ssl( mbedtls_ssl_context *ssl, unsigned char hash[36] ) { mbedtls_md5_context md5; mbedtls_sha1_context sha1; @@ -1846,8 +1003,8 @@ static inline void ssl_calc_verify_ssl( const mbedtls_ssl_context *ssl, mbedtls_md5_clone( &md5, &ssl->handshake->fin_md5 ); mbedtls_sha1_clone( &sha1, &ssl->handshake->fin_sha1 ); - mbedtls_platform_memset( pad_1, 0x36, 48 ); - mbedtls_platform_memset( pad_2, 0x5C, 48 ); + memset( pad_1, 0x36, 48 ); + memset( pad_2, 0x5C, 48 ); mbedtls_md5_update_ret( &md5, ssl->session_negotiate->master, 48 ); mbedtls_md5_update_ret( &md5, pad_1, 48 ); @@ -1869,9 +1026,7 @@ static inline void ssl_calc_verify_ssl( const mbedtls_ssl_context *ssl, mbedtls_sha1_update_ret( &sha1, hash + 16, 20 ); mbedtls_sha1_finish_ret( &sha1, hash + 16 ); - *hlen = 36; - - MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, *hlen ); + MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, 36 ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) ); mbedtls_md5_free( &md5 ); @@ -1882,9 +1037,7 @@ static inline void ssl_calc_verify_ssl( const mbedtls_ssl_context *ssl, #endif /* MBEDTLS_SSL_PROTO_SSL3 */ #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) -static inline void ssl_calc_verify_tls( const mbedtls_ssl_context *ssl, - unsigned char hash[36], - size_t *hlen ) +void ssl_calc_verify_tls( mbedtls_ssl_context *ssl, unsigned char hash[36] ) { mbedtls_md5_context md5; mbedtls_sha1_context sha1; @@ -1900,9 +1053,7 @@ static inline void ssl_calc_verify_tls( const mbedtls_ssl_context *ssl, mbedtls_md5_finish_ret( &md5, hash ); mbedtls_sha1_finish_ret( &sha1, hash + 16 ); - *hlen = 36; - - MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, *hlen ); + MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, 36 ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) ); mbedtls_md5_free( &md5 ); @@ -1914,9 +1065,7 @@ static inline void ssl_calc_verify_tls( const mbedtls_ssl_context *ssl, #if defined(MBEDTLS_SSL_PROTO_TLS1_2) #if defined(MBEDTLS_SHA256_C) -static inline void ssl_calc_verify_tls_sha256( const mbedtls_ssl_context *ssl, - unsigned char hash[32], - size_t *hlen ) +void ssl_calc_verify_tls_sha256( mbedtls_ssl_context *ssl, unsigned char hash[32] ) { mbedtls_sha256_context sha256; @@ -1927,9 +1076,7 @@ static inline void ssl_calc_verify_tls_sha256( const mbedtls_ssl_context *ssl, mbedtls_sha256_clone( &sha256, &ssl->handshake->fin_sha256 ); mbedtls_sha256_finish_ret( &sha256, hash ); - *hlen = 32; - - MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, *hlen ); + MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, 32 ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) ); mbedtls_sha256_free( &sha256 ); @@ -1939,9 +1086,7 @@ static inline void ssl_calc_verify_tls_sha256( const mbedtls_ssl_context *ssl, #endif /* MBEDTLS_SHA256_C */ #if defined(MBEDTLS_SHA512_C) -static inline void ssl_calc_verify_tls_sha384( const mbedtls_ssl_context *ssl, - unsigned char hash[48], - size_t *hlen ) +void ssl_calc_verify_tls_sha384( mbedtls_ssl_context *ssl, unsigned char hash[48] ) { mbedtls_sha512_context sha512; @@ -1952,9 +1097,7 @@ static inline void ssl_calc_verify_tls_sha384( const mbedtls_ssl_context *ssl, mbedtls_sha512_clone( &sha512, &ssl->handshake->fin_sha512 ); mbedtls_sha512_finish_ret( &sha512, hash ); - *hlen = 48; - - MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, *hlen ); + MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, 48 ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) ); mbedtls_sha512_free( &sha512 ); @@ -1964,405 +1107,6 @@ static inline void ssl_calc_verify_tls_sha384( const mbedtls_ssl_context *ssl, #endif /* MBEDTLS_SHA512_C */ #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ -int mbedtls_ssl_calc_verify( int minor_ver, - mbedtls_md_type_t hash, - mbedtls_ssl_context const *ssl, - unsigned char *dst, - size_t *hlen ) -{ -#if !defined(MBEDTLS_SSL_PROTO_TLS1_2) || !defined(MBEDTLS_SHA512_C) - (void) hash; -#endif - -#if defined(MBEDTLS_SSL_PROTO_SSL3) - if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) - ssl_calc_verify_ssl( ssl, dst, hlen ); - else -#endif -#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) - if( mbedtls_ssl_ver_lt( minor_ver, MBEDTLS_SSL_MINOR_VERSION_3 ) ) - ssl_calc_verify_tls( ssl, dst, hlen ); - else -#endif -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) -#if defined(MBEDTLS_SHA512_C) - if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 && - hash == MBEDTLS_MD_SHA384 ) - { - ssl_calc_verify_tls_sha384( ssl, dst, hlen ); - } - else -#endif -#if defined(MBEDTLS_SHA256_C) - if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) - { - ssl_calc_verify_tls_sha256( ssl, dst, hlen ); - } - else -#endif -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - { - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - return( 0 ); -} - -/* - * Compute master secret if needed - * - * Parameters: - * [in/out] handshake - * [in] resume, premaster, extended_ms, calc_verify, tls_prf - * [out] premaster (cleared) - * [out] master - * [in] ssl: optionally used for debugging and calc_verify - */ -static int ssl_compute_master( mbedtls_ssl_handshake_params *handshake, - unsigned char *master, - const mbedtls_ssl_context *ssl ) -{ - int ret; - -/* #if !defined(MBEDTLS_DEBUG_C) && !defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) */ -/* ssl = NULL; /\* make sure we don't use it except for debug and EMS *\/ */ -/* (void) ssl; */ -/* #endif */ - - mbedtls_ssl_ciphersuite_handle_t const ciphersuite = - mbedtls_ssl_handshake_get_ciphersuite( handshake ); - -#if !defined(MBEDTLS_SSL_NO_SESSION_RESUMPTION) - if( handshake->resume == MBEDTLS_SSL_FI_FLAG_SET ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "no premaster (session resumed)" ) ); - return( 0 ); - } -#endif /* !MBEDTLS_SSL_NO_SESSION_RESUMPTION */ - - MBEDTLS_SSL_DEBUG_BUF( 3, "premaster secret", handshake->premaster, - handshake->pmslen ); - -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) - if( mbedtls_ssl_hs_get_extended_ms( handshake ) - == MBEDTLS_SSL_EXTENDED_MS_ENABLED ) - { - unsigned char session_hash[48]; - size_t hash_len; - - mbedtls_ssl_calc_verify( - mbedtls_ssl_get_minor_ver( ssl ), - mbedtls_ssl_suite_get_mac( ciphersuite ), - ssl, session_hash, &hash_len ); - - MBEDTLS_SSL_DEBUG_BUF( 3, "session hash for extended master secret", - session_hash, hash_len ); - - ret = ssl_prf( mbedtls_ssl_get_minor_ver( ssl ), - mbedtls_ssl_suite_get_mac( ciphersuite ), - handshake->premaster, handshake->pmslen, - "extended master secret", - session_hash, hash_len, - master, 48 ); - } - else -#endif - { - ret = ssl_prf( mbedtls_ssl_get_minor_ver( ssl ), - mbedtls_ssl_suite_get_mac( ciphersuite ), - handshake->premaster, handshake->pmslen, - "master secret", - handshake->randbytes, 64, - master, 48 ); - } - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "prf", ret ); - return( ret ); - } - - if( handshake->premaster == mbedtls_platform_zeroize( - handshake->premaster, sizeof(handshake->premaster) ) ) - { - return( 0 ); - } - - return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); -} - -int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl ) -{ - volatile int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> derive keys" ) ); - ssl->handshake->key_derivation_done = MBEDTLS_SSL_FI_FLAG_UNSET; - /* Compute master secret if needed */ - ret = ssl_compute_master( ssl->handshake, - ssl->session_negotiate->master, - ssl ); - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "ssl_compute_master", ret ); - return( ret ); - } - - /* Swap the client and server random values: - * - MS derivation wanted client+server (RFC 5246 8.1) - * - key derivation wants server+client (RFC 5246 6.3) */ - { - unsigned char tmp[64]; - mbedtls_platform_memcpy( tmp, ssl->handshake->randbytes, 64 ); - mbedtls_platform_memcpy( ssl->handshake->randbytes, tmp + 32, 32 ); - mbedtls_platform_memcpy( ssl->handshake->randbytes + 32, tmp, 32 ); - mbedtls_platform_zeroize( tmp, sizeof( tmp ) ); - } - - /* Populate transform structure */ - ret = ssl_populate_transform( ssl->transform_negotiate, - mbedtls_ssl_session_get_ciphersuite( ssl->session_negotiate ), - ssl->session_negotiate->master, -#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC) -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) - ssl->session_negotiate->encrypt_then_mac, -#endif -#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) - ssl->session_negotiate->trunc_hmac, -#endif -#endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */ -#if defined(MBEDTLS_ZLIB_SUPPORT) - ssl->session_negotiate->compression, -#endif - ssl->handshake->randbytes, - mbedtls_ssl_get_minor_ver( ssl ), - mbedtls_ssl_conf_get_endpoint( ssl->conf ), - ssl ); - if( ret == 0 ) - { - mbedtls_platform_random_delay(); - if( ret == 0 ) - { - ssl->handshake->key_derivation_done = MBEDTLS_SSL_FI_FLAG_SET; - } - else - { - return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); - } - } - else - { - MBEDTLS_SSL_DEBUG_RET( 1, "ssl_populate_transform", ret ); - return( ret ); - } - - /* We no longer need Server/ClientHello.random values */ - mbedtls_platform_zeroize( ssl->handshake->randbytes, - sizeof( ssl->handshake->randbytes ) ); - - /* Allocate compression buffer */ -#if defined(MBEDTLS_ZLIB_SUPPORT) - if( ssl->session_negotiate->compression == MBEDTLS_SSL_COMPRESS_DEFLATE && - ssl->compress_buf == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "Allocating compression buffer" ) ); - ssl->compress_buf = mbedtls_calloc( 1, MBEDTLS_SSL_COMPRESS_BUFFER_LEN ); - if( ssl->compress_buf == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed", - MBEDTLS_SSL_COMPRESS_BUFFER_LEN ) ); - return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); - } - } -#endif - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= derive keys" ) ); - - return( 0 ); -} - -int mbedtls_ssl_build_pms( mbedtls_ssl_context *ssl ) -{ - volatile int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; - - mbedtls_ssl_ciphersuite_handle_t ciphersuite_info = - mbedtls_ssl_handshake_get_ciphersuite( ssl->handshake ); -#if defined(MBEDTLS_USE_TINYCRYPT) - if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA || - mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA || - mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_ECDH_RSA || - mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA ) - { - ret = uECC_shared_secret( ssl->handshake->ecdh_peerkey, - ssl->handshake->ecdh_privkey, - ssl->handshake->premaster ); - if( ret == UECC_FAULT_DETECTED ) - return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); - if( ret != UECC_SUCCESS ) - return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); - ssl->handshake->premaster_generated = MBEDTLS_SSL_FI_FLAG_SET; - - ssl->handshake->pmslen = NUM_ECC_BYTES; - } - else -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) - if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_DHE_RSA ) - { - ret = mbedtls_dhm_calc_secret( &ssl->handshake->dhm_ctx, - ssl->handshake->premaster, - MBEDTLS_PREMASTER_SIZE, - &ssl->handshake->pmslen, - mbedtls_ssl_conf_get_frng( ssl->conf ), - mbedtls_ssl_conf_get_prng( ssl->conf ) ); - if( ret == 0 ) - { - mbedtls_platform_random_delay(); - if( ret == 0 ) - { - ssl->handshake->premaster_generated = MBEDTLS_SSL_FI_FLAG_SET; - } - else - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_calc_secret", - MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); - return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); - } - } - else - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_calc_secret", ret ); - return( ret ); - } - - MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->handshake->dhm_ctx.K ); - } - else -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */ -#if defined(MBEDTLS_ECDH_C) && \ - ( defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) ) - if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA || - mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA || - mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_ECDH_RSA || - mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA ) - { - ret = mbedtls_ecdh_calc_secret( &ssl->handshake->ecdh_ctx, - &ssl->handshake->pmslen, - ssl->handshake->premaster, - MBEDTLS_MPI_MAX_SIZE, - mbedtls_ssl_conf_get_frng( ssl->conf ), - mbedtls_ssl_conf_get_prng( ssl->conf ) ); - if( ret == 0 ) - { - mbedtls_platform_random_delay(); - if( ret == 0 ) - { - ssl->handshake->premaster_generated = MBEDTLS_SSL_FI_FLAG_SET; - } - else - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_calc_secret", ret ); - return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); - } - } - else - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_calc_secret", ret ); - return( ret ); - } - - MBEDTLS_SSL_DEBUG_MPI( 3, "ECDH: z", &ssl->handshake->ecdh_ctx.z ); - } - else -#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) - if( mbedtls_ssl_ciphersuite_uses_psk( ciphersuite_info ) ) - { - ret = mbedtls_ssl_psk_derive_premaster( ssl, - mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) ); - if( ret == 0 ) - { - mbedtls_platform_random_delay(); - if( ret == 0 ) - { - ssl->handshake->premaster_generated = MBEDTLS_SSL_FI_FLAG_SET; - } - else - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_psk_derive_premaster", ret ); - return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); - } - } - else - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_psk_derive_premaster", ret ); - return( ret ); - } - } - else -#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) == - MBEDTLS_KEY_EXCHANGE_ECJPAKE ) - { - ret = mbedtls_ecjpake_derive_secret( &ssl->handshake->ecjpake_ctx, - ssl->handshake->premaster, 32, &ssl->handshake->pmslen, - mbedtls_ssl_conf_get_frng( ssl->conf ), - mbedtls_ssl_conf_get_prng( ssl->conf ) ); - if( ret == 0 ) - { - mbedtls_platform_random_delay(); - if( ret == 0 ) - { - ssl->handshake->premaster_generated = MBEDTLS_SSL_FI_FLAG_SET; - } - else - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_derive_secret", ret ); - return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); - } - } - else - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_derive_secret", ret ); - return( ret ); - } - } - else -#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) - if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_RSA ) - { - ((void) ret); - /* The premaster secret has already been set by - * ssl_rsa_generate_partial_pms(). Only the - * PMS length needs to be set. */ - ssl->handshake->pmslen = 48; - } - else -#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - return( 0 ); -} - #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl, mbedtls_key_exchange_type_t key_ex ) { @@ -2391,12 +1135,13 @@ int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl, mbedtls_key_exch if( end - p < 2 ) return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - p = mbedtls_platform_put_uint16_be( p, psk_len ); + *(p++) = (unsigned char)( psk_len >> 8 ); + *(p++) = (unsigned char)( psk_len ); if( end < p || (size_t)( end - p ) < psk_len ) return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - mbedtls_platform_memset( p, 0, psk_len ); + memset( p, 0, psk_len ); p += psk_len; } else @@ -2426,13 +1171,13 @@ int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl, mbedtls_key_exch /* Write length only when we know the actual value */ if( ( ret = mbedtls_dhm_calc_secret( &ssl->handshake->dhm_ctx, p + 2, end - ( p + 2 ), &len, - mbedtls_ssl_conf_get_frng( ssl->conf ), - mbedtls_ssl_conf_get_prng( ssl->conf ) ) ) != 0 ) + ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_calc_secret", ret ); return( ret ); } - p = mbedtls_platform_put_uint16_be( p, len ); + *(p++) = (unsigned char)( len >> 8 ); + *(p++) = (unsigned char)( len ); p += len; MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->handshake->dhm_ctx.K ); @@ -2445,32 +1190,19 @@ int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl, mbedtls_key_exch int ret; size_t zlen; -#if defined(MBEDTLS_USE_TINYCRYPT) - ret = uECC_shared_secret( ssl->handshake->ecdh_peerkey, - ssl->handshake->ecdh_privkey, - p + 2 ); - if( ret == UECC_FAULT_DETECTED ) - return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); - if( ret != UECC_SUCCESS ) - return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); - - zlen = NUM_ECC_BYTES; -#else /* MBEDTLS_USE_TINYCRYPT */ if( ( ret = mbedtls_ecdh_calc_secret( &ssl->handshake->ecdh_ctx, &zlen, p + 2, end - ( p + 2 ), - mbedtls_ssl_conf_get_frng( ssl->conf ), - mbedtls_ssl_conf_get_prng( ssl->conf ) ) ) != 0 ) + ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_calc_secret", ret ); return( ret ); } - MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx, - MBEDTLS_DEBUG_ECDH_Z ); -#endif /* MBEDTLS_USE_TINYCRYPT */ - - p = mbedtls_platform_put_uint16_be( p, zlen ); + *(p++) = (unsigned char)( zlen >> 8 ); + *(p++) = (unsigned char)( zlen ); p += zlen; + + MBEDTLS_SSL_DEBUG_MPI( 3, "ECDH: z", &ssl->handshake->ecdh_ctx.z ); } else #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ @@ -2483,21 +1215,17 @@ int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl, mbedtls_key_exch if( end - p < 2 ) return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - p = mbedtls_platform_put_uint16_be( p, psk_len ); + *(p++) = (unsigned char)( psk_len >> 8 ); + *(p++) = (unsigned char)( psk_len ); if( end < p || (size_t)( end - p ) < psk_len ) return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - if( mbedtls_platform_memcpy( p, psk, psk_len ) != p ) - { - return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); - } + memcpy( p, psk, psk_len ); p += psk_len; ssl->handshake->pmslen = p - ssl->handshake->premaster; - ssl->handshake->premaster_generated = MBEDTLS_SSL_FI_FLAG_SET; - return( 0 ); } #endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ @@ -2525,11 +1253,12 @@ static void ssl_mac( mbedtls_md_context_t *md_ctx, else padlen = 40; - mbedtls_platform_memcpy( header, ctr, 8 ); - header[8] = (unsigned char) type; - (void)mbedtls_platform_put_uint16_be( &header[9], len ); + memcpy( header, ctr, 8 ); + header[ 8] = (unsigned char) type; + header[ 9] = (unsigned char)( len >> 8 ); + header[10] = (unsigned char)( len ); - mbedtls_platform_memset( padding, 0x36, padlen ); + memset( padding, 0x36, padlen ); mbedtls_md_starts( md_ctx ); mbedtls_md_update( md_ctx, secret, md_size ); mbedtls_md_update( md_ctx, padding, padlen ); @@ -2537,7 +1266,7 @@ static void ssl_mac( mbedtls_md_context_t *md_ctx, mbedtls_md_update( md_ctx, buf, len ); mbedtls_md_finish( md_ctx, out ); - mbedtls_platform_memset( padding, 0x5C, padlen ); + memset( padding, 0x5C, padlen ); mbedtls_md_starts( md_ctx ); mbedtls_md_update( md_ctx, secret, md_size ); mbedtls_md_update( md_ctx, padding, padlen ); @@ -2546,9 +1275,15 @@ static void ssl_mac( mbedtls_md_context_t *md_ctx, } #endif /* MBEDTLS_SSL_PROTO_SSL3 */ +#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER) || \ + ( defined(MBEDTLS_CIPHER_MODE_CBC) && \ + ( defined(MBEDTLS_AES_C) || defined(MBEDTLS_CAMELLIA_C) ) ) +#define SSL_SOME_MODES_USE_MAC +#endif + /* The function below is only used in the Lucky 13 counter-measure in - * mbedtls_ssl_decrypt_buf(). These are the defines that guard the call site. */ -#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC) && \ + * ssl_decrypt_buf(). These are the defines that guard the call site. */ +#if defined(SSL_SOME_MODES_USE_MAC) && \ ( defined(MBEDTLS_SSL_PROTO_TLS1) || \ defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ defined(MBEDTLS_SSL_PROTO_TLS1_2) ) @@ -2570,273 +1305,73 @@ static void ssl_read_memory( unsigned char *p, size_t len ) /* * Encryption/decryption functions */ - -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) -/* This functions transforms a DTLS plaintext fragment and a record content - * type into an instance of the DTLSInnerPlaintext structure: - * - * struct { - * opaque content[DTLSPlaintext.length]; - * ContentType real_type; - * uint8 zeros[length_of_padding]; - * } DTLSInnerPlaintext; - * - * Input: - * - `content`: The beginning of the buffer holding the - * plaintext to be wrapped. - * - `*content_size`: The length of the plaintext in Bytes. - * - `max_len`: The number of Bytes available starting from - * `content`. This must be `>= *content_size`. - * - `rec_type`: The desired record content type. - * - * Output: - * - `content`: The beginning of the resulting DTLSInnerPlaintext structure. - * - `*content_size`: The length of the resulting DTLSInnerPlaintext structure. - * - * Returns: - * - `0` on success. - * - A negative error code if `max_len` didn't offer enough space - * for the expansion. - */ -static int ssl_cid_build_inner_plaintext( unsigned char *content, - size_t *content_size, - size_t remaining, - uint8_t rec_type ) -{ - size_t len = *content_size; - size_t pad = ( MBEDTLS_SSL_CID_PADDING_GRANULARITY - - ( len + 1 ) % MBEDTLS_SSL_CID_PADDING_GRANULARITY ) % - MBEDTLS_SSL_CID_PADDING_GRANULARITY; - - /* Write real content type */ - if( remaining == 0 ) - return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); - content[ len ] = rec_type; - len++; - remaining--; - - if( remaining < pad ) - return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); - mbedtls_platform_memset( content + len, 0, pad ); - len += pad; - remaining -= pad; - - *content_size = len; - return( 0 ); -} - -/* This function parses a DTLSInnerPlaintext structure. - * See ssl_cid_build_inner_plaintext() for details. */ -static int ssl_cid_parse_inner_plaintext( unsigned char const *content, - size_t *content_size, - uint8_t *rec_type ) -{ - size_t remaining = *content_size; - - /* Determine length of padding by skipping zeroes from the back. */ - do - { - if( remaining == 0 ) - return( -1 ); - remaining--; - } while( content[ remaining ] == 0 ); - - *content_size = remaining; - *rec_type = content[ remaining ]; - - return( 0 ); -} -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - -/* `add_data` must have size 13 Bytes if the CID extension is disabled, - * and 13 + 1 + CID-length Bytes if the CID extension is enabled. */ -static void ssl_extract_add_data_from_record( unsigned char* add_data, - size_t *add_data_len, - mbedtls_record *rec ) -{ - /* Quoting RFC 5246 (TLS 1.2): - * - * additional_data = seq_num + TLSCompressed.type + - * TLSCompressed.version + TLSCompressed.length; - * - * For the CID extension, this is extended as follows - * (quoting draft-ietf-tls-dtls-connection-id-05, - * https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05): - * - * additional_data = seq_num + DTLSPlaintext.type + - * DTLSPlaintext.version + - * cid + - * cid_length + - * length_of_DTLSInnerPlaintext; - */ - - mbedtls_platform_memcpy( add_data, rec->ctr, sizeof( rec->ctr ) ); - add_data[8] = rec->type; - mbedtls_platform_memcpy( add_data + 9, rec->ver, sizeof( rec->ver ) ); - -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - if( rec->cid_len != 0 ) - { - mbedtls_platform_memcpy( add_data + 11, rec->cid, rec->cid_len ); - add_data[11 + rec->cid_len + 0] = rec->cid_len; - (void)mbedtls_platform_put_uint16_be( &add_data[11 + rec->cid_len + 1], - rec->data_len ); - *add_data_len = 13 + 1 + rec->cid_len; - } - else -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - { - (void)mbedtls_platform_put_uint16_be( &add_data[11], rec->data_len ); - *add_data_len = 13; - } -} - -int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl, - mbedtls_ssl_transform *transform, - mbedtls_record *rec, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) +static int ssl_encrypt_buf( mbedtls_ssl_context *ssl ) { mbedtls_cipher_mode_t mode; int auth_done = 0; - unsigned char * data; - unsigned char add_data[13 + 1 + MBEDTLS_SSL_CID_OUT_LEN_MAX ]; - size_t add_data_len; - size_t post_avail; - int encryption_status = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; - - /* The SSL context is only used for debugging purposes! */ -#if !defined(MBEDTLS_DEBUG_C) - ssl = NULL; /* make sure we don't use it except for debug */ - ((void) ssl); -#endif - - /* The PRNG is used for dynamic IV generation that's used - * for CBC transformations in TLS 1.1 and TLS 1.2. */ -#if !( defined(MBEDTLS_CIPHER_MODE_CBC) && \ - ( defined(MBEDTLS_AES_C) || \ - defined(MBEDTLS_ARIA_C) || \ - defined(MBEDTLS_CAMELLIA_C) ) && \ - ( defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2) ) ) - ((void) f_rng); - ((void) p_rng); -#endif MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> encrypt buf" ) ); - if( transform == NULL ) + if( ssl->session_out == NULL || ssl->transform_out == NULL ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "no transform provided to encrypt_buf" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - if( rec == NULL - || rec->buf == NULL - || rec->buf_len < rec->data_offset - || rec->buf_len - rec->data_offset < rec->data_len -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - || rec->cid_len != 0 -#endif - ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad record structure provided to encrypt_buf" ) ); + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); } - data = rec->buf + rec->data_offset; - post_avail = rec->buf_len - ( rec->data_len + rec->data_offset ); + mode = mbedtls_cipher_get_cipher_mode( &ssl->transform_out->cipher_ctx_enc ); + MBEDTLS_SSL_DEBUG_BUF( 4, "before encrypt: output payload", - data, rec->data_len ); -#if defined(MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS) - mode = mbedtls_cipher_get_cipher_mode( &transform->cipher_ctx ); -#else - mode = mbedtls_cipher_get_cipher_mode( &transform->cipher_ctx_enc ); -#endif - if( rec->data_len > MBEDTLS_SSL_OUT_CONTENT_LEN ) + ssl->out_msg, ssl->out_msglen ); + + if( ssl->out_msglen > MBEDTLS_SSL_MAX_CONTENT_LEN ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "Record content %u too large, maximum %d", - (unsigned) rec->data_len, - MBEDTLS_SSL_OUT_CONTENT_LEN ) ); + (unsigned) ssl->out_msglen, + MBEDTLS_SSL_MAX_CONTENT_LEN ) ); return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); } -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - /* - * Add CID information - */ - rec->cid_len = transform->out_cid_len; - /* Not using more secure mbedtls_platform_memcpy as cid is public */ - memcpy( rec->cid, transform->out_cid, transform->out_cid_len ); - MBEDTLS_SSL_DEBUG_BUF( 3, "CID", rec->cid, rec->cid_len ); - if( rec->cid_len != 0 ) - { - int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; - /* - * Wrap plaintext into DTLSInnerPlaintext structure. - * See ssl_cid_build_inner_plaintext() for more information. - * - * Note that this changes `rec->data_len`, and hence - * `post_avail` needs to be recalculated afterwards. - */ - if( ( ret = ssl_cid_build_inner_plaintext( data, - &rec->data_len, - post_avail, - rec->type ) ) != 0 ) - { - return( ret ); - } - - rec->type = MBEDTLS_SSL_MSG_CID; - } -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - - post_avail = rec->buf_len - ( rec->data_len + rec->data_offset ); - /* * Add MAC before if needed */ -#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC) +#if defined(SSL_SOME_MODES_USE_MAC) if( mode == MBEDTLS_MODE_STREAM || ( mode == MBEDTLS_MODE_CBC #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) - && transform->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED + && ssl->session_out->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED #endif ) ) { - if( post_avail < transform->maclen ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "Buffer provided for encrypted record not large enough" ) ); - return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); - } - #if defined(MBEDTLS_SSL_PROTO_SSL3) - if( mbedtls_ssl_transform_get_minor_ver( transform ) == - MBEDTLS_SSL_MINOR_VERSION_0 ) + if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) { unsigned char mac[SSL_MAC_MAX_BYTES]; - ssl_mac( &transform->md_ctx_enc, transform->mac_enc, - data, rec->data_len, rec->ctr, rec->type, mac ); - mbedtls_platform_memcpy( data + rec->data_len, mac, transform->maclen ); + + ssl_mac( &ssl->transform_out->md_ctx_enc, + ssl->transform_out->mac_enc, + ssl->out_msg, ssl->out_msglen, + ssl->out_ctr, ssl->out_msgtype, + mac ); + + memcpy( ssl->out_msg + ssl->out_msglen, mac, ssl->transform_out->maclen ); } else #endif #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( mbedtls_ssl_ver_geq( - mbedtls_ssl_transform_get_minor_ver( transform ), - MBEDTLS_SSL_MINOR_VERSION_1 ) ) + if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 ) { unsigned char mac[MBEDTLS_SSL_MAC_ADD]; - ssl_extract_add_data_from_record( add_data, &add_data_len, rec ); + mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, ssl->out_ctr, 8 ); + mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, ssl->out_hdr, 3 ); + mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, ssl->out_len, 2 ); + mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, + ssl->out_msg, ssl->out_msglen ); + mbedtls_md_hmac_finish( &ssl->transform_out->md_ctx_enc, mac ); + mbedtls_md_hmac_reset( &ssl->transform_out->md_ctx_enc ); - mbedtls_md_hmac_update( &transform->md_ctx_enc, add_data, - add_data_len ); - mbedtls_md_hmac_update( &transform->md_ctx_enc, - data, rec->data_len ); - mbedtls_md_hmac_finish( &transform->md_ctx_enc, mac ); - mbedtls_md_hmac_reset( &transform->md_ctx_enc ); - - mbedtls_platform_memcpy( data + rec->data_len, mac, transform->maclen ); + memcpy( ssl->out_msg + ssl->out_msglen, mac, ssl->transform_out->maclen ); } else #endif @@ -2845,14 +1380,14 @@ int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl, return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); } - MBEDTLS_SSL_DEBUG_BUF( 4, "computed mac", data + rec->data_len, - transform->maclen ); + MBEDTLS_SSL_DEBUG_BUF( 4, "computed mac", + ssl->out_msg + ssl->out_msglen, + ssl->transform_out->maclen ); - rec->data_len += transform->maclen; - post_avail -= transform->maclen; + ssl->out_msglen += ssl->transform_out->maclen; auth_done++; } -#endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */ +#endif /* AEAD not the only option */ /* * Encrypt @@ -2861,37 +1396,23 @@ int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl, if( mode == MBEDTLS_MODE_STREAM ) { int ret; - size_t olen; + size_t olen = 0; + MBEDTLS_SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, " - "including %d bytes of padding", - rec->data_len, 0 ) ); -#if defined(MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS) - if( ( ret = mbedtls_ssl_switch_key( transform, MBEDTLS_ENCRYPT ) ) - != 0 ) + "including %d bytes of padding", + ssl->out_msglen, 0 ) ); + + if( ( ret = mbedtls_cipher_crypt( &ssl->transform_out->cipher_ctx_enc, + ssl->transform_out->iv_enc, + ssl->transform_out->ivlen, + ssl->out_msg, ssl->out_msglen, + ssl->out_msg, &olen ) ) != 0 ) { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_switch_key", ret ); + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret ); return( ret ); } - if( ( ret = encryption_status = mbedtls_cipher_crypt( &transform->cipher_ctx, - transform->iv_enc, transform->ivlen, - data, rec->data_len, - data, &olen ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret ); - return( ret ); - } -#else - if( ( ret = encryption_status = mbedtls_cipher_crypt( &transform->cipher_ctx_enc, - transform->iv_enc, transform->ivlen, - data, rec->data_len, - data, &olen ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret ); - return( ret ); - } -#endif - if( rec->data_len != olen ) + if( ssl->out_msglen != olen ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); @@ -2899,235 +1420,164 @@ int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl, } else #endif /* MBEDTLS_ARC4_C || MBEDTLS_CIPHER_NULL_CIPHER */ - -#if defined(MBEDTLS_GCM_C) || \ - defined(MBEDTLS_CCM_C) || \ - defined(MBEDTLS_CHACHAPOLY_C) +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C) if( mode == MBEDTLS_MODE_GCM || - mode == MBEDTLS_MODE_CCM || - mode == MBEDTLS_MODE_CHACHAPOLY ) + mode == MBEDTLS_MODE_CCM ) { int ret; - unsigned char iv[12]; - size_t explicit_iv_len = transform->ivlen - transform->fixed_ivlen; + size_t enc_msglen, olen; + unsigned char *enc_msg; + unsigned char add_data[13]; + unsigned char taglen = ssl->transform_out->ciphersuite_info->flags & + MBEDTLS_CIPHERSUITE_SHORT_TAG ? 8 : 16; - /* Check that there's space for both the authentication tag - * and the explicit IV before and after the record content. */ - if( post_avail < transform->taglen || - rec->data_offset < explicit_iv_len ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "Buffer provided for encrypted record not large enough" ) ); - return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); - } + memcpy( add_data, ssl->out_ctr, 8 ); + add_data[8] = ssl->out_msgtype; + mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver, + ssl->conf->transport, add_data + 9 ); + add_data[11] = ( ssl->out_msglen >> 8 ) & 0xFF; + add_data[12] = ssl->out_msglen & 0xFF; + + MBEDTLS_SSL_DEBUG_BUF( 4, "additional data used for AEAD", + add_data, 13 ); /* * Generate IV */ - if( transform->ivlen == 12 && transform->fixed_ivlen == 4 ) - { - /* GCM and CCM: fixed || explicit (=seqnum) */ - mbedtls_platform_memcpy( iv, transform->iv_enc, transform->fixed_ivlen ); - mbedtls_platform_memcpy( iv + transform->fixed_ivlen, rec->ctr, - explicit_iv_len ); - /* Prefix record content with explicit IV. */ - mbedtls_platform_memcpy( data - explicit_iv_len, rec->ctr, explicit_iv_len ); - } - else if( transform->ivlen == 12 && transform->fixed_ivlen == 12 ) - { - /* ChachaPoly: fixed XOR sequence number */ - uint_fast8_t i; - - mbedtls_platform_memcpy( iv, transform->iv_enc, transform->fixed_ivlen ); - - for( i = 0; i < 8; i++ ) - iv[i+4] ^= rec->ctr[i]; - } - else + if( ssl->transform_out->ivlen - ssl->transform_out->fixed_ivlen != 8 ) { /* Reminder if we ever add an AEAD mode with a different size */ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); } - ssl_extract_add_data_from_record( add_data, &add_data_len, rec ); + memcpy( ssl->transform_out->iv_enc + ssl->transform_out->fixed_ivlen, + ssl->out_ctr, 8 ); + memcpy( ssl->out_iv, ssl->out_ctr, 8 ); + + MBEDTLS_SSL_DEBUG_BUF( 4, "IV used", ssl->out_iv, + ssl->transform_out->ivlen - ssl->transform_out->fixed_ivlen ); + + /* + * Fix pointer positions and message length with added IV + */ + enc_msg = ssl->out_msg; + enc_msglen = ssl->out_msglen; + ssl->out_msglen += ssl->transform_out->ivlen - + ssl->transform_out->fixed_ivlen; - MBEDTLS_SSL_DEBUG_BUF( 4, "IV used (internal)", - iv, transform->ivlen ); - MBEDTLS_SSL_DEBUG_BUF( 4, "IV used (transmitted)", - data - explicit_iv_len, explicit_iv_len ); - MBEDTLS_SSL_DEBUG_BUF( 4, "additional data used for AEAD", - add_data, add_data_len ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, " - "including 0 bytes of padding", - rec->data_len ) ); + "including %d bytes of padding", + ssl->out_msglen, 0 ) ); /* * Encrypt and authenticate */ -#if defined(MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS) - if( ( ret = mbedtls_ssl_switch_key( transform, MBEDTLS_ENCRYPT ) ) - != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_switch_key", ret ); - return( ret ); - } - - if( ( ret = encryption_status = mbedtls_cipher_auth_encrypt( &transform->cipher_ctx, - iv, transform->ivlen, - add_data, add_data_len, /* add data */ - data, rec->data_len, /* source */ - data, &rec->data_len, /* destination */ - data + rec->data_len, transform->taglen ) ) != 0 ) + if( ( ret = mbedtls_cipher_auth_encrypt( &ssl->transform_out->cipher_ctx_enc, + ssl->transform_out->iv_enc, + ssl->transform_out->ivlen, + add_data, 13, + enc_msg, enc_msglen, + enc_msg, &olen, + enc_msg + enc_msglen, taglen ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_auth_encrypt", ret ); return( ret ); } -#else - if( ( ret = encryption_status = mbedtls_cipher_auth_encrypt( &transform->cipher_ctx_enc, - iv, transform->ivlen, - add_data, add_data_len, /* add data */ - data, rec->data_len, /* source */ - data, &rec->data_len, /* destination */ - data + rec->data_len, transform->taglen ) ) != 0 ) + + if( olen != enc_msglen ) { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_auth_encrypt", ret ); - return( ret ); + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); } -#endif - MBEDTLS_SSL_DEBUG_BUF( 4, "after encrypt: tag", - data + rec->data_len, transform->taglen ); - - rec->data_len += transform->taglen + explicit_iv_len; - rec->data_offset -= explicit_iv_len; - post_avail -= transform->taglen; + ssl->out_msglen += taglen; auth_done++; + + MBEDTLS_SSL_DEBUG_BUF( 4, "after encrypt: tag", enc_msg + enc_msglen, taglen ); } else #endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C */ #if defined(MBEDTLS_CIPHER_MODE_CBC) && \ - ( defined(MBEDTLS_AES_C) || defined(MBEDTLS_CAMELLIA_C) || defined(MBEDTLS_ARIA_C) ) + ( defined(MBEDTLS_AES_C) || defined(MBEDTLS_CAMELLIA_C) ) if( mode == MBEDTLS_MODE_CBC ) { int ret; - size_t padlen, i; - size_t olen; + unsigned char *enc_msg; + size_t enc_msglen, padlen, olen = 0, i; - /* Currently we're always using minimal padding - * (up to 255 bytes would be allowed). */ - padlen = transform->ivlen - ( rec->data_len + 1 ) % transform->ivlen; - if( padlen == transform->ivlen ) + padlen = ssl->transform_out->ivlen - ( ssl->out_msglen + 1 ) % + ssl->transform_out->ivlen; + if( padlen == ssl->transform_out->ivlen ) padlen = 0; - /* Check there's enough space in the buffer for the padding. */ - if( post_avail < padlen + 1 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "Buffer provided for encrypted record not large enough" ) ); - return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); - } - for( i = 0; i <= padlen; i++ ) - data[rec->data_len + i] = (unsigned char) padlen; + ssl->out_msg[ssl->out_msglen + i] = (unsigned char) padlen; - rec->data_len += padlen + 1; - post_avail -= padlen + 1; + ssl->out_msglen += padlen + 1; + + enc_msglen = ssl->out_msglen; + enc_msg = ssl->out_msg; #if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2) /* * Prepend per-record IV for block cipher in TLS v1.1 and up as per * Method 1 (6.2.3.2. in RFC4346 and RFC5246) */ - if( mbedtls_ssl_ver_geq( - mbedtls_ssl_transform_get_minor_ver( transform ), - MBEDTLS_SSL_MINOR_VERSION_2 ) ) + if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 ) { - if( f_rng == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "No PRNG provided to encrypt_record routine" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - if( rec->data_offset < transform->ivlen ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "Buffer provided for encrypted record not large enough" ) ); - return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); - } - /* * Generate IV */ - ret = f_rng( p_rng, transform->iv_enc, transform->ivlen ); + ret = ssl->conf->f_rng( ssl->conf->p_rng, ssl->transform_out->iv_enc, + ssl->transform_out->ivlen ); if( ret != 0 ) return( ret ); - mbedtls_platform_memcpy( data - transform->ivlen, transform->iv_enc, - transform->ivlen ); + memcpy( ssl->out_iv, ssl->transform_out->iv_enc, + ssl->transform_out->ivlen ); + /* + * Fix pointer positions and message length with added IV + */ + enc_msg = ssl->out_msg; + enc_msglen = ssl->out_msglen; + ssl->out_msglen += ssl->transform_out->ivlen; } #endif /* MBEDTLS_SSL_PROTO_TLS1_1 || MBEDTLS_SSL_PROTO_TLS1_2 */ MBEDTLS_SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, " "including %d bytes of IV and %d bytes of padding", - rec->data_len, transform->ivlen, + ssl->out_msglen, ssl->transform_out->ivlen, padlen + 1 ) ); -#if defined(MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS) - if( ( ret = mbedtls_ssl_switch_key( transform, MBEDTLS_ENCRYPT ) ) - != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_switch_key", ret ); - return( ret ); - } - if( ( ret = encryption_status = mbedtls_cipher_crypt( &transform->cipher_ctx, - transform->iv_enc, - transform->ivlen, - data, rec->data_len, - data, &olen ) ) != 0 ) + if( ( ret = mbedtls_cipher_crypt( &ssl->transform_out->cipher_ctx_enc, + ssl->transform_out->iv_enc, + ssl->transform_out->ivlen, + enc_msg, enc_msglen, + enc_msg, &olen ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret ); return( ret ); } -#else - if( ( ret = encryption_status = mbedtls_cipher_crypt( &transform->cipher_ctx_enc, - transform->iv_enc, - transform->ivlen, - data, rec->data_len, - data, &olen ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret ); - return( ret ); - } -#endif - if( rec->data_len != olen ) + if( enc_msglen != olen ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); } #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) - if( mbedtls_ssl_ver_lt( - mbedtls_ssl_transform_get_minor_ver( transform ), - MBEDTLS_SSL_MINOR_VERSION_2 ) ) + if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_2 ) { /* * Save IV in SSL3 and TLS1 */ -#if defined(MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS) - mbedtls_platform_memcpy( transform->iv_enc, transform->cipher_ctx.iv, - transform->ivlen ); -#else - mbedtls_platform_memcpy( transform->iv_enc, transform->cipher_ctx_enc.iv, - transform->ivlen ); -#endif + memcpy( ssl->transform_out->iv_enc, + ssl->transform_out->cipher_ctx_enc.iv, + ssl->transform_out->ivlen ); } - else #endif - { - data -= transform->ivlen; - rec->data_offset -= transform->ivlen; - rec->data_len += transform->ivlen; - } #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) if( auth_done == 0 ) @@ -3142,37 +1592,34 @@ int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl, * IV + // except for TLS 1.0 * ENC(content + padding + padding_length)); */ - - if( post_avail < transform->maclen) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "Buffer provided for encrypted record not large enough" ) ); - return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); - } - - ssl_extract_add_data_from_record( add_data, &add_data_len, rec ); + unsigned char pseudo_hdr[13]; MBEDTLS_SSL_DEBUG_MSG( 3, ( "using encrypt then mac" ) ); - MBEDTLS_SSL_DEBUG_BUF( 4, "MAC'd meta-data", add_data, - add_data_len ); - mbedtls_md_hmac_update( &transform->md_ctx_enc, add_data, - add_data_len ); - mbedtls_md_hmac_update( &transform->md_ctx_enc, - data, rec->data_len ); - mbedtls_md_hmac_finish( &transform->md_ctx_enc, mac ); - mbedtls_md_hmac_reset( &transform->md_ctx_enc ); + memcpy( pseudo_hdr + 0, ssl->out_ctr, 8 ); + memcpy( pseudo_hdr + 8, ssl->out_hdr, 3 ); + pseudo_hdr[11] = (unsigned char)( ( ssl->out_msglen >> 8 ) & 0xFF ); + pseudo_hdr[12] = (unsigned char)( ( ssl->out_msglen ) & 0xFF ); - mbedtls_platform_memcpy( data + rec->data_len, mac, transform->maclen ); + MBEDTLS_SSL_DEBUG_BUF( 4, "MAC'd meta-data", pseudo_hdr, 13 ); - rec->data_len += transform->maclen; - post_avail -= transform->maclen; + mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, pseudo_hdr, 13 ); + mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, + ssl->out_iv, ssl->out_msglen ); + mbedtls_md_hmac_finish( &ssl->transform_out->md_ctx_enc, mac ); + mbedtls_md_hmac_reset( &ssl->transform_out->md_ctx_enc ); + + memcpy( ssl->out_iv + ssl->out_msglen, mac, + ssl->transform_out->maclen ); + + ssl->out_msglen += ssl->transform_out->maclen; auth_done++; } #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ } else #endif /* MBEDTLS_CIPHER_MODE_CBC && - ( MBEDTLS_AES_C || MBEDTLS_CAMELLIA_C || MBEDTLS_ARIA_C ) */ + ( MBEDTLS_AES_C || MBEDTLS_CAMELLIA_C ) */ { MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); @@ -3187,91 +1634,54 @@ int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= encrypt buf" ) ); - if( encryption_status == 0 ) - { - return( 0 ); - } - return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); + return( 0 ); } -int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl, - mbedtls_ssl_transform *transform, - mbedtls_record *rec ) +static int ssl_decrypt_buf( mbedtls_ssl_context *ssl ) { - size_t olen; + size_t i; mbedtls_cipher_mode_t mode; - int ret, auth_done = 0; -#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC) + int auth_done = 0; +#if defined(SSL_SOME_MODES_USE_MAC) size_t padlen = 0, correct = 1; #endif - unsigned char* data; - unsigned char add_data[13 + 1 + MBEDTLS_SSL_CID_IN_LEN_MAX ]; - size_t add_data_len; - -#if !defined(MBEDTLS_DEBUG_C) - ssl = NULL; /* make sure we don't use it except for debug */ - ((void) ssl); -#endif MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> decrypt buf" ) ); - if( rec == NULL || - rec->buf == NULL || - rec->buf_len < rec->data_offset || - rec->buf_len - rec->data_offset < rec->data_len ) + + if( ssl->session_in == NULL || ssl->transform_in == NULL ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad record structure provided to decrypt_buf" ) ); + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); } - data = rec->buf + rec->data_offset; -#if defined(MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS) - mode = mbedtls_cipher_get_cipher_mode( &transform->cipher_ctx ); -#else - mode = mbedtls_cipher_get_cipher_mode( &transform->cipher_ctx_dec ); -#endif -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - /* - * Match record's CID with incoming CID. - */ - if( rec->cid_len != transform->in_cid_len || - memcmp( rec->cid, transform->in_cid, rec->cid_len ) != 0 ) // use regular memcmp as CID is public + mode = mbedtls_cipher_get_cipher_mode( &ssl->transform_in->cipher_ctx_dec ); + + if( ssl->in_msglen < ssl->transform_in->minlen ) { - return( MBEDTLS_ERR_SSL_UNEXPECTED_CID ); + MBEDTLS_SSL_DEBUG_MSG( 1, ( "in_msglen (%d) < minlen (%d)", + ssl->in_msglen, ssl->transform_in->minlen ) ); + return( MBEDTLS_ERR_SSL_INVALID_MAC ); } -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ #if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER) if( mode == MBEDTLS_MODE_STREAM ) { + int ret; + size_t olen = 0; + padlen = 0; -#if defined(MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS) - if( ( ret = mbedtls_ssl_switch_key( transform, MBEDTLS_DECRYPT ) ) - != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_switch_key", ret ); - return( ret ); - } - if( ( ret = mbedtls_cipher_crypt( &transform->cipher_ctx, - transform->iv_dec, - transform->ivlen, - data, rec->data_len, - data, &olen ) ) != 0 ) + + if( ( ret = mbedtls_cipher_crypt( &ssl->transform_in->cipher_ctx_dec, + ssl->transform_in->iv_dec, + ssl->transform_in->ivlen, + ssl->in_msg, ssl->in_msglen, + ssl->in_msg, &olen ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret ); return( ret ); } -#else - if( ( ret = mbedtls_cipher_crypt( &transform->cipher_ctx_dec, - transform->iv_dec, - transform->ivlen, - data, rec->data_len, - data, &olen ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret ); - return( ret ); - } -#endif - if( rec->data_len != olen ) + + if( ssl->in_msglen != olen ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); @@ -3279,99 +1689,61 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl, } else #endif /* MBEDTLS_ARC4_C || MBEDTLS_CIPHER_NULL_CIPHER */ -#if defined(MBEDTLS_GCM_C) || \ - defined(MBEDTLS_CCM_C) || \ - defined(MBEDTLS_CHACHAPOLY_C) +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C) if( mode == MBEDTLS_MODE_GCM || - mode == MBEDTLS_MODE_CCM || - mode == MBEDTLS_MODE_CHACHAPOLY ) + mode == MBEDTLS_MODE_CCM ) { - unsigned char iv[12]; - size_t explicit_iv_len = transform->ivlen - transform->fixed_ivlen; + int ret; + size_t dec_msglen, olen; + unsigned char *dec_msg; + unsigned char *dec_msg_result; + unsigned char add_data[13]; + unsigned char taglen = ssl->transform_in->ciphersuite_info->flags & + MBEDTLS_CIPHERSUITE_SHORT_TAG ? 8 : 16; + size_t explicit_iv_len = ssl->transform_in->ivlen - + ssl->transform_in->fixed_ivlen; - /* - * Prepare IV from explicit and implicit data. - */ - - /* Check that there's enough space for the explicit IV - * (at the beginning of the record) and the MAC (at the - * end of the record). */ - if( rec->data_len < explicit_iv_len + transform->taglen ) + if( ssl->in_msglen < explicit_iv_len + taglen ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%d) < explicit_iv_len (%d) " - "+ taglen (%d)", rec->data_len, - explicit_iv_len, transform->taglen ) ); + "+ taglen (%d)", ssl->in_msglen, + explicit_iv_len, taglen ) ); return( MBEDTLS_ERR_SSL_INVALID_MAC ); } + dec_msglen = ssl->in_msglen - explicit_iv_len - taglen; -#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C) - if( transform->ivlen == 12 && transform->fixed_ivlen == 4 ) - { - /* GCM and CCM: fixed || explicit */ + dec_msg = ssl->in_msg; + dec_msg_result = ssl->in_msg; + ssl->in_msglen = dec_msglen; - /* Fixed */ - mbedtls_platform_memcpy( iv, transform->iv_dec, transform->fixed_ivlen ); - /* Explicit */ - mbedtls_platform_memcpy( iv + transform->fixed_ivlen, data, 8 ); - } - else -#endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C */ -#if defined(MBEDTLS_CHACHAPOLY_C) - if( transform->ivlen == 12 && transform->fixed_ivlen == 12 ) - { - /* ChachaPoly: fixed XOR sequence number */ - uint_fast8_t i; + memcpy( add_data, ssl->in_ctr, 8 ); + add_data[8] = ssl->in_msgtype; + mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver, + ssl->conf->transport, add_data + 9 ); + add_data[11] = ( ssl->in_msglen >> 8 ) & 0xFF; + add_data[12] = ssl->in_msglen & 0xFF; - mbedtls_platform_memcpy( iv, transform->iv_dec, transform->fixed_ivlen ); - - for( i = 0; i < 8; i++ ) - iv[i+4] ^= rec->ctr[i]; - } - else -#endif /* MBEDTLS_CHACHAPOLY_C */ - { - /* Reminder if we ever add an AEAD mode with a different size */ - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - /* Group changes to data, data_len, and add_data, because - * add_data depends on data_len. */ - data += explicit_iv_len; - rec->data_offset += explicit_iv_len; - rec->data_len -= explicit_iv_len + transform->taglen; - - ssl_extract_add_data_from_record( add_data, &add_data_len, rec ); MBEDTLS_SSL_DEBUG_BUF( 4, "additional data used for AEAD", - add_data, add_data_len ); + add_data, 13 ); - /* Because of the check above, we know that there are - * explicit_iv_len Bytes preceeding data, and taglen - * bytes following data + data_len. This justifies - * the debug message and the invocation of - * mbedtls_cipher_auth_decrypt() below. */ + memcpy( ssl->transform_in->iv_dec + ssl->transform_in->fixed_ivlen, + ssl->in_iv, + ssl->transform_in->ivlen - ssl->transform_in->fixed_ivlen ); - MBEDTLS_SSL_DEBUG_BUF( 4, "IV used", iv, transform->ivlen ); - MBEDTLS_SSL_DEBUG_BUF( 4, "TAG used", data + rec->data_len, - transform->taglen ); + MBEDTLS_SSL_DEBUG_BUF( 4, "IV used", ssl->transform_in->iv_dec, + ssl->transform_in->ivlen ); + MBEDTLS_SSL_DEBUG_BUF( 4, "TAG used", dec_msg + dec_msglen, taglen ); /* * Decrypt and authenticate */ -#if defined(MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS) - if( ( ret = mbedtls_ssl_switch_key( transform, MBEDTLS_DECRYPT ) ) - != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_switch_key", ret ); - return( ret ); - } - if( ( ret = mbedtls_cipher_auth_decrypt( &transform->cipher_ctx, - iv, transform->ivlen, - add_data, add_data_len, - data, rec->data_len, - data, &olen, - data + rec->data_len, - transform->taglen ) ) != 0 ) + if( ( ret = mbedtls_cipher_auth_decrypt( &ssl->transform_in->cipher_ctx_dec, + ssl->transform_in->iv_dec, + ssl->transform_in->ivlen, + add_data, 13, + dec_msg, dec_msglen, + dec_msg_result, &olen, + dec_msg + dec_msglen, taglen ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_auth_decrypt", ret ); @@ -3380,28 +1752,9 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl, return( ret ); } -#else - if( ( ret = mbedtls_cipher_auth_decrypt( &transform->cipher_ctx_dec, - iv, transform->ivlen, - add_data, add_data_len, - data, rec->data_len, - data, &olen, - data + rec->data_len, - transform->taglen ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_auth_decrypt", ret ); - - if( ret == MBEDTLS_ERR_CIPHER_AUTH_FAILED ) - return( MBEDTLS_ERR_SSL_INVALID_MAC ); - - return( ret ); - } -#endif - auth_done++; - /* Double-check that AEAD decryption doesn't change content length. */ - if( olen != rec->data_len ) + if( olen != dec_msglen ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); @@ -3410,98 +1763,78 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl, else #endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C */ #if defined(MBEDTLS_CIPHER_MODE_CBC) && \ - ( defined(MBEDTLS_AES_C) || defined(MBEDTLS_CAMELLIA_C) || defined(MBEDTLS_ARIA_C) ) + ( defined(MBEDTLS_AES_C) || defined(MBEDTLS_CAMELLIA_C) ) if( mode == MBEDTLS_MODE_CBC ) { + /* + * Decrypt and check the padding + */ + int ret; + unsigned char *dec_msg; + unsigned char *dec_msg_result; + size_t dec_msglen; size_t minlen = 0; + size_t olen = 0; /* * Check immediate ciphertext sanity */ #if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( mbedtls_ssl_ver_geq( - mbedtls_ssl_transform_get_minor_ver( transform ), - MBEDTLS_SSL_MINOR_VERSION_2 ) ) - { - /* The ciphertext is prefixed with the CBC IV. */ - minlen += transform->ivlen; - } + if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 ) + minlen += ssl->transform_in->ivlen; #endif - /* Size considerations: - * - * - The CBC cipher text must not be empty and hence - * at least of size transform->ivlen. - * - * Together with the potential IV-prefix, this explains - * the first of the two checks below. - * - * - The record must contain a MAC, either in plain or - * encrypted, depending on whether Encrypt-then-MAC - * is used or not. - * - If it is, the message contains the IV-prefix, - * the CBC ciphertext, and the MAC. - * - If it is not, the padded plaintext, and hence - * the CBC ciphertext, has at least length maclen + 1 - * because there is at least the padding length byte. - * - * As the CBC ciphertext is not empty, both cases give the - * lower bound minlen + maclen + 1 on the record size, which - * we test for in the second check below. - */ - if( rec->data_len < minlen + transform->ivlen || - rec->data_len < minlen + transform->maclen + 1 ) + if( ssl->in_msglen < minlen + ssl->transform_in->ivlen || + ssl->in_msglen < minlen + ssl->transform_in->maclen + 1 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%d) < max( ivlen(%d), maclen (%d) " - "+ 1 ) ( + expl IV )", rec->data_len, - transform->ivlen, - transform->maclen ) ); + "+ 1 ) ( + expl IV )", ssl->in_msglen, + ssl->transform_in->ivlen, + ssl->transform_in->maclen ) ); return( MBEDTLS_ERR_SSL_INVALID_MAC ); } + dec_msglen = ssl->in_msglen; + dec_msg = ssl->in_msg; + dec_msg_result = ssl->in_msg; + /* * Authenticate before decrypt if enabled */ #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) - if( transform->encrypt_then_mac == MBEDTLS_SSL_ETM_ENABLED ) + if( ssl->session_in->encrypt_then_mac == MBEDTLS_SSL_ETM_ENABLED ) { unsigned char mac_expect[MBEDTLS_SSL_MAC_ADD]; + unsigned char pseudo_hdr[13]; MBEDTLS_SSL_DEBUG_MSG( 3, ( "using encrypt then mac" ) ); - /* Update data_len in tandem with add_data. - * - * The subtraction is safe because of the previous check - * data_len >= minlen + maclen + 1. - * - * Afterwards, we know that data + data_len is followed by at - * least maclen Bytes, which justifies the call to - * mbedtls_platform_memequal() below. - * - * Further, we still know that data_len > minlen */ - rec->data_len -= transform->maclen; - ssl_extract_add_data_from_record( add_data, &add_data_len, rec ); + dec_msglen -= ssl->transform_in->maclen; + ssl->in_msglen -= ssl->transform_in->maclen; - /* Calculate expected MAC. */ - MBEDTLS_SSL_DEBUG_BUF( 4, "MAC'd meta-data", add_data, - add_data_len ); - mbedtls_md_hmac_update( &transform->md_ctx_dec, add_data, - add_data_len ); - mbedtls_md_hmac_update( &transform->md_ctx_dec, - data, rec->data_len ); - mbedtls_md_hmac_finish( &transform->md_ctx_dec, mac_expect ); - mbedtls_md_hmac_reset( &transform->md_ctx_dec ); + memcpy( pseudo_hdr + 0, ssl->in_ctr, 8 ); + memcpy( pseudo_hdr + 8, ssl->in_hdr, 3 ); + pseudo_hdr[11] = (unsigned char)( ( ssl->in_msglen >> 8 ) & 0xFF ); + pseudo_hdr[12] = (unsigned char)( ( ssl->in_msglen ) & 0xFF ); - MBEDTLS_SSL_DEBUG_BUF( 4, "message mac", data + rec->data_len, - transform->maclen ); + MBEDTLS_SSL_DEBUG_BUF( 4, "MAC'd meta-data", pseudo_hdr, 13 ); + + mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, pseudo_hdr, 13 ); + mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, + ssl->in_iv, ssl->in_msglen ); + mbedtls_md_hmac_finish( &ssl->transform_in->md_ctx_dec, mac_expect ); + mbedtls_md_hmac_reset( &ssl->transform_in->md_ctx_dec ); + + MBEDTLS_SSL_DEBUG_BUF( 4, "message mac", ssl->in_iv + ssl->in_msglen, + ssl->transform_in->maclen ); MBEDTLS_SSL_DEBUG_BUF( 4, "expected mac", mac_expect, - transform->maclen ); + ssl->transform_in->maclen ); - /* Compare expected MAC with MAC at the end of the record. */ - if( mbedtls_platform_memequal( data + rec->data_len, mac_expect, - transform->maclen ) != 0 ) + if( mbedtls_ssl_safer_memcmp( ssl->in_iv + ssl->in_msglen, mac_expect, + ssl->transform_in->maclen ) != 0 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "message mac does not match" ) ); + return( MBEDTLS_ERR_SSL_INVALID_MAC ); } auth_done++; @@ -3511,14 +1844,10 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl, /* * Check length sanity */ - - /* We know from above that data_len > minlen >= 0, - * so the following check in particular implies that - * data_len >= minlen + ivlen ( = minlen or 2 * minlen ). */ - if( rec->data_len % transform->ivlen != 0 ) + if( ssl->in_msglen % ssl->transform_in->ivlen != 0 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%d) %% ivlen (%d) != 0", - rec->data_len, transform->ivlen ) ); + ssl->in_msglen, ssl->transform_in->ivlen ) ); return( MBEDTLS_ERR_SSL_INVALID_MAC ); } @@ -3526,114 +1855,66 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl, /* * Initialize for prepended IV for block cipher in TLS v1.1 and up */ - if( mbedtls_ssl_ver_geq( - mbedtls_ssl_transform_get_minor_ver( transform ), - MBEDTLS_SSL_MINOR_VERSION_2 ) ) + if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 ) { - /* Safe because data_len >= minlen + ivlen = 2 * ivlen. */ - mbedtls_platform_memcpy( transform->iv_dec, data, transform->ivlen ); + dec_msglen -= ssl->transform_in->ivlen; + ssl->in_msglen -= ssl->transform_in->ivlen; - data += transform->ivlen; - rec->data_offset += transform->ivlen; - rec->data_len -= transform->ivlen; + for( i = 0; i < ssl->transform_in->ivlen; i++ ) + ssl->transform_in->iv_dec[i] = ssl->in_iv[i]; } #endif /* MBEDTLS_SSL_PROTO_TLS1_1 || MBEDTLS_SSL_PROTO_TLS1_2 */ - /* We still have data_len % ivlen == 0 and data_len >= ivlen here. */ -#if defined(MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS) - if( ( ret = mbedtls_ssl_switch_key( transform, MBEDTLS_DECRYPT ) ) - != 0 ) + if( ( ret = mbedtls_cipher_crypt( &ssl->transform_in->cipher_ctx_dec, + ssl->transform_in->iv_dec, + ssl->transform_in->ivlen, + dec_msg, dec_msglen, + dec_msg_result, &olen ) ) != 0 ) { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_switch_key", ret ); + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret ); return( ret ); } - if( ( ret = mbedtls_cipher_crypt( &transform->cipher_ctx, - transform->iv_dec, transform->ivlen, - data, rec->data_len, data, &olen ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret ); - return( ret ); - } -#else - if( ( ret = mbedtls_cipher_crypt( &transform->cipher_ctx_dec, - transform->iv_dec, transform->ivlen, - data, rec->data_len, data, &olen ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret ); - return( ret ); - } -#endif - /* Double-check that length hasn't changed during decryption. */ - if( rec->data_len != olen ) + if( dec_msglen != olen ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); } #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) - if( mbedtls_ssl_ver_lt( - mbedtls_ssl_transform_get_minor_ver( transform ), - MBEDTLS_SSL_MINOR_VERSION_2 ) ) + if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_2 ) { /* - * Save IV in SSL3 and TLS1, where CBC decryption of consecutive - * records is equivalent to CBC decryption of the concatenation - * of the records; in other words, IVs are maintained across - * record decryptions. + * Save IV in SSL3 and TLS1 */ -#if defined(MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS) - mbedtls_platform_memcpy( transform->iv_dec, transform->cipher_ctx.iv, - transform->ivlen ); -#else - mbedtls_platform_memcpy( transform->iv_dec, transform->cipher_ctx_dec.iv, - transform->ivlen ); -#endif + memcpy( ssl->transform_in->iv_dec, + ssl->transform_in->cipher_ctx_dec.iv, + ssl->transform_in->ivlen ); } #endif - /* Safe since data_len >= minlen + maclen + 1, so after having - * subtracted at most minlen and maclen up to this point, - * data_len > 0 (because of data_len % ivlen == 0, it's actually - * >= ivlen ). */ - padlen = data[rec->data_len - 1]; + padlen = 1 + ssl->in_msg[ssl->in_msglen - 1]; - if( auth_done == 1 ) - { - correct *= ( rec->data_len >= padlen + 1 ); - padlen *= ( rec->data_len >= padlen + 1 ); - } - else + if( ssl->in_msglen < ssl->transform_in->maclen + padlen && + auth_done == 0 ) { #if defined(MBEDTLS_SSL_DEBUG_ALL) - if( rec->data_len < transform->maclen + padlen + 1 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%d) < maclen (%d) + padlen (%d)", - rec->data_len, - transform->maclen, - padlen + 1 ) ); - } + MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%d) < maclen (%d) + padlen (%d)", + ssl->in_msglen, ssl->transform_in->maclen, padlen ) ); #endif - - correct *= ( rec->data_len >= transform->maclen + padlen + 1 ); - padlen *= ( rec->data_len >= transform->maclen + padlen + 1 ); + padlen = 0; + correct = 0; } - padlen++; - - /* Regardless of the validity of the padding, - * we have data_len >= padlen here. */ - #if defined(MBEDTLS_SSL_PROTO_SSL3) - if( mbedtls_ssl_transform_get_minor_ver( transform ) == - MBEDTLS_SSL_MINOR_VERSION_0 ) + if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) { - if( padlen > transform->ivlen ) + if( padlen > ssl->transform_in->ivlen ) { #if defined(MBEDTLS_SSL_DEBUG_ALL) MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad padding length: is %d, " - "should be no more than %d", - padlen, transform->ivlen ) ); + "should be no more than %d", + padlen, ssl->transform_in->ivlen ) ); #endif correct = 0; } @@ -3642,33 +1923,39 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl, #endif /* MBEDTLS_SSL_PROTO_SSL3 */ #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( mbedtls_ssl_ver_gt( - mbedtls_ssl_transform_get_minor_ver( transform ), - MBEDTLS_SSL_MINOR_VERSION_0 ) ) + if( ssl->minor_ver > MBEDTLS_SSL_MINOR_VERSION_0 ) { - /* The padding check involves a series of up to 256 - * consecutive memory reads at the end of the record - * plaintext buffer. In order to hide the length and - * validity of the padding, always perform exactly - * `min(256,plaintext_len)` reads (but take into account - * only the last `padlen` bytes for the padding check). */ - size_t pad_count = 0; - size_t real_count = 0; - volatile unsigned char* const check = data; + /* + * TLSv1+: always check the padding up to the first failure + * and fake check up to 256 bytes of padding + */ + size_t pad_count = 0, real_count = 1; + size_t padding_idx = ssl->in_msglen - padlen; - /* Index of first padding byte; it has been ensured above - * that the subtraction is safe. */ - size_t const padding_idx = rec->data_len - padlen; - size_t const num_checks = rec->data_len <= 256 ? rec->data_len : 256; - size_t const start_idx = rec->data_len - num_checks; - size_t idx; + /* + * Padding is guaranteed to be incorrect if: + * 1. padlen > ssl->in_msglen + * + * 2. padding_idx > MBEDTLS_SSL_MAX_CONTENT_LEN + + * ssl->transform_in->maclen + * + * In both cases we reset padding_idx to a safe value (0) to + * prevent out-of-buffer reads. + */ + correct &= ( padlen <= ssl->in_msglen ); + correct &= ( padding_idx <= MBEDTLS_SSL_MAX_CONTENT_LEN + + ssl->transform_in->maclen ); - for( idx = start_idx; idx < rec->data_len; idx++ ) + padding_idx *= correct; + + for( i = 0; i < 256; i++ ) { - real_count |= ( idx >= padding_idx ); - pad_count += real_count * ( check[idx] == padlen - 1 ); + real_count &= ( i < padlen ); + pad_count += real_count * + ( ssl->in_msg[padding_idx + i] == padlen - 1 ); } - correct &= ( pad_count == padlen ); + + correct &= ( pad_count == padlen ); /* Only 1 on correct padding */ #if defined(MBEDTLS_SSL_DEBUG_ALL) if( padlen > 0 && correct == 0 ) @@ -3684,15 +1971,11 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl, return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); } - /* If the padding was found to be invalid, padlen == 0 - * and the subtraction is safe. If the padding was found valid, - * padlen hasn't been changed and the previous assertion - * data_len >= padlen still holds. */ - rec->data_len -= padlen; + ssl->in_msglen -= padlen; } else #endif /* MBEDTLS_CIPHER_MODE_CBC && - ( MBEDTLS_AES_C || MBEDTLS_CAMELLIA_C || MBEDTLS_ARIA_C ) */ + ( MBEDTLS_AES_C || MBEDTLS_CAMELLIA_C ) */ { MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); @@ -3700,51 +1983,37 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl, #if defined(MBEDTLS_SSL_DEBUG_ALL) MBEDTLS_SSL_DEBUG_BUF( 4, "raw buffer after decryption", - data, rec->data_len ); + ssl->in_msg, ssl->in_msglen ); #endif /* * Authenticate if not done yet. * Compute the MAC regardless of the padding result (RFC4346, CBCTIME). */ -#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC) +#if defined(SSL_SOME_MODES_USE_MAC) if( auth_done == 0 ) { unsigned char mac_expect[MBEDTLS_SSL_MAC_ADD]; - /* If the initial value of padlen was such that - * data_len < maclen + padlen + 1, then padlen - * got reset to 1, and the initial check - * data_len >= minlen + maclen + 1 - * guarantees that at this point we still - * have at least data_len >= maclen. - * - * If the initial value of padlen was such that - * data_len >= maclen + padlen + 1, then we have - * subtracted either padlen + 1 (if the padding was correct) - * or 0 (if the padding was incorrect) since then, - * hence data_len >= maclen in any case. - */ - rec->data_len -= transform->maclen; - ssl_extract_add_data_from_record( add_data, &add_data_len, rec ); + ssl->in_msglen -= ssl->transform_in->maclen; + + ssl->in_len[0] = (unsigned char)( ssl->in_msglen >> 8 ); + ssl->in_len[1] = (unsigned char)( ssl->in_msglen ); #if defined(MBEDTLS_SSL_PROTO_SSL3) - if( mbedtls_ssl_transform_get_minor_ver( transform ) == - MBEDTLS_SSL_MINOR_VERSION_0 ) + if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) { - ssl_mac( &transform->md_ctx_dec, - transform->mac_dec, - data, rec->data_len, - rec->ctr, rec->type, - mac_expect ); + ssl_mac( &ssl->transform_in->md_ctx_dec, + ssl->transform_in->mac_dec, + ssl->in_msg, ssl->in_msglen, + ssl->in_ctr, ssl->in_msgtype, + mac_expect ); } else #endif /* MBEDTLS_SSL_PROTO_SSL3 */ #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( mbedtls_ssl_ver_gt( - mbedtls_ssl_transform_get_minor_ver( transform ), - MBEDTLS_SSL_MINOR_VERSION_0 ) ) + if( ssl->minor_ver > MBEDTLS_SSL_MINOR_VERSION_0 ) { /* * Process MAC and always update for padlen afterwards to make @@ -3774,25 +2043,21 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl, * linking an extra division function in some builds). */ size_t j, extra_run = 0; - unsigned char tmp[MBEDTLS_MD_MAX_BLOCK_SIZE]; /* * The next two sizes are the minimum and maximum values of * in_msglen over all padlen values. * * They're independent of padlen, since we previously did - * data_len -= padlen. + * in_msglen -= padlen. * * Note that max_len + maclen is never more than the buffer * length, as we previously did in_msglen -= maclen too. */ - const size_t max_len = rec->data_len + padlen; + const size_t max_len = ssl->in_msglen + padlen; const size_t min_len = ( max_len > 256 ) ? max_len - 256 : 0; - memset( tmp, 0, sizeof( tmp ) ); - - switch( mbedtls_md_get_type( - mbedtls_md_get_handle( &transform->md_ctx_dec ) ) ) + switch( ssl->transform_in->ciphersuite_info->mac ) { #if defined(MBEDTLS_MD5_C) || defined(MBEDTLS_SHA1_C) || \ defined(MBEDTLS_SHA256_C) @@ -3800,17 +2065,15 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl, case MBEDTLS_MD_SHA1: case MBEDTLS_MD_SHA256: /* 8 bytes of message size, 64-byte compression blocks */ - extra_run = - ( add_data_len + rec->data_len + padlen + 8 ) / 64 - - ( add_data_len + rec->data_len + 8 ) / 64; + extra_run = ( 13 + ssl->in_msglen + padlen + 8 ) / 64 - + ( 13 + ssl->in_msglen + 8 ) / 64; break; #endif #if defined(MBEDTLS_SHA512_C) case MBEDTLS_MD_SHA384: /* 16 bytes of message size, 128-byte compression blocks */ - extra_run = - ( add_data_len + rec->data_len + padlen + 16 ) / 128 - - ( add_data_len + rec->data_len + 16 ) / 128; + extra_run = ( 13 + ssl->in_msglen + padlen + 16 ) / 128 - + ( 13 + ssl->in_msglen + 16 ) / 128; break; #endif default: @@ -3820,29 +2083,30 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl, extra_run &= correct * 0xFF; - mbedtls_md_hmac_update( &transform->md_ctx_dec, add_data, - add_data_len ); - mbedtls_md_hmac_update( &transform->md_ctx_dec, data, - rec->data_len ); + mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_ctr, 8 ); + mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_hdr, 3 ); + mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_len, 2 ); + mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_msg, + ssl->in_msglen ); /* Make sure we access everything even when padlen > 0. This * makes the synchronisation requirements for just-in-time * Prime+Probe attacks much tighter and hopefully impractical. */ - ssl_read_memory( data + rec->data_len, padlen ); - mbedtls_md_hmac_finish( &transform->md_ctx_dec, mac_expect ); + ssl_read_memory( ssl->in_msg + ssl->in_msglen, padlen ); + mbedtls_md_hmac_finish( &ssl->transform_in->md_ctx_dec, mac_expect ); /* Call mbedtls_md_process at least once due to cache attacks * that observe whether md_process() was called of not */ for( j = 0; j < extra_run + 1; j++ ) - mbedtls_md_process( &transform->md_ctx_dec, tmp ); + mbedtls_md_process( &ssl->transform_in->md_ctx_dec, ssl->in_msg ); - mbedtls_md_hmac_reset( &transform->md_ctx_dec ); + mbedtls_md_hmac_reset( &ssl->transform_in->md_ctx_dec ); /* Make sure we access all the memory that could contain the MAC, * before we check it in the next code block. This makes the * synchronisation requirements for just-in-time Prime+Probe * attacks much tighter and hopefully impractical. */ - ssl_read_memory( data + min_len, - max_len - min_len + transform->maclen ); + ssl_read_memory( ssl->in_msg + min_len, + max_len - min_len + ssl->transform_in->maclen ); } else #endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \ @@ -3853,12 +2117,13 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl, } #if defined(MBEDTLS_SSL_DEBUG_ALL) - MBEDTLS_SSL_DEBUG_BUF( 4, "expected mac", mac_expect, transform->maclen ); - MBEDTLS_SSL_DEBUG_BUF( 4, "message mac", data + rec->data_len, transform->maclen ); + MBEDTLS_SSL_DEBUG_BUF( 4, "expected mac", mac_expect, ssl->transform_in->maclen ); + MBEDTLS_SSL_DEBUG_BUF( 4, "message mac", ssl->in_msg + ssl->in_msglen, + ssl->transform_in->maclen ); #endif - if( mbedtls_platform_memequal( data + rec->data_len, mac_expect, - transform->maclen ) != 0 ) + if( mbedtls_ssl_safer_memcmp( ssl->in_msg + ssl->in_msglen, mac_expect, + ssl->transform_in->maclen ) != 0 ) { #if defined(MBEDTLS_SSL_DEBUG_ALL) MBEDTLS_SSL_DEBUG_MSG( 1, ( "message mac does not match" ) ); @@ -3873,7 +2138,7 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl, */ if( correct == 0 ) return( MBEDTLS_ERR_SSL_INVALID_MAC ); -#endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */ +#endif /* SSL_SOME_MODES_USE_MAC */ /* Make extra sure authentication was performed, exactly once */ if( auth_done != 1 ) @@ -3882,15 +2147,53 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl, return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); } -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - if( rec->cid_len != 0 ) + if( ssl->in_msglen == 0 ) { - ret = ssl_cid_parse_inner_plaintext( data, &rec->data_len, - &rec->type ); - if( ret != 0 ) +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) + if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 + && ssl->in_msgtype != MBEDTLS_SSL_MSG_APPLICATION_DATA ) + { + /* TLS v1.2 explicitly disallows zero-length messages which are not application data */ + MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid zero-length message type: %d", ssl->in_msgtype ) ); return( MBEDTLS_ERR_SSL_INVALID_RECORD ); + } +#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ + + ssl->nb_zero++; + + /* + * Three or more empty messages may be a DoS attack + * (excessive CPU consumption). + */ + if( ssl->nb_zero > 3 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "received four consecutive empty " + "messages, possible DoS attack" ) ); + return( MBEDTLS_ERR_SSL_INVALID_MAC ); + } + } + else + ssl->nb_zero = 0; + +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + { + ; /* in_ctr read from peer, not maintained internally */ + } + else +#endif + { + for( i = 8; i > ssl_ep_len( ssl ); i-- ) + if( ++ssl->in_ctr[i - 1] != 0 ) + break; + + /* The loop goes to its end iff the counter is wrapping */ + if( i == ssl_ep_len( ssl ) ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "incoming message counter would wrap" ) ); + return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING ); + } } -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= decrypt buf" ) ); @@ -3912,18 +2215,13 @@ static int ssl_compress_buf( mbedtls_ssl_context *ssl ) ptrdiff_t bytes_written = ssl->out_msg - ssl->out_buf; size_t len_pre = ssl->out_msglen; unsigned char *msg_pre = ssl->compress_buf; -#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) - size_t out_buf_len = ssl->out_buf_len; -#else - size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN; -#endif MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> compress buf" ) ); if( len_pre == 0 ) return( 0 ); - mbedtls_platform_memcpy( msg_pre, ssl->out_msg, len_pre ); + memcpy( msg_pre, ssl->out_msg, len_pre ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "before compression: msglen = %d, ", ssl->out_msglen ) ); @@ -3934,7 +2232,7 @@ static int ssl_compress_buf( mbedtls_ssl_context *ssl ) ssl->transform_out->ctx_deflate.next_in = msg_pre; ssl->transform_out->ctx_deflate.avail_in = len_pre; ssl->transform_out->ctx_deflate.next_out = msg_post; - ssl->transform_out->ctx_deflate.avail_out = out_buf_len - bytes_written; + ssl->transform_out->ctx_deflate.avail_out = MBEDTLS_SSL_BUFFER_LEN - bytes_written; ret = deflate( &ssl->transform_out->ctx_deflate, Z_SYNC_FLUSH ); if( ret != Z_OK ) @@ -3943,7 +2241,7 @@ static int ssl_compress_buf( mbedtls_ssl_context *ssl ) return( MBEDTLS_ERR_SSL_COMPRESSION_FAILED ); } - ssl->out_msglen = out_buf_len - + ssl->out_msglen = MBEDTLS_SSL_BUFFER_LEN - ssl->transform_out->ctx_deflate.avail_out - bytes_written; MBEDTLS_SSL_DEBUG_MSG( 3, ( "after compression: msglen = %d, ", @@ -3964,18 +2262,13 @@ static int ssl_decompress_buf( mbedtls_ssl_context *ssl ) ptrdiff_t header_bytes = ssl->in_msg - ssl->in_buf; size_t len_pre = ssl->in_msglen; unsigned char *msg_pre = ssl->compress_buf; -#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) - size_t in_buf_len = ssl->in_buf_len; -#else - size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN; -#endif MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> decompress buf" ) ); if( len_pre == 0 ) return( 0 ); - mbedtls_platform_memcpy( msg_pre, ssl->in_msg, len_pre ); + memcpy( msg_pre, ssl->in_msg, len_pre ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "before decompression: msglen = %d, ", ssl->in_msglen ) ); @@ -3986,7 +2279,7 @@ static int ssl_decompress_buf( mbedtls_ssl_context *ssl ) ssl->transform_in->ctx_inflate.next_in = msg_pre; ssl->transform_in->ctx_inflate.avail_in = len_pre; ssl->transform_in->ctx_inflate.next_out = msg_post; - ssl->transform_in->ctx_inflate.avail_out = in_buf_len - + ssl->transform_in->ctx_inflate.avail_out = MBEDTLS_SSL_BUFFER_LEN - header_bytes; ret = inflate( &ssl->transform_in->ctx_inflate, Z_SYNC_FLUSH ); @@ -3996,7 +2289,7 @@ static int ssl_decompress_buf( mbedtls_ssl_context *ssl ) return( MBEDTLS_ERR_SSL_COMPRESSION_FAILED ); } - ssl->in_msglen = in_buf_len - + ssl->in_msglen = MBEDTLS_SSL_BUFFER_LEN - ssl->transform_in->ctx_inflate.avail_out - header_bytes; MBEDTLS_SSL_DEBUG_MSG( 3, ( "after decompression: msglen = %d, ", @@ -4021,10 +2314,8 @@ static int ssl_resend_hello_request( mbedtls_ssl_context *ssl ) * timeout if we were using the usual handshake doubling scheme */ if( ssl->conf->renego_max_records < 0 ) { - uint32_t ratio = - mbedtls_ssl_conf_get_hs_timeout_max( ssl->conf ) / - mbedtls_ssl_conf_get_hs_timeout_min( ssl->conf ) + 1; - int_fast8_t doublings = 1; + uint32_t ratio = ssl->conf->hs_timeout_max / ssl->conf->hs_timeout_min + 1; + unsigned char doublings = 1; while( ratio != 0 ) { @@ -4063,36 +2354,29 @@ int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want ) { int ret; size_t len; -#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) - size_t in_buf_len = ssl->in_buf_len; -#else - size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN; -#endif MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> fetch input" ) ); - if( mbedtls_ssl_get_recv( ssl ) == NULL && - mbedtls_ssl_get_recv_timeout( ssl ) == NULL ) + if( ssl->f_recv == NULL && ssl->f_recv_timeout == NULL ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad usage of mbedtls_ssl_set_bio() " "or mbedtls_ssl_set_bio()" ) ); return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); } - if( nb_want > in_buf_len - (size_t)( ssl->in_hdr - ssl->in_buf ) ) + if( nb_want > MBEDTLS_SSL_BUFFER_LEN - (size_t)( ssl->in_hdr - ssl->in_buf ) ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "requesting more data than fits" ) ); return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); } #if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) ) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) { uint32_t timeout; /* Just to be sure */ - if( mbedtls_ssl_get_set_timer( ssl ) == NULL || - mbedtls_ssl_get_get_timer( ssl ) == NULL ) + if( ssl->f_set_timer == NULL || ssl->f_get_timer == NULL ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "You must use " "mbedtls_ssl_set_timer_cb() for DTLS" ) ); @@ -4144,7 +2428,7 @@ int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want ) } /* - * A record can't be split across datagrams. If we need to read but + * A record can't be split accross datagrams. If we need to read but * are not at the beginning of a new record, the caller did something * wrong. */ @@ -4160,31 +2444,23 @@ int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want ) * that will end up being dropped. */ if( ssl_check_timer( ssl ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "timer has expired" ) ); ret = MBEDTLS_ERR_SSL_TIMEOUT; - } else { - len = in_buf_len - ( ssl->in_hdr - ssl->in_buf ); + len = MBEDTLS_SSL_BUFFER_LEN - ( ssl->in_hdr - ssl->in_buf ); if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) timeout = ssl->handshake->retransmit_timeout; else - timeout = mbedtls_ssl_conf_get_read_timeout( ssl->conf ); + timeout = ssl->conf->read_timeout; MBEDTLS_SSL_DEBUG_MSG( 3, ( "f_recv_timeout: %u ms", timeout ) ); - if( mbedtls_ssl_get_recv_timeout( ssl ) != NULL ) - { - ret = mbedtls_ssl_get_recv_timeout( ssl ) - ( ssl->p_bio, ssl->in_hdr, len, timeout ); - } + if( ssl->f_recv_timeout != NULL ) + ret = ssl->f_recv_timeout( ssl->p_bio, ssl->in_hdr, len, + timeout ); else - { - ret = mbedtls_ssl_get_recv( ssl ) - ( ssl->p_bio, ssl->in_hdr, len ); - } + ret = ssl->f_recv( ssl->p_bio, ssl->in_hdr, len ); MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_recv(_timeout)", ret ); @@ -4214,8 +2490,7 @@ int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want ) return( MBEDTLS_ERR_SSL_WANT_READ ); } #if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION) - else if( mbedtls_ssl_conf_get_endpoint( ssl->conf ) == - MBEDTLS_SSL_IS_SERVER && + else if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING ) { if( ( ret = ssl_resend_hello_request( ssl ) ) != 0 ) @@ -4234,9 +2509,8 @@ int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want ) ssl->in_left = ret; } - MBEDTLS_SSL_TRANSPORT_ELSE -#endif /* MBEDTLS_SSL_PROTO_DTLS */ -#if defined(MBEDTLS_SSL_PROTO_TLS) + else +#endif { MBEDTLS_SSL_DEBUG_MSG( 2, ( "in_left: %d, nb_want: %d", ssl->in_left, nb_want ) ); @@ -4249,15 +2523,15 @@ int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want ) ret = MBEDTLS_ERR_SSL_TIMEOUT; else { - if( mbedtls_ssl_get_recv_timeout( ssl ) != NULL ) + if( ssl->f_recv_timeout != NULL ) { - ret = mbedtls_ssl_get_recv_timeout( ssl )( ssl->p_bio, - ssl->in_hdr + ssl->in_left, len, - mbedtls_ssl_conf_get_read_timeout( ssl->conf ) ); + ret = ssl->f_recv_timeout( ssl->p_bio, + ssl->in_hdr + ssl->in_left, len, + ssl->conf->read_timeout ); } else { - ret = mbedtls_ssl_get_recv( ssl )( ssl->p_bio, + ret = ssl->f_recv( ssl->p_bio, ssl->in_hdr + ssl->in_left, len ); } } @@ -4283,7 +2557,6 @@ int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want ) ssl->in_left += ret; } } -#endif /* MBEDTLS_SSL_PROTO_TLS */ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= fetch input" ) ); @@ -4296,11 +2569,11 @@ int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want ) int mbedtls_ssl_flush_output( mbedtls_ssl_context *ssl ) { int ret; - unsigned char *buf; + unsigned char *buf, i; MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> flush output" ) ); - if( mbedtls_ssl_get_send( ssl ) == NULL ) + if( ssl->f_send == NULL ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad usage of mbedtls_ssl_set_bio() " "or mbedtls_ssl_set_bio()" ) ); @@ -4317,10 +2590,11 @@ int mbedtls_ssl_flush_output( mbedtls_ssl_context *ssl ) while( ssl->out_left > 0 ) { MBEDTLS_SSL_DEBUG_MSG( 2, ( "message length: %d, out_left: %d", - mbedtls_ssl_out_hdr_len( ssl ) + ssl->out_msglen, ssl->out_left ) ); + mbedtls_ssl_hdr_len( ssl ) + ssl->out_msglen, ssl->out_left ) ); - buf = ssl->out_hdr - ssl->out_left; - ret = mbedtls_ssl_get_send( ssl )( ssl->p_bio, buf, ssl->out_left ); + buf = ssl->out_hdr + mbedtls_ssl_hdr_len( ssl ) + + ssl->out_msglen - ssl->out_left; + ret = ssl->f_send( ssl->p_bio, buf, ssl->out_left ); MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_send", ret ); @@ -4338,19 +2612,16 @@ int mbedtls_ssl_flush_output( mbedtls_ssl_context *ssl ) ssl->out_left -= ret; } -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) ) + for( i = 8; i > ssl_ep_len( ssl ); i-- ) + if( ++ssl->out_ctr[i - 1] != 0 ) + break; + + /* The loop goes to its end iff the counter is wrapping */ + if( i == ssl_ep_len( ssl ) ) { - ssl->out_hdr = ssl->out_buf; + MBEDTLS_SSL_DEBUG_MSG( 1, ( "outgoing message counter would wrap" ) ); + return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING ); } - MBEDTLS_SSL_TRANSPORT_ELSE -#endif -#if defined(MBEDTLS_SSL_PROTO_TLS) - { - ssl->out_hdr = ssl->out_buf + 8; - } -#endif - ssl_update_out_pointers( ssl, ssl->transform_out ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= flush output" ) ); @@ -4361,140 +2632,12 @@ int mbedtls_ssl_flush_output( mbedtls_ssl_context *ssl ) * Functions to handle the DTLS retransmission state machine */ #if defined(MBEDTLS_SSL_PROTO_DTLS) -static int ssl_swap_epochs( mbedtls_ssl_context *ssl ); - -static int mbedtls_ssl_flight_transmit_msg( mbedtls_ssl_context *ssl, mbedtls_ssl_flight_item *msg ) -{ - size_t max_frag_len; - int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; - int const is_retransmitting = - ( ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING ); - int const is_finished = - ( msg->type == MBEDTLS_SSL_MSG_HANDSHAKE && - msg->p[0] == MBEDTLS_SSL_HS_FINISHED ); - - uint8_t const force_flush = ssl->disable_datagram_packing == 1 ? - SSL_FORCE_FLUSH : SSL_DONT_FORCE_FLUSH; - - /* Swap epochs before sending Finished: we can't do it after - * sending ChangeCipherSpec, in case write returns WANT_READ. - * Must be done before copying, may change out_msg pointer */ - if( is_retransmitting && is_finished && ssl->handshake->cur_msg_p == ( msg->p + 12 ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "swap epochs to send finished message" ) ); - if( ( ret = ssl_swap_epochs( ssl ) ) != 0 ) - return( ret ); - } - - ret = ssl_get_remaining_payload_in_datagram( ssl ); - if( ret < 0 ) - return( ret ); - max_frag_len = (size_t) ret; - - /* CCS is copied as is, while HS messages may need fragmentation */ - if( msg->type == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC ) - { - if( max_frag_len == 0 ) - { - if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 ) - return( ret ); - - return( 0 ); - } - - mbedtls_platform_memcpy( ssl->out_msg, msg->p, msg->len ); - ssl->out_msglen = msg->len; - ssl->out_msgtype = msg->type; - - /* Update position inside current message */ - ssl->handshake->cur_msg_p += msg->len; - } - else - { - const unsigned char * const p = ssl->handshake->cur_msg_p; - const size_t hs_len = msg->len - 12; - const size_t frag_off = p - ( msg->p + 12 ); - const size_t rem_len = hs_len - frag_off; - size_t cur_hs_frag_len, max_hs_frag_len; - - if( ( max_frag_len < 12 ) || ( max_frag_len == 12 && hs_len != 0 ) ) - { - if( is_finished && is_retransmitting ) - { - if( ( ret = ssl_swap_epochs( ssl ) ) != 0 ) - return( ret ); - } - - if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 ) - return( ret ); - - return( 0 ); - } - max_hs_frag_len = max_frag_len - 12; - - cur_hs_frag_len = rem_len > max_hs_frag_len ? - max_hs_frag_len : rem_len; - - if( frag_off == 0 && cur_hs_frag_len != hs_len ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "fragmenting handshake message (%u > %u)", - (unsigned) cur_hs_frag_len, - (unsigned) max_hs_frag_len ) ); - } - - /* Messages are stored with handshake headers as if not fragmented, - * copy beginning of headers then fill fragmentation fields. - * Handshake headers: type(1) len(3) seq(2) f_off(3) f_len(3) */ - mbedtls_platform_memcpy( ssl->out_msg, msg->p, 6 ); - - (void)mbedtls_platform_put_uint24_be( &ssl->out_msg[6], frag_off ); - (void)mbedtls_platform_put_uint24_be( &ssl->out_msg[9], - cur_hs_frag_len ); - - MBEDTLS_SSL_DEBUG_BUF( 3, "handshake header", ssl->out_msg, 12 ); - - /* Copy the handshake message content and set records fields */ - mbedtls_platform_memcpy( ssl->out_msg + 12, p, cur_hs_frag_len ); - ssl->out_msglen = cur_hs_frag_len + 12; - ssl->out_msgtype = msg->type; - - /* Update position inside current message */ - ssl->handshake->cur_msg_p += cur_hs_frag_len; - } - - /* If done with the current message move to the next one if any */ - if( ssl->handshake->cur_msg_p >= msg->p + msg->len ) - { - if( msg->next != NULL ) - { - ssl->handshake->cur_msg = msg->next; - ssl->handshake->cur_msg_p = msg->next->p + 12; - } - else - { - ssl->handshake->cur_msg = NULL; - ssl->handshake->cur_msg_p = NULL; - } - } - - /* Actually send the message out */ - if( ( ret = mbedtls_ssl_write_record( ssl, force_flush ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret ); - return( ret ); - } - return( ret ); -} - /* * Append current handshake message to current outgoing flight */ static int ssl_flight_append( mbedtls_ssl_context *ssl ) { mbedtls_ssl_flight_item *msg; - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_flight_append" ) ); - MBEDTLS_SSL_DEBUG_BUF( 4, "message appended to flight", - ssl->out_msg, ssl->out_msglen ); /* Allocate space for current message */ if( ( msg = mbedtls_calloc( 1, sizeof( mbedtls_ssl_flight_item ) ) ) == NULL ) @@ -4512,7 +2655,7 @@ static int ssl_flight_append( mbedtls_ssl_context *ssl ) } /* Copy current handshake message with headers */ - mbedtls_platform_memcpy( msg->p, ssl->out_msg, ssl->out_msglen ); + memcpy( msg->p, ssl->out_msg, ssl->out_msglen ); msg->len = ssl->out_msglen; msg->type = ssl->out_msgtype; msg->next = NULL; @@ -4528,25 +2671,6 @@ static int ssl_flight_append( mbedtls_ssl_context *ssl ) cur->next = msg; } -#if defined(MBEDTLS_SSL_IMMEDIATE_TRANSMISSION) - ssl->handshake->cur_msg = msg; - ssl->handshake->cur_msg_p = msg->p + 12; - { - int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; - while( ssl->handshake->cur_msg != NULL ) - { - if( ( ret = mbedtls_ssl_flight_transmit_msg( ssl, ssl->handshake->cur_msg ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flight_transmit_msg", ret ); - return( ret ); - } - - if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 ) - return( ret ); - } - } -#endif - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_flight_append" ) ); return( 0 ); } @@ -4576,18 +2700,15 @@ static void ssl_dtls_replay_reset( mbedtls_ssl_context *ssl ); /* * Swap transform_out and out_ctr with the alternative ones */ -static int ssl_swap_epochs( mbedtls_ssl_context *ssl ) +static void ssl_swap_epochs( mbedtls_ssl_context *ssl ) { mbedtls_ssl_transform *tmp_transform; unsigned char tmp_out_ctr[8]; -#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) - int ret; -#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */ if( ssl->transform_out == ssl->handshake->alt_transform_out ) { MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip swap epochs" ) ); - return( 0 ); + return; } MBEDTLS_SSL_DEBUG_MSG( 3, ( "swap epochs" ) ); @@ -4598,12 +2719,19 @@ static int ssl_swap_epochs( mbedtls_ssl_context *ssl ) ssl->handshake->alt_transform_out = tmp_transform; /* Swap epoch + sequence_number */ - mbedtls_platform_memcpy( tmp_out_ctr, ssl->cur_out_ctr, 8 ); - mbedtls_platform_memcpy( ssl->cur_out_ctr, ssl->handshake->alt_out_ctr, 8 ); - mbedtls_platform_memcpy( ssl->handshake->alt_out_ctr, tmp_out_ctr, 8 ); + memcpy( tmp_out_ctr, ssl->out_ctr, 8 ); + memcpy( ssl->out_ctr, ssl->handshake->alt_out_ctr, 8 ); + memcpy( ssl->handshake->alt_out_ctr, tmp_out_ctr, 8 ); /* Adjust to the newly activated transform */ - ssl_update_out_pointers( ssl, ssl->transform_out ); + if( ssl->transform_out != NULL && + ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 ) + { + ssl->out_msg = ssl->out_iv + ssl->transform_out->ivlen - + ssl->transform_out->fixed_ivlen; + } + else + ssl->out_msg = ssl->out_iv; #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) if( mbedtls_ssl_hw_record_activate != NULL ) @@ -4614,82 +2742,59 @@ static int ssl_swap_epochs( mbedtls_ssl_context *ssl ) return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); } } -#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */ - - return( 0 ); +#endif } /* * Retransmit the current flight of messages. - */ -int mbedtls_ssl_resend( mbedtls_ssl_context *ssl ) -{ - int ret = 0; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> mbedtls_ssl_resend" ) ); - - ret = mbedtls_ssl_flight_transmit( ssl ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= mbedtls_ssl_resend" ) ); - - return( ret ); -} - -#if defined(MBEDTLS_SSL_IMMEDIATE_TRANSMISSION) -void mbedtls_ssl_immediate_flight_done( mbedtls_ssl_context *ssl ) -{ - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> mbedtls_ssl_immediate_flight_done" ) ); - - /* Update state and set timer */ - if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER ) - ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED; - else - { - ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING; - ssl_set_timer( ssl, ssl->handshake->retransmit_timeout ); - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= mbedtls_ssl_immediate_flight_done" ) ); -} -#endif - -/* - * Transmit or retransmit the current flight of messages. * * Need to remember the current message in case flush_output returns * WANT_WRITE, causing us to exit this function and come back later. * This function must be called until state is no longer SENDING. */ -int mbedtls_ssl_flight_transmit( mbedtls_ssl_context *ssl ) +int mbedtls_ssl_resend( mbedtls_ssl_context *ssl ) { - int ret; - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> mbedtls_ssl_flight_transmit" ) ); + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> mbedtls_ssl_resend" ) ); if( ssl->handshake->retransmit_state != MBEDTLS_SSL_RETRANS_SENDING ) { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "initialise flight transmission" ) ); + MBEDTLS_SSL_DEBUG_MSG( 2, ( "initialise resending" ) ); ssl->handshake->cur_msg = ssl->handshake->flight; - ssl->handshake->cur_msg_p = ssl->handshake->flight->p + 12; - if( ( ret = ssl_swap_epochs( ssl ) ) != 0 ) - return( ret ); + ssl_swap_epochs( ssl ); ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_SENDING; } while( ssl->handshake->cur_msg != NULL ) { - if( ( ret = mbedtls_ssl_flight_transmit_msg( ssl, ssl->handshake->cur_msg ) ) != 0 ) + int ret; + mbedtls_ssl_flight_item *cur = ssl->handshake->cur_msg; + + /* Swap epochs before sending Finished: we can't do it after + * sending ChangeCipherSpec, in case write returns WANT_READ. + * Must be done before copying, may change out_msg pointer */ + if( cur->type == MBEDTLS_SSL_MSG_HANDSHAKE && + cur->p[0] == MBEDTLS_SSL_HS_FINISHED ) { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flight_transmit_msg", ret ); + ssl_swap_epochs( ssl ); + } + + memcpy( ssl->out_msg, cur->p, cur->len ); + ssl->out_msglen = cur->len; + ssl->out_msgtype = cur->type; + + ssl->handshake->cur_msg = cur->next; + + MBEDTLS_SSL_DEBUG_BUF( 3, "resent handshake message header", ssl->out_msg, 12 ); + + if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret ); return( ret ); } } - if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 ) - return( ret ); - - /* Update state and set timer */ if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER ) ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED; else @@ -4698,9 +2803,9 @@ int mbedtls_ssl_flight_transmit( mbedtls_ssl_context *ssl ) ssl_set_timer( ssl, ssl->handshake->retransmit_timeout ); } - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= mbedtls_ssl_flight_transmit" ) ); + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= mbedtls_ssl_resend" ) ); - return( ret ); + return( 0 ); } /* @@ -4716,12 +2821,6 @@ void mbedtls_ssl_recv_flight_completed( mbedtls_ssl_context *ssl ) /* The next incoming flight will start with this msg_seq */ ssl->handshake->in_flight_start_seq = ssl->handshake->in_msg_seq; - /* We don't want to remember CCS's across flight boundaries. */ - ssl->handshake->buffering.seen_ccs = 0; - - /* Clear future message buffering structure. */ - ssl_buffering_free( ssl ); - /* Cancel timer */ ssl_set_timer( ssl, 0 ); @@ -4753,101 +2852,43 @@ void mbedtls_ssl_send_flight_completed( mbedtls_ssl_context *ssl ) #endif /* MBEDTLS_SSL_PROTO_DTLS */ /* - * Handshake layer functions + * Record layer functions */ /* - * Write (DTLS: or queue) current handshake (including CCS) message. - * - * - fill in handshake headers - * - update handshake checksum - * - DTLS: save message for resending - * - then pass to the record layer - * - * DTLS: except for HelloRequest, messages are only queued, and will only be - * actually sent when calling flight_transmit() or resend(). - * - * Inputs: - * - ssl->out_msglen: 4 + actual handshake message len - * (4 is the size of handshake headers for TLS) - * - ssl->out_msg[0]: the handshake type (ClientHello, ServerHello, etc) - * - ssl->out_msg + 4: the handshake message body - * - * Outputs, ie state before passing to flight_append() or write_record(): - * - ssl->out_msglen: the length of the record contents - * (including handshake headers but excluding record headers) - * - ssl->out_msg: the record contents (handshake headers + content) + * Write current record. + * Uses ssl->out_msgtype, ssl->out_msglen and bytes at ssl->out_msg. */ -int mbedtls_ssl_write_handshake_msg( mbedtls_ssl_context *ssl ) +int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl ) { - int ret; - const size_t hs_len = ssl->out_msglen - 4; - const unsigned char hs_type = ssl->out_msg[0]; + int ret, done = 0, out_msg_type; + size_t len = ssl->out_msglen; - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write handshake message" ) ); + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write record" ) ); - /* - * Sanity checks - */ - if( ssl->out_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE && - ssl->out_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC ) +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && + ssl->handshake != NULL && + ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING ) { - /* In SSLv3, the client might send a NoCertificate alert. */ -#if defined(MBEDTLS_SSL_PROTO_SSL3) && defined(MBEDTLS_SSL_CLI_C) - if( ! ( mbedtls_ssl_get_minor_ver( ssl ) == MBEDTLS_SSL_MINOR_VERSION_0 && - ssl->out_msgtype == MBEDTLS_SSL_MSG_ALERT && - mbedtls_ssl_conf_get_endpoint( ssl->conf ) == - MBEDTLS_SSL_IS_CLIENT ) ) -#endif /* MBEDTLS_SSL_PROTO_SSL3 && MBEDTLS_SSL_SRV_C */ + ; /* Skip special handshake treatment when resending */ + } + else +#endif + if( ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE ) + { + out_msg_type = ssl->out_msg[0]; + + if( out_msg_type != MBEDTLS_SSL_HS_HELLO_REQUEST && + ssl->handshake == NULL ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); } - } - /* Whenever we send anything different from a - * HelloRequest we should be in a handshake - double check. */ - if( ! ( ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && - hs_type == MBEDTLS_SSL_HS_HELLO_REQUEST ) && - ssl->handshake == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) && - ssl->handshake != NULL && - ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } -#endif - - /* Double-check that we did not exceed the bounds - * of the outgoing record buffer. - * This should never fail as the various message - * writing functions must obey the bounds of the - * outgoing record buffer, but better be safe. - * - * Note: We deliberately do not check for the MTU or MFL here. - */ - if( ssl->out_msglen > MBEDTLS_SSL_OUT_CONTENT_LEN ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "Record too large: " - "size %u, maximum %u", - (unsigned) ssl->out_msglen, - (unsigned) MBEDTLS_SSL_OUT_CONTENT_LEN ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - /* - * Fill handshake headers - */ - if( ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE ) - { - (void)mbedtls_platform_put_uint24_be( &ssl->out_msg[1], hs_len ); + ssl->out_msg[1] = (unsigned char)( ( len - 4 ) >> 16 ); + ssl->out_msg[2] = (unsigned char)( ( len - 4 ) >> 8 ); + ssl->out_msg[3] = (unsigned char)( ( len - 4 ) ); /* * DTLS has additional fields in the Handshake layer, @@ -4857,26 +2898,27 @@ int mbedtls_ssl_write_handshake_msg( mbedtls_ssl_context *ssl ) * uint24 fragment_length; */ #if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) ) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) { /* Make room for the additional DTLS fields */ - if( MBEDTLS_SSL_OUT_CONTENT_LEN - ssl->out_msglen < 8 ) + if( MBEDTLS_SSL_MAX_CONTENT_LEN - ssl->out_msglen < 8 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "DTLS handshake message too large: " "size %u, maximum %u", - (unsigned) ( hs_len ), - (unsigned) ( MBEDTLS_SSL_OUT_CONTENT_LEN - 12 ) ) ); + (unsigned) ( ssl->in_hslen - 4 ), + (unsigned) ( MBEDTLS_SSL_MAX_CONTENT_LEN - 12 ) ) ); return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); } - memmove( ssl->out_msg + 12, ssl->out_msg + 4, hs_len ); + memmove( ssl->out_msg + 12, ssl->out_msg + 4, len - 4 ); ssl->out_msglen += 8; + len += 8; /* Write message_seq and update it, except for HelloRequest */ - if( hs_type != MBEDTLS_SSL_HS_HELLO_REQUEST ) + if( out_msg_type != MBEDTLS_SSL_HS_HELLO_REQUEST ) { - (void)mbedtls_platform_put_uint16_be( &ssl->out_msg[4], - ssl->handshake->out_msg_seq ); + ssl->out_msg[4] = ( ssl->handshake->out_msg_seq >> 8 ) & 0xFF; + ssl->out_msg[5] = ( ssl->handshake->out_msg_seq ) & 0xFF; ++( ssl->handshake->out_msg_seq ); } else @@ -4885,31 +2927,23 @@ int mbedtls_ssl_write_handshake_msg( mbedtls_ssl_context *ssl ) ssl->out_msg[5] = 0; } - /* Handshake hashes are computed without fragmentation, - * so set frag_offset = 0 and frag_len = hs_len for now */ - if( mbedtls_platform_memset( ssl->out_msg + 6, 0x00, 3 ) != - ssl->out_msg + 6 ) - { - return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); - } - if( mbedtls_platform_memcpy( ssl->out_msg + 9, ssl->out_msg + 1, 3 ) != - ssl->out_msg + 9 ) - { - return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); - } + /* We don't fragment, so frag_offset = 0 and frag_len = len */ + memset( ssl->out_msg + 6, 0x00, 3 ); + memcpy( ssl->out_msg + 9, ssl->out_msg + 1, 3 ); } #endif /* MBEDTLS_SSL_PROTO_DTLS */ - /* Update running hashes of handshake messages seen */ - if( hs_type != MBEDTLS_SSL_HS_HELLO_REQUEST ) - mbedtls_ssl_update_checksum( ssl, ssl->out_msg, ssl->out_msglen ); + if( out_msg_type != MBEDTLS_SSL_HS_HELLO_REQUEST ) + ssl->handshake->update_checksum( ssl, ssl->out_msg, len ); } - /* Either send now, or just save to be sent (and resent) later */ + /* Save handshake and CCS messages for resending */ #if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) && - ! ( ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && - hs_type == MBEDTLS_SSL_HS_HELLO_REQUEST ) ) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && + ssl->handshake != NULL && + ssl->handshake->retransmit_state != MBEDTLS_SSL_RETRANS_SENDING && + ( ssl->out_msgtype == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC || + ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE ) ) { if( ( ret = ssl_flight_append( ssl ) ) != 0 ) { @@ -4917,40 +2951,7 @@ int mbedtls_ssl_write_handshake_msg( mbedtls_ssl_context *ssl ) return( ret ); } } - else #endif - { - if( ( ret = mbedtls_ssl_write_record( ssl, SSL_FORCE_FLUSH ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_record", ret ); - return( ret ); - } - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write handshake message" ) ); - - return( 0 ); -} - -/* - * Record layer functions - */ - -/* - * Write current record. - * - * Uses: - * - ssl->out_msgtype: type of the message (AppData, Handshake, Alert, CCS) - * - ssl->out_msglen: length of the record content (excl headers) - * - ssl->out_msg: record content - */ -int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl, uint8_t force_flush ) -{ - int ret, done = 0; - size_t len = ssl->out_msglen; - uint8_t flush = force_flush; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write record" ) ); #if defined(MBEDTLS_ZLIB_SUPPORT) if( ssl->transform_out != NULL && @@ -4984,151 +2985,38 @@ int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl, uint8_t force_flush ) #endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */ if( !done ) { - unsigned i; - size_t protected_record_size; - volatile int encrypted_fi = 0; -#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) - size_t out_buf_len = ssl->out_buf_len; -#else - size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN; -#endif + ssl->out_hdr[0] = (unsigned char) ssl->out_msgtype; + mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver, + ssl->conf->transport, ssl->out_hdr + 1 ); - /* Skip writing the record content type to after the encryption, - * as it may change when using the CID extension. */ - - mbedtls_ssl_write_version( mbedtls_ssl_get_major_ver( ssl ), - mbedtls_ssl_get_minor_ver( ssl ), - mbedtls_ssl_conf_get_transport( ssl->conf ), - ssl->out_hdr + 1 ); - - mbedtls_platform_memcpy( ssl->out_ctr, ssl->cur_out_ctr, 8 ); - (void)mbedtls_platform_put_uint16_be( ssl->out_len, len ); + ssl->out_len[0] = (unsigned char)( len >> 8 ); + ssl->out_len[1] = (unsigned char)( len ); if( ssl->transform_out != NULL ) { - mbedtls_record rec; - - rec.buf = ssl->out_iv; - rec.buf_len = out_buf_len - ( ssl->out_iv - ssl->out_buf ); - rec.data_len = ssl->out_msglen; - rec.data_offset = ssl->out_msg - rec.buf; - - mbedtls_platform_memcpy( &rec.ctr[0], ssl->out_ctr, 8 ); - mbedtls_ssl_write_version( mbedtls_ssl_get_major_ver( ssl ), - mbedtls_ssl_get_minor_ver( ssl ), - mbedtls_ssl_conf_get_transport( ssl->conf ), - rec.ver ); - rec.type = ssl->out_msgtype; - -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - /* The CID is set by mbedtls_ssl_encrypt_buf(). */ - rec.cid_len = 0; -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - - if( ( ret = mbedtls_ssl_encrypt_buf( ssl, ssl->transform_out, &rec, - mbedtls_ssl_conf_get_frng( ssl->conf ), - mbedtls_ssl_conf_get_prng( ssl->conf ) ) ) != 0 ) + if( ( ret = ssl_encrypt_buf( ssl ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "ssl_encrypt_buf", ret ); return( ret ); } - if( rec.data_offset != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - /* Update the record content type and CID. */ - ssl->out_msgtype = rec.type; -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID ) - /* Not using more secure mbedtls_platform_memcpy as cid is public */ - memcpy( ssl->out_cid, rec.cid, rec.cid_len ); -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - ssl->out_msglen = len = rec.data_len; - (void)mbedtls_platform_put_uint16_be( ssl->out_len, rec.data_len ); - encrypted_fi = 1; + len = ssl->out_msglen; + ssl->out_len[0] = (unsigned char)( len >> 8 ); + ssl->out_len[1] = (unsigned char)( len ); } - /* Double check to ensure the encryption has been done */ - if( ssl->transform_out != NULL && encrypted_fi == 0 ) - { - return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); - } - - protected_record_size = len + mbedtls_ssl_out_hdr_len( ssl ); - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - /* In case of DTLS, double-check that we don't exceed - * the remaining space in the datagram. */ - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) ) - { - ret = ssl_get_remaining_space_in_datagram( ssl ); - if( ret < 0 ) - return( ret ); - - if( protected_record_size > (size_t) ret ) - { - /* Should never happen */ - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - /* Now write the potentially updated record content type. */ - ssl->out_hdr[0] = (unsigned char) ssl->out_msgtype; + ssl->out_left = mbedtls_ssl_hdr_len( ssl ) + ssl->out_msglen; MBEDTLS_SSL_DEBUG_MSG( 3, ( "output record: msgtype = %d, " - "version = [%d:%d], msglen = %d", - ssl->out_hdr[0], ssl->out_hdr[1], - ssl->out_hdr[2], len ) ); + "version = [%d:%d], msglen = %d", + ssl->out_hdr[0], ssl->out_hdr[1], ssl->out_hdr[2], + ( ssl->out_len[0] << 8 ) | ssl->out_len[1] ) ); MBEDTLS_SSL_DEBUG_BUF( 4, "output record sent to network", - ssl->out_hdr, protected_record_size ); - - ssl->out_left += protected_record_size; - ssl->out_hdr += protected_record_size; - ssl_update_out_pointers( ssl, ssl->transform_out ); - - for( i = 8; i > ssl_ep_len( ssl ); i-- ) - if( ++ssl->cur_out_ctr[i - 1] != 0 ) - break; - - /* The loop goes to its end iff the counter is wrapping */ - if( i == ssl_ep_len( ssl ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "outgoing message counter would wrap" ) ); - return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING ); - } + ssl->out_hdr, mbedtls_ssl_hdr_len( ssl ) + ssl->out_msglen ); } -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) && - flush == SSL_DONT_FORCE_FLUSH ) - { - size_t remaining; - ret = ssl_get_remaining_payload_in_datagram( ssl ); - if( ret < 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "ssl_get_remaining_payload_in_datagram", - ret ); - return( ret ); - } - - remaining = (size_t) ret; - if( remaining == 0 ) - { - flush = SSL_FORCE_FLUSH; - } - else - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Still %u bytes available in current datagram", (unsigned) remaining ) ); - } - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - if( ( flush == SSL_FORCE_FLUSH ) && - ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 ) + if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flush_output", ret ); return( ret ); @@ -5140,48 +3028,6 @@ int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl, uint8_t force_flush ) } #if defined(MBEDTLS_SSL_PROTO_DTLS) - -static int ssl_hs_is_proper_fragment( mbedtls_ssl_context *ssl ) -{ - if( ssl->in_msglen < ssl->in_hslen || - mbedtls_platform_memequal( ssl->in_msg + 6, "\0\0\0", 3 ) != 0 || - mbedtls_platform_memequal( ssl->in_msg + 9, ssl->in_msg + 1, 3 ) != 0 ) - { - return( PROPER_HS_FRAGMENT ); - } - return( 0 ); -} - -static uint32_t ssl_get_hs_frag_len( mbedtls_ssl_context const *ssl ) -{ - return( (uint32_t)mbedtls_platform_get_uint24_be( &ssl->in_msg[9] ) ); -} - -static uint32_t ssl_get_hs_frag_off( mbedtls_ssl_context const *ssl ) -{ - return( (uint32_t)mbedtls_platform_get_uint24_be( &ssl->in_msg[6] ) ); -} - -static int ssl_check_hs_header( mbedtls_ssl_context const *ssl ) -{ - uint32_t msg_len, frag_off, frag_len; - - msg_len = ssl_get_hs_total_len( ssl ); - frag_off = ssl_get_hs_frag_off( ssl ); - frag_len = ssl_get_hs_frag_len( ssl ); - - if( frag_off > msg_len ) - return( -1 ); - - if( frag_len > msg_len - frag_off ) - return( -1 ); - - if( frag_len + 12 > ssl->in_msglen ) - return( -1 ); - - return( 0 ); -} - /* * Mark bits in bitmask (used for DTLS HS reassembly) */ @@ -5225,7 +3071,6 @@ static void ssl_bitmask_set( unsigned char *mask, size_t offset, size_t len ) memset( mask + offset / 8, 0xFF, len / 8 ); } -#define BITMASK_CHECK_FAILED 0x75555555 /* * Check that bitmask is full */ @@ -5235,37 +3080,172 @@ static int ssl_bitmask_check( unsigned char *mask, size_t len ) for( i = 0; i < len / 8; i++ ) if( mask[i] != 0xFF ) - return( BITMASK_CHECK_FAILED ); + return( -1 ); for( i = 0; i < len % 8; i++ ) if( ( mask[len / 8] & ( 1 << ( 7 - i ) ) ) == 0 ) - return( BITMASK_CHECK_FAILED ); + return( -1 ); return( 0 ); } -/* msg_len does not include the handshake header */ -static size_t ssl_get_reassembly_buffer_size( size_t msg_len, - unsigned add_bitmap ) +/* + * Reassemble fragmented DTLS handshake messages. + * + * Use a temporary buffer for reassembly, divided in two parts: + * - the first holds the reassembled message (including handshake header), + * - the second holds a bitmask indicating which parts of the message + * (excluding headers) have been received so far. + */ +static int ssl_reassemble_dtls_handshake( mbedtls_ssl_context *ssl ) { - size_t alloc_len; + unsigned char *msg, *bitmask; + size_t frag_len, frag_off; + size_t msg_len = ssl->in_hslen - 12; /* Without headers */ - alloc_len = 12; /* Handshake header */ - alloc_len += msg_len; /* Content buffer */ + if( ssl->handshake == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "not supported outside handshake (for now)" ) ); + return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); + } - if( add_bitmap ) - alloc_len += msg_len / 8 + ( msg_len % 8 != 0 ); /* Bitmap */ + /* + * For first fragment, check size and allocate buffer + */ + if( ssl->handshake->hs_msg == NULL ) + { + size_t alloc_len; - return( alloc_len ); + MBEDTLS_SSL_DEBUG_MSG( 2, ( "initialize reassembly, total length = %d", + msg_len ) ); + + if( ssl->in_hslen > MBEDTLS_SSL_MAX_CONTENT_LEN ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake message too large" ) ); + return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); + } + + /* The bitmask needs one bit per byte of message excluding header */ + alloc_len = 12 + msg_len + msg_len / 8 + ( msg_len % 8 != 0 ); + + ssl->handshake->hs_msg = mbedtls_calloc( 1, alloc_len ); + if( ssl->handshake->hs_msg == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc failed (%d bytes)", alloc_len ) ); + return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); + } + + /* Prepare final header: copy msg_type, length and message_seq, + * then add standardised fragment_offset and fragment_length */ + memcpy( ssl->handshake->hs_msg, ssl->in_msg, 6 ); + memset( ssl->handshake->hs_msg + 6, 0, 3 ); + memcpy( ssl->handshake->hs_msg + 9, + ssl->handshake->hs_msg + 1, 3 ); + } + else + { + /* Make sure msg_type and length are consistent */ + if( memcmp( ssl->handshake->hs_msg, ssl->in_msg, 4 ) != 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "fragment header mismatch" ) ); + return( MBEDTLS_ERR_SSL_INVALID_RECORD ); + } + } + + msg = ssl->handshake->hs_msg + 12; + bitmask = msg + msg_len; + + /* + * Check and copy current fragment + */ + frag_off = ( ssl->in_msg[6] << 16 ) | + ( ssl->in_msg[7] << 8 ) | + ssl->in_msg[8]; + frag_len = ( ssl->in_msg[9] << 16 ) | + ( ssl->in_msg[10] << 8 ) | + ssl->in_msg[11]; + + if( frag_off + frag_len > msg_len ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid fragment offset/len: %d + %d > %d", + frag_off, frag_len, msg_len ) ); + return( MBEDTLS_ERR_SSL_INVALID_RECORD ); + } + + if( frag_len + 12 > ssl->in_msglen ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid fragment length: %d + 12 > %d", + frag_len, ssl->in_msglen ) ); + return( MBEDTLS_ERR_SSL_INVALID_RECORD ); + } + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "adding fragment, offset = %d, length = %d", + frag_off, frag_len ) ); + + memcpy( msg + frag_off, ssl->in_msg + 12, frag_len ); + ssl_bitmask_set( bitmask, frag_off, frag_len ); + + /* + * Do we have the complete message by now? + * If yes, finalize it, else ask to read the next record. + */ + if( ssl_bitmask_check( bitmask, msg_len ) != 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "message is not complete yet" ) ); + return( MBEDTLS_ERR_SSL_WANT_READ ); + } + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "handshake message completed" ) ); + + if( frag_len + 12 < ssl->in_msglen ) + { + /* + * We'got more handshake messages in the same record. + * This case is not handled now because no know implementation does + * that and it's hard to test, so we prefer to fail cleanly for now. + */ + MBEDTLS_SSL_DEBUG_MSG( 1, ( "last fragment not alone in its record" ) ); + return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); + } + + if( ssl->in_left > ssl->next_record_offset ) + { + /* + * We've got more data in the buffer after the current record, + * that we don't want to overwrite. Move it before writing the + * reassembled message, and adjust in_left and next_record_offset. + */ + unsigned char *cur_remain = ssl->in_hdr + ssl->next_record_offset; + unsigned char *new_remain = ssl->in_msg + ssl->in_hslen; + size_t remain_len = ssl->in_left - ssl->next_record_offset; + + /* First compute and check new lengths */ + ssl->next_record_offset = new_remain - ssl->in_hdr; + ssl->in_left = ssl->next_record_offset + remain_len; + + if( ssl->in_left > MBEDTLS_SSL_BUFFER_LEN - + (size_t)( ssl->in_hdr - ssl->in_buf ) ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "reassembled message too large for buffer" ) ); + return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); + } + + memmove( new_remain, cur_remain, remain_len ); + } + + memcpy( ssl->in_msg, ssl->handshake->hs_msg, ssl->in_hslen ); + + mbedtls_zeroize( ssl->handshake->hs_msg, ssl->in_hslen ); + mbedtls_free( ssl->handshake->hs_msg ); + ssl->handshake->hs_msg = NULL; + + MBEDTLS_SSL_DEBUG_BUF( 3, "reassembled handshake message", + ssl->in_msg, ssl->in_hslen ); + + return( 0 ); } - #endif /* MBEDTLS_SSL_PROTO_DTLS */ -static uint32_t ssl_get_hs_total_len( mbedtls_ssl_context const *ssl ) -{ - return( (uint32_t)mbedtls_platform_get_uint24_be( &ssl->in_msg[1] ) ); -} - int mbedtls_ssl_prepare_handshake_record( mbedtls_ssl_context *ssl ) { if( ssl->in_msglen < mbedtls_ssl_hs_hdr_len( ssl ) ) @@ -5275,39 +3255,25 @@ int mbedtls_ssl_prepare_handshake_record( mbedtls_ssl_context *ssl ) return( MBEDTLS_ERR_SSL_INVALID_RECORD ); } - ssl->in_hslen = mbedtls_ssl_hs_hdr_len( ssl ) + ssl_get_hs_total_len( ssl ); + ssl->in_hslen = mbedtls_ssl_hs_hdr_len( ssl ) + ( + ( ssl->in_msg[1] << 16 ) | + ( ssl->in_msg[2] << 8 ) | + ssl->in_msg[3] ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "handshake message: msglen =" " %d, type = %d, hslen = %d", ssl->in_msglen, ssl->in_msg[0], ssl->in_hslen ) ); #if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) ) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) { int ret; - unsigned int recv_msg_seq = (unsigned int) - mbedtls_platform_get_uint16_be( &ssl->in_msg[4] ); - - if( ssl_check_hs_header( ssl ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid handshake header" ) ); - return( MBEDTLS_ERR_SSL_INVALID_RECORD ); - } + unsigned int recv_msg_seq = ( ssl->in_msg[4] << 8 ) | ssl->in_msg[5]; + /* ssl->handshake is NULL when receiving ClientHello for renego */ if( ssl->handshake != NULL && - ( ( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER && - recv_msg_seq != ssl->handshake->in_msg_seq ) || - ( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER && - ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_HELLO ) ) ) + recv_msg_seq != ssl->handshake->in_msg_seq ) { - if( recv_msg_seq > ssl->handshake->in_msg_seq ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "received future handshake message of sequence number %u (next %u)", - recv_msg_seq, - ssl->handshake->in_msg_seq ) ); - return( MBEDTLS_ERR_SSL_EARLY_MESSAGE ); - } - /* Retransmit only on last message from previous flight, to avoid * too many retransmissions. * Besides, No sane server ever retransmits HelloVerifyRequest */ @@ -5333,71 +3299,53 @@ int mbedtls_ssl_prepare_handshake_record( mbedtls_ssl_context *ssl ) ssl->handshake->in_msg_seq ) ); } - return( MBEDTLS_ERR_SSL_CONTINUE_PROCESSING ); + return( MBEDTLS_ERR_SSL_WANT_READ ); } /* Wait until message completion to increment in_msg_seq */ - /* Message reassembly is handled alongside buffering of future - * messages; the commonality is that both handshake fragments and - * future messages cannot be forwarded immediately to the - * handshake logic layer. */ - if( ssl_hs_is_proper_fragment( ssl ) == PROPER_HS_FRAGMENT ) + /* Reassemble if current message is fragmented or reassembly is + * already in progress */ + if( ssl->in_msglen < ssl->in_hslen || + memcmp( ssl->in_msg + 6, "\0\0\0", 3 ) != 0 || + memcmp( ssl->in_msg + 9, ssl->in_msg + 1, 3 ) != 0 || + ( ssl->handshake != NULL && ssl->handshake->hs_msg != NULL ) ) { MBEDTLS_SSL_DEBUG_MSG( 2, ( "found fragmented DTLS handshake message" ) ); - return( MBEDTLS_ERR_SSL_EARLY_MESSAGE ); + + if( ( ret = ssl_reassemble_dtls_handshake( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "ssl_reassemble_dtls_handshake", ret ); + return( ret ); + } } } - MBEDTLS_SSL_TRANSPORT_ELSE + else #endif /* MBEDTLS_SSL_PROTO_DTLS */ -#if defined(MBEDTLS_SSL_PROTO_TLS) + /* With TLS we don't handle fragmentation (for now) */ + if( ssl->in_msglen < ssl->in_hslen ) { - /* With TLS we don't handle fragmentation (for now) */ - if( ssl->in_msglen < ssl->in_hslen ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "TLS handshake fragmentation not supported" ) ); - return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); - } + MBEDTLS_SSL_DEBUG_MSG( 1, ( "TLS handshake fragmentation not supported" ) ); + return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); } -#endif /* MBEDTLS_SSL_PROTO_TLS */ return( 0 ); } void mbedtls_ssl_update_handshake_status( mbedtls_ssl_context *ssl ) { - mbedtls_ssl_handshake_params * const hs = ssl->handshake; - if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER && hs != NULL ) - mbedtls_ssl_update_checksum( ssl, ssl->in_msg, ssl->in_hslen ); + if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER && + ssl->handshake != NULL ) + { + ssl->handshake->update_checksum( ssl, ssl->in_msg, ssl->in_hslen ); + } /* Handshake message is complete, increment counter */ #if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) && + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && ssl->handshake != NULL ) { - unsigned offset; - mbedtls_ssl_hs_buffer *hs_buf; - - /* Increment handshake sequence number */ - hs->in_msg_seq++; - - /* - * Clear up handshake buffering and reassembly structure. - */ - - /* Free first entry */ - ssl_buffering_free_slot( ssl, 0 ); - - /* Shift all other entries */ - for( offset = 0, hs_buf = &hs->buffering.hs[0]; - offset + 1 < MBEDTLS_SSL_MAX_BUFFERED_HS; - offset++, hs_buf++ ) - { - *hs_buf = *(hs_buf + 1); - } - - /* Create a fresh last entry */ - mbedtls_platform_memset( hs_buf, 0, sizeof( mbedtls_ssl_hs_buffer ) ); + ssl->handshake->in_msg_seq++; } #endif } @@ -5429,38 +3377,16 @@ static inline uint64_t ssl_load_six_bytes( unsigned char *buf ) ( (uint64_t) buf[5] ) ); } -static int mbedtls_ssl_dtls_record_replay_check( mbedtls_ssl_context *ssl, uint8_t *record_in_ctr ) -{ - int ret; - unsigned char *original_in_ctr; - - // save original in_ctr - original_in_ctr = ssl->in_ctr; - - // use counter from record - ssl->in_ctr = record_in_ctr; - - ret = mbedtls_ssl_dtls_replay_check( (mbedtls_ssl_context const *) ssl ); - - // restore the counter - ssl->in_ctr = original_in_ctr; - - return ret; -} - /* * Return 0 if sequence number is acceptable, -1 otherwise */ -int mbedtls_ssl_dtls_replay_check( mbedtls_ssl_context const *ssl ) +int mbedtls_ssl_dtls_replay_check( mbedtls_ssl_context *ssl ) { uint64_t rec_seqnum = ssl_load_six_bytes( ssl->in_ctr + 2 ); uint64_t bit; - if( mbedtls_ssl_conf_get_anti_replay( ssl->conf ) == - MBEDTLS_SSL_ANTI_REPLAY_DISABLED ) - { + if( ssl->conf->anti_replay == MBEDTLS_SSL_ANTI_REPLAY_DISABLED ) return( 0 ); - } if( rec_seqnum > ssl->in_window_top ) return( 0 ); @@ -5483,11 +3409,8 @@ void mbedtls_ssl_dtls_replay_update( mbedtls_ssl_context *ssl ) { uint64_t rec_seqnum = ssl_load_six_bytes( ssl->in_ctr + 2 ); - if( mbedtls_ssl_conf_get_anti_replay( ssl->conf ) == - MBEDTLS_SSL_ANTI_REPLAY_DISABLED ) - { + if( ssl->conf->anti_replay == MBEDTLS_SSL_ANTI_REPLAY_DISABLED ) return; - } if( rec_seqnum > ssl->in_window_top ) { @@ -5541,6 +3464,9 @@ static int ssl_check_dtls_clihlo_cookie( size_t sid_len, cookie_len; unsigned char *p; + if( f_cookie_write == NULL || f_cookie_check == NULL ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + /* * Structure of ClientHello with record and handshake headers, * and expected values. We don't need to check a lot, more checks will be @@ -5614,7 +3540,7 @@ static int ssl_check_dtls_clihlo_cookie( return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); /* Copy most fields and adapt others */ - mbedtls_platform_memcpy( obuf, in, 25 ); + memcpy( obuf, in, 25 ); obuf[13] = MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST; obuf[25] = 0xfe; obuf[26] = 0xff; @@ -5632,12 +3558,12 @@ static int ssl_check_dtls_clihlo_cookie( /* Go back and fill length fields */ obuf[27] = (unsigned char)( *olen - 28 ); - (void)mbedtls_platform_put_uint24_be( &obuf[14], ( *olen - 25 ) ); - obuf[22] = obuf[14]; - obuf[23] = obuf[15]; - obuf[24] = obuf[16]; + obuf[14] = obuf[22] = (unsigned char)( ( *olen - 25 ) >> 16 ); + obuf[15] = obuf[23] = (unsigned char)( ( *olen - 25 ) >> 8 ); + obuf[16] = obuf[24] = (unsigned char)( ( *olen - 25 ) ); - (void)mbedtls_platform_put_uint16_be( &obuf[11], ( *olen - 13 ) ); + obuf[11] = (unsigned char)( ( *olen - 13 ) >> 8 ); + obuf[12] = (unsigned char)( ( *olen - 13 ) ); return( MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED ); } @@ -5650,61 +3576,45 @@ static int ssl_check_dtls_clihlo_cookie( * that looks like a ClientHello. * * - if the input looks like a ClientHello without cookies, - * send back HelloVerifyRequest, then return 0 + * send back HelloVerifyRequest, then + * return MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED * - if the input looks like a ClientHello with a valid cookie, * reset the session of the current context, and * return MBEDTLS_ERR_SSL_CLIENT_RECONNECT * - if anything goes wrong, return a specific error code * - * This function is called (through ssl_check_client_reconnect()) when an - * unexpected record is found in ssl_get_next_record(), which will discard the - * record if we return 0, and bubble up the return value otherwise (this - * includes the case of MBEDTLS_ERR_SSL_CLIENT_RECONNECT and of unexpected - * errors, and is the right thing to do in both cases). + * mbedtls_ssl_read_record() will ignore the record if anything else than + * MBEDTLS_ERR_SSL_CLIENT_RECONNECT or 0 is returned, although this function + * cannot not return 0. */ static int ssl_handle_possible_reconnect( mbedtls_ssl_context *ssl ) { int ret; size_t len; - if( ssl->conf->f_cookie_write == NULL || - ssl->conf->f_cookie_check == NULL ) - { - /* If we can't use cookies to verify reachability of the peer, - * drop the record. */ - MBEDTLS_SSL_DEBUG_MSG( 1, ( "no cookie callbacks, " - "can't check reconnect validity" ) ); - return( 0 ); - } - ret = ssl_check_dtls_clihlo_cookie( ssl->conf->f_cookie_write, ssl->conf->f_cookie_check, ssl->conf->p_cookie, ssl->cli_id, ssl->cli_id_len, ssl->in_buf, ssl->in_left, - ssl->out_buf, MBEDTLS_SSL_OUT_CONTENT_LEN, &len ); + ssl->out_buf, MBEDTLS_SSL_MAX_CONTENT_LEN, &len ); MBEDTLS_SSL_DEBUG_RET( 2, "ssl_check_dtls_clihlo_cookie", ret ); if( ret == MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED ) { - int send_ret; - MBEDTLS_SSL_DEBUG_MSG( 1, ( "sending HelloVerifyRequest" ) ); - MBEDTLS_SSL_DEBUG_BUF( 4, "output record sent to network", - ssl->out_buf, len ); /* Don't check write errors as we can't do anything here. * If the error is permanent we'll catch it later, * if it's not, then hopefully it'll work next time. */ - send_ret = mbedtls_ssl_get_send( ssl )( ssl->p_bio, ssl->out_buf, len ); - MBEDTLS_SSL_DEBUG_RET( 2, "mbedtls_ssl_get_send", send_ret ); - (void) send_ret; - return( 0 ); + (void) ssl->f_send( ssl->p_bio, ssl->out_buf, len ); + + return( MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED ); } if( ret == 0 ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "cookie is valid, resetting context" ) ); + /* Got a valid cookie, partially reset context */ if( ( ret = ssl_session_reset_int( ssl, 1 ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "reset", ret ); @@ -5718,19 +3628,6 @@ static int ssl_handle_possible_reconnect( mbedtls_ssl_context *ssl ) } #endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */ -static int ssl_check_record_type( uint8_t record_type ) -{ - if( record_type != MBEDTLS_SSL_MSG_HANDSHAKE && - record_type != MBEDTLS_SSL_MSG_ALERT && - record_type != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC && - record_type != MBEDTLS_SSL_MSG_APPLICATION_DATA ) - { - return( MBEDTLS_ERR_SSL_INVALID_RECORD ); - } - - return( 0 ); -} - /* * ContentType type; * ProtocolVersion version; @@ -5750,233 +3647,170 @@ static int ssl_check_record_type( uint8_t record_type ) * Point 2 is needed when the peer is resending, and we have already received * the first record from a datagram but are still waiting for the others. */ -static int ssl_parse_record_header( mbedtls_ssl_context const *ssl, - unsigned char *buf, - size_t len, - mbedtls_record *rec ) +static int ssl_parse_record_header( mbedtls_ssl_context *ssl ) { int major_ver, minor_ver; - size_t const rec_hdr_type_offset = 0; - size_t const rec_hdr_type_len = 1; + MBEDTLS_SSL_DEBUG_BUF( 4, "input record header", ssl->in_hdr, mbedtls_ssl_hdr_len( ssl ) ); - size_t const rec_hdr_version_offset = rec_hdr_type_offset + - rec_hdr_type_len; - size_t const rec_hdr_version_len = 2; + ssl->in_msgtype = ssl->in_hdr[0]; + ssl->in_msglen = ( ssl->in_len[0] << 8 ) | ssl->in_len[1]; + mbedtls_ssl_read_version( &major_ver, &minor_ver, ssl->conf->transport, ssl->in_hdr + 1 ); - size_t const rec_hdr_ctr_len = 8; -#if defined(MBEDTLS_SSL_PROTO_DTLS) - uint32_t rec_epoch; - size_t const rec_hdr_ctr_offset = rec_hdr_version_offset + - rec_hdr_version_len; + MBEDTLS_SSL_DEBUG_MSG( 3, ( "input record: msgtype = %d, " + "version = [%d:%d], msglen = %d", + ssl->in_msgtype, + major_ver, minor_ver, ssl->in_msglen ) ); -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - size_t const rec_hdr_cid_offset = rec_hdr_ctr_offset + - rec_hdr_ctr_len; - size_t rec_hdr_cid_len = 0; -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - size_t rec_hdr_len_offset; /* To be determined */ - size_t const rec_hdr_len_len = 2; - - /* - * Check minimum lengths for record header. - */ + /* Check record type */ + if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE && + ssl->in_msgtype != MBEDTLS_SSL_MSG_ALERT && + ssl->in_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC && + ssl->in_msgtype != MBEDTLS_SSL_MSG_APPLICATION_DATA ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "unknown record type" ) ); #if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) ) - { - rec_hdr_len_offset = rec_hdr_ctr_offset + rec_hdr_ctr_len; - } - MBEDTLS_SSL_TRANSPORT_ELSE -#endif /* MBEDTLS_SSL_PROTO_DTLS */ -#if defined(MBEDTLS_SSL_PROTO_TLS) - { - rec_hdr_len_offset = rec_hdr_version_offset + rec_hdr_version_len; - } + /* Silently ignore invalid DTLS records as recommended by RFC 6347 + * Section 4.1.2.7 */ + if( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ) #endif /* MBEDTLS_SSL_PROTO_DTLS */ + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); - if( len < rec_hdr_len_offset + rec_hdr_len_len ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "datagram of length %u too small to hold DTLS record header of length %u", - (unsigned) len, - (unsigned)( rec_hdr_len_len + rec_hdr_len_len ) ) ); return( MBEDTLS_ERR_SSL_INVALID_RECORD ); } - /* - * Parse and validate record content type - */ - - rec->type = buf[ rec_hdr_type_offset ]; - - /* Check record content type */ -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - rec->cid_len = 0; - - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) && - mbedtls_ssl_conf_get_cid_len( ssl->conf ) != 0 && - rec->type == MBEDTLS_SSL_MSG_CID ) - { - /* Shift pointers to account for record header including CID - * struct { - * ContentType special_type = tls12_cid; - * ProtocolVersion version; - * uint16 epoch; - * uint48 sequence_number; - * opaque cid[cid_length]; // Additional field compared to - * // default DTLS record format - * uint16 length; - * opaque enc_content[DTLSCiphertext.length]; - * } DTLSCiphertext; - */ - - /* So far, we only support static CID lengths - * fixed in the configuration. */ - rec_hdr_cid_len = mbedtls_ssl_conf_get_cid_len( ssl->conf ); - rec_hdr_len_offset += rec_hdr_cid_len; - - if( len < rec_hdr_len_offset + rec_hdr_len_len ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "datagram of length %u too small to hold DTLS record header including CID, length %u", - (unsigned) len, - (unsigned)( rec_hdr_len_offset + rec_hdr_len_len ) ) ); - return( MBEDTLS_ERR_SSL_INVALID_RECORD ); - } - - /* configured CID len is guaranteed at most 255, see - * MBEDTLS_SSL_CID_OUT_LEN_MAX in check_config.h */ - rec->cid_len = (uint8_t) rec_hdr_cid_len; - /* Not using more secure mbedtls_platform_memcpy as cid is public */ - memcpy( rec->cid, buf + rec_hdr_cid_offset, rec_hdr_cid_len ); - } - else -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - { - if( ssl_check_record_type( rec->type ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "unknown record type %u", - (unsigned) rec->type ) ); - return( MBEDTLS_ERR_SSL_INVALID_RECORD ); - } - } - - /* - * Parse and validate record version - */ - - rec->ver[0] = buf[ rec_hdr_version_offset + 0 ]; - rec->ver[1] = buf[ rec_hdr_version_offset + 1 ]; - mbedtls_ssl_read_version( &major_ver, &minor_ver, - mbedtls_ssl_conf_get_transport( ssl->conf ), - &rec->ver[0] ); - - if( major_ver != mbedtls_ssl_get_major_ver( ssl ) ) + /* Check version */ + if( major_ver != ssl->major_ver ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "major version mismatch" ) ); return( MBEDTLS_ERR_SSL_INVALID_RECORD ); } - if( mbedtls_ssl_ver_gt( minor_ver, - mbedtls_ssl_conf_get_max_minor_ver( ssl->conf ) ) ) + if( minor_ver > ssl->conf->max_minor_ver ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "minor version mismatch" ) ); return( MBEDTLS_ERR_SSL_INVALID_RECORD ); } - /* - * Parse/Copy record sequence number. - */ - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) ) + /* Check length against the size of our buffer */ + if( ssl->in_msglen > MBEDTLS_SSL_BUFFER_LEN + - (size_t)( ssl->in_msg - ssl->in_buf ) ) { - /* Copy explicit record sequence number from input buffer. */ - /* Not using more secure mbedtls_platform_memcpy as sequence number is public */ - memcpy( &rec->ctr[0], buf + rec_hdr_ctr_offset, - rec_hdr_ctr_len ); - } - MBEDTLS_SSL_TRANSPORT_ELSE -#endif /* MBEDTLS_SSL_PROTO_DTLS */ -#if defined(MBEDTLS_SSL_PROTO_TLS) - { - /* Copy implicit record sequence number from SSL context structure. */ - /* Not using more secure mbedtls_platform_memcpy as sequence number is public */ - memcpy( &rec->ctr[0], ssl->in_ctr, rec_hdr_ctr_len ); - } -#endif /* MBEDTLS_SSL_PROTO_TLS */ - - /* - * Parse record length. - */ - - rec->data_offset = rec_hdr_len_offset + rec_hdr_len_len; - rec->data_len = mbedtls_platform_get_uint16_be( &buf[rec_hdr_len_offset] ); - MBEDTLS_SSL_DEBUG_BUF( 4, "input record header", buf, rec->data_offset ); - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "input record: msgtype = %d, " - "version = [%d:%d], msglen = %d", - rec->type, - major_ver, minor_ver, rec->data_len ) ); - - rec->buf = buf; - rec->buf_len = rec->data_offset + rec->data_len; - - if( rec->data_len == 0 ) + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) ); return( MBEDTLS_ERR_SSL_INVALID_RECORD ); + } - /* - * DTLS-related tests. - * Check epoch before checking length constraint because - * the latter varies with the epoch. E.g., if a ChangeCipherSpec - * message gets duplicated before the corresponding Finished message, - * the second ChangeCipherSpec should be discarded because it belongs - * to an old epoch, but not because its length is shorter than - * the minimum record length for packets using the new record transform. - * Note that these two kinds of failures are handled differently, - * as an unexpected record is silently skipped but an invalid - * record leads to the entire datagram being dropped. - */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) ) + /* Check length against bounds of the current transform and version */ + if( ssl->transform_in == NULL ) { - rec_epoch = (uint32_t)mbedtls_platform_get_uint16_be( rec->ctr ); - - /* Check that the datagram is large enough to contain a record - * of the advertised length. */ - if( len < rec->data_offset + rec->data_len ) + if( ssl->in_msglen < 1 || + ssl->in_msglen > MBEDTLS_SSL_MAX_CONTENT_LEN ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "Datagram of length %u too small to contain record of advertised length %u.", - (unsigned) len, - (unsigned)( rec->data_offset + rec->data_len ) ) ); + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) ); + return( MBEDTLS_ERR_SSL_INVALID_RECORD ); + } + } + else + { + if( ssl->in_msglen < ssl->transform_in->minlen ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) ); return( MBEDTLS_ERR_SSL_INVALID_RECORD ); } - /* Records from other, non-matching epochs are silently discarded. - * (The case of same-port Client reconnects must be considered in - * the caller). */ +#if defined(MBEDTLS_SSL_PROTO_SSL3) + if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 && + ssl->in_msglen > ssl->transform_in->minlen + MBEDTLS_SSL_MAX_CONTENT_LEN ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) ); + return( MBEDTLS_ERR_SSL_INVALID_RECORD ); + } +#endif +#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ + defined(MBEDTLS_SSL_PROTO_TLS1_2) + /* + * TLS encrypted messages can have up to 256 bytes of padding + */ + if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 && + ssl->in_msglen > ssl->transform_in->minlen + + MBEDTLS_SSL_MAX_CONTENT_LEN + 256 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) ); + return( MBEDTLS_ERR_SSL_INVALID_RECORD ); + } +#endif + } + + /* + * DTLS-related tests done last, because most of them may result in + * silently dropping the record (but not the whole datagram), and we only + * want to consider that after ensuring that the "basic" fields (type, + * version, length) are sane. + */ +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + { + unsigned int rec_epoch = ( ssl->in_ctr[0] << 8 ) | ssl->in_ctr[1]; + + /* Drop unexpected ChangeCipherSpec messages */ + if( ssl->in_msgtype == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC && + ssl->state != MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC && + ssl->state != MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "dropping unexpected ChangeCipherSpec" ) ); + return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD ); + } + + /* Drop unexpected ApplicationData records, + * except at the beginning of renegotiations */ + if( ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA && + ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER +#if defined(MBEDTLS_SSL_RENEGOTIATION) + && ! ( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && + ssl->state == MBEDTLS_SSL_SERVER_HELLO ) +#endif + ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "dropping unexpected ApplicationData" ) ); + return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD ); + } + + /* Check epoch (and sequence number) with DTLS */ if( rec_epoch != ssl->in_epoch ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "record from another epoch: " "expected %d, received %d", ssl->in_epoch, rec_epoch ) ); - /* Records from the next epoch are considered for buffering - * (concretely: early Finished messages). */ - if( rec_epoch == (unsigned) ssl->in_epoch + 1 ) +#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C) + /* + * Check for an epoch 0 ClientHello. We can't use in_msg here to + * access the first byte of record content (handshake type), as we + * have an active transform (possibly iv_len != 0), so use the + * fact that the record header len is 13 instead. + */ + if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && + ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER && + rec_epoch == 0 && + ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && + ssl->in_left > 13 && + ssl->in_buf[13] == MBEDTLS_SSL_HS_CLIENT_HELLO ) { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Consider record for buffering" ) ); - return( MBEDTLS_ERR_SSL_EARLY_MESSAGE ); + MBEDTLS_SSL_DEBUG_MSG( 1, ( "possible client reconnect " + "from the same port" ) ); + return( ssl_handle_possible_reconnect( ssl ) ); } - - return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD ); + else +#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */ + return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD ); } + #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) - /* For records from the correct epoch, check whether their - * sequence number has been seen before. */ - else if( mbedtls_ssl_dtls_record_replay_check( (mbedtls_ssl_context *) ssl, - &rec->ctr[0] ) != 0 ) + /* Replay detection only works for the current epoch */ + if( rec_epoch == ssl->in_epoch && + mbedtls_ssl_dtls_replay_check( ssl ) != 0 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "replayed record" ) ); return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD ); @@ -5988,46 +3822,15 @@ static int ssl_parse_record_header( mbedtls_ssl_context const *ssl, return( 0 ); } - -#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C) -static int ssl_check_client_reconnect( mbedtls_ssl_context *ssl ) -{ - unsigned int rec_epoch = (unsigned int) - mbedtls_platform_get_uint16_be( &ssl->in_ctr[0] ); - - /* - * Check for an epoch 0 ClientHello. We can't use in_msg here to - * access the first byte of record content (handshake type), as we - * have an active transform (possibly iv_len != 0), so use the - * fact that the record header len is 13 instead. - */ - if( rec_epoch == 0 && - mbedtls_ssl_conf_get_endpoint( ssl->conf ) == - MBEDTLS_SSL_IS_SERVER && - ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER && - ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && - ssl->in_left > 13 && - ssl->in_buf[13] == MBEDTLS_SSL_HS_CLIENT_HELLO ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "possible client reconnect " - "from the same port" ) ); - return( ssl_handle_possible_reconnect( ssl ) ); - } - - return( 0 ); -} -#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */ - /* - * If applicable, decrypt record content + * If applicable, decrypt (and decompress) record content */ -static int ssl_prepare_record_content( mbedtls_ssl_context *ssl, - mbedtls_record *rec ) +static int ssl_prepare_record_content( mbedtls_ssl_context *ssl ) { int ret, done = 0; MBEDTLS_SSL_DEBUG_BUF( 4, "input record from network", - rec->buf, rec->buf_len ); + ssl->in_hdr, mbedtls_ssl_hdr_len( ssl ) + ssl->in_msglen ); #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) if( mbedtls_ssl_hw_record_read != NULL ) @@ -6047,116 +3850,41 @@ static int ssl_prepare_record_content( mbedtls_ssl_context *ssl, #endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */ if( !done && ssl->transform_in != NULL ) { - unsigned char const old_msg_type = rec->type; - - if( ( ret = mbedtls_ssl_decrypt_buf( ssl, ssl->transform_in, - rec ) ) != 0 ) + if( ( ret = ssl_decrypt_buf( ssl ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "ssl_decrypt_buf", ret ); - -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - if( ret == MBEDTLS_ERR_SSL_UNEXPECTED_CID && - mbedtls_ssl_conf_get_ignore_unexpected_cid( ssl->conf ) - == MBEDTLS_SSL_UNEXPECTED_CID_IGNORE ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "ignoring unexpected CID" ) ); - ret = MBEDTLS_ERR_SSL_CONTINUE_PROCESSING; - } -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - return( ret ); } - if( old_msg_type != rec->type ) - { - MBEDTLS_SSL_DEBUG_MSG( 4, ( "record type after decrypt (before %d): %d", - old_msg_type, rec->type ) ); - } - MBEDTLS_SSL_DEBUG_BUF( 4, "input payload after decrypt", - rec->buf + rec->data_offset, rec->data_len ); + ssl->in_msg, ssl->in_msglen ); -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - /* We have already checked the record content type - * in ssl_parse_record_header(), failing or silently - * dropping the record in the case of an unknown type. - * - * Since with the use of CIDs, the record content type - * might change during decryption, re-check the record - * content type, but treat a failure as fatal this time. */ - if( ssl_check_record_type( rec->type ) ) + if( ssl->in_msglen > MBEDTLS_SSL_MAX_CONTENT_LEN ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "unknown record type" ) ); + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) ); return( MBEDTLS_ERR_SSL_INVALID_RECORD ); } -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - - if( rec->data_len == 0 ) - { -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( mbedtls_ssl_get_minor_ver( ssl ) == MBEDTLS_SSL_MINOR_VERSION_3 - && rec->type != MBEDTLS_SSL_MSG_APPLICATION_DATA ) - { - /* TLS v1.2 explicitly disallows zero-length messages which are not application data */ - MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid zero-length message type: %d", ssl->in_msgtype ) ); - return( MBEDTLS_ERR_SSL_INVALID_RECORD ); - } -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - - ssl->nb_zero++; - - /* - * Three or more empty messages may be a DoS attack - * (excessive CPU consumption). - */ - if( ssl->nb_zero > 3 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "received four consecutive empty " - "messages, possible DoS attack" ) ); - /* Treat the records as if they were not properly authenticated, - * thereby failing the connection if we see more than allowed - * by the configured bad MAC threshold. */ - return( MBEDTLS_ERR_SSL_INVALID_MAC ); - } - } - else - ssl->nb_zero = 0; - - /* Only needed for TLS, as with DTLS in_ctr is read from the header */ -#if defined(MBEDTLS_SSL_PROTO_TLS) - if( MBEDTLS_SSL_TRANSPORT_IS_TLS( ssl->conf->transport ) ) - { - unsigned i; - for( i = 8; i > 0; i-- ) - if( ++ssl->in_ctr[i - 1] != 0 ) - break; - - /* The loop goes to its end only if the counter is wrapping around */ - if( i == 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "incoming message counter would wrap" ) ); - return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING ); - } - } -#endif /* MBEDTLS_SSL_PROTO_TLS */ - } +#if defined(MBEDTLS_ZLIB_SUPPORT) + if( ssl->transform_in != NULL && + ssl->session_in->compression == MBEDTLS_SSL_COMPRESS_DEFLATE ) + { + if( ( ret = ssl_decompress_buf( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "ssl_decompress_buf", ret ); + return( ret ); + } + } +#endif /* MBEDTLS_ZLIB_SUPPORT */ + #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) ) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) { mbedtls_ssl_dtls_replay_update( ssl ); } #endif - /* Check actual (decrypted) record content length against - * configured maximum. */ - if( ssl->in_msglen > MBEDTLS_SSL_IN_CONTENT_LEN ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) ); - return( MBEDTLS_ERR_SSL_INVALID_RECORD ); - } - return( 0 ); } @@ -6169,14 +3897,7 @@ static void ssl_handshake_wrapup_free_hs_transform( mbedtls_ssl_context *ssl ); * RFC 6347 4.1.2.7) and continue reading until a valid record is found. * */ - -/* Helper functions for mbedtls_ssl_read_record(). */ -static int ssl_consume_current_message( mbedtls_ssl_context *ssl ); -static int ssl_get_next_record( mbedtls_ssl_context *ssl ); -static int ssl_record_is_in_progress( mbedtls_ssl_context *ssl ); - -int mbedtls_ssl_read_record( mbedtls_ssl_context *ssl, - unsigned update_hs_digest ) +int mbedtls_ssl_read_record( mbedtls_ssl_context *ssl ) { int ret; @@ -6186,72 +3907,30 @@ int mbedtls_ssl_read_record( mbedtls_ssl_context *ssl, { do { - ret = ssl_consume_current_message( ssl ); - if( ret != 0 ) - return( ret ); - - if( ssl_record_is_in_progress( ssl ) == 0 ) + if( ( ret = mbedtls_ssl_read_record_layer( ssl ) ) != 0 ) { -#if defined(MBEDTLS_SSL_PROTO_DTLS) - int have_buffered = 0; - - /* We only check for buffered messages if the - * current datagram is fully consumed. */ - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) && - ssl_next_record_is_in_datagram( ssl ) == 0 ) - { - if( ssl_load_buffered_message( ssl ) == 0 ) - have_buffered = 1; - } - - if( have_buffered == 0 ) -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - { - ret = ssl_get_next_record( ssl ); - if( ret == MBEDTLS_ERR_SSL_CONTINUE_PROCESSING ) - continue; - - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_get_next_record" ), ret ); - ssl_send_pending_fatal_alert( ssl ); - return( ret ); - } - } + MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ssl_read_record_layer" ), ret ); + return( ret ); } ret = mbedtls_ssl_handle_message_type( ssl ); -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ret == MBEDTLS_ERR_SSL_EARLY_MESSAGE ) - { - /* Buffer future message */ - ret = ssl_buffer_message( ssl ); - if( ret != 0 ) - return( ret ); - - ret = MBEDTLS_ERR_SSL_CONTINUE_PROCESSING; - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - } while( MBEDTLS_ERR_SSL_NON_FATAL == ret || - MBEDTLS_ERR_SSL_CONTINUE_PROCESSING == ret ); + } while( MBEDTLS_ERR_SSL_NON_FATAL == ret ); if( 0 != ret ) { - MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ssl_handle_message_type" ), ret ); + MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ssl_read_record_layer" ), ret ); return( ret ); } - if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && - update_hs_digest == 1 ) + if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE ) { mbedtls_ssl_update_handshake_status( ssl ); } } else { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "reuse previously read message" ) ); + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= reuse previously read message" ) ); ssl->keep_current_message = 0; } @@ -6260,365 +3939,13 @@ int mbedtls_ssl_read_record( mbedtls_ssl_context *ssl, return( 0 ); } -#if defined(MBEDTLS_SSL_PROTO_DTLS) -static int ssl_next_record_is_in_datagram( mbedtls_ssl_context *ssl ) +int mbedtls_ssl_read_record_layer( mbedtls_ssl_context *ssl ) { - if( ssl->in_left > ssl->next_record_offset ) - return( 1 ); + int ret; - return( 0 ); -} - -static int ssl_load_buffered_message( mbedtls_ssl_context *ssl ) -{ - mbedtls_ssl_handshake_params * const hs = ssl->handshake; - mbedtls_ssl_hs_buffer * hs_buf; - int ret = 0; - - if( hs == NULL ) - return( -1 ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_load_buffered_messsage" ) ); - - if( ssl->state == MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC || - ssl->state == MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC ) - { - /* Check if we have seen a ChangeCipherSpec before. - * If yes, synthesize a CCS record. */ - if( !hs->buffering.seen_ccs ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "CCS not seen in the current flight" ) ); - ret = -1; - goto exit; - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Injecting buffered CCS message" ) ); - ssl->in_msgtype = MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC; - ssl->in_msglen = 1; - ssl->in_msg[0] = 1; - - /* As long as they are equal, the exact value doesn't matter. */ - ssl->in_left = 0; - ssl->next_record_offset = 0; - - hs->buffering.seen_ccs = 0; - goto exit; - } - -#if defined(MBEDTLS_DEBUG_C) - /* Debug only */ - { - unsigned offset; - for( offset = 1; offset < MBEDTLS_SSL_MAX_BUFFERED_HS; offset++ ) - { - hs_buf = &hs->buffering.hs[offset]; - if( hs_buf->is_valid == 1 ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Future message with sequence number %u %s buffered.", - hs->in_msg_seq + offset, - hs_buf->is_complete ? "fully" : "partially" ) ); - } - } - } -#endif /* MBEDTLS_DEBUG_C */ - - /* Check if we have buffered and/or fully reassembled the - * next handshake message. */ - hs_buf = &hs->buffering.hs[0]; - if( ( hs_buf->is_valid == 1 ) && ( hs_buf->is_complete == 1 ) ) - { - /* Synthesize a record containing the buffered HS message. */ - size_t msg_len = mbedtls_platform_get_uint24_be( &hs_buf->data[1] ); - - /* Double-check that we haven't accidentally buffered - * a message that doesn't fit into the input buffer. */ - if( msg_len + 12 > MBEDTLS_SSL_IN_CONTENT_LEN ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Next handshake message has been buffered - load" ) ); - MBEDTLS_SSL_DEBUG_BUF( 3, "Buffered handshake message (incl. header)", - hs_buf->data, msg_len + 12 ); - - ssl->in_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; - ssl->in_hslen = msg_len + 12; - ssl->in_msglen = msg_len + 12; - mbedtls_platform_memcpy( ssl->in_msg, hs_buf->data, ssl->in_hslen ); - - ret = 0; - goto exit; - } - else - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Next handshake message %u not or only partially bufffered", - hs->in_msg_seq ) ); - } - - ret = -1; - -exit: - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_load_buffered_message" ) ); - return( ret ); -} - -static int ssl_buffer_make_space( mbedtls_ssl_context *ssl, - size_t desired ) -{ - int offset; - mbedtls_ssl_handshake_params * const hs = ssl->handshake; - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Attempt to free buffered messages to have %u bytes available", - (unsigned) desired ) ); - - /* Get rid of future records epoch first, if such exist. */ - ssl_free_buffered_record( ssl ); - - /* Check if we have enough space available now. */ - if( desired <= ( MBEDTLS_SSL_DTLS_MAX_BUFFERING - - hs->buffering.total_bytes_buffered ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Enough space available after freeing future epoch record" ) ); - return( 0 ); - } - - /* We don't have enough space to buffer the next expected handshake - * message. Remove buffers used for future messages to gain space, - * starting with the most distant one. */ - for( offset = MBEDTLS_SSL_MAX_BUFFERED_HS - 1; - offset >= 0; offset-- ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Free buffering slot %d to make space for reassembly of next handshake message", - offset ) ); - - ssl_buffering_free_slot( ssl, (uint8_t) offset ); - - /* Check if we have enough space available now. */ - if( desired <= ( MBEDTLS_SSL_DTLS_MAX_BUFFERING - - hs->buffering.total_bytes_buffered ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Enough space available after freeing buffered HS messages" ) ); - return( 0 ); - } - } - - return( -1 ); -} - -static int ssl_buffer_message( mbedtls_ssl_context *ssl ) -{ - int ret = 0; - mbedtls_ssl_handshake_params * const hs = ssl->handshake; - - if( hs == NULL ) - return( 0 ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_buffer_message" ) ); - - switch( ssl->in_msgtype ) - { - case MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC: - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Remember CCS message" ) ); - - hs->buffering.seen_ccs = 1; - break; - - case MBEDTLS_SSL_MSG_HANDSHAKE: - { - unsigned recv_msg_seq_offset; - unsigned recv_msg_seq = (unsigned) - mbedtls_platform_get_uint16_be( &ssl->in_msg[4] ); - - mbedtls_ssl_hs_buffer *hs_buf; - size_t msg_len = ssl->in_hslen - 12; - - /* We should never receive an old handshake - * message - double-check nonetheless. */ - if( recv_msg_seq < ssl->handshake->in_msg_seq ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - recv_msg_seq_offset = recv_msg_seq - ssl->handshake->in_msg_seq; - if( recv_msg_seq_offset >= MBEDTLS_SSL_MAX_BUFFERED_HS ) - { - /* Silently ignore -- message too far in the future */ - MBEDTLS_SSL_DEBUG_MSG( 2, - ( "Ignore future HS message with sequence number %u, " - "buffering window %u - %u", - recv_msg_seq, ssl->handshake->in_msg_seq, - ssl->handshake->in_msg_seq + MBEDTLS_SSL_MAX_BUFFERED_HS - 1 ) ); - - goto exit; - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffering HS message with sequence number %u, offset %u ", - recv_msg_seq, recv_msg_seq_offset ) ); - - hs_buf = &hs->buffering.hs[ recv_msg_seq_offset ]; - - /* Check if the buffering for this seq nr has already commenced. */ - if( !hs_buf->is_valid ) - { - size_t reassembly_buf_sz; - - hs_buf->is_fragmented = - ( ssl_hs_is_proper_fragment( ssl ) == PROPER_HS_FRAGMENT ); - - /* We copy the message back into the input buffer - * after reassembly, so check that it's not too large. - * This is an implementation-specific limitation - * and not one from the standard, hence it is not - * checked in ssl_check_hs_header(). */ - if( msg_len + 12 > MBEDTLS_SSL_IN_CONTENT_LEN ) - { - /* Ignore message */ - goto exit; - } - - /* Check if we have enough space to buffer the message. */ - if( hs->buffering.total_bytes_buffered > - MBEDTLS_SSL_DTLS_MAX_BUFFERING ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - reassembly_buf_sz = ssl_get_reassembly_buffer_size( msg_len, - hs_buf->is_fragmented ); - - if( reassembly_buf_sz > ( MBEDTLS_SSL_DTLS_MAX_BUFFERING - - hs->buffering.total_bytes_buffered ) ) - { - if( recv_msg_seq_offset > 0 ) - { - /* If we can't buffer a future message because - * of space limitations -- ignore. */ - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffering of future message of size %u would exceed the compile-time limit %u (already %u bytes buffered) -- ignore\n", - (unsigned) msg_len, MBEDTLS_SSL_DTLS_MAX_BUFFERING, - (unsigned) hs->buffering.total_bytes_buffered ) ); - goto exit; - } - else - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffering of future message of size %u would exceed the compile-time limit %u (already %u bytes buffered) -- attempt to make space by freeing buffered future messages\n", - (unsigned) msg_len, MBEDTLS_SSL_DTLS_MAX_BUFFERING, - (unsigned) hs->buffering.total_bytes_buffered ) ); - } - - if( ssl_buffer_make_space( ssl, reassembly_buf_sz ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Reassembly of next message of size %u (%u with bitmap) would exceed the compile-time limit %u (already %u bytes buffered) -- fail\n", - (unsigned) msg_len, - (unsigned) reassembly_buf_sz, - MBEDTLS_SSL_DTLS_MAX_BUFFERING, - (unsigned) hs->buffering.total_bytes_buffered ) ); - ret = MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL; - goto exit; - } - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "initialize reassembly, total length = %d", - msg_len ) ); - - hs_buf->data = mbedtls_calloc( 1, reassembly_buf_sz ); - if( hs_buf->data == NULL ) - { - ret = MBEDTLS_ERR_SSL_ALLOC_FAILED; - goto exit; - } - hs_buf->data_len = reassembly_buf_sz; - - /* Prepare final header: copy msg_type, length and message_seq, - * then add standardised fragment_offset and fragment_length */ - if( mbedtls_platform_memcpy( hs_buf->data, ssl->in_msg, 6 ) != - hs_buf->data ) - { - ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; - goto exit; - } - if( mbedtls_platform_memset( hs_buf->data + 6, 0, 3 ) != - hs_buf->data + 6 ) - { - ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; - goto exit; - } - if( mbedtls_platform_memcpy( hs_buf->data + 9, hs_buf->data + 1, 3 ) != - hs_buf->data + 9 ) - { - ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; - goto exit; - } - - hs_buf->is_valid = 1; - - hs->buffering.total_bytes_buffered += reassembly_buf_sz; - } - else - { - /* Make sure msg_type and length are consistent */ - if( memcmp( hs_buf->data, ssl->in_msg, 4 ) != 0 ) // use regular memcmp as msg type is public - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "Fragment header mismatch - ignore" ) ); - /* Ignore */ - goto exit; - } - } - - if( !hs_buf->is_complete ) - { - size_t frag_len, frag_off; - unsigned char * const msg = hs_buf->data + 12; - - /* - * Check and copy current fragment - */ - - /* Validation of header fields already done in - * mbedtls_ssl_prepare_handshake_record(). */ - frag_off = ssl_get_hs_frag_off( ssl ); - frag_len = ssl_get_hs_frag_len( ssl ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "adding fragment, offset = %d, length = %d", - frag_off, frag_len ) ); - mbedtls_platform_memcpy( msg + frag_off, ssl->in_msg + 12, frag_len ); - - if( hs_buf->is_fragmented ) - { - unsigned char * const bitmask = msg + msg_len; - ssl_bitmask_set( bitmask, frag_off, frag_len ); - hs_buf->is_complete = ( ssl_bitmask_check( bitmask, - msg_len ) == 0 ); - } - else - { - hs_buf->is_complete = 1; - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "message %scomplete", - hs_buf->is_complete ? "" : "not yet " ) ); - } - - break; - } - - default: - /* We don't buffer other types of messages. */ - break; - } - -exit: - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_buffer_message" ) ); - return( ret ); -} -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - -static int ssl_consume_current_message( mbedtls_ssl_context *ssl ) -{ /* + * Step A + * * Consume last content-layer message and potentially * update in_msglen which keeps track of the contents' * consumption state. @@ -6630,6 +3957,11 @@ static int ssl_consume_current_message( mbedtls_ssl_context *ssl ) * (2) Alert messages: * Consume whole record content, in_msglen = 0. * + * NOTE: This needs to be fixed, since like for + * handshake messages it is allowed to have + * multiple alerts witin a single record. + * Internal reference IOTSSL-1321. + * * (3) Change cipher spec: * Consume whole record content, in_msglen = 0. * @@ -6657,12 +3989,12 @@ static int ssl_consume_current_message( mbedtls_ssl_context *ssl ) */ /* Notes: - * (1) in_hslen is not necessarily the size of the + * (1) in_hslen is *NOT* necessarily the size of the * current handshake content: If DTLS handshake * fragmentation is used, that's the fragment * size instead. Using the total handshake message - * size here is faulty and should be changed at - * some point. + * size here is FAULTY and should be changed at + * some point. Internal reference IOTSSL-1414. * (2) While it doesn't seem to cause problems, one * has to be very careful not to assume that in_hslen * is always <= in_msglen in a sensible communication. @@ -6700,215 +4032,44 @@ static int ssl_consume_current_message( mbedtls_ssl_context *ssl ) ssl->in_msglen = 0; } - return( 0 ); -} + /* + * Step B + * + * Fetch and decode new record if current one is fully consumed. + * + */ -static int ssl_record_is_in_progress( mbedtls_ssl_context *ssl ) -{ if( ssl->in_msglen > 0 ) - return( 1 ); + { + /* There's something left to be processed in the current record. */ + return( 0 ); + } - return( 0 ); -} + /* Need to fetch a new record */ #if defined(MBEDTLS_SSL_PROTO_DTLS) - -static void ssl_free_buffered_record( mbedtls_ssl_context *ssl ) -{ - mbedtls_ssl_handshake_params * const hs = ssl->handshake; - if( hs == NULL ) - return; - - if( hs->buffering.future_record.data != NULL ) - { - hs->buffering.total_bytes_buffered -= - hs->buffering.future_record.len; - - mbedtls_free( hs->buffering.future_record.data ); - hs->buffering.future_record.data = NULL; - } -} - -static int ssl_load_buffered_record( mbedtls_ssl_context *ssl ) -{ - mbedtls_ssl_handshake_params * const hs = ssl->handshake; - unsigned char * rec; - size_t rec_len; - unsigned rec_epoch; -#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) - size_t in_buf_len = ssl->in_buf_len; -#else - size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN; +read_record_header: #endif - if( MBEDTLS_SSL_TRANSPORT_IS_TLS( ssl->conf->transport ) ) - return( 0 ); + /* Current record either fully processed or to be discarded. */ - if( hs == NULL ) - return( 0 ); - - rec = hs->buffering.future_record.data; - rec_len = hs->buffering.future_record.len; - rec_epoch = hs->buffering.future_record.epoch; - - if( rec == NULL ) - return( 0 ); - - /* Only consider loading future records if the - * input buffer is empty. */ - if( ssl_next_record_is_in_datagram( ssl ) == 1 ) - return( 0 ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_load_buffered_record" ) ); - - if( rec_epoch != ssl->in_epoch ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffered record not from current epoch." ) ); - goto exit; - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Found buffered record from current epoch - load" ) ); - - /* Double-check that the record is not too large */ - if( rec_len > in_buf_len - (size_t)( ssl->in_hdr - ssl->in_buf ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - mbedtls_platform_memcpy( ssl->in_hdr, rec, rec_len ); - ssl->in_left = rec_len; - ssl->next_record_offset = 0; - - ssl_free_buffered_record( ssl ); - -exit: - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_load_buffered_record" ) ); - return( 0 ); -} - -static int ssl_buffer_future_record( mbedtls_ssl_context *ssl, - mbedtls_record const *rec ) -{ - mbedtls_ssl_handshake_params * const hs = ssl->handshake; - - /* Don't buffer future records outside handshakes. */ - if( hs == NULL ) - return( 0 ); - - /* Only buffer handshake records (we are only interested - * in Finished messages). */ - if( rec->type != MBEDTLS_SSL_MSG_HANDSHAKE ) - return( 0 ); - - /* Don't buffer more than one future epoch record. */ - if( hs->buffering.future_record.data != NULL ) - return( 0 ); - - /* Don't buffer record if there's not enough buffering space remaining. */ - if( rec->buf_len > ( MBEDTLS_SSL_DTLS_MAX_BUFFERING - - hs->buffering.total_bytes_buffered ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffering of future epoch record of size %u would exceed the compile-time limit %u (already %u bytes buffered) -- ignore\n", - (unsigned) rec->buf_len, MBEDTLS_SSL_DTLS_MAX_BUFFERING, - (unsigned) hs->buffering.total_bytes_buffered ) ); - return( 0 ); - } - - /* Buffer record */ - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffer record from epoch %u", - ssl->in_epoch + 1 ) ); - MBEDTLS_SSL_DEBUG_BUF( 3, "Buffered record", rec->buf, rec->buf_len ); - - /* ssl_parse_record_header() only considers records - * of the next epoch as candidates for buffering. */ - hs->buffering.future_record.epoch = ssl->in_epoch + 1; - hs->buffering.future_record.len = rec->buf_len; - - hs->buffering.future_record.data = - mbedtls_calloc( 1, hs->buffering.future_record.len ); - if( hs->buffering.future_record.data == NULL ) - { - /* If we run out of RAM trying to buffer a - * record from the next epoch, just ignore. */ - return( 0 ); - } - - mbedtls_platform_memcpy( hs->buffering.future_record.data, rec->buf, rec->buf_len ); - - hs->buffering.total_bytes_buffered += rec->buf_len; - return( 0 ); -} - -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - -static int ssl_get_next_record( mbedtls_ssl_context *ssl ) -{ - int ret; - mbedtls_record rec; - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - /* We might have buffered a future record; if so, - * and if the epoch matches now, load it. - * On success, this call will set ssl->in_left to - * the length of the buffered record, so that - * the calls to ssl_fetch_input() below will - * essentially be no-ops. */ - ret = ssl_load_buffered_record( ssl ); - if( ret != 0 ) - return( ret ); -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - /* Ensure that we have enough space available for the default form - * of TLS / DTLS record headers (5 Bytes for TLS, 13 Bytes for DTLS, - * with no space for CIDs counted in). */ - ret = mbedtls_ssl_fetch_input( ssl, mbedtls_ssl_in_hdr_len( ssl ) ); - if( ret != 0 ) + if( ( ret = mbedtls_ssl_fetch_input( ssl, mbedtls_ssl_hdr_len( ssl ) ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret ); return( ret ); } - ret = ssl_parse_record_header( ssl, ssl->in_hdr, ssl->in_left, &rec ); - if( ret != 0 ) + if( ( ret = ssl_parse_record_header( ssl ) ) != 0 ) { #if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) ) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && + ret != MBEDTLS_ERR_SSL_CLIENT_RECONNECT ) { - if( ret == MBEDTLS_ERR_SSL_EARLY_MESSAGE ) - { - ret = ssl_buffer_future_record( ssl, &rec ); - if( ret != 0 ) - return( ret ); - - /* Fall through to handling of unexpected records */ - ret = MBEDTLS_ERR_SSL_UNEXPECTED_RECORD; - } - if( ret == MBEDTLS_ERR_SSL_UNEXPECTED_RECORD ) { -#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C) - /* Reset in pointers to default state for TLS/DTLS records, - * assuming no CID and no offset between record content and - * record plaintext. */ - ssl_update_in_pointers( ssl ); - - /* Setup internal message pointers from record structure. */ - ssl->in_msgtype = rec.type; -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - ssl->in_len = ssl->in_cid + rec.cid_len; -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - ssl->in_msg = ssl->in_len + 2; - ssl->in_msglen = rec.data_len; - - ret = ssl_check_client_reconnect( ssl ); - MBEDTLS_SSL_DEBUG_RET( 2, "ssl_check_client_reconnect", ret ); - if( ret != 0 ) - return( ret ); -#endif - /* Skip unexpected record (but not whole datagram) */ - ssl->next_record_offset = rec.buf_len; + ssl->next_record_offset = ssl->in_msglen + + mbedtls_ssl_hdr_len( ssl ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "discarding unexpected record " "(header)" ) ); @@ -6924,54 +4085,38 @@ static int ssl_get_next_record( mbedtls_ssl_context *ssl ) } /* Get next record */ - return( MBEDTLS_ERR_SSL_CONTINUE_PROCESSING ); + goto read_record_header; } - else #endif - { - return( ret ); - } + return( ret ); } -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) ) - { - /* Remember offset of next record within datagram. */ - ssl->next_record_offset = rec.buf_len; - if( ssl->next_record_offset < ssl->in_left ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "more than one record within datagram" ) ); - } - } - MBEDTLS_SSL_TRANSPORT_ELSE -#endif /* MBEDTLS_SSL_PROTO_DTLS */ -#if defined(MBEDTLS_SSL_PROTO_TLS) - { - /* - * Fetch record contents from underlying transport. - */ - ret = mbedtls_ssl_fetch_input( ssl, rec.buf_len ); - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret ); - return( ret ); - } - - ssl->in_left = 0; - } -#endif /* MBEDTLS_SSL_PROTO_TLS */ - /* - * Decrypt record contents. + * Read and optionally decrypt the message contents */ + if( ( ret = mbedtls_ssl_fetch_input( ssl, + mbedtls_ssl_hdr_len( ssl ) + ssl->in_msglen ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret ); + return( ret ); + } - if( ( ret = ssl_prepare_record_content( ssl, &rec ) ) != 0 ) + /* Done reading this record, get ready for the next one */ +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + ssl->next_record_offset = ssl->in_msglen + mbedtls_ssl_hdr_len( ssl ); + else +#endif + ssl->in_left = 0; + + if( ( ret = ssl_prepare_record_content( ssl ) ) != 0 ) { #if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) ) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) { /* Silently discard invalid records */ - if( ret == MBEDTLS_ERR_SSL_INVALID_MAC ) + if( ret == MBEDTLS_ERR_SSL_INVALID_RECORD || + ret == MBEDTLS_ERR_SSL_INVALID_MAC ) { /* Except when waiting for Finished as a bad mac here * probably means something went wrong in the handshake @@ -6982,7 +4127,8 @@ static int ssl_get_next_record( mbedtls_ssl_context *ssl ) #if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES) if( ret == MBEDTLS_ERR_SSL_INVALID_MAC ) { - mbedtls_ssl_pend_fatal_alert( ssl, + mbedtls_ssl_send_alert_message( ssl, + MBEDTLS_SSL_ALERT_LEVEL_FATAL, MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC ); } #endif @@ -6990,8 +4136,8 @@ static int ssl_get_next_record( mbedtls_ssl_context *ssl ) } #if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) - if( mbedtls_ssl_conf_get_badmac_limit( ssl->conf ) != 0 && - ++ssl->badmac_seen >= mbedtls_ssl_conf_get_badmac_limit( ssl->conf ) ) + if( ssl->conf->badmac_limit != 0 && + ++ssl->badmac_seen >= ssl->conf->badmac_limit ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "too many records with bad MAC" ) ); return( MBEDTLS_ERR_SSL_INVALID_MAC ); @@ -7005,69 +4151,66 @@ static int ssl_get_next_record( mbedtls_ssl_context *ssl ) ssl->in_left = 0; MBEDTLS_SSL_DEBUG_MSG( 1, ( "discarding invalid record (mac)" ) ); - return( MBEDTLS_ERR_SSL_CONTINUE_PROCESSING ); + goto read_record_header; } return( ret ); } - MBEDTLS_SSL_TRANSPORT_ELSE -#endif /* MBEDTLS_SSL_PROTO_DTLS */ -#if defined(MBEDTLS_SSL_PROTO_TLS) + else +#endif { /* Error out (and send alert) on invalid records */ #if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES) if( ret == MBEDTLS_ERR_SSL_INVALID_MAC ) { - mbedtls_ssl_pend_fatal_alert( ssl, + mbedtls_ssl_send_alert_message( ssl, + MBEDTLS_SSL_ALERT_LEVEL_FATAL, MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC ); } #endif return( ret ); } -#endif /* MBEDTLS_SSL_PROTO_TLS */ } - - /* Reset in pointers to default state for TLS/DTLS records, - * assuming no CID and no offset between record content and - * record plaintext. */ - ssl_update_in_pointers( ssl ); -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - ssl->in_len = ssl->in_cid + rec.cid_len; -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - ssl->in_msg = ssl->in_len + 2; - - /* The record content type may change during decryption, - * so re-read it. */ - ssl->in_msgtype = rec.type; - /* Also update the input buffer, because unfortunately - * the server-side ssl_parse_client_hello() reparses the - * record header when receiving a ClientHello initiating - * a renegotiation. */ - ssl->in_hdr[0] = rec.type; - ssl->in_msg = rec.buf + rec.data_offset; - ssl->in_msglen = rec.data_len; - (void)mbedtls_platform_put_uint16_be( ssl->in_len, rec.data_len ); - -#if defined(MBEDTLS_ZLIB_SUPPORT) - if( ssl->transform_in != NULL && - ssl->session_in->compression == MBEDTLS_SSL_COMPRESS_DEFLATE ) + /* + * When we sent the last flight of the handshake, we MUST respond to a + * retransmit of the peer's previous flight with a retransmit. (In + * practice, only the Finished message will make it, other messages + * including CCS use the old transform so they're dropped as invalid.) + * + * If the record we received is not a handshake message, however, it + * means the peer received our last flight so we can clean up + * handshake info. + * + * This check needs to be done before prepare_handshake() due to an edge + * case: if the client immediately requests renegotiation, this + * finishes the current handshake first, avoiding the new ClientHello + * being mistaken for an ancient message in the current handshake. + */ +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && + ssl->handshake != NULL && + ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER ) { - if( ( ret = ssl_decompress_buf( ssl ) ) != 0 ) + if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && + ssl->in_msg[0] == MBEDTLS_SSL_HS_FINISHED ) { - MBEDTLS_SSL_DEBUG_RET( 1, "ssl_decompress_buf", ret ); - return( ret ); - } + MBEDTLS_SSL_DEBUG_MSG( 2, ( "received retransmit of last flight" ) ); - /* Check actual (decompress) record content length against - * configured maximum. */ - if( ssl->in_msglen > MBEDTLS_SSL_IN_CONTENT_LEN ) + if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_resend", ret ); + return( ret ); + } + + return( MBEDTLS_ERR_SSL_WANT_READ ); + } + else { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) ); - return( MBEDTLS_ERR_SSL_INVALID_RECORD ); + ssl_handshake_wrapup_free_hs_transform( ssl ); } } -#endif /* MBEDTLS_ZLIB_SUPPORT */ +#endif return( 0 ); } @@ -7087,39 +4230,6 @@ int mbedtls_ssl_handle_message_type( mbedtls_ssl_context *ssl ) } } - if( ssl->in_msgtype == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC ) - { - if( ssl->in_msglen != 1 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid CCS message, len: %d", - ssl->in_msglen ) ); - return( MBEDTLS_ERR_SSL_INVALID_RECORD ); - } - - if( ssl->in_msg[0] != 1 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid CCS message, content: %02x", - ssl->in_msg[0] ) ); - return( MBEDTLS_ERR_SSL_INVALID_RECORD ); - } - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) && - ssl->state != MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC && - ssl->state != MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC ) - { - if( ssl->handshake == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "dropping ChangeCipherSpec outside handshake" ) ); - return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD ); - } - - MBEDTLS_SSL_DEBUG_MSG( 1, ( "received out-of-order ChangeCipherSpec - remember" ) ); - return( MBEDTLS_ERR_SSL_EARLY_MESSAGE ); - } -#endif - } - if( ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT ) { if( ssl->in_msglen != 2 ) @@ -7156,16 +4266,15 @@ int mbedtls_ssl_handle_message_type( mbedtls_ssl_context *ssl ) if( ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING && ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION ) { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a SSLv3 no renegotiation alert" ) ); + MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a SSLv3 no_cert" ) ); /* Will be handled when trying to parse ServerHello */ return( 0 ); } #endif #if defined(MBEDTLS_SSL_PROTO_SSL3) && defined(MBEDTLS_SSL_SRV_C) - if( mbedtls_ssl_get_minor_ver( ssl ) == MBEDTLS_SSL_MINOR_VERSION_0 && - mbedtls_ssl_conf_get_endpoint( ssl->conf ) == - MBEDTLS_SSL_IS_SERVER && + if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 && + ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING && ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_CERT ) { @@ -7179,31 +4288,6 @@ int mbedtls_ssl_handle_message_type( mbedtls_ssl_context *ssl ) return MBEDTLS_ERR_SSL_NON_FATAL; } -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) ) - { - /* Drop unexpected ApplicationData records, - * except at the beginning of renegotiations */ - if( ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA && - ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER -#if defined(MBEDTLS_SSL_RENEGOTIATION) - && ! ( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && - ssl->state == MBEDTLS_SSL_SERVER_HELLO ) -#endif - ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "dropping unexpected ApplicationData" ) ); - return( MBEDTLS_ERR_SSL_NON_FATAL ); - } - - if( ssl->handshake != NULL && - ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER ) - { - ssl_handshake_wrapup_free_hs_transform( ssl ); - } - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - return( 0 ); } @@ -7222,8 +4306,8 @@ int mbedtls_ssl_send_fatal_handshake_failure( mbedtls_ssl_context *ssl ) } int mbedtls_ssl_send_alert_message( mbedtls_ssl_context *ssl, - unsigned char level, - unsigned char message ) + unsigned char level, + unsigned char message ) { int ret; @@ -7238,7 +4322,7 @@ int mbedtls_ssl_send_alert_message( mbedtls_ssl_context *ssl, ssl->out_msg[0] = level; ssl->out_msg[1] = message; - if( ( ret = mbedtls_ssl_write_record( ssl, SSL_FORCE_FLUSH ) ) != 0 ) + if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret ); return( ret ); @@ -7248,58 +4332,30 @@ int mbedtls_ssl_send_alert_message( mbedtls_ssl_context *ssl, return( 0 ); } -#if defined(MBEDTLS_X509_CRT_PARSE_C) -static void ssl_clear_peer_cert( mbedtls_ssl_session *session ) -{ -#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - if( session->peer_cert != NULL ) - { - mbedtls_x509_crt_free( session->peer_cert ); - mbedtls_free( session->peer_cert ); - session->peer_cert = NULL; - } -#elif defined(MBEDTLS_SSL_RENEGOTIATION) - if( session->peer_cert_digest != NULL ) - { - /* Zeroization is not necessary. */ - mbedtls_free( session->peer_cert_digest ); - session->peer_cert_digest = NULL; - session->peer_cert_digest_type = MBEDTLS_MD_NONE; - session->peer_cert_digest_len = 0; - } -#else - ((void) session); -#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE && MBEDTLS_SSL_RENEGOTIATION */ -} -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - /* * Handshake functions */ -#if !defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) +#if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) /* No certificate support -> dummy functions */ int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl ) { - mbedtls_ssl_ciphersuite_handle_t ciphersuite_info = - mbedtls_ssl_handshake_get_ciphersuite( ssl->handshake ); + const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate" ) ); - if( !mbedtls_ssl_ciphersuite_uses_srv_cert( ciphersuite_info ) ) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) { MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) ); - if( ssl->state == MBEDTLS_SSL_CLIENT_CERTIFICATE ) - { - ssl->state = MBEDTLS_SSL_CLIENT_KEY_EXCHANGE; - } - else if( ssl->state == MBEDTLS_SSL_SERVER_CERTIFICATE ) - { - ssl->state = MBEDTLS_SSL_SERVER_KEY_EXCHANGE; - } - else - { - ssl->state = MBEDTLS_SSL_INVALID; - } + ssl->state++; return( 0 ); } @@ -7309,26 +4365,17 @@ int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl ) int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl ) { - mbedtls_ssl_ciphersuite_handle_t ciphersuite_info = - mbedtls_ssl_handshake_get_ciphersuite( ssl->handshake ); + const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate" ) ); - if( !mbedtls_ssl_ciphersuite_uses_srv_cert( ciphersuite_info ) ) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) { MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) ); - if( ssl->state == MBEDTLS_SSL_CLIENT_CERTIFICATE ) - { - ssl->state = MBEDTLS_SSL_CLIENT_KEY_EXCHANGE; - } - else if( ssl->state == MBEDTLS_SSL_SERVER_CERTIFICATE ) - { - ssl->state = MBEDTLS_SSL_SERVER_KEY_EXCHANGE; - } - else - { - ssl->state = MBEDTLS_SSL_INVALID; - } + ssl->state++; return( 0 ); } @@ -7336,7 +4383,7 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl ) return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); } -#else /* MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ +#else /* Some certificate support -> implement write and parse */ int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl ) @@ -7344,48 +4391,27 @@ int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl ) int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; size_t i, n; const mbedtls_x509_crt *crt; - mbedtls_ssl_ciphersuite_handle_t ciphersuite_info = - mbedtls_ssl_handshake_get_ciphersuite( ssl->handshake ); + const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate" ) ); - if( !mbedtls_ssl_ciphersuite_uses_srv_cert( ciphersuite_info ) ) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) { MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) ); - if( ssl->state == MBEDTLS_SSL_CLIENT_CERTIFICATE ) - { - ssl->state = MBEDTLS_SSL_CLIENT_KEY_EXCHANGE; - } - else if( ssl->state == MBEDTLS_SSL_SERVER_CERTIFICATE ) - { - ssl->state = MBEDTLS_SSL_SERVER_KEY_EXCHANGE; - } - else - { - ssl->state = MBEDTLS_SSL_INVALID; - } + ssl->state++; return( 0 ); } #if defined(MBEDTLS_SSL_CLI_C) - if( mbedtls_ssl_conf_get_endpoint( ssl->conf ) == - MBEDTLS_SSL_IS_CLIENT ) + if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) { if( ssl->client_auth == 0 ) { MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) ); - if( ssl->state == MBEDTLS_SSL_CLIENT_CERTIFICATE ) - { - ssl->state = MBEDTLS_SSL_CLIENT_KEY_EXCHANGE; - } - else if( ssl->state == MBEDTLS_SSL_SERVER_CERTIFICATE ) - { - ssl->state = MBEDTLS_SSL_SERVER_KEY_EXCHANGE; - } - else - { - ssl->state = MBEDTLS_SSL_INVALID; - } + ssl->state++; return( 0 ); } @@ -7395,7 +4421,7 @@ int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl ) * (otherwise an empty Certificate message will be sent). */ if( mbedtls_ssl_own_cert( ssl ) == NULL && - mbedtls_ssl_get_minor_ver( ssl ) == MBEDTLS_SSL_MINOR_VERSION_0 ) + ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) { ssl->out_msglen = 2; ssl->out_msgtype = MBEDTLS_SSL_MSG_ALERT; @@ -7409,7 +4435,7 @@ int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl ) } #endif /* MBEDTLS_SSL_CLI_C */ #if defined(MBEDTLS_SSL_SRV_C) - if( mbedtls_ssl_conf_get_endpoint( ssl->conf ) == MBEDTLS_SSL_IS_SERVER ) + if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) { if( mbedtls_ssl_own_cert( ssl ) == NULL ) { @@ -7436,20 +4462,24 @@ int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl ) while( crt != NULL ) { n = crt->raw.len; - if( n > MBEDTLS_SSL_OUT_CONTENT_LEN - 3 - i ) + if( n > MBEDTLS_SSL_MAX_CONTENT_LEN - 3 - i ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "certificate too large, %d > %d", - i + 3 + n, MBEDTLS_SSL_OUT_CONTENT_LEN ) ); + i + 3 + n, MBEDTLS_SSL_MAX_CONTENT_LEN ) ); return( MBEDTLS_ERR_SSL_CERTIFICATE_TOO_LARGE ); } - (void)mbedtls_platform_put_uint24_be( &ssl->out_msg[i], n ); + ssl->out_msg[i ] = (unsigned char)( n >> 16 ); + ssl->out_msg[i + 1] = (unsigned char)( n >> 8 ); + ssl->out_msg[i + 2] = (unsigned char)( n ); - i += 3; mbedtls_platform_memcpy( ssl->out_msg + i, crt->raw.p, n ); + i += 3; memcpy( ssl->out_msg + i, crt->raw.p, n ); i += n; crt = crt->next; } - (void)mbedtls_platform_put_uint24_be( &ssl->out_msg[4], ( i - 7 ) ); + ssl->out_msg[4] = (unsigned char)( ( i - 7 ) >> 16 ); + ssl->out_msg[5] = (unsigned char)( ( i - 7 ) >> 8 ); + ssl->out_msg[6] = (unsigned char)( ( i - 7 ) ); ssl->out_msglen = i; ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; @@ -7459,22 +4489,11 @@ int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl ) write_msg: #endif - if( ssl->state == MBEDTLS_SSL_CLIENT_CERTIFICATE ) - { - ssl->state = MBEDTLS_SSL_CLIENT_KEY_EXCHANGE; - } - else if( ssl->state == MBEDTLS_SSL_SERVER_CERTIFICATE ) - { - ssl->state = MBEDTLS_SSL_SERVER_KEY_EXCHANGE; - } - else - { - ssl->state = MBEDTLS_SSL_INVALID; - } + ssl->state++; - if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 ) + if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 ) { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret ); + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret ); return( ret ); } @@ -7483,78 +4502,118 @@ write_msg: return( ret ); } -#if defined(MBEDTLS_SSL_RENEGOTIATION) && defined(MBEDTLS_SSL_CLI_C) - -#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) -#define PEER_CRT_CHANGED 0x75555555 -static int ssl_check_peer_crt_unchanged( mbedtls_ssl_context *ssl, - unsigned char *crt_buf, - size_t crt_buf_len ) +int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl ) { - mbedtls_x509_crt const * const peer_crt = ssl->session->peer_cert; + int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; + size_t i, n; + const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; + int authmode = ssl->conf->authmode; + uint8_t alert; - if( peer_crt == NULL ) - return( PEER_CRT_CHANGED ); + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate" ) ); - if( peer_crt->raw.len != crt_buf_len ) - return( PEER_CRT_CHANGED ); - - return( mbedtls_platform_memequal( peer_crt->raw.p, crt_buf, crt_buf_len ) ); -} -#elif defined(MBEDTLS_SSL_RENEGOTIATION) -#define PEER_CRT_CHANGED 0x75555555 -static int ssl_check_peer_crt_unchanged( mbedtls_ssl_context *ssl, - unsigned char *crt_buf, - size_t crt_buf_len ) -{ - int ret; - unsigned char const * const peer_cert_digest = - ssl->session->peer_cert_digest; - mbedtls_md_type_t const peer_cert_digest_type = - ssl->session->peer_cert_digest_type; - mbedtls_md_handle_t digest_info = - mbedtls_md_info_from_type( peer_cert_digest_type ); - unsigned char tmp_digest[MBEDTLS_SSL_PEER_CERT_DIGEST_MAX_LEN]; - size_t digest_len; - - if( peer_cert_digest == NULL || - digest_info == MBEDTLS_MD_INVALID_HANDLE ) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) { - return( PEER_CRT_CHANGED ); + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) ); + ssl->state++; + return( 0 ); } - digest_len = mbedtls_md_get_size( digest_info ); - if( digest_len > MBEDTLS_SSL_PEER_CERT_DIGEST_MAX_LEN ) - return( PEER_CRT_CHANGED ); +#if defined(MBEDTLS_SSL_SRV_C) + if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ) + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) ); + ssl->state++; + return( 0 ); + } - ret = mbedtls_md( digest_info, crt_buf, crt_buf_len, tmp_digest ); - if( ret != 0 ) - return( PEER_CRT_CHANGED ); - - return( mbedtls_platform_memequal( tmp_digest, peer_cert_digest, digest_len ) ); -} -#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE && MBEDTLS_SSL_RENEGOTIATION */ -#endif /* MBEDTLS_SSL_RENEGOTIATION && MBEDTLS_SSL_CLI_C */ - -/* - * Once the certificate message is read, parse it into a cert chain and - * perform basic checks, but leave actual verification to the caller - */ -static int ssl_parse_certificate_chain( mbedtls_ssl_context *ssl, - mbedtls_x509_crt *chain ) -{ - volatile int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; -#if defined(MBEDTLS_SSL_RENEGOTIATION) && defined(MBEDTLS_SSL_CLI_C) - int crt_cnt=0; +#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) + if( ssl->handshake->sni_authmode != MBEDTLS_SSL_VERIFY_UNSET ) + authmode = ssl->handshake->sni_authmode; #endif - size_t i, n; - uint8_t alert; + + if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && + authmode == MBEDTLS_SSL_VERIFY_NONE ) + { + ssl->session_negotiate->verify_result = MBEDTLS_X509_BADCERT_SKIP_VERIFY; + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) ); + ssl->state++; + return( 0 ); + } +#endif + + if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 ) + { + /* mbedtls_ssl_read_record may have sent an alert already. We + let it decide whether to alert. */ + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); + return( ret ); + } + + ssl->state++; + +#if defined(MBEDTLS_SSL_SRV_C) +#if defined(MBEDTLS_SSL_PROTO_SSL3) + /* + * Check if the client sent an empty certificate + */ + if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && + ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) + { + if( ssl->in_msglen == 2 && + ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT && + ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING && + ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_CERT ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "SSLv3 client has no certificate" ) ); + + /* The client was asked for a certificate but didn't send + one. The client should know what's going on, so we + don't send an alert. */ + ssl->session_negotiate->verify_result = MBEDTLS_X509_BADCERT_MISSING; + if( authmode == MBEDTLS_SSL_VERIFY_OPTIONAL ) + return( 0 ); + else + return( MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE ); + } + } +#endif /* MBEDTLS_SSL_PROTO_SSL3 */ + +#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ + defined(MBEDTLS_SSL_PROTO_TLS1_2) + if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && + ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_0 ) + { + if( ssl->in_hslen == 3 + mbedtls_ssl_hs_hdr_len( ssl ) && + ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && + ssl->in_msg[0] == MBEDTLS_SSL_HS_CERTIFICATE && + memcmp( ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ), "\0\0\0", 3 ) == 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "TLSv1 client has no certificate" ) ); + + /* The client was asked for a certificate but didn't send + one. The client should know what's going on, so we + don't send an alert. */ + ssl->session_negotiate->verify_result = MBEDTLS_X509_BADCERT_MISSING; + if( authmode == MBEDTLS_SSL_VERIFY_OPTIONAL ) + return( 0 ); + else + return( MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE ); + } + } +#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \ + MBEDTLS_SSL_PROTO_TLS1_2 */ +#endif /* MBEDTLS_SSL_SRV_C */ if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); } @@ -7562,8 +4621,8 @@ static int ssl_parse_certificate_chain( mbedtls_ssl_context *ssl, ssl->in_hslen < mbedtls_ssl_hs_hdr_len( ssl ) + 3 + 3 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ); } @@ -7572,728 +4631,266 @@ static int ssl_parse_certificate_chain( mbedtls_ssl_context *ssl, /* * Same message structure as in mbedtls_ssl_write_certificate() */ - n = mbedtls_platform_get_uint16_be( &ssl->in_msg[i + 1] ); + n = ( ssl->in_msg[i+1] << 8 ) | ssl->in_msg[i+2]; if( ssl->in_msg[i] != 0 || ssl->in_hslen != n + 3 + mbedtls_ssl_hs_hdr_len( ssl ) ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ); } - /* Make &ssl->in_msg[i] point to the beginning of the CRT chain. */ + /* In case we tried to reuse a session but it failed */ + if( ssl->session_negotiate->peer_cert != NULL ) + { + mbedtls_x509_crt_free( ssl->session_negotiate->peer_cert ); + mbedtls_free( ssl->session_negotiate->peer_cert ); + } + + if( ( ssl->session_negotiate->peer_cert = mbedtls_calloc( 1, + sizeof( mbedtls_x509_crt ) ) ) == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed", + sizeof( mbedtls_x509_crt ) ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR ); + return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); + } + + mbedtls_x509_crt_init( ssl->session_negotiate->peer_cert ); + i += 3; - /* Iterate through and parse the CRTs in the provided chain. */ while( i < ssl->in_hslen ) { - /* Check that there's room for the next CRT's length fields. */ if ( i + 3 > ssl->in_hslen ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ); } - /* In theory, the CRT can be up to 2**24 Bytes, but we don't support - * anything beyond 2**16 ~ 64K. */ if( ssl->in_msg[i] != 0 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ); } - /* Read length of the next CRT in the chain. */ - n = mbedtls_platform_get_uint16_be( &ssl->in_msg[i + 1] ); + n = ( (unsigned int) ssl->in_msg[i + 1] << 8 ) + | (unsigned int) ssl->in_msg[i + 2]; i += 3; if( n < 128 || i + n > ssl->in_hslen ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ); } - /* Check if we're handling the first CRT in the chain. */ -#if defined(MBEDTLS_SSL_RENEGOTIATION) && defined(MBEDTLS_SSL_CLI_C) - if( crt_cnt++ == 0 && - mbedtls_ssl_conf_get_endpoint( ssl->conf ) == - MBEDTLS_SSL_IS_CLIENT && - ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS ) - { - /* During client-side renegotiation, check that the server's - * end-CRTs hasn't changed compared to the initial handshake, - * mitigating the triple handshake attack. On success, reuse - * the original end-CRT instead of parsing it again. */ - MBEDTLS_SSL_DEBUG_MSG( 3, ( "Check that peer CRT hasn't changed during renegotiation" ) ); - if( ssl_check_peer_crt_unchanged( ssl, - &ssl->in_msg[i], - n ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "new server cert during renegotiation" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED ); - return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ); - } - - /* Now we can safely free the original chain. */ - ssl_clear_peer_cert( ssl->session ); - } -#endif /* MBEDTLS_SSL_RENEGOTIATION && MBEDTLS_SSL_CLI_C */ - - /* Parse the next certificate in the chain. */ -#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - ret = mbedtls_x509_crt_parse_der( chain, ssl->in_msg + i, n ); -#else - /* If we don't need to store the CRT chain permanently, parse - * it in-place from the input buffer instead of making a copy. */ - ret = mbedtls_x509_crt_parse_der_nocopy( chain, ssl->in_msg + i, n ); -#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ + ret = mbedtls_x509_crt_parse_der( ssl->session_negotiate->peer_cert, + ssl->in_msg + i, n ); switch( ret ) { - case 0: /* ok */ - mbedtls_platform_random_delay(); - if( ret != 0 ) - { - alert = MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR; - ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; - goto crt_parse_der_failed; - } - break; - case MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG + MBEDTLS_ERR_OID_NOT_FOUND: - /* Ignore certificate with an unknown algorithm: maybe a - * prior certificate was already trusted. */ - mbedtls_platform_random_delay(); - if( ret != MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG + MBEDTLS_ERR_OID_NOT_FOUND ) - { - alert = MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR; - ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; - goto crt_parse_der_failed; - } - break; + case 0: /*ok*/ + case MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG + MBEDTLS_ERR_OID_NOT_FOUND: + /* Ignore certificate with an unknown algorithm: maybe a + prior certificate was already trusted. */ + break; - case MBEDTLS_ERR_X509_ALLOC_FAILED: - alert = MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR; - goto crt_parse_der_failed; + case MBEDTLS_ERR_X509_ALLOC_FAILED: + alert = MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR; + goto crt_parse_der_failed; - case MBEDTLS_ERR_X509_UNKNOWN_VERSION: - alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT; - goto crt_parse_der_failed; + case MBEDTLS_ERR_X509_UNKNOWN_VERSION: + alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT; + goto crt_parse_der_failed; - default: - alert = MBEDTLS_SSL_ALERT_MSG_BAD_CERT; - crt_parse_der_failed: - mbedtls_ssl_pend_fatal_alert( ssl, alert ); - MBEDTLS_SSL_DEBUG_RET( 1, " mbedtls_x509_crt_parse_der", ret ); - return( ret ); + default: + alert = MBEDTLS_SSL_ALERT_MSG_BAD_CERT; + crt_parse_der_failed: + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, alert ); + MBEDTLS_SSL_DEBUG_RET( 1, " mbedtls_x509_crt_parse_der", ret ); + return( ret ); } i += n; } - MBEDTLS_SSL_DEBUG_CRT( 3, "peer certificate", chain ); - return( 0 ); -} + MBEDTLS_SSL_DEBUG_CRT( 3, "peer certificate", ssl->session_negotiate->peer_cert ); -#if defined(MBEDTLS_SSL_SRV_C) -static int ssl_srv_check_client_no_crt_notification( mbedtls_ssl_context *ssl ) -{ - if( mbedtls_ssl_conf_get_endpoint( ssl->conf ) == MBEDTLS_SSL_IS_CLIENT ) - return( -1 ); - -#if defined(MBEDTLS_SSL_PROTO_SSL3) /* - * Check if the client sent an empty certificate + * On client, make sure the server cert doesn't change during renego to + * avoid "triple handshake" attack: https://secure-resumption.com/ */ - if( mbedtls_ssl_get_minor_ver( ssl ) == MBEDTLS_SSL_MINOR_VERSION_0 ) +#if defined(MBEDTLS_SSL_RENEGOTIATION) && defined(MBEDTLS_SSL_CLI_C) + if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT && + ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS ) { - if( ssl->in_msglen == 2 && - ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT && - ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING && - ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_CERT ) + if( ssl->session->peer_cert == NULL ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "SSLv3 client has no certificate" ) ); - return( 0 ); + MBEDTLS_SSL_DEBUG_MSG( 1, ( "new server cert during renegotiation" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED ); + return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ); } - return( -1 ); - } -#endif /* MBEDTLS_SSL_PROTO_SSL3 */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( ssl->in_hslen == 3 + mbedtls_ssl_hs_hdr_len( ssl ) && - ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && - ssl->in_msg[0] == MBEDTLS_SSL_HS_CERTIFICATE && - memcmp( ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ), "\0\0\0", 3 ) == 0 ) // use regular memcmp as comparing public data - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "TLSv1 client has no certificate" ) ); - return( 0 ); - } - -#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \ - MBEDTLS_SSL_PROTO_TLS1_2 */ - - return( -1 ); -} -#endif /* MBEDTLS_SSL_SRV_C */ - -/* Check if a certificate message is expected. - * Return either - * - SSL_CERTIFICATE_EXPECTED, or - * - SSL_CERTIFICATE_SKIP - * indicating whether a Certificate message is expected or not. - */ -#define SSL_CERTIFICATE_EXPECTED 0 -#define SSL_CERTIFICATE_SKIP 0xff -static int ssl_parse_certificate_coordinate( mbedtls_ssl_context *ssl, - int authmode ) -{ - mbedtls_ssl_ciphersuite_handle_t ciphersuite_info = - mbedtls_ssl_handshake_get_ciphersuite( ssl->handshake ); - - if( !mbedtls_ssl_ciphersuite_uses_srv_cert( ciphersuite_info ) ) - return( SSL_CERTIFICATE_SKIP ); - -#if defined(MBEDTLS_SSL_SRV_C) - if( mbedtls_ssl_conf_get_endpoint( ssl->conf ) == MBEDTLS_SSL_IS_SERVER ) - { - if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) == - MBEDTLS_KEY_EXCHANGE_RSA_PSK ) + if( ssl->session->peer_cert->raw.len != + ssl->session_negotiate->peer_cert->raw.len || + memcmp( ssl->session->peer_cert->raw.p, + ssl->session_negotiate->peer_cert->raw.p, + ssl->session->peer_cert->raw.len ) != 0 ) { - return( SSL_CERTIFICATE_SKIP ); - } - - if( authmode == MBEDTLS_SSL_VERIFY_NONE ) - { - ssl->session_negotiate->verify_result = - MBEDTLS_X509_BADCERT_SKIP_VERIFY; - return( SSL_CERTIFICATE_SKIP ); + MBEDTLS_SSL_DEBUG_MSG( 1, ( "server cert changed during renegotiation" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED ); + return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ); } } -#else - ((void) authmode); -#endif /* MBEDTLS_SSL_SRV_C */ +#endif /* MBEDTLS_SSL_RENEGOTIATION && MBEDTLS_SSL_CLI_C */ - return( SSL_CERTIFICATE_EXPECTED ); -} - -static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl, - volatile int authmode, - mbedtls_x509_crt *chain, - void *rs_ctx ) -{ - volatile int verify_ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE; - volatile int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; - volatile int flow_counter = 0; - mbedtls_ssl_ciphersuite_handle_t ciphersuite_info = - mbedtls_ssl_handshake_get_ciphersuite( ssl->handshake ); - mbedtls_x509_crt *ca_chain; - mbedtls_x509_crl *ca_crl; - - if( authmode == MBEDTLS_SSL_VERIFY_NONE ) + if( authmode != MBEDTLS_SSL_VERIFY_NONE ) { - return( 0 ); - } + mbedtls_x509_crt *ca_chain; + mbedtls_x509_crl *ca_crl; - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate verify" ) ); #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - if( ssl->handshake->sni_ca_chain != NULL ) - { - ca_chain = ssl->handshake->sni_ca_chain; - ca_crl = ssl->handshake->sni_ca_crl; - } - else -#endif - { - ca_chain = ssl->conf->ca_chain; - ca_crl = ssl->conf->ca_crl; - } - - /* - * Main check: verify certificate - */ - verify_ret = mbedtls_x509_crt_verify_restartable( - chain, - ca_chain, ca_crl, - ssl->conf->cert_profile, -#if defined(MBEDTLS_X509_CRT_PARSE_C) && !defined(MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION) - ssl->hostname, -#endif /* MBEDTLS_X509_CRT_PARSE_C && !MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION */ - &ssl->session_negotiate->verify_result, -#if !defined(MBEDTLS_X509_REMOVE_VERIFY_CALLBACK) - ssl->conf->f_vrfy, ssl->conf->p_vrfy, -#endif /* MBEDTLS_X509_REMOVE_VERIFY_CALLBACK */ - rs_ctx ); - - if( verify_ret == 0 ) - { - mbedtls_platform_random_delay(); - if( verify_ret == 0 ) + if( ssl->handshake->sni_ca_chain != NULL ) { - flow_counter++; + ca_chain = ssl->handshake->sni_ca_chain; + ca_crl = ssl->handshake->sni_ca_crl; } else - { - return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); - } - } - if( verify_ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "x509_verify_cert", verify_ret ); - flow_counter++; - } - -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( verify_ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) - return( MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS ); #endif - - /* - * Secondary checks: always done, but change 'ret' only if it was 0 - */ - -#if defined(MBEDTLS_ECP_C) || defined(MBEDTLS_USE_TINYCRYPT) - { -#if defined(MBEDTLS_USE_TINYCRYPT) - ret = mbedtls_ssl_check_curve_uecc( ssl, MBEDTLS_UECC_DP_SECP256R1 ); -#else /* MBEDTLS_USE_TINYCRYPT */ - mbedtls_pk_context *pk; - ret = mbedtls_x509_crt_pk_acquire( chain, &pk ); - if( ret != 0 ) { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_x509_crt_pk_acquire", ret ); - return( ret ); + ca_chain = ssl->conf->ca_chain; + ca_crl = ssl->conf->ca_crl; } - /* If certificate uses an EC key, make sure the curve is OK */ - if( mbedtls_pk_can_do( pk, MBEDTLS_PK_ECKEY ) ) - { - ret = mbedtls_ssl_check_curve( ssl, mbedtls_pk_ec( *pk )->grp.id ); - } - - mbedtls_x509_crt_pk_release( chain ); -#endif /* MBEDTLS_USE_TINYCRYPT */ + /* + * Main check: verify certificate + */ + ret = mbedtls_x509_crt_verify_with_profile( + ssl->session_negotiate->peer_cert, + ca_chain, ca_crl, + ssl->conf->cert_profile, + ssl->hostname, + &ssl->session_negotiate->verify_result, + ssl->conf->f_vrfy, ssl->conf->p_vrfy ); if( ret != 0 ) { - ssl->session_negotiate->verify_result |= MBEDTLS_X509_BADCERT_BAD_KEY; - - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate (EC key curve)" ) ); - if( verify_ret == 0 ) - verify_ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE; - flow_counter++; + MBEDTLS_SSL_DEBUG_RET( 1, "x509_verify_cert", ret ); } - if( ret == 0 ) + + /* + * Secondary checks: always done, but change 'ret' only if it was 0 + */ + +#if defined(MBEDTLS_ECP_C) { - flow_counter++; + const mbedtls_pk_context *pk = &ssl->session_negotiate->peer_cert->pk; + + /* If certificate uses an EC key, make sure the curve is OK */ + if( mbedtls_pk_can_do( pk, MBEDTLS_PK_ECKEY ) && + mbedtls_ssl_check_curve( ssl, mbedtls_pk_ec( *pk )->grp.id ) != 0 ) + { + ssl->session_negotiate->verify_result |= MBEDTLS_X509_BADCERT_BAD_KEY; + + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate (EC key curve)" ) ); + if( ret == 0 ) + ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE; + } } - } -#endif /* MBEDTLS_ECP_C || MEDTLS_USE_TINYCRYPT */ +#endif /* MBEDTLS_ECP_C */ - ret = mbedtls_ssl_check_cert_usage( chain, - ciphersuite_info, - ( mbedtls_ssl_conf_get_endpoint( ssl->conf ) == - MBEDTLS_SSL_IS_CLIENT ), - &ssl->session_negotiate->verify_result ); - if( ret == 0 ) - { - flow_counter++; - } - else - { - flow_counter++; - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate (usage extensions)" ) ); - if( verify_ret == 0 ) - verify_ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE; - } + if( mbedtls_ssl_check_cert_usage( ssl->session_negotiate->peer_cert, + ciphersuite_info, + ! ssl->conf->endpoint, + &ssl->session_negotiate->verify_result ) != 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate (usage extensions)" ) ); + if( ret == 0 ) + ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE; + } - /* mbedtls_x509_crt_verify_with_profile is supposed to report a - * verification failure through MBEDTLS_ERR_X509_CERT_VERIFY_FAILED, - * with details encoded in the verification flags. All other kinds - * of error codes, including those from the user provided f_vrfy - * functions, are treated as fatal and lead to a failure of - * ssl_parse_certificate even if verification was optional. */ - if( authmode == MBEDTLS_SSL_VERIFY_OPTIONAL && - ( verify_ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED || - verify_ret == MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ) ) - { - mbedtls_platform_random_delay(); + /* mbedtls_x509_crt_verify_with_profile is supposed to report a + * verification failure through MBEDTLS_ERR_X509_CERT_VERIFY_FAILED, + * with details encoded in the verification flags. All other kinds + * of error codes, including those from the user provided f_vrfy + * functions, are treated as fatal and lead to a failure of + * ssl_parse_certificate even if verification was optional. */ if( authmode == MBEDTLS_SSL_VERIFY_OPTIONAL && - ( verify_ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED || - verify_ret == MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ) ) + ( ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED || + ret == MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ) ) { - verify_ret = 0; - flow_counter++; + ret = 0; } - else + + if( ca_chain == NULL && authmode == MBEDTLS_SSL_VERIFY_REQUIRED ) { - return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); + MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no CA chain" ) ); + ret = MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED; } - } else { - flow_counter++; - } - if( ca_chain == NULL && authmode == MBEDTLS_SSL_VERIFY_REQUIRED ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no CA chain" ) ); - verify_ret = MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED; - flow_counter++; - } - else - { - flow_counter++; - } - - if( verify_ret != 0 ) - { - uint8_t alert; - - /* The certificate may have been rejected for several reasons. - Pick one and send the corresponding alert. Which alert to send - may be a subject of debate in some cases. */ - if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_OTHER ) - alert = MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED; - else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_CN_MISMATCH ) - alert = MBEDTLS_SSL_ALERT_MSG_BAD_CERT; - else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_KEY_USAGE ) - alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT; - else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_EXT_KEY_USAGE ) - alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT; - else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_NS_CERT_TYPE ) - alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT; - else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_BAD_PK ) - alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT; - else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_BAD_KEY ) - alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT; - else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_EXPIRED ) - alert = MBEDTLS_SSL_ALERT_MSG_CERT_EXPIRED; - else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_REVOKED ) - alert = MBEDTLS_SSL_ALERT_MSG_CERT_REVOKED; - else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_NOT_TRUSTED ) - alert = MBEDTLS_SSL_ALERT_MSG_UNKNOWN_CA; - else - alert = MBEDTLS_SSL_ALERT_MSG_CERT_UNKNOWN; - mbedtls_ssl_pend_fatal_alert( ssl, alert ); - } - - if( verify_ret == 0 && -#if defined(MBEDTLS_ECP_C) || defined(MBEDTLS_USE_TINYCRYPT) - flow_counter == 5 ) -#else - flow_counter == 4 ) -#endif - { - mbedtls_platform_random_delay(); - if( verify_ret == 0 && -#if defined(MBEDTLS_ECP_C) || defined(MBEDTLS_USE_TINYCRYPT) - flow_counter == 5 ) -#else - flow_counter == 4 ) -#endif + if( ret != 0 ) { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> PEER AUTHENTICATED" ) ); - ssl->handshake->peer_authenticated = MBEDTLS_SSL_FI_FLAG_SET; + /* The certificate may have been rejected for several reasons. + Pick one and send the corresponding alert. Which alert to send + may be a subject of debate in some cases. */ + if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_OTHER ) + alert = MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED; + else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_CN_MISMATCH ) + alert = MBEDTLS_SSL_ALERT_MSG_BAD_CERT; + else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_KEY_USAGE ) + alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT; + else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_EXT_KEY_USAGE ) + alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT; + else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_NS_CERT_TYPE ) + alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT; + else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_BAD_PK ) + alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT; + else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_BAD_KEY ) + alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT; + else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_EXPIRED ) + alert = MBEDTLS_SSL_ALERT_MSG_CERT_EXPIRED; + else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_REVOKED ) + alert = MBEDTLS_SSL_ALERT_MSG_CERT_REVOKED; + else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_NOT_TRUSTED ) + alert = MBEDTLS_SSL_ALERT_MSG_UNKNOWN_CA; + else + alert = MBEDTLS_SSL_ALERT_MSG_CERT_UNKNOWN; + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + alert ); } - else - { - return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); - } - } else { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> PEER NOT AUTHENTICATED, %d", flow_counter)); - } #if defined(MBEDTLS_DEBUG_C) - if( ssl->session_negotiate->verify_result != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "! Certificate verification flags %x", - ssl->session_negotiate->verify_result ) ); - } - else - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "Certificate verification flags clear" ) ); - } -#endif /* MBEDTLS_DEBUG_C */ - - return( verify_ret ); -} - - -#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) && defined(MBEDTLS_SSL_DELAYED_SERVER_CERT_VERIFICATION) -/* mbedtls_ssl_parse_delayed_certificate_verify() defines a wrapper around ssl_parse_certificate_verify - * to call it in ssl_cli.c rather than purely internal to ssl_tls.c. - */ -int mbedtls_ssl_parse_delayed_certificate_verify( mbedtls_ssl_context *ssl, - int authmode, - mbedtls_x509_crt *chain, - void *rs_ctx ) -{ - - return( ssl_parse_certificate_verify( ssl, - authmode, - chain, - rs_ctx ) ); - -} -#endif /* MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED && MBEDTLS_SSL_DELAYED_SERVER_CERT_VERIFICATION */ - - -#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - -#if defined(MBEDTLS_SSL_RENEGOTIATION) -static int ssl_remember_peer_crt_digest( mbedtls_ssl_context *ssl, - unsigned char *start, size_t len ) -{ - int ret; - /* Remember digest of the peer's end-CRT. */ - ssl->session_negotiate->peer_cert_digest = - mbedtls_calloc( 1, MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN ); - if( ssl->session_negotiate->peer_cert_digest == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed", - sizeof( MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN ) ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR ); - - return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); - } - - ret = mbedtls_md( mbedtls_md_info_from_type( - MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_TYPE ), - start, len, - ssl->session_negotiate->peer_cert_digest ); - - ssl->session_negotiate->peer_cert_digest_type = - MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_TYPE; - ssl->session_negotiate->peer_cert_digest_len = - MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN; - - return( ret ); -} -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - -static int ssl_remember_peer_pubkey( mbedtls_ssl_context *ssl, - unsigned char *start, size_t len ) -{ - unsigned char *end = start + len; - int ret; - - /* Make a copy of the peer's raw public key. */ - mbedtls_pk_init( &ssl->handshake->peer_pubkey ); - ret = mbedtls_pk_parse_subpubkey( &start, end, - &ssl->handshake->peer_pubkey ); - if( ret != 0 ) - { - /* We should have parsed the public key before. */ - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - ssl->handshake->got_peer_pubkey = 1; - return( 0 ); -} -#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - -int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl ) -{ - volatile int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; - volatile int ret_verify = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; - volatile int check_cert_initiated = 0; - volatile int crt_expected = SSL_CERTIFICATE_EXPECTED; -#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - const int authmode = ssl->handshake->sni_authmode != MBEDTLS_SSL_VERIFY_UNSET - ? ssl->handshake->sni_authmode - : mbedtls_ssl_conf_get_authmode( ssl->conf ); -#else - const int authmode = mbedtls_ssl_conf_get_authmode( ssl->conf ); -#endif - void *rs_ctx = NULL; - mbedtls_x509_crt *chain = NULL; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate" ) ); - - crt_expected = ssl_parse_certificate_coordinate( ssl, authmode ); - if( crt_expected == SSL_CERTIFICATE_SKIP ) - { - mbedtls_platform_random_delay(); - crt_expected = ssl_parse_certificate_coordinate( ssl, authmode ); - if( crt_expected == SSL_CERTIFICATE_SKIP ) + if( ssl->session_negotiate->verify_result != 0 ) { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) ); - ret = 0; - goto exit; + MBEDTLS_SSL_DEBUG_MSG( 3, ( "! Certificate verification flags %x", + ssl->session_negotiate->verify_result ) ); } - } - -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( ssl->handshake->ecrs_enabled && - ssl->handshake->ecrs_state == ssl_ecrs_crt_verify ) - { - chain = ssl->handshake->ecrs_peer_cert; - ssl->handshake->ecrs_peer_cert = NULL; - goto crt_verify; - } -#endif - - if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 ) - { - /* mbedtls_ssl_read_record may have sent an alert already. We - let it decide whether to alert. */ - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); - goto exit; - } - -#if defined(MBEDTLS_SSL_SRV_C) - if( ssl_srv_check_client_no_crt_notification( ssl ) == 0 ) - { - ssl->session_negotiate->verify_result = MBEDTLS_X509_BADCERT_MISSING; - - if( authmode == MBEDTLS_SSL_VERIFY_OPTIONAL ) - ret = 0; else - ret = MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE; - - goto exit; - } -#endif /* MBEDTLS_SSL_SRV_C */ - - /* Clear existing peer CRT structure in case we tried to - * reuse a session but it failed, and allocate a new one. */ - ssl_clear_peer_cert( ssl->session_negotiate ); - - chain = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt ) ); - if( chain == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed", - sizeof( mbedtls_x509_crt ) ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR ); - - ret = MBEDTLS_ERR_SSL_ALLOC_FAILED; - goto exit; - } - mbedtls_x509_crt_init( chain ); - - ret = ssl_parse_certificate_chain( ssl, chain ); - if( ret != 0 ) - goto exit; - -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( ssl->handshake->ecrs_enabled) - ssl->handshake->ecrs_state = ssl_ecrs_crt_verify; - -crt_verify: - check_cert_initiated = 1; - if( ssl->handshake->ecrs_enabled) - rs_ctx = &ssl->handshake->ecrs_ctx; -#endif - -#if defined(MBEDTLS_SSL_DELAYED_SERVER_CERT_VERIFICATION) - if ( mbedtls_ssl_conf_get_endpoint( ssl->conf ) == MBEDTLS_SSL_IS_CLIENT ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "delay server certificate verification" ) ); - check_cert_initiated = 0; - ret = 0; - } - else -#endif /* MBEDTLS_SSL_DELAYED_SERVER_CERT_VERIFICATION */ - { - ret_verify = ssl_parse_certificate_verify( ssl, authmode, - chain, rs_ctx ); - ret = ret_verify; - if( ret_verify != 0 ) { - goto exit; + MBEDTLS_SSL_DEBUG_MSG( 3, ( "Certificate verification flags clear" ) ); } +#endif /* MBEDTLS_DEBUG_C */ } -#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - { - size_t pk_len; - unsigned char *pk_start; - - /* We parse the CRT chain without copying, so - * these pointers point into the input buffer, - * and are hence still valid after freeing the - * CRT chain. */ - -#if defined(MBEDTLS_SSL_RENEGOTIATION) - unsigned char *crt_start; - size_t crt_len; - - crt_start = chain->raw.p; - crt_len = chain->raw.len; -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - - pk_start = chain->cache->pk_raw.p; - pk_len = chain->cache->pk_raw.len; - - /* Free the CRT structures before computing - * digest and copying the peer's public key. */ - mbedtls_x509_crt_free( chain ); - mbedtls_free( chain ); - chain = NULL; - -#if defined(MBEDTLS_SSL_RENEGOTIATION) - ret = ssl_remember_peer_crt_digest( ssl, crt_start, crt_len ); - if( ret != 0 ) - goto exit; -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - - ret = ssl_remember_peer_pubkey( ssl, pk_start, pk_len ); - if( ret != 0 ) - goto exit; - } -#else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - /* Pass ownership to session structure. */ - ssl->session_negotiate->peer_cert = chain; - chain = NULL; -#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse certificate" ) ); -exit: - - if( check_cert_initiated && ( ret == 0 ) ) - { - ret = ret_verify; - } - if( ret == 0 ) - { - if( ssl->state == MBEDTLS_SSL_CLIENT_CERTIFICATE ) - { - ssl->state = MBEDTLS_SSL_CLIENT_KEY_EXCHANGE; - } - else if( ssl->state == MBEDTLS_SSL_SERVER_CERTIFICATE ) - { - ssl->state = MBEDTLS_SSL_SERVER_KEY_EXCHANGE; - } - else - { - ssl->state = MBEDTLS_SSL_INVALID; - } - } - -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( ret == MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS ) - { - ssl->handshake->ecrs_peer_cert = chain; - chain = NULL; - } -#endif - - if( chain != NULL ) - { - mbedtls_x509_crt_free( chain ); - mbedtls_free( chain ); - } - return( ret ); } -#endif /* MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ +#endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED + !MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED + !MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED + !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED + !MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED + !MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED + !MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ int mbedtls_ssl_write_change_cipher_spec( mbedtls_ssl_context *ssl ) { @@ -8305,22 +4902,11 @@ int mbedtls_ssl_write_change_cipher_spec( mbedtls_ssl_context *ssl ) ssl->out_msglen = 1; ssl->out_msg[0] = 1; - if( ssl->state == MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC ) - { - ssl->state = MBEDTLS_SSL_CLIENT_FINISHED; - } - else if( ssl->state == MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC ) - { - ssl->state = MBEDTLS_SSL_SERVER_FINISHED; - } - else - { - ssl->state = MBEDTLS_SSL_INVALID; - } + ssl->state++; - if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 ) + if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 ) { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret ); + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret ); return( ret ); } @@ -8335,7 +4921,7 @@ int mbedtls_ssl_parse_change_cipher_spec( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse change cipher spec" ) ); - if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 ) + if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); return( ret ); @@ -8344,13 +4930,18 @@ int mbedtls_ssl_parse_change_cipher_spec( mbedtls_ssl_context *ssl ) if( ssl->in_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad change cipher spec message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); } - /* CCS records are only accepted if they have length 1 and content '1', - * so we don't need to check this here. */ + if( ssl->in_msglen != 1 || ssl->in_msg[0] != 1 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad change cipher spec message" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + return( MBEDTLS_ERR_SSL_BAD_HS_CHANGE_CIPHER_SPEC ); + } /* * Switch to our negotiated transform and session parameters for inbound @@ -8361,7 +4952,7 @@ int mbedtls_ssl_parse_change_cipher_spec( mbedtls_ssl_context *ssl ) ssl->session_in = ssl->session_negotiate; #if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) ) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) { #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) ssl_dtls_replay_reset( ssl ); @@ -8376,15 +4967,20 @@ int mbedtls_ssl_parse_change_cipher_spec( mbedtls_ssl_context *ssl ) return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING ); } } - MBEDTLS_SSL_TRANSPORT_ELSE + else #endif /* MBEDTLS_SSL_PROTO_DTLS */ -#if defined(MBEDTLS_SSL_PROTO_TLS) - { - mbedtls_platform_memset( ssl->in_ctr, 0, 8 ); - } -#endif + memset( ssl->in_ctr, 0, 8 ); - ssl_update_in_pointers( ssl ); + /* + * Set the in_msg pointer to the correct location based on IV length + */ + if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 ) + { + ssl->in_msg = ssl->in_iv + ssl->transform_negotiate->ivlen - + ssl->transform_negotiate->fixed_ivlen; + } + else + ssl->in_msg = ssl->in_iv; #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) if( mbedtls_ssl_hw_record_activate != NULL ) @@ -8392,36 +4988,54 @@ int mbedtls_ssl_parse_change_cipher_spec( mbedtls_ssl_context *ssl ) if( ( ret = mbedtls_ssl_hw_record_activate( ssl, MBEDTLS_SSL_CHANNEL_INBOUND ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_activate", ret ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR ); return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); } } #endif - if( ssl->state == MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC ) - { - ssl->state = MBEDTLS_SSL_CLIENT_FINISHED; - } - else if( ssl->state == MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC ) - { - ssl->state = MBEDTLS_SSL_SERVER_FINISHED; - } - else - { - ssl->state = MBEDTLS_SSL_INVALID; - } + ssl->state++; MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse change cipher spec" ) ); return( 0 ); } +void mbedtls_ssl_optimize_checksum( mbedtls_ssl_context *ssl, + const mbedtls_ssl_ciphersuite_t *ciphersuite_info ) +{ + ((void) ciphersuite_info); + +#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ + defined(MBEDTLS_SSL_PROTO_TLS1_1) + if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 ) + ssl->handshake->update_checksum = ssl_update_checksum_md5sha1; + else +#endif +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) +#if defined(MBEDTLS_SHA512_C) + if( ciphersuite_info->mac == MBEDTLS_MD_SHA384 ) + ssl->handshake->update_checksum = ssl_update_checksum_sha384; + else +#endif +#if defined(MBEDTLS_SHA256_C) + if( ciphersuite_info->mac != MBEDTLS_MD_SHA384 ) + ssl->handshake->update_checksum = ssl_update_checksum_sha256; + else +#endif +#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return; + } +} + void mbedtls_ssl_reset_checksum( mbedtls_ssl_context *ssl ) { #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ defined(MBEDTLS_SSL_PROTO_TLS1_1) - mbedtls_md5_starts_ret( &ssl->handshake->fin_md5 ); + mbedtls_md5_starts_ret( &ssl->handshake->fin_md5 ); mbedtls_sha1_starts_ret( &ssl->handshake->fin_sha1 ); #endif #if defined(MBEDTLS_SSL_PROTO_TLS1_2) @@ -8434,6 +5048,296 @@ void mbedtls_ssl_reset_checksum( mbedtls_ssl_context *ssl ) #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ } +static void ssl_update_checksum_start( mbedtls_ssl_context *ssl, + const unsigned char *buf, size_t len ) +{ +#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ + defined(MBEDTLS_SSL_PROTO_TLS1_1) + mbedtls_md5_update_ret( &ssl->handshake->fin_md5 , buf, len ); + mbedtls_sha1_update_ret( &ssl->handshake->fin_sha1, buf, len ); +#endif +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) +#if defined(MBEDTLS_SHA256_C) + mbedtls_sha256_update_ret( &ssl->handshake->fin_sha256, buf, len ); +#endif +#if defined(MBEDTLS_SHA512_C) + mbedtls_sha512_update_ret( &ssl->handshake->fin_sha512, buf, len ); +#endif +#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ +} + +#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ + defined(MBEDTLS_SSL_PROTO_TLS1_1) +static void ssl_update_checksum_md5sha1( mbedtls_ssl_context *ssl, + const unsigned char *buf, size_t len ) +{ + mbedtls_md5_update_ret( &ssl->handshake->fin_md5 , buf, len ); + mbedtls_sha1_update_ret( &ssl->handshake->fin_sha1, buf, len ); +} +#endif + +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) +#if defined(MBEDTLS_SHA256_C) +static void ssl_update_checksum_sha256( mbedtls_ssl_context *ssl, + const unsigned char *buf, size_t len ) +{ + mbedtls_sha256_update_ret( &ssl->handshake->fin_sha256, buf, len ); +} +#endif + +#if defined(MBEDTLS_SHA512_C) +static void ssl_update_checksum_sha384( mbedtls_ssl_context *ssl, + const unsigned char *buf, size_t len ) +{ + mbedtls_sha512_update_ret( &ssl->handshake->fin_sha512, buf, len ); +} +#endif +#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ + +#if defined(MBEDTLS_SSL_PROTO_SSL3) +static void ssl_calc_finished_ssl( + mbedtls_ssl_context *ssl, unsigned char *buf, int from ) +{ + const char *sender; + mbedtls_md5_context md5; + mbedtls_sha1_context sha1; + + unsigned char padbuf[48]; + unsigned char md5sum[16]; + unsigned char sha1sum[20]; + + mbedtls_ssl_session *session = ssl->session_negotiate; + if( !session ) + session = ssl->session; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc finished ssl" ) ); + + mbedtls_md5_init( &md5 ); + mbedtls_sha1_init( &sha1 ); + + mbedtls_md5_clone( &md5, &ssl->handshake->fin_md5 ); + mbedtls_sha1_clone( &sha1, &ssl->handshake->fin_sha1 ); + + /* + * SSLv3: + * hash = + * MD5( master + pad2 + + * MD5( handshake + sender + master + pad1 ) ) + * + SHA1( master + pad2 + + * SHA1( handshake + sender + master + pad1 ) ) + */ + +#if !defined(MBEDTLS_MD5_ALT) + MBEDTLS_SSL_DEBUG_BUF( 4, "finished md5 state", (unsigned char *) + md5.state, sizeof( md5.state ) ); +#endif + +#if !defined(MBEDTLS_SHA1_ALT) + MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha1 state", (unsigned char *) + sha1.state, sizeof( sha1.state ) ); +#endif + + sender = ( from == MBEDTLS_SSL_IS_CLIENT ) ? "CLNT" + : "SRVR"; + + memset( padbuf, 0x36, 48 ); + + mbedtls_md5_update_ret( &md5, (const unsigned char *) sender, 4 ); + mbedtls_md5_update_ret( &md5, session->master, 48 ); + mbedtls_md5_update_ret( &md5, padbuf, 48 ); + mbedtls_md5_finish_ret( &md5, md5sum ); + + mbedtls_sha1_update_ret( &sha1, (const unsigned char *) sender, 4 ); + mbedtls_sha1_update_ret( &sha1, session->master, 48 ); + mbedtls_sha1_update_ret( &sha1, padbuf, 40 ); + mbedtls_sha1_finish_ret( &sha1, sha1sum ); + + memset( padbuf, 0x5C, 48 ); + + mbedtls_md5_starts_ret( &md5 ); + mbedtls_md5_update_ret( &md5, session->master, 48 ); + mbedtls_md5_update_ret( &md5, padbuf, 48 ); + mbedtls_md5_update_ret( &md5, md5sum, 16 ); + mbedtls_md5_finish_ret( &md5, buf ); + + mbedtls_sha1_starts_ret( &sha1 ); + mbedtls_sha1_update_ret( &sha1, session->master, 48 ); + mbedtls_sha1_update_ret( &sha1, padbuf , 40 ); + mbedtls_sha1_update_ret( &sha1, sha1sum, 20 ); + mbedtls_sha1_finish_ret( &sha1, buf + 16 ); + + MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, 36 ); + + mbedtls_md5_free( &md5 ); + mbedtls_sha1_free( &sha1 ); + + mbedtls_zeroize( padbuf, sizeof( padbuf ) ); + mbedtls_zeroize( md5sum, sizeof( md5sum ) ); + mbedtls_zeroize( sha1sum, sizeof( sha1sum ) ); + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc finished" ) ); +} +#endif /* MBEDTLS_SSL_PROTO_SSL3 */ + +#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) +static void ssl_calc_finished_tls( + mbedtls_ssl_context *ssl, unsigned char *buf, int from ) +{ + int len = 12; + const char *sender; + mbedtls_md5_context md5; + mbedtls_sha1_context sha1; + unsigned char padbuf[36]; + + mbedtls_ssl_session *session = ssl->session_negotiate; + if( !session ) + session = ssl->session; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc finished tls" ) ); + + mbedtls_md5_init( &md5 ); + mbedtls_sha1_init( &sha1 ); + + mbedtls_md5_clone( &md5, &ssl->handshake->fin_md5 ); + mbedtls_sha1_clone( &sha1, &ssl->handshake->fin_sha1 ); + + /* + * TLSv1: + * hash = PRF( master, finished_label, + * MD5( handshake ) + SHA1( handshake ) )[0..11] + */ + +#if !defined(MBEDTLS_MD5_ALT) + MBEDTLS_SSL_DEBUG_BUF( 4, "finished md5 state", (unsigned char *) + md5.state, sizeof( md5.state ) ); +#endif + +#if !defined(MBEDTLS_SHA1_ALT) + MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha1 state", (unsigned char *) + sha1.state, sizeof( sha1.state ) ); +#endif + + sender = ( from == MBEDTLS_SSL_IS_CLIENT ) + ? "client finished" + : "server finished"; + + mbedtls_md5_finish_ret( &md5, padbuf ); + mbedtls_sha1_finish_ret( &sha1, padbuf + 16 ); + + ssl->handshake->tls_prf( session->master, 48, sender, + padbuf, 36, buf, len ); + + MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, len ); + + mbedtls_md5_free( &md5 ); + mbedtls_sha1_free( &sha1 ); + + mbedtls_zeroize( padbuf, sizeof( padbuf ) ); + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc finished" ) ); +} +#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 */ + +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) +#if defined(MBEDTLS_SHA256_C) +static void ssl_calc_finished_tls_sha256( + mbedtls_ssl_context *ssl, unsigned char *buf, int from ) +{ + int len = 12; + const char *sender; + mbedtls_sha256_context sha256; + unsigned char padbuf[32]; + + mbedtls_ssl_session *session = ssl->session_negotiate; + if( !session ) + session = ssl->session; + + mbedtls_sha256_init( &sha256 ); + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc finished tls sha256" ) ); + + mbedtls_sha256_clone( &sha256, &ssl->handshake->fin_sha256 ); + + /* + * TLSv1.2: + * hash = PRF( master, finished_label, + * Hash( handshake ) )[0.11] + */ + +#if !defined(MBEDTLS_SHA256_ALT) + MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha2 state", (unsigned char *) + sha256.state, sizeof( sha256.state ) ); +#endif + + sender = ( from == MBEDTLS_SSL_IS_CLIENT ) + ? "client finished" + : "server finished"; + + mbedtls_sha256_finish_ret( &sha256, padbuf ); + + ssl->handshake->tls_prf( session->master, 48, sender, + padbuf, 32, buf, len ); + + MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, len ); + + mbedtls_sha256_free( &sha256 ); + + mbedtls_zeroize( padbuf, sizeof( padbuf ) ); + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc finished" ) ); +} +#endif /* MBEDTLS_SHA256_C */ + +#if defined(MBEDTLS_SHA512_C) +static void ssl_calc_finished_tls_sha384( + mbedtls_ssl_context *ssl, unsigned char *buf, int from ) +{ + int len = 12; + const char *sender; + mbedtls_sha512_context sha512; + unsigned char padbuf[48]; + + mbedtls_ssl_session *session = ssl->session_negotiate; + if( !session ) + session = ssl->session; + + mbedtls_sha512_init( &sha512 ); + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc finished tls sha384" ) ); + + mbedtls_sha512_clone( &sha512, &ssl->handshake->fin_sha512 ); + + /* + * TLSv1.2: + * hash = PRF( master, finished_label, + * Hash( handshake ) )[0.11] + */ + +#if !defined(MBEDTLS_SHA512_ALT) + MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha512 state", (unsigned char *) + sha512.state, sizeof( sha512.state ) ); +#endif + + sender = ( from == MBEDTLS_SSL_IS_CLIENT ) + ? "client finished" + : "server finished"; + + mbedtls_sha512_finish_ret( &sha512, padbuf ); + + ssl->handshake->tls_prf( session->master, 48, sender, + padbuf, 48, buf, len ); + + MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, len ); + + mbedtls_sha512_free( &sha512 ); + + mbedtls_zeroize( padbuf, sizeof( padbuf ) ); + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc finished" ) ); +} +#endif /* MBEDTLS_SHA512_C */ +#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ + static void ssl_handshake_wrapup_free_hs_transform( mbedtls_ssl_context *ssl ) { MBEDTLS_SSL_DEBUG_MSG( 3, ( "=> handshake wrapup: final free" ) ); @@ -8441,7 +5345,7 @@ static void ssl_handshake_wrapup_free_hs_transform( mbedtls_ssl_context *ssl ) /* * Free our handshake params */ - mbedtls_ssl_handshake_free( ssl ); + mbedtls_ssl_handshake_free( ssl->handshake ); mbedtls_free( ssl->handshake ); ssl->handshake = NULL; @@ -8459,21 +5363,10 @@ static void ssl_handshake_wrapup_free_hs_transform( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_DEBUG_MSG( 3, ( "<= handshake wrapup: final free" ) ); } -int mbedtls_ssl_handshake_wrapup( mbedtls_ssl_context *ssl ) +void mbedtls_ssl_handshake_wrapup( mbedtls_ssl_context *ssl ) { - volatile int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; + int resume = ssl->handshake->resume; -#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - volatile const int authmode = ssl->handshake->sni_authmode != MBEDTLS_SSL_VERIFY_UNSET - ? ssl->handshake->sni_authmode - : mbedtls_ssl_conf_get_authmode( ssl->conf ); -#else - volatile const int authmode = mbedtls_ssl_conf_get_authmode( ssl->conf ); -#endif -#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) - volatile int crt_expected = SSL_CERTIFICATE_EXPECTED; - crt_expected = ssl_parse_certificate_coordinate( ssl, authmode ); -#endif MBEDTLS_SSL_DEBUG_MSG( 3, ( "=> handshake wrapup" ) ); #if defined(MBEDTLS_SSL_RENEGOTIATION) @@ -8501,110 +5394,19 @@ int mbedtls_ssl_handshake_wrapup( mbedtls_ssl_context *ssl ) ssl->session = ssl->session_negotiate; ssl->session_negotiate = NULL; -#if defined(MBEDTLS_SSL_SRV_C) && !defined(MBEDTLS_SSL_NO_SESSION_CACHE) /* * Add cache entry */ if( ssl->conf->f_set_cache != NULL && ssl->session->id_len != 0 && - ssl->handshake->resume == MBEDTLS_SSL_FI_FLAG_UNSET ) + resume == 0 ) { if( ssl->conf->f_set_cache( ssl->conf->p_cache, ssl->session ) != 0 ) MBEDTLS_SSL_DEBUG_MSG( 1, ( "cache did not store session" ) ); } -#endif /* MBEDTLS_SSL_SRV_C && !MBEDTLS_SSL_NO_SESSION_CACHE */ - if( authmode == MBEDTLS_SSL_VERIFY_NONE || - authmode == MBEDTLS_SSL_VERIFY_OPTIONAL || -#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) - crt_expected == SSL_CERTIFICATE_SKIP ) -#else - 1 ) -#endif - { - mbedtls_platform_random_delay(); - if( authmode == MBEDTLS_SSL_VERIFY_NONE || - authmode == MBEDTLS_SSL_VERIFY_OPTIONAL || -#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) - crt_expected == SSL_CERTIFICATE_SKIP ) -#else - 1 ) -#endif - { - ssl->handshake->peer_authenticated = MBEDTLS_SSL_FI_FLAG_SET; - } - else - { - ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; - goto cleanup; - } - } - -#if !defined(MBEDTLS_SSL_NO_SESSION_RESUMPTION) - if( ssl->handshake->resume == MBEDTLS_SSL_FI_FLAG_SET ) - { - mbedtls_platform_random_delay(); - if( ssl->handshake->resume == MBEDTLS_SSL_FI_FLAG_SET ) - { - /* When doing session resume, no premaster or peer authentication */ - ssl->handshake->peer_authenticated = MBEDTLS_SSL_FI_FLAG_SET; - ssl->handshake->premaster_generated = MBEDTLS_SSL_FI_FLAG_SET; - } - else - { - ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; - goto cleanup; - } - } -#endif - - if( ssl->handshake->peer_authenticated == MBEDTLS_SSL_FI_FLAG_SET ) - { - mbedtls_platform_random_delay(); - if( ssl->handshake->peer_authenticated == MBEDTLS_SSL_FI_FLAG_SET ) - { - ret = 0; - } - else - { - ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; - goto cleanup; - } - } - else - { - ret = MBEDTLS_ERR_SSL_PEER_VERIFY_FAILED; - goto cleanup; - } - - if( ssl->handshake->hello_random_set == MBEDTLS_SSL_FI_FLAG_SET && - ssl->handshake->key_derivation_done == MBEDTLS_SSL_FI_FLAG_SET && - ssl->handshake->premaster_generated == MBEDTLS_SSL_FI_FLAG_SET ) - { - mbedtls_platform_random_delay(); - if( ssl->handshake->hello_random_set == MBEDTLS_SSL_FI_FLAG_SET && - ssl->handshake->key_derivation_done == MBEDTLS_SSL_FI_FLAG_SET && - ssl->handshake->premaster_generated == MBEDTLS_SSL_FI_FLAG_SET ) - { - ret = 0; - } - else - { - ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; - goto cleanup; - } - } - else - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "hello random %d", ssl->handshake->hello_random_set ) ); - MBEDTLS_SSL_DEBUG_MSG( 3, ( "key_derivation_done %d", ssl->handshake->key_derivation_done ) ); - MBEDTLS_SSL_DEBUG_MSG( 3, ( "premaster_generated %d", ssl->handshake->premaster_generated ) ); - ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - -cleanup: #if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) && + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && ssl->handshake->flight != NULL ) { /* Cancel handshake timer */ @@ -8618,10 +5420,9 @@ cleanup: #endif ssl_handshake_wrapup_free_hs_transform( ssl ); - ssl->state = MBEDTLS_SSL_HANDSHAKE_OVER; + ssl->state++; MBEDTLS_SSL_DEBUG_MSG( 3, ( "<= handshake wrapup" ) ); - return ret; } int mbedtls_ssl_write_finished( mbedtls_ssl_context *ssl ) @@ -8630,15 +5431,18 @@ int mbedtls_ssl_write_finished( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write finished" ) ); - ssl_update_out_pointers( ssl, ssl->transform_negotiate ); + /* + * Set the out_msg pointer to the correct location based on IV length + */ + if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 ) + { + ssl->out_msg = ssl->out_iv + ssl->transform_negotiate->ivlen - + ssl->transform_negotiate->fixed_ivlen; + } + else + ssl->out_msg = ssl->out_iv; - ssl_calc_finished( mbedtls_ssl_get_minor_ver( ssl ), - mbedtls_ssl_suite_get_mac( - mbedtls_ssl_ciphersuite_from_id( - mbedtls_ssl_session_get_ciphersuite( - ssl->session_negotiate ) ) ), - ssl, ssl->out_msg + 4, - mbedtls_ssl_conf_get_endpoint( ssl->conf ) ); + ssl->handshake->calc_finished( ssl, ssl->out_msg + 4, ssl->conf->endpoint ); /* * RFC 5246 7.4.9 (Page 63) says 12 is the default length and ciphersuites @@ -8646,55 +5450,34 @@ int mbedtls_ssl_write_finished( mbedtls_ssl_context *ssl ) * ciphersuite does this (and this is unlikely to change as activity has * moved to TLS 1.3 now) so we can keep the hardcoded 12 here. */ - hash_len = ( mbedtls_ssl_get_minor_ver( ssl ) == MBEDTLS_SSL_MINOR_VERSION_0 ) ? 36 : 12; + hash_len = ( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) ? 36 : 12; #if defined(MBEDTLS_SSL_RENEGOTIATION) ssl->verify_data_len = hash_len; - mbedtls_platform_memcpy( ssl->own_verify_data, ssl->out_msg + 4, hash_len ); + memcpy( ssl->own_verify_data, ssl->out_msg + 4, hash_len ); #endif ssl->out_msglen = 4 + hash_len; ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; ssl->out_msg[0] = MBEDTLS_SSL_HS_FINISHED; -#if !defined(MBEDTLS_SSL_NO_SESSION_RESUMPTION) /* * In case of session resuming, invert the client and server * ChangeCipherSpec messages order. */ - if( ssl->handshake->resume == MBEDTLS_SSL_FI_FLAG_SET ) + if( ssl->handshake->resume != 0 ) { #if defined(MBEDTLS_SSL_CLI_C) - if( mbedtls_ssl_conf_get_endpoint( ssl->conf ) == - MBEDTLS_SSL_IS_CLIENT ) - { + if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP; - } #endif #if defined(MBEDTLS_SSL_SRV_C) - if( mbedtls_ssl_conf_get_endpoint( ssl->conf ) == - MBEDTLS_SSL_IS_SERVER ) - { + if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) ssl->state = MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC; - } #endif } else -#endif /* !MBEDTLS_SSL_NO_SESSION_RESUMPTION */ - { - if( ssl->state == MBEDTLS_SSL_CLIENT_FINISHED ) - { - ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC; - } - else if( ssl->state == MBEDTLS_SSL_SERVER_FINISHED ) - { - ssl->state = MBEDTLS_SSL_FLUSH_BUFFERS; - } - else - { - ssl->state = MBEDTLS_SSL_INVALID; - } - } + ssl->state++; /* * Switch to our negotiated transform and session parameters for outbound @@ -8703,20 +5486,20 @@ int mbedtls_ssl_write_finished( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_DEBUG_MSG( 3, ( "switching to new transform spec for outbound data" ) ); #if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) ) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) { - uint_fast8_t i; + unsigned char i; /* Remember current epoch settings for resending */ ssl->handshake->alt_transform_out = ssl->transform_out; - mbedtls_platform_memcpy( ssl->handshake->alt_out_ctr, ssl->cur_out_ctr, 8 ); + memcpy( ssl->handshake->alt_out_ctr, ssl->out_ctr, 8 ); /* Set sequence_number to zero */ - memset( ssl->cur_out_ctr + 2, 0, 6 ); + memset( ssl->out_ctr + 2, 0, 6 ); /* Increment epoch */ for( i = 2; i > 0; i-- ) - if( ++ssl->cur_out_ctr[i - 1] != 0 ) + if( ++ssl->out_ctr[i - 1] != 0 ) break; /* The loop goes to its end iff the counter is wrapping */ @@ -8726,13 +5509,9 @@ int mbedtls_ssl_write_finished( mbedtls_ssl_context *ssl ) return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING ); } } - MBEDTLS_SSL_TRANSPORT_ELSE + else #endif /* MBEDTLS_SSL_PROTO_DTLS */ -#if defined(MBEDTLS_SSL_PROTO_TLS) - { - mbedtls_platform_memset( ssl->cur_out_ctr, 0, 8 ); - } -#endif + memset( ssl->out_ctr, 0, 8 ); ssl->transform_out = ssl->transform_negotiate; ssl->session_out = ssl->session_negotiate; @@ -8749,31 +5528,16 @@ int mbedtls_ssl_write_finished( mbedtls_ssl_context *ssl ) #endif #if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) ) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) mbedtls_ssl_send_flight_completed( ssl ); #endif - if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 ) + if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 ) { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret ); + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret ); return( ret ); } -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) ) - { -#if defined(MBEDTLS_SSL_IMMEDIATE_TRANSMISSION) - mbedtls_ssl_immediate_flight_done( ssl ); -#else - if( ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flight_transmit", ret ); - return( ret ); - } -#endif - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write finished" ) ); return( 0 ); @@ -8793,15 +5557,9 @@ int mbedtls_ssl_parse_finished( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse finished" ) ); - ssl_calc_finished( mbedtls_ssl_get_minor_ver( ssl ), - mbedtls_ssl_suite_get_mac( - mbedtls_ssl_ciphersuite_from_id( - mbedtls_ssl_session_get_ciphersuite( - ssl->session_negotiate ) ) ), - ssl, buf, - mbedtls_ssl_conf_get_endpoint( ssl->conf ) ^ 1 ); + ssl->handshake->calc_finished( ssl, buf, ssl->conf->endpoint ^ 1 ); - if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 ) + if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); return( ret ); @@ -8810,14 +5568,14 @@ int mbedtls_ssl_parse_finished( mbedtls_ssl_context *ssl ) if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); } /* There is currently no ciphersuite using another length with TLS 1.2 */ #if defined(MBEDTLS_SSL_PROTO_SSL3) - if( mbedtls_ssl_get_minor_ver( ssl ) == MBEDTLS_SSL_MINOR_VERSION_0 ) + if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) hash_len = 36; else #endif @@ -8827,56 +5585,41 @@ int mbedtls_ssl_parse_finished( mbedtls_ssl_context *ssl ) ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) + hash_len ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_FINISHED ); } - if( mbedtls_platform_memequal( ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ), - buf, hash_len ) != 0 ) + if( mbedtls_ssl_safer_memcmp( ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ), + buf, hash_len ) != 0 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) ); - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_FINISHED ); } #if defined(MBEDTLS_SSL_RENEGOTIATION) ssl->verify_data_len = hash_len; - mbedtls_platform_memcpy( ssl->peer_verify_data, buf, hash_len ); + memcpy( ssl->peer_verify_data, buf, hash_len ); #endif -#if !defined(MBEDTLS_SSL_NO_SESSION_RESUMPTION) - if( ssl->handshake->resume == MBEDTLS_SSL_FI_FLAG_SET ) + if( ssl->handshake->resume != 0 ) { #if defined(MBEDTLS_SSL_CLI_C) - if( mbedtls_ssl_conf_get_endpoint( ssl->conf ) == MBEDTLS_SSL_IS_CLIENT ) + if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) ssl->state = MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC; #endif #if defined(MBEDTLS_SSL_SRV_C) - if( mbedtls_ssl_conf_get_endpoint( ssl->conf ) == MBEDTLS_SSL_IS_SERVER ) + if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP; #endif } else -#endif /* !MBEDTLS_SSL_NO_SESSION_RESUMPTION */ - { - if( ssl->state == MBEDTLS_SSL_CLIENT_FINISHED ) - { - ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC; - } - else if( ssl->state == MBEDTLS_SSL_SERVER_FINISHED ) - { - ssl->state = MBEDTLS_SSL_FLUSH_BUFFERS; - } - else - { - ssl->state = MBEDTLS_SSL_INVALID; - } - } + ssl->state++; #if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) ) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) mbedtls_ssl_recv_flight_completed( ssl ); #endif @@ -8907,6 +5650,8 @@ static void ssl_handshake_params_init( mbedtls_ssl_handshake_params *handshake ) #endif #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ + handshake->update_checksum = ssl_update_checksum_start; + #if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) mbedtls_ssl_sig_hash_set_init( &handshake->hash_algs ); @@ -8926,34 +5671,20 @@ static void ssl_handshake_params_init( mbedtls_ssl_handshake_params *handshake ) #endif #endif -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - mbedtls_x509_crt_restart_init( &handshake->ecrs_ctx ); -#endif - #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) handshake->sni_authmode = MBEDTLS_SSL_VERIFY_UNSET; #endif - -#if defined(MBEDTLS_X509_CRT_PARSE_C) && \ - !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - mbedtls_pk_init( &handshake->peer_pubkey ); -#endif } -void mbedtls_ssl_transform_init( mbedtls_ssl_transform *transform ) +static void ssl_transform_init( mbedtls_ssl_transform *transform ) { memset( transform, 0, sizeof(mbedtls_ssl_transform) ); -#if defined(MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS) - mbedtls_cipher_init( &transform->cipher_ctx ); -#else + mbedtls_cipher_init( &transform->cipher_ctx_enc ); mbedtls_cipher_init( &transform->cipher_ctx_dec ); -#endif -#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC) mbedtls_md_init( &transform->md_ctx_enc ); mbedtls_md_init( &transform->md_ctx_dec ); -#endif } void mbedtls_ssl_session_init( mbedtls_ssl_session *session ) @@ -8969,7 +5700,7 @@ static int ssl_handshake_init( mbedtls_ssl_context *ssl ) if( ssl->session_negotiate ) mbedtls_ssl_session_free( ssl->session_negotiate ); if( ssl->handshake ) - mbedtls_ssl_handshake_free( ssl ); + mbedtls_ssl_handshake_free( ssl->handshake ); /* * Either the pointers are now NULL or cleared properly and can be freed. @@ -8990,12 +5721,6 @@ static int ssl_handshake_init( mbedtls_ssl_context *ssl ) ssl->handshake = mbedtls_calloc( 1, sizeof(mbedtls_ssl_handshake_params) ); } -#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) - /* If the buffers are too small - reallocate */ - handle_buffer_resizing( ssl, BUFFER_UPSIZING, MBEDTLS_SSL_IN_BUFFER_LEN, - MBEDTLS_SSL_OUT_BUFFER_LEN ); -#endif - /* All pointers should exist and can be directly freed without issue */ if( ssl->handshake == NULL || ssl->transform_negotiate == NULL || @@ -9016,18 +5741,20 @@ static int ssl_handshake_init( mbedtls_ssl_context *ssl ) /* Initialize structures */ mbedtls_ssl_session_init( ssl->session_negotiate ); - mbedtls_ssl_transform_init( ssl->transform_negotiate ); + ssl_transform_init( ssl->transform_negotiate ); ssl_handshake_params_init( ssl->handshake ); #if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) ) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) { ssl->handshake->alt_transform_out = ssl->transform_out; - if( mbedtls_ssl_conf_get_endpoint( ssl->conf ) == MBEDTLS_SSL_IS_CLIENT ) + if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_PREPARING; else ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING; + + ssl_set_timer( ssl, 0 ); } #endif @@ -9063,105 +5790,6 @@ static int ssl_cookie_check_dummy( void *ctx, } #endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY && MBEDTLS_SSL_SRV_C */ -/* Once ssl->out_hdr as the address of the beginning of the - * next outgoing record is set, deduce the other pointers. - * - * Note: For TLS, we save the implicit record sequence number - * (entering MAC computation) in the 8 bytes before ssl->out_hdr, - * and the caller has to make sure there's space for this. - */ - -static void ssl_update_out_pointers( mbedtls_ssl_context *ssl, - mbedtls_ssl_transform *transform ) -{ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) ) - { - ssl->out_ctr = ssl->out_hdr + 3; -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - ssl->out_cid = ssl->out_ctr + 8; - ssl->out_len = ssl->out_cid; - if( transform != NULL ) - ssl->out_len += transform->out_cid_len; -#else /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - ssl->out_len = ssl->out_ctr + 8; -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - ssl->out_iv = ssl->out_len + 2; - } - MBEDTLS_SSL_TRANSPORT_ELSE -#endif /* MBEDTLS_SSL_PROTO_DTLS */ -#if defined(MBEDTLS_SSL_PROTO_TLS) - { - ssl->out_ctr = ssl->out_hdr - 8; - ssl->out_len = ssl->out_hdr + 3; -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - ssl->out_cid = ssl->out_len; -#endif - ssl->out_iv = ssl->out_hdr + 5; - } -#endif /* MBEDTLS_SSL_PROTO_TLS */ - - /* Adjust out_msg to make space for explicit IV, if used. */ - if( transform != NULL && - mbedtls_ssl_ver_geq( - mbedtls_ssl_get_minor_ver( ssl ), - MBEDTLS_SSL_MINOR_VERSION_2 ) ) - { - ssl->out_msg = ssl->out_iv + transform->ivlen - transform->fixed_ivlen; - } - else - ssl->out_msg = ssl->out_iv; -} - -/* Once ssl->in_hdr as the address of the beginning of the - * next incoming record is set, deduce the other pointers. - * - * Note: For TLS, we save the implicit record sequence number - * (entering MAC computation) in the 8 bytes before ssl->in_hdr, - * and the caller has to make sure there's space for this. - */ - -static void ssl_update_in_pointers( mbedtls_ssl_context *ssl ) -{ - /* This function sets the pointers to match the case - * of unprotected TLS/DTLS records, with ssl->in_msg - * pointing to the beginning of the record content. - * - * When decrypting a protected record, ssl->in_msg - * will be shifted to point to the beginning of the - * record plaintext. - */ - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) ) - { - /* This sets the header pointers to match records - * without CID. When we receive a record containing - * a CID, the fields are shifted accordingly in - * ssl_parse_record_header(). */ - ssl->in_ctr = ssl->in_hdr + 3; -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - ssl->in_cid = ssl->in_ctr + 8; - ssl->in_len = ssl->in_cid; /* Default: no CID */ -#else /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - ssl->in_len = ssl->in_ctr + 8; -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - ssl->in_msg = ssl->in_len + 2; - } - MBEDTLS_SSL_TRANSPORT_ELSE -#endif /* MBEDTLS_SSL_PROTO_DTLS */ -#if defined(MBEDTLS_SSL_PROTO_TLS) - { - ssl->in_ctr = ssl->in_hdr - 8; - ssl->in_len = ssl->in_hdr + 3; -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - ssl->in_cid = ssl->in_len; -#endif - ssl->in_msg = ssl->in_hdr + 5; - } -#endif /* MBEDTLS_SSL_PROTO_TLS */ -} - /* * Initialize an SSL context */ @@ -9173,80 +5801,61 @@ void mbedtls_ssl_init( mbedtls_ssl_context *ssl ) /* * Setup an SSL context */ - -static void ssl_reset_in_out_pointers( mbedtls_ssl_context *ssl ) -{ - /* Set the incoming and outgoing record pointers. */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) ) - { - ssl->out_hdr = ssl->out_buf; - ssl->in_hdr = ssl->in_buf; - } - MBEDTLS_SSL_TRANSPORT_ELSE -#endif /* MBEDTLS_SSL_PROTO_DTLS */ -#if defined(MBEDTLS_SSL_PROTO_TLS) - { - ssl->out_hdr = ssl->out_buf + 8; - ssl->in_hdr = ssl->in_buf + 8; - } -#endif /* MBEDTLS_SSL_PROTO_TLS */ - - /* Derive other internal pointers. */ - ssl_update_out_pointers( ssl, NULL /* no transform enabled */ ); - ssl_update_in_pointers ( ssl ); -} - int mbedtls_ssl_setup( mbedtls_ssl_context *ssl, const mbedtls_ssl_config *conf ) { int ret; - size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN; - size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN; + const size_t len = MBEDTLS_SSL_BUFFER_LEN; ssl->conf = conf; -#if defined(MBEDTLS_USE_TINYCRYPT) - uECC_set_rng( &uecc_rng_wrapper ); -#endif - /* * Prepare base structures */ - - /* Set to NULL in case of an error condition */ + ssl->in_buf = NULL; ssl->out_buf = NULL; - -#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) - ssl->in_buf_len = in_buf_len; -#endif - ssl->in_buf = mbedtls_calloc( 1, in_buf_len ); - if( ssl->in_buf == NULL ) + if( ( ssl-> in_buf = mbedtls_calloc( 1, len ) ) == NULL || + ( ssl->out_buf = mbedtls_calloc( 1, len ) ) == NULL ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed", in_buf_len) ); + MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed", len ) ); ret = MBEDTLS_ERR_SSL_ALLOC_FAILED; goto error; } -#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) - ssl->out_buf_len = out_buf_len; -#endif - - ssl->out_buf = mbedtls_calloc( 1, out_buf_len ); - if( ssl->out_buf == NULL ) +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed", out_buf_len) ); - ret = MBEDTLS_ERR_SSL_ALLOC_FAILED; - goto error; - } + ssl->out_hdr = ssl->out_buf; + ssl->out_ctr = ssl->out_buf + 3; + ssl->out_len = ssl->out_buf + 11; + ssl->out_iv = ssl->out_buf + 13; + ssl->out_msg = ssl->out_buf + 13; - ssl_reset_in_out_pointers( ssl ); + ssl->in_hdr = ssl->in_buf; + ssl->in_ctr = ssl->in_buf + 3; + ssl->in_len = ssl->in_buf + 11; + ssl->in_iv = ssl->in_buf + 13; + ssl->in_msg = ssl->in_buf + 13; + } + else +#endif + { + ssl->out_ctr = ssl->out_buf; + ssl->out_hdr = ssl->out_buf + 8; + ssl->out_len = ssl->out_buf + 11; + ssl->out_iv = ssl->out_buf + 13; + ssl->out_msg = ssl->out_buf + 13; + + ssl->in_ctr = ssl->in_buf; + ssl->in_hdr = ssl->in_buf + 8; + ssl->in_len = ssl->in_buf + 11; + ssl->in_iv = ssl->in_buf + 13; + ssl->in_msg = ssl->in_buf + 13; + } if( ( ret = ssl_handshake_init( ssl ) ) != 0 ) goto error; - ssl->pending_fatal_alert_msg = MBEDTLS_SSL_ALERT_MSG_NONE; - return( 0 ); error: @@ -9255,17 +5864,13 @@ error: ssl->conf = NULL; -#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) - ssl->in_buf_len = 0; - ssl->out_buf_len = 0; -#endif - ssl->in_buf = NULL; ssl->out_buf = NULL; ssl->in_hdr = NULL; ssl->in_ctr = NULL; ssl->in_len = NULL; + ssl->in_iv = NULL; ssl->in_msg = NULL; ssl->out_hdr = NULL; @@ -9287,18 +5892,6 @@ error: static int ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial ) { int ret; -#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) - size_t in_buf_len = ssl->in_buf_len; - size_t out_buf_len = ssl->out_buf_len; -#else - size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN; - size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN; -#endif - -#if !defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) || \ - !defined(MBEDTLS_SSL_SRV_C) - ((void) partial); -#endif ssl->state = MBEDTLS_SSL_HELLO_REQUEST; @@ -9310,16 +5903,18 @@ static int ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial ) ssl->renego_records_seen = 0; ssl->verify_data_len = 0; - mbedtls_platform_memset( ssl->own_verify_data, 0, MBEDTLS_SSL_VERIFY_DATA_MAX_LEN ); - mbedtls_platform_memset( ssl->peer_verify_data, 0, MBEDTLS_SSL_VERIFY_DATA_MAX_LEN ); + memset( ssl->own_verify_data, 0, MBEDTLS_SSL_VERIFY_DATA_MAX_LEN ); + memset( ssl->peer_verify_data, 0, MBEDTLS_SSL_VERIFY_DATA_MAX_LEN ); #endif ssl->secure_renegotiation = MBEDTLS_SSL_LEGACY_RENEGOTIATION; ssl->in_offt = NULL; - ssl_reset_in_out_pointers( ssl ); + ssl->in_msg = ssl->in_buf + 13; ssl->in_msgtype = 0; ssl->in_msglen = 0; + if( partial == 0 ) + ssl->in_left = 0; #if defined(MBEDTLS_SSL_PROTO_DTLS) ssl->next_record_offset = 0; ssl->in_epoch = 0; @@ -9333,6 +5928,7 @@ static int ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial ) ssl->keep_current_message = 0; + ssl->out_msg = ssl->out_buf + 13; ssl->out_msgtype = 0; ssl->out_msglen = 0; ssl->out_left = 0; @@ -9341,23 +5937,16 @@ static int ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial ) ssl->split_done = 0; #endif - memset( ssl->cur_out_ctr, 0, sizeof( ssl->cur_out_ctr ) ); - ssl->transform_in = NULL; ssl->transform_out = NULL; ssl->session_in = NULL; ssl->session_out = NULL; - mbedtls_platform_memset( ssl->out_buf, 0, out_buf_len ); + memset( ssl->out_buf, 0, MBEDTLS_SSL_BUFFER_LEN ); -#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C) if( partial == 0 ) -#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */ - { - ssl->in_left = 0; - mbedtls_platform_memset( ssl->in_buf, 0, in_buf_len ); - } + memset( ssl->in_buf, 0, MBEDTLS_SSL_BUFFER_LEN ); #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) if( mbedtls_ssl_hw_record_reset != NULL ) @@ -9390,9 +5979,7 @@ static int ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial ) #endif #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C) -#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) if( partial == 0 ) -#endif { mbedtls_free( ssl->cli_id ); ssl->cli_id = NULL; @@ -9418,79 +6005,44 @@ int mbedtls_ssl_session_reset( mbedtls_ssl_context *ssl ) /* * SSL set accessors */ -#if !defined(MBEDTLS_SSL_CONF_ENDPOINT) void mbedtls_ssl_conf_endpoint( mbedtls_ssl_config *conf, int endpoint ) { conf->endpoint = endpoint; } -#endif /* MBEDTLS_SSL_CONF_ENDPOINT */ -#if !defined(MBEDTLS_SSL_CONF_TRANSPORT) void mbedtls_ssl_conf_transport( mbedtls_ssl_config *conf, int transport ) { conf->transport = transport; } -#endif /* MBEDTLS_SSL_CONF_TRANSPORT */ -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) && \ - !defined(MBEDTLS_SSL_CONF_ANTI_REPLAY) +#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) void mbedtls_ssl_conf_dtls_anti_replay( mbedtls_ssl_config *conf, char mode ) { - conf->anti_replay = mode; + conf->anti_replay = mode; } -#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY && !MBEDTLS_SSL_CONF_ANTI_REPLAY */ +#endif -#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) && \ - !defined(MBEDTLS_SSL_CONF_BADMAC_LIMIT) -void mbedtls_ssl_conf_dtls_badmac_limit( mbedtls_ssl_config *conf, - unsigned limit ) +#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) +void mbedtls_ssl_conf_dtls_badmac_limit( mbedtls_ssl_config *conf, unsigned limit ) { conf->badmac_limit = limit; } -#endif /* MBEDTLS_SSL_DTLS_BADMAC_LIMIT && !MBEDTLS_SSL_CONF_BADMAC_LIMIT */ +#endif #if defined(MBEDTLS_SSL_PROTO_DTLS) - -void mbedtls_ssl_set_datagram_packing( mbedtls_ssl_context *ssl, - unsigned allow_packing ) -{ - ssl->disable_datagram_packing = !allow_packing; -} - -#if !( defined(MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX) && \ - defined(MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN) ) -void mbedtls_ssl_conf_handshake_timeout( mbedtls_ssl_config *conf, - uint32_t min, uint32_t max ) +void mbedtls_ssl_conf_handshake_timeout( mbedtls_ssl_config *conf, uint32_t min, uint32_t max ) { conf->hs_timeout_min = min; conf->hs_timeout_max = max; } -#else /* !( MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN && - MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX ) */ -void mbedtls_ssl_conf_handshake_timeout( mbedtls_ssl_config *conf, - uint32_t min, uint32_t max ) -{ - ((void) conf); - ((void) min); - ((void) max); -} -#endif /* MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN && - MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX */ - -#endif /* MBEDTLS_SSL_PROTO_DTLS */ +#endif void mbedtls_ssl_conf_authmode( mbedtls_ssl_config *conf, int authmode ) { -#if !defined(MBEDTLS_SSL_CONF_AUTHMODE) - conf->authmode = authmode; -#else - ((void) conf); - ((void) authmode); -#endif /* MBEDTLS_SSL_CONF_AUTHMODE */ + conf->authmode = authmode; } -#if defined(MBEDTLS_X509_CRT_PARSE_C) && \ - !defined(MBEDTLS_X509_REMOVE_VERIFY_CALLBACK) +#if defined(MBEDTLS_X509_CRT_PARSE_C) void mbedtls_ssl_conf_verify( mbedtls_ssl_config *conf, int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), void *p_vrfy ) @@ -9498,9 +6050,8 @@ void mbedtls_ssl_conf_verify( mbedtls_ssl_config *conf, conf->f_vrfy = f_vrfy; conf->p_vrfy = p_vrfy; } -#endif /* MBEDTLS_X509_CRT_PARSE_C && !MBEDTLS_X509_REMOVE_VERIFY_CALLBACK */ +#endif /* MBEDTLS_X509_CRT_PARSE_C */ -#if !defined(MBEDTLS_SSL_CONF_RNG) void mbedtls_ssl_conf_rng( mbedtls_ssl_config *conf, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) @@ -9508,9 +6059,7 @@ void mbedtls_ssl_conf_rng( mbedtls_ssl_config *conf, conf->f_rng = f_rng; conf->p_rng = p_rng; } -#endif -#if defined(MBEDTLS_DEBUG_C) void mbedtls_ssl_conf_dbg( mbedtls_ssl_config *conf, void (*f_dbg)(void *, int, const char *, int, const char *), void *p_dbg ) @@ -9518,46 +6067,24 @@ void mbedtls_ssl_conf_dbg( mbedtls_ssl_config *conf, conf->f_dbg = f_dbg; conf->p_dbg = p_dbg; } -#endif /* MBEDTLS_DEBUG_C */ -#if !defined(MBEDTLS_SSL_CONF_RECV) && \ - !defined(MBEDTLS_SSL_CONF_SEND) && \ - !defined(MBEDTLS_SSL_CONF_RECV_TIMEOUT) void mbedtls_ssl_set_bio( mbedtls_ssl_context *ssl, void *p_bio, mbedtls_ssl_send_t *f_send, mbedtls_ssl_recv_t *f_recv, mbedtls_ssl_recv_timeout_t *f_recv_timeout ) { - ssl->p_bio = p_bio; - ssl->f_send = f_send; - ssl->f_recv = f_recv; + ssl->p_bio = p_bio; + ssl->f_send = f_send; + ssl->f_recv = f_recv; ssl->f_recv_timeout = f_recv_timeout; } -#else -void mbedtls_ssl_set_bio_ctx( mbedtls_ssl_context *ssl, - void *p_bio ) -{ - ssl->p_bio = p_bio; -} -#endif -#if defined(MBEDTLS_SSL_PROTO_DTLS) -void mbedtls_ssl_set_mtu( mbedtls_ssl_context *ssl, uint16_t mtu ) -{ - ssl->mtu = mtu; -} -#endif - -#if !defined(MBEDTLS_SSL_CONF_READ_TIMEOUT) void mbedtls_ssl_conf_read_timeout( mbedtls_ssl_config *conf, uint32_t timeout ) { conf->read_timeout = timeout; } -#endif /* MBEDTLS_SSL_CONF_READ_TIMEOUT */ -#if !defined(MBEDTLS_SSL_CONF_SET_TIMER) && \ - !defined(MBEDTLS_SSL_CONF_GET_TIMER) void mbedtls_ssl_set_timer_cb( mbedtls_ssl_context *ssl, void *p_timer, mbedtls_ssl_set_timer_t *f_set_timer, @@ -9566,20 +6093,12 @@ void mbedtls_ssl_set_timer_cb( mbedtls_ssl_context *ssl, ssl->p_timer = p_timer; ssl->f_set_timer = f_set_timer; ssl->f_get_timer = f_get_timer; - /* Make sure we start with no timer running */ - ssl_set_timer( ssl, 0 ); -} -#else -void mbedtls_ssl_set_timer_cb_ctx( mbedtls_ssl_context *ssl, - void *p_timer ) -{ - ssl->p_timer = p_timer; - /* Make sure we start with no timer running */ - ssl_set_timer( ssl, 0 ); -} -#endif -#if defined(MBEDTLS_SSL_SRV_C) && !defined(MBEDTLS_SSL_NO_SESSION_CACHE) + /* Make sure we start with no timer running */ + ssl_set_timer( ssl, 0 ); +} + +#if defined(MBEDTLS_SSL_SRV_C) void mbedtls_ssl_conf_session_cache( mbedtls_ssl_config *conf, void *p_cache, int (*f_get_cache)(void *, mbedtls_ssl_session *), @@ -9589,9 +6108,9 @@ void mbedtls_ssl_conf_session_cache( mbedtls_ssl_config *conf, conf->f_get_cache = f_get_cache; conf->f_set_cache = f_set_cache; } -#endif /* MBEDTLS_SSL_SRV_C && !MBEDTLS_SSL_NO_SESSION_CACHE */ +#endif /* MBEDTLS_SSL_SRV_C */ -#if defined(MBEDTLS_SSL_CLI_C) && !defined(MBEDTLS_SSL_NO_SESSION_RESUMPTION) +#if defined(MBEDTLS_SSL_CLI_C) int mbedtls_ssl_set_session( mbedtls_ssl_context *ssl, const mbedtls_ssl_session *session ) { int ret; @@ -9599,29 +6118,27 @@ int mbedtls_ssl_set_session( mbedtls_ssl_context *ssl, const mbedtls_ssl_session if( ssl == NULL || session == NULL || ssl->session_negotiate == NULL || - mbedtls_ssl_conf_get_endpoint( ssl->conf ) != MBEDTLS_SSL_IS_CLIENT ) + ssl->conf->endpoint != MBEDTLS_SSL_IS_CLIENT ) { return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); } - if( ( ret = mbedtls_ssl_session_copy( ssl->session_negotiate, - session ) ) != 0 ) + if( ( ret = ssl_session_copy( ssl->session_negotiate, session ) ) != 0 ) return( ret ); - ssl->handshake->resume = MBEDTLS_SSL_FI_FLAG_SET; + ssl->handshake->resume = 1; return( 0 ); } -#endif /* MBEDTLS_SSL_CLI_C && !MBEDTLS_SSL_NO_SESSION_RESUMPTION */ +#endif /* MBEDTLS_SSL_CLI_C */ -#if !defined(MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE) void mbedtls_ssl_conf_ciphersuites( mbedtls_ssl_config *conf, const int *ciphersuites ) { - conf->ciphersuite_list[0] = ciphersuites; - conf->ciphersuite_list[1] = ciphersuites; - conf->ciphersuite_list[2] = ciphersuites; - conf->ciphersuite_list[3] = ciphersuites; + conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_0] = ciphersuites; + conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_1] = ciphersuites; + conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_2] = ciphersuites; + conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_3] = ciphersuites; } void mbedtls_ssl_conf_ciphersuites_for_version( mbedtls_ssl_config *conf, @@ -9631,16 +6148,11 @@ void mbedtls_ssl_conf_ciphersuites_for_version( mbedtls_ssl_config *conf, if( major != MBEDTLS_SSL_MAJOR_VERSION_3 ) return; - if( mbedtls_ssl_ver_lt( minor, MBEDTLS_SSL_MINOR_VERSION_0 ) || - mbedtls_ssl_ver_gt( minor, MBEDTLS_SSL_MINOR_VERSION_3 ) ) - { + if( minor < MBEDTLS_SSL_MINOR_VERSION_0 || minor > MBEDTLS_SSL_MINOR_VERSION_3 ) return; - } - conf->ciphersuite_list[mbedtls_ssl_minor_ver_index( minor )] = - ciphersuites; + conf->ciphersuite_list[minor] = ciphersuites; } -#endif /* MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE */ #if defined(MBEDTLS_X509_CRT_PARSE_C) void mbedtls_ssl_conf_cert_profile( mbedtls_ssl_config *conf, @@ -9733,7 +6245,7 @@ int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl, if( ssl->handshake == NULL || ssl->conf == NULL ) return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - if( mbedtls_ssl_conf_get_endpoint( ssl->conf ) == MBEDTLS_SSL_IS_SERVER ) + if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) role = MBEDTLS_ECJPAKE_SERVER; else role = MBEDTLS_ECJPAKE_CLIENT; @@ -9759,14 +6271,14 @@ int mbedtls_ssl_conf_psk( mbedtls_ssl_config *conf, /* Identity len will be encoded on two bytes */ if( ( psk_identity_len >> 16 ) != 0 || - psk_identity_len > MBEDTLS_SSL_OUT_CONTENT_LEN ) + psk_identity_len > MBEDTLS_SSL_MAX_CONTENT_LEN ) { return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); } if( conf->psk != NULL ) { - mbedtls_platform_zeroize( conf->psk, conf->psk_len ); + mbedtls_zeroize( conf->psk, conf->psk_len ); mbedtls_free( conf->psk ); conf->psk = NULL; @@ -9792,8 +6304,8 @@ int mbedtls_ssl_conf_psk( mbedtls_ssl_config *conf, conf->psk_len = psk_len; conf->psk_identity_len = psk_identity_len; - mbedtls_platform_memcpy( conf->psk, psk, conf->psk_len ); - mbedtls_platform_memcpy( conf->psk_identity, psk_identity, conf->psk_identity_len ); + memcpy( conf->psk, psk, conf->psk_len ); + memcpy( conf->psk_identity, psk_identity, conf->psk_identity_len ); return( 0 ); } @@ -9809,8 +6321,7 @@ int mbedtls_ssl_set_hs_psk( mbedtls_ssl_context *ssl, if( ssl->handshake->psk != NULL ) { - mbedtls_platform_zeroize( ssl->handshake->psk, - ssl->handshake->psk_len ); + mbedtls_zeroize( ssl->handshake->psk, ssl->handshake->psk_len ); mbedtls_free( ssl->handshake->psk ); ssl->handshake->psk_len = 0; } @@ -9819,7 +6330,7 @@ int mbedtls_ssl_set_hs_psk( mbedtls_ssl_context *ssl, return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); ssl->handshake->psk_len = psk_len; - mbedtls_platform_memcpy( ssl->handshake->psk, psk, ssl->handshake->psk_len ); + memcpy( ssl->handshake->psk, psk, ssl->handshake->psk_len ); return( 0 ); } @@ -9904,17 +6415,11 @@ void mbedtls_ssl_conf_dhm_min_bitlen( mbedtls_ssl_config *conf, void mbedtls_ssl_conf_sig_hashes( mbedtls_ssl_config *conf, const int *hashes ) { -#if !defined(MBEDTLS_SSL_CONF_SINGLE_SIG_HASH) conf->sig_hashes = hashes; -#else - ((void) conf); - ((void) hashes); -#endif /* MBEDTLS_SSL_CONF_SINGLE_SIG_HASH */ } #endif /* MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ #if defined(MBEDTLS_ECP_C) -#if !defined(MBEDTLS_SSL_CONF_SINGLE_EC) /* * Set the allowed elliptic curves */ @@ -9923,10 +6428,9 @@ void mbedtls_ssl_conf_curves( mbedtls_ssl_config *conf, { conf->curve_list = curve_list; } -#endif /* MBEDTLS_SSL_CONF_SINGLE_EC */ #endif /* MBEDTLS_ECP_C */ -#if defined(MBEDTLS_X509_CRT_PARSE_C) && !defined(MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION) +#if defined(MBEDTLS_X509_CRT_PARSE_C) int mbedtls_ssl_set_hostname( mbedtls_ssl_context *ssl, const char *hostname ) { /* Initialize to suppress unnecessary compiler warning */ @@ -9947,7 +6451,7 @@ int mbedtls_ssl_set_hostname( mbedtls_ssl_context *ssl, const char *hostname ) if( ssl->hostname != NULL ) { - mbedtls_platform_zeroize( ssl->hostname, strlen( ssl->hostname ) ); + mbedtls_zeroize( ssl->hostname, strlen( ssl->hostname ) ); mbedtls_free( ssl->hostname ); } @@ -9963,7 +6467,6 @@ int mbedtls_ssl_set_hostname( mbedtls_ssl_context *ssl, const char *hostname ) if( ssl->hostname == NULL ) return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); - /* Not using more secure mbedtls_platform_memcpy as hostname is public in initial handshake */ memcpy( ssl->hostname, hostname, hostname_len ); ssl->hostname[hostname_len] = '\0'; @@ -9971,7 +6474,7 @@ int mbedtls_ssl_set_hostname( mbedtls_ssl_context *ssl, const char *hostname ) return( 0 ); } -#endif /* MBEDTLS_X509_CRT_PARSE_C && !MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION */ +#endif /* MBEDTLS_X509_CRT_PARSE_C */ #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) void mbedtls_ssl_conf_sni( mbedtls_ssl_config *conf, @@ -10016,27 +6519,17 @@ const char *mbedtls_ssl_get_alpn_protocol( const mbedtls_ssl_context *ssl ) } #endif /* MBEDTLS_SSL_ALPN */ -#if !defined(MBEDTLS_SSL_CONF_MAX_MINOR_VER) || \ - !defined(MBEDTLS_SSL_CONF_MAX_MAJOR_VER) -void mbedtls_ssl_conf_max_version( mbedtls_ssl_config *conf, - int major, int minor ) +void mbedtls_ssl_conf_max_version( mbedtls_ssl_config *conf, int major, int minor ) { conf->max_major_ver = major; conf->max_minor_ver = minor; } -#endif /* MBEDTLS_SSL_CONF_MAX_MINOR_VER || - MBEDTLS_SSL_CONF_MAX_MAJOR_VER */ -#if !defined(MBEDTLS_SSL_CONF_MIN_MINOR_VER) || \ - !defined(MBEDTLS_SSL_CONF_MIN_MAJOR_VER) -void mbedtls_ssl_conf_min_version( mbedtls_ssl_config *conf, - int major, int minor ) +void mbedtls_ssl_conf_min_version( mbedtls_ssl_config *conf, int major, int minor ) { conf->min_major_ver = major; conf->min_minor_ver = minor; } -#endif /* MBEDTLS_SSL_CONF_MIN_MINOR_VER || - MBEDTLS_SSL_CONF_MIN_MAJOR_VER */ #if defined(MBEDTLS_SSL_FALLBACK_SCSV) && defined(MBEDTLS_SSL_CLI_C) void mbedtls_ssl_conf_fallback( mbedtls_ssl_config *conf, char fallback ) @@ -10045,7 +6538,7 @@ void mbedtls_ssl_conf_fallback( mbedtls_ssl_config *conf, char fallback ) } #endif -#if defined(MBEDTLS_SSL_SRV_C) && !defined(MBEDTLS_SSL_CONF_CERT_REQ_CA_LIST) +#if defined(MBEDTLS_SSL_SRV_C) void mbedtls_ssl_conf_cert_req_ca_list( mbedtls_ssl_config *conf, char cert_req_ca_list ) { @@ -10061,20 +6554,11 @@ void mbedtls_ssl_conf_encrypt_then_mac( mbedtls_ssl_config *conf, char etm ) #endif #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) -#if !defined(MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET) void mbedtls_ssl_conf_extended_master_secret( mbedtls_ssl_config *conf, char ems ) { conf->extended_ms = ems; } -#endif /* !MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET */ -#if !defined(MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET) -void mbedtls_ssl_conf_extended_master_secret_enforce( mbedtls_ssl_config *conf, - char ems_enf ) -{ - conf->enforce_extended_master_secret = ems_enf; -} -#endif /* !MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET */ -#endif /* !MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ +#endif #if defined(MBEDTLS_ARC4_C) void mbedtls_ssl_conf_arc4_support( mbedtls_ssl_config *conf, char arc4 ) @@ -10087,7 +6571,7 @@ void mbedtls_ssl_conf_arc4_support( mbedtls_ssl_config *conf, char arc4 ) int mbedtls_ssl_conf_max_frag_len( mbedtls_ssl_config *conf, unsigned char mfl_code ) { if( mfl_code >= MBEDTLS_SSL_MAX_FRAG_LEN_INVALID || - ssl_mfl_code_to_length( mfl_code ) > MBEDTLS_TLS_EXT_ADV_CONTENT_LEN ) + mfl_code_to_length[mfl_code] > MBEDTLS_SSL_MAX_CONTENT_LEN ) { return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); } @@ -10112,12 +6596,10 @@ void mbedtls_ssl_conf_cbc_record_splitting( mbedtls_ssl_config *conf, char split } #endif -#if !defined(MBEDTLS_SSL_CONF_ALLOW_LEGACY_RENEGOTIATION) void mbedtls_ssl_conf_legacy_renegotiation( mbedtls_ssl_config *conf, int allow_legacy ) { conf->allow_legacy_renegotiation = allow_legacy; } -#endif /* !MBEDTLS_SSL_CONF_ALLOW_LEGACY_RENEGOTIATION */ #if defined(MBEDTLS_SSL_RENEGOTIATION) void mbedtls_ssl_conf_renegotiation( mbedtls_ssl_config *conf, int renegotiation ) @@ -10133,7 +6615,7 @@ void mbedtls_ssl_conf_renegotiation_enforced( mbedtls_ssl_config *conf, int max_ void mbedtls_ssl_conf_renegotiation_period( mbedtls_ssl_config *conf, const unsigned char period[8] ) { - mbedtls_platform_memcpy( conf->renego_period, period, 8 ); + memcpy( conf->renego_period, period, 8 ); } #endif /* MBEDTLS_SSL_RENEGOTIATION */ @@ -10168,43 +6650,6 @@ void mbedtls_ssl_conf_export_keys_cb( mbedtls_ssl_config *conf, } #endif -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) -void mbedtls_ssl_conf_async_private_cb( - mbedtls_ssl_config *conf, - mbedtls_ssl_async_sign_t *f_async_sign, - mbedtls_ssl_async_decrypt_t *f_async_decrypt, - mbedtls_ssl_async_resume_t *f_async_resume, - mbedtls_ssl_async_cancel_t *f_async_cancel, - void *async_config_data ) -{ - conf->f_async_sign_start = f_async_sign; - conf->f_async_decrypt_start = f_async_decrypt; - conf->f_async_resume = f_async_resume; - conf->f_async_cancel = f_async_cancel; - conf->p_async_config_data = async_config_data; -} - -void *mbedtls_ssl_conf_get_async_config_data( const mbedtls_ssl_config *conf ) -{ - return( conf->p_async_config_data ); -} - -void *mbedtls_ssl_get_async_operation_data( const mbedtls_ssl_context *ssl ) -{ - if( ssl->handshake == NULL ) - return( NULL ); - else - return( ssl->handshake->user_async_ctx ); -} - -void mbedtls_ssl_set_async_operation_data( mbedtls_ssl_context *ssl, - void *ctx ) -{ - if( ssl->handshake != NULL ) - ssl->handshake->user_async_ctx = ctx; -} -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ - /* * SSL get accessors */ @@ -10213,61 +6658,6 @@ size_t mbedtls_ssl_get_bytes_avail( const mbedtls_ssl_context *ssl ) return( ssl->in_offt == NULL ? 0 : ssl->in_msglen ); } -int mbedtls_ssl_check_pending( const mbedtls_ssl_context *ssl ) -{ - /* - * Case A: We're currently holding back - * a message for further processing. - */ - - if( ssl->keep_current_message == 1 ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: record held back for processing" ) ); - return( 1 ); - } - - /* - * Case B: Further records are pending in the current datagram. - */ - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) && - ssl->in_left > ssl->next_record_offset ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: more records within current datagram" ) ); - return( 1 ); - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - /* - * Case C: A handshake message is being processed. - */ - - if( ssl->in_hslen > 0 && ssl->in_hslen < ssl->in_msglen ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: more handshake messages within current record" ) ); - return( 1 ); - } - - /* - * Case D: An application data message is being processed - */ - if( ssl->in_offt != NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: application data record is being processed" ) ); - return( 1 ); - } - - /* - * In all other cases, the rest of the message can be dropped. - * As in ssl_get_next_record, this needs to be adapted if - * we implement support for multiple alerts in single records. - */ - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: nothing pending" ) ); - return( 0 ); -} - uint32_t mbedtls_ssl_get_verify_result( const mbedtls_ssl_context *ssl ) { if( ssl->session != NULL ) @@ -10281,21 +6671,18 @@ uint32_t mbedtls_ssl_get_verify_result( const mbedtls_ssl_context *ssl ) const char *mbedtls_ssl_get_ciphersuite( const mbedtls_ssl_context *ssl ) { - int suite; - if( ssl == NULL || ssl->session == NULL ) return( NULL ); - suite = mbedtls_ssl_session_get_ciphersuite( ssl->session ); - return( mbedtls_ssl_get_ciphersuite_name( suite ) ); + return mbedtls_ssl_get_ciphersuite_name( ssl->session->ciphersuite ); } const char *mbedtls_ssl_get_version( const mbedtls_ssl_context *ssl ) { #if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) ) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) { - switch( mbedtls_ssl_get_minor_ver( ssl ) ) + switch( ssl->minor_ver ) { case MBEDTLS_SSL_MINOR_VERSION_2: return( "DTLSv1.0" ); @@ -10307,87 +6694,54 @@ const char *mbedtls_ssl_get_version( const mbedtls_ssl_context *ssl ) return( "unknown (DTLS)" ); } } - MBEDTLS_SSL_TRANSPORT_ELSE -#endif /* MBEDTLS_SSL_PROTO_DTLS */ -#if defined(MBEDTLS_SSL_PROTO_TLS) +#endif + + switch( ssl->minor_ver ) { - switch( mbedtls_ssl_get_minor_ver( ssl ) ) - { - case MBEDTLS_SSL_MINOR_VERSION_0: - return( "SSLv3.0" ); + case MBEDTLS_SSL_MINOR_VERSION_0: + return( "SSLv3.0" ); - case MBEDTLS_SSL_MINOR_VERSION_1: - return( "TLSv1.0" ); + case MBEDTLS_SSL_MINOR_VERSION_1: + return( "TLSv1.0" ); - case MBEDTLS_SSL_MINOR_VERSION_2: - return( "TLSv1.1" ); + case MBEDTLS_SSL_MINOR_VERSION_2: + return( "TLSv1.1" ); - case MBEDTLS_SSL_MINOR_VERSION_3: - return( "TLSv1.2" ); + case MBEDTLS_SSL_MINOR_VERSION_3: + return( "TLSv1.2" ); - default: - return( "unknown" ); - } + default: + return( "unknown" ); } -#endif /* MBEDTLS_SSL_PROTO_TLS */ } int mbedtls_ssl_get_record_expansion( const mbedtls_ssl_context *ssl ) { size_t transform_expansion = 0; const mbedtls_ssl_transform *transform = ssl->transform_out; - - size_t out_hdr_len = mbedtls_ssl_out_hdr_len( ssl ); + unsigned block_size; if( transform == NULL ) - return( (int) out_hdr_len ); + return( (int) mbedtls_ssl_hdr_len( ssl ) ); #if defined(MBEDTLS_ZLIB_SUPPORT) if( ssl->session_out->compression != MBEDTLS_SSL_COMPRESS_NULL ) return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); #endif -#if defined(MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS) - switch( mbedtls_cipher_get_cipher_mode( &transform->cipher_ctx ) ) -#else + switch( mbedtls_cipher_get_cipher_mode( &transform->cipher_ctx_enc ) ) -#endif { -#if defined(MBEDTLS_GCM_C) || \ - defined(MBEDTLS_CCM_C) || \ - defined(MBEDTLS_CHACHAPOLY_C) -#if defined(MBEDTLS_GCM_C) case MBEDTLS_MODE_GCM: -#endif -#if defined(MBEDTLS_CCM_C) case MBEDTLS_MODE_CCM: -#endif -#if defined(MBEDTLS_CHACHAPOLY_C) - case MBEDTLS_MODE_CHACHAPOLY: -#endif - transform_expansion = - transform->ivlen - transform->fixed_ivlen + transform->taglen; - break; - -#endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C || - MBEDTLS_CHACHAPOLY_C */ - -#if defined(MBEDTLS_CIPHER_MODE_STREAM) case MBEDTLS_MODE_STREAM: - transform_expansion = transform->maclen; + transform_expansion = transform->minlen; break; -#endif /* MBEDTLS_CIPHER_MODE_STREAM */ -#if defined(MBEDTLS_CIPHER_MODE_CBC) case MBEDTLS_MODE_CBC: - { - size_t block_size; -#if defined(MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS) - block_size = mbedtls_cipher_get_block_size( - &transform->cipher_ctx ); -#else + block_size = mbedtls_cipher_get_block_size( &transform->cipher_ctx_enc ); -#endif + /* Expansion due to the addition of the MAC. */ transform_expansion += transform->maclen; @@ -10399,828 +6753,68 @@ int mbedtls_ssl_get_record_expansion( const mbedtls_ssl_context *ssl ) /* For TLS 1.1 or higher, an explicit IV is added * after the record header. */ #if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( mbedtls_ssl_ver_geq( - mbedtls_ssl_get_minor_ver( ssl ), - MBEDTLS_SSL_MINOR_VERSION_2 ) ) - { + if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 ) transform_expansion += block_size; - } #endif /* MBEDTLS_SSL_PROTO_TLS1_1 || MBEDTLS_SSL_PROTO_TLS1_2 */ break; - } -#endif /* MBEDTLS_CIPHER_MODE_CBC */ default: MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); } -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - if( transform->out_cid_len != 0 ) - transform_expansion += MBEDTLS_SSL_MAX_CID_EXPANSION; -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - - return( (int)( out_hdr_len + transform_expansion ) ); + return( (int)( mbedtls_ssl_hdr_len( ssl ) + transform_expansion ) ); } #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) -size_t mbedtls_ssl_get_input_max_frag_len( const mbedtls_ssl_context *ssl ) -{ - size_t max_len = MBEDTLS_SSL_MAX_CONTENT_LEN; - size_t read_mfl; - - /* Use the configured MFL for the client if we're past SERVER_HELLO_DONE */ - if( mbedtls_ssl_conf_get_endpoint( ssl->conf ) == MBEDTLS_SSL_IS_CLIENT && - ssl->state >= MBEDTLS_SSL_SERVER_HELLO_DONE ) - { - return ssl_mfl_code_to_length( ssl->conf->mfl_code ); - } - - /* Check if a smaller max length was negotiated */ - if( ssl->session_out != NULL ) - { - read_mfl = ssl_mfl_code_to_length( ssl->session_out->mfl_code ); - if( read_mfl < max_len ) - { - max_len = read_mfl; - } - } - - // During a handshake, use the value being negotiated - if( ssl->session_negotiate != NULL ) - { - read_mfl = ssl_mfl_code_to_length( ssl->session_negotiate->mfl_code ); - if( read_mfl < max_len ) - { - max_len = read_mfl; - } - } - - return( max_len ); -} - -size_t mbedtls_ssl_get_output_max_frag_len( const mbedtls_ssl_context *ssl ) +size_t mbedtls_ssl_get_max_frag_len( const mbedtls_ssl_context *ssl ) { size_t max_len; /* * Assume mfl_code is correct since it was checked when set */ - max_len = ssl_mfl_code_to_length( ssl->conf->mfl_code ); + max_len = mfl_code_to_length[ssl->conf->mfl_code]; - /* Check if a smaller max length was negotiated */ + /* + * Check if a smaller max length was negotiated + */ if( ssl->session_out != NULL && - ssl_mfl_code_to_length( ssl->session_out->mfl_code ) < max_len ) + mfl_code_to_length[ssl->session_out->mfl_code] < max_len ) { - max_len = ssl_mfl_code_to_length( ssl->session_out->mfl_code ); + max_len = mfl_code_to_length[ssl->session_out->mfl_code]; } - /* During a handshake, use the value being negotiated */ - if( ssl->session_negotiate != NULL && - ssl_mfl_code_to_length( ssl->session_negotiate->mfl_code ) < max_len ) - { - max_len = ssl_mfl_code_to_length( ssl->session_negotiate->mfl_code ); - } - - return( max_len ); + return max_len; } - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -size_t mbedtls_ssl_get_max_frag_len( const mbedtls_ssl_context *ssl ) -{ - return mbedtls_ssl_get_output_max_frag_len( ssl ); -} -#endif /* !MBEDTLS_DEPRECATED_REMOVED */ #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) -static size_t ssl_get_current_mtu( const mbedtls_ssl_context *ssl ) -{ - /* Return unlimited mtu for client hello messages to avoid fragmentation. */ - if( mbedtls_ssl_conf_get_endpoint( ssl->conf ) == MBEDTLS_SSL_IS_CLIENT && - ( ssl->state == MBEDTLS_SSL_CLIENT_HELLO || - ssl->state == MBEDTLS_SSL_SERVER_HELLO ) ) - return( 0 ); - - if( ssl->handshake == NULL || ssl->handshake->mtu == 0 ) - return( ssl->mtu ); - - if( ssl->mtu == 0 ) - return( ssl->handshake->mtu ); - - return( ssl->mtu < ssl->handshake->mtu ? - ssl->mtu : ssl->handshake->mtu ); -} -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - -int mbedtls_ssl_get_max_out_record_payload( const mbedtls_ssl_context *ssl ) -{ - size_t max_len = MBEDTLS_SSL_OUT_CONTENT_LEN; - -#if !defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) && \ - !defined(MBEDTLS_SSL_PROTO_DTLS) - (void) ssl; -#endif - -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) - const size_t mfl = mbedtls_ssl_get_output_max_frag_len( ssl ); - - if( max_len > mfl ) - max_len = mfl; -#endif - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl_get_current_mtu( ssl ) != 0 ) - { - const size_t mtu = ssl_get_current_mtu( ssl ); - const int ret = mbedtls_ssl_get_record_expansion( ssl ); - const size_t overhead = (size_t) ret; - - if( ret < 0 ) - return( ret ); - - if( mtu <= overhead ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "MTU too low for record expansion" ) ); - return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); - } - - if( max_len > mtu - overhead ) - max_len = mtu - overhead; - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - -#if !defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) && \ - !defined(MBEDTLS_SSL_PROTO_DTLS) - ((void) ssl); -#endif - - return( (int) max_len ); -} - #if defined(MBEDTLS_X509_CRT_PARSE_C) const mbedtls_x509_crt *mbedtls_ssl_get_peer_cert( const mbedtls_ssl_context *ssl ) { if( ssl == NULL || ssl->session == NULL ) return( NULL ); -#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) return( ssl->session->peer_cert ); -#else - return( NULL ); -#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ } #endif /* MBEDTLS_X509_CRT_PARSE_C */ #if defined(MBEDTLS_SSL_CLI_C) -int mbedtls_ssl_get_session( const mbedtls_ssl_context *ssl, - mbedtls_ssl_session *dst ) +int mbedtls_ssl_get_session( const mbedtls_ssl_context *ssl, mbedtls_ssl_session *dst ) { if( ssl == NULL || dst == NULL || ssl->session == NULL || - mbedtls_ssl_conf_get_endpoint( ssl->conf ) != MBEDTLS_SSL_IS_CLIENT ) + ssl->conf->endpoint != MBEDTLS_SSL_IS_CLIENT ) { return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); } - return( mbedtls_ssl_session_copy( dst, ssl->session ) ); + return( ssl_session_copy( dst, ssl->session ) ); } #endif /* MBEDTLS_SSL_CLI_C */ -const mbedtls_ssl_session *mbedtls_ssl_get_session_pointer( const mbedtls_ssl_context *ssl ) -{ - if( ssl == NULL ) - return( NULL ); - - return( ssl->session ); -} - -/* - * Define ticket header determining Mbed TLS version - * and structure of the ticket. - */ - -/* - * Define bitflag determining compile-time settings influencing - * structure of serialized SSL sessions. - */ - -#if defined(MBEDTLS_HAVE_TIME) -#define SSL_SERIALIZED_SESSION_CONFIG_TIME 1 -#else -#define SSL_SERIALIZED_SESSION_CONFIG_TIME 0 -#endif /* MBEDTLS_HAVE_TIME */ - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -#define SSL_SERIALIZED_SESSION_CONFIG_CRT 1 -#else -#define SSL_SERIALIZED_SESSION_CONFIG_CRT 0 -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -#if defined(MBEDTLS_SSL_CLI_C) && defined(MBEDTLS_SSL_SESSION_TICKETS) -#define SSL_SERIALIZED_SESSION_CONFIG_CLIENT_TICKET 1 -#else -#define SSL_SERIALIZED_SESSION_CONFIG_CLIENT_TICKET 0 -#endif /* MBEDTLS_SSL_CLI_C && MBEDTLS_SSL_SESSION_TICKETS */ - -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) -#define SSL_SERIALIZED_SESSION_CONFIG_MFL 1 -#else -#define SSL_SERIALIZED_SESSION_CONFIG_MFL 0 -#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ - -#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) -#define SSL_SERIALIZED_SESSION_CONFIG_TRUNC_HMAC 1 -#else -#define SSL_SERIALIZED_SESSION_CONFIG_TRUNC_HMAC 0 -#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ - -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) -#define SSL_SERIALIZED_SESSION_CONFIG_ETM 1 -#else -#define SSL_SERIALIZED_SESSION_CONFIG_ETM 0 -#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) -#define SSL_SERIALIZED_SESSION_CONFIG_TICKET 1 -#else -#define SSL_SERIALIZED_SESSION_CONFIG_TICKET 0 -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ - -#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) -#define SSL_SERIALIZED_SESSION_CONFIG_KEEP_CRT 1 -#else -#define SSL_SERIALIZED_SESSION_CONFIG_KEEP_CRT 0 -#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - -#if defined(MBEDTLS_ZLIB_SUPPORT) -#define SSL_SERIALIZED_SESSION_CONFIG_COMPRESSION 1 -#else -#define SSL_SERIALIZED_SESSION_CONFIG_COMPRESSION 0 -#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - -#define SSL_SERIALIZED_SESSION_CONFIG_TIME_BIT 0 -#define SSL_SERIALIZED_SESSION_CONFIG_CRT_BIT 1 -#define SSL_SERIALIZED_SESSION_CONFIG_CLIENT_TICKET_BIT 2 -#define SSL_SERIALIZED_SESSION_CONFIG_MFL_BIT 3 -#define SSL_SERIALIZED_SESSION_CONFIG_TRUNC_HMAC_BIT 4 -#define SSL_SERIALIZED_SESSION_CONFIG_ETM_BIT 5 -#define SSL_SERIALIZED_SESSION_CONFIG_TICKET_BIT 6 -#define SSL_SERIALIZED_SESSION_CONFIG_KEEP_CRT_BIT 7 -#define SSL_SERIALIZED_SESSION_CONFIG_COMPRESSION_BIT 8 - -#define SSL_SERIALIZED_SESSION_CONFIG_BITFLAG \ - ( (uint16_t) ( \ - ( SSL_SERIALIZED_SESSION_CONFIG_TIME << SSL_SERIALIZED_SESSION_CONFIG_TIME_BIT ) | \ - ( SSL_SERIALIZED_SESSION_CONFIG_CRT << SSL_SERIALIZED_SESSION_CONFIG_CRT_BIT ) | \ - ( SSL_SERIALIZED_SESSION_CONFIG_CLIENT_TICKET << SSL_SERIALIZED_SESSION_CONFIG_CLIENT_TICKET_BIT ) | \ - ( SSL_SERIALIZED_SESSION_CONFIG_MFL << SSL_SERIALIZED_SESSION_CONFIG_MFL_BIT ) | \ - ( SSL_SERIALIZED_SESSION_CONFIG_TRUNC_HMAC << SSL_SERIALIZED_SESSION_CONFIG_TRUNC_HMAC_BIT ) | \ - ( SSL_SERIALIZED_SESSION_CONFIG_ETM << SSL_SERIALIZED_SESSION_CONFIG_ETM_BIT ) | \ - ( SSL_SERIALIZED_SESSION_CONFIG_TICKET << SSL_SERIALIZED_SESSION_CONFIG_TICKET_BIT ) | \ - ( SSL_SERIALIZED_SESSION_CONFIG_COMPRESSION << SSL_SERIALIZED_SESSION_CONFIG_COMPRESSION_BIT ) | \ - ( SSL_SERIALIZED_SESSION_CONFIG_KEEP_CRT << SSL_SERIALIZED_SESSION_CONFIG_KEEP_CRT_BIT ) ) ) - -static unsigned char ssl_serialized_session_header[] = { - MBEDTLS_VERSION_MAJOR, - MBEDTLS_VERSION_MINOR, - MBEDTLS_VERSION_PATCH, - ( SSL_SERIALIZED_SESSION_CONFIG_BITFLAG >> 8 ) & 0xFF, - ( SSL_SERIALIZED_SESSION_CONFIG_BITFLAG >> 0 ) & 0xFF, -}; - -/* - * Serialize a session in the following format: - * (in the presentation language of TLS, RFC 8446 section 3) - * - * opaque mbedtls_version[3]; // major, minor, patch - * opaque session_format[2]; // version-specific 16-bit field determining - * // the format of the remaining - * // serialized data. - * - * Note: When updating the format, remember to keep - * these version+format bytes. - * - * // In this version, `session_format` determines - * // the setting of those compile-time - * // configuration options which influence - * // the structure of mbedtls_ssl_session. - * uint64 start_time; - * uint8 ciphersuite[2]; // defined by the standard - * uint8 compression; // 0 or 1 - * uint8 session_id_len; // at most 32 - * opaque session_id[32]; - * opaque master[48]; // fixed length in the standard - * uint32 verify_result; - * select (MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) { - * case enabled: opaque peer_cert<0..2^24-1>; // length 0 means no cert - * case disabled: uint8_t peer_cert_digest_type; - * opaque peer_cert_digest<0..2^8-1>; - * } - * opaque ticket<0..2^24-1>; // length 0 means no ticket - * uint32 ticket_lifetime; - * uint8 mfl_code; // up to 255 according to standard - * uint8 trunc_hmac; // 0 or 1 - * uint8 encrypt_then_mac; // 0 or 1 - * - * The order is the same as in the definition of the structure, except - * verify_result is put before peer_cert so that all mandatory fields come - * together in one block. - */ -static int ssl_session_save( const mbedtls_ssl_session *session, - unsigned char omit_header, - unsigned char *buf, - size_t buf_len, - size_t *olen ) -{ - unsigned char *p = buf; - size_t used = 0; -#if defined(MBEDTLS_HAVE_TIME) - uint64_t start; -#endif -#if defined(MBEDTLS_X509_CRT_PARSE_C) -#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - size_t cert_len; -#endif -#endif - - if( !omit_header ) - { - /* - * Add version identifier - */ - - used += sizeof( ssl_serialized_session_header ); - - if( used <= buf_len ) - { - mbedtls_platform_memcpy( p, ssl_serialized_session_header, - sizeof( ssl_serialized_session_header ) ); - p += sizeof( ssl_serialized_session_header ); - } - } - - /* - * Time - */ -#if defined(MBEDTLS_HAVE_TIME) - used += 8; - - if( used <= buf_len ) - { - start = (uint64_t) session->start; - - *p++ = (unsigned char)( ( start >> 56 ) & 0xFF ); - *p++ = (unsigned char)( ( start >> 48 ) & 0xFF ); - *p++ = (unsigned char)( ( start >> 40 ) & 0xFF ); - *p++ = (unsigned char)( ( start >> 32 ) & 0xFF ); - *p++ = (unsigned char)( ( start >> 24 ) & 0xFF ); - *p++ = (unsigned char)( ( start >> 16 ) & 0xFF ); - *p++ = (unsigned char)( ( start >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( start ) & 0xFF ); - } -#endif /* MBEDTLS_HAVE_TIME */ - - /* - * Basic mandatory fields - */ - { - size_t const ciphersuite_len = 2; -#if defined(MBEDTLS_ZLIB_SUPPORT) - size_t const compression_len = 1; -#else - size_t const compression_len = 0; -#endif - size_t const id_len_len = 1; - size_t const id_len = 32; - size_t const master_len = 48; - size_t const verif_result_len = 4; - - size_t const basic_len = - ciphersuite_len + - compression_len + - id_len_len + - id_len + - master_len + - verif_result_len; - - used += basic_len; - } - - if( used <= buf_len ) - { - const int ciphersuite = - mbedtls_ssl_session_get_ciphersuite( session ); - p = mbedtls_platform_put_uint16_be( p, ciphersuite ); - -#if defined(MBEDTLS_ZLIB_SUPPORT) - *p++ = (unsigned char)( - mbedtls_ssl_session_get_compression( session ) ); -#endif - - *p++ = (unsigned char)( session->id_len & 0xFF ); - /* Not using more secure mbedtls_platform_memcpy as session id is public */ - memcpy( p, session->id, 32 ); - p += 32; - - mbedtls_platform_memcpy( p, session->master, 48 ); - p += 48; - p = mbedtls_platform_put_uint32_be( p, session->verify_result ); - } - - /* - * Peer's end-entity certificate - */ -#if defined(MBEDTLS_X509_CRT_PARSE_C) -#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - if( session->peer_cert == NULL ) - cert_len = 0; - else - cert_len = session->peer_cert->raw.len; - - used += 3 + cert_len; - - if( used <= buf_len ) - { - p = mbedtls_platform_put_uint24_be( p, cert_len ); - - if( session->peer_cert != NULL ) - { - mbedtls_platform_memcpy( p, session->peer_cert->raw.p, cert_len ); - p += cert_len; - } - } - -#elif defined(MBEDTLS_SSL_RENEGOTIATION) - /* Digest of peer certificate */ - if( session->peer_cert_digest != NULL ) - { - used += 1 /* type */ + 1 /* length */ + session->peer_cert_digest_len; - if( used <= buf_len ) - { - *p++ = (unsigned char) session->peer_cert_digest_type; - *p++ = (unsigned char) session->peer_cert_digest_len; - mbedtls_platform_memcpy( p, session->peer_cert_digest, - session->peer_cert_digest_len ); - p += session->peer_cert_digest_len; - } - } - else - { - used += 2; - if( used <= buf_len ) - { - *p++ = (unsigned char) MBEDTLS_MD_NONE; - *p++ = 0; - } - } -#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE && MBEDTLS_SSL_RENEGOTIATION */ -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - - /* - * Session ticket if any, plus associated data - */ -#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C) - used += 3 + session->ticket_len + 4; /* len + ticket + lifetime */ - - if( used <= buf_len ) - { - p = mbedtls_platform_put_uint24_be( p, session->ticket_len ); - - if( session->ticket != NULL ) - { - mbedtls_platform_memcpy( p, session->ticket, session->ticket_len ); - p += session->ticket_len; - } - - p = mbedtls_platform_put_uint32_be( p, session->ticket_lifetime ); - } -#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */ - - /* - * Misc extension-related info - */ -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) - used += 1; - - if( used <= buf_len ) - *p++ = session->mfl_code; -#endif - -#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) - used += 1; - - if( used <= buf_len ) - *p++ = (unsigned char)( ( session->trunc_hmac ) & 0xFF ); -#endif - -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) - used += 1; - - if( used <= buf_len ) - *p++ = (unsigned char)( ( session->encrypt_then_mac ) & 0xFF ); -#endif - - /* Done */ - *olen = used; - - if( used > buf_len ) - return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); - - return( 0 ); -} - -/* - * Public wrapper for ssl_session_save() - */ -int mbedtls_ssl_session_save( const mbedtls_ssl_session *session, - unsigned char *buf, - size_t buf_len, - size_t *olen ) -{ - return( ssl_session_save( session, 0, buf, buf_len, olen ) ); -} - -/* - * Deserialize session, see mbedtls_ssl_session_save() for format. - * - * This internal version is wrapped by a public function that cleans up in - * case of error, and has an extra option omit_header. - */ -static int ssl_session_load( mbedtls_ssl_session *session, - unsigned char omit_header, - const unsigned char *buf, - size_t len ) -{ - const unsigned char *p = buf; - const unsigned char * const end = buf + len; - int ciphersuite; -#if defined(MBEDTLS_HAVE_TIME) - uint64_t start; -#endif -#if defined(MBEDTLS_X509_CRT_PARSE_C) -#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - size_t cert_len; -#endif -#endif - - if( !omit_header ) - { - /* - * Check version identifier - */ - - if( (size_t)( end - p ) < sizeof( ssl_serialized_session_header ) ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - // use regular memcmp as session header is public data - if( memcmp( p, ssl_serialized_session_header, - sizeof( ssl_serialized_session_header ) ) != 0 ) - { - return( MBEDTLS_ERR_SSL_VERSION_MISMATCH ); - } - p += sizeof( ssl_serialized_session_header ); - } - - /* - * Time - */ -#if defined(MBEDTLS_HAVE_TIME) - if( 8 > (size_t)( end - p ) ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - start = ( (uint64_t) p[0] << 56 ) | - ( (uint64_t) p[1] << 48 ) | - ( (uint64_t) p[2] << 40 ) | - ( (uint64_t) p[3] << 32 ) | - ( (uint64_t) p[4] << 24 ) | - ( (uint64_t) p[5] << 16 ) | - ( (uint64_t) p[6] << 8 ) | - ( (uint64_t) p[7] ); - p += 8; - - session->start = (time_t) start; -#endif /* MBEDTLS_HAVE_TIME */ - - /* - * Basic mandatory fields - */ - { - size_t const ciphersuite_len = 2; -#if defined(MBEDTLS_ZLIB_SUPPORT) - size_t const compression_len = 1; -#else - size_t const compression_len = 0; -#endif - size_t const id_len_len = 1; - size_t const id_len = 32; - size_t const master_len = 48; - size_t const verif_result_len = 4; - - size_t const basic_len = - ciphersuite_len + - compression_len + - id_len_len + - id_len + - master_len + - verif_result_len; - - if( basic_len > (size_t)( end - p ) ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - } - - ciphersuite = (int)mbedtls_platform_get_uint16_be( p ); - p += 2; - -#if !defined(MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE) - session->ciphersuite = ciphersuite; -#else - if( ciphersuite != - MBEDTLS_SSL_SUITE_ID( MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE ) ) - { - return( MBEDTLS_ERR_SSL_VERSION_MISMATCH ); - } -#endif - -#if defined(MBEDTLS_ZLIB_SUPPORT) - session->compression = *p++; -#endif - - session->id_len = *p++; - /* Not using more secure mbedtls_platform_memcpy as session id is public */ - memcpy( session->id, p, 32 ); - p += 32; - - mbedtls_platform_memcpy( session->master, p, 48 ); - p += 48; - - session->verify_result = (uint32_t)mbedtls_platform_get_uint32_be( p ); - p += 4; - - /* Immediately clear invalid pointer values that have been read, in case - * we exit early before we replaced them with valid ones. */ -#if defined(MBEDTLS_X509_CRT_PARSE_C) -#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - session->peer_cert = NULL; -#elif defined(MBEDTLS_SSL_RENEGOTIATION) - session->peer_cert_digest = NULL; -#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE && MBEDTLS_SSL_RENEGOTIATION */ -#endif -#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C) - session->ticket = NULL; -#endif - - /* - * Peer certificate - */ -#if defined(MBEDTLS_X509_CRT_PARSE_C) -#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - if( 3 > (size_t)( end - p ) ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - cert_len = mbedtls_platform_get_uint24_be( &p[0] ); - - p += 3; - - if( cert_len == 0 ) - { - session->peer_cert = NULL; - } - else - { - int ret; - - if( cert_len > (size_t)( end - p ) ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - session->peer_cert = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt ) ); - - if( session->peer_cert == NULL ) - return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); - - mbedtls_x509_crt_init( session->peer_cert ); - - if( ( ret = mbedtls_x509_crt_parse_der( session->peer_cert, - p, cert_len ) ) != 0 ) - { - mbedtls_x509_crt_free( session->peer_cert ); - mbedtls_free( session->peer_cert ); - session->peer_cert = NULL; - return( ret ); - } - - p += cert_len; - } -#elif defined(MBEDTLS_SSL_RENEGOTIATION) - /* Deserialize CRT digest from the end of the ticket. */ - if( 2 > (size_t)( end - p ) ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - session->peer_cert_digest_type = (mbedtls_md_type_t) *p++; - session->peer_cert_digest_len = (size_t) *p++; - - if( session->peer_cert_digest_len != 0 ) - { - mbedtls_md_handle_t md_info = - mbedtls_md_info_from_type( session->peer_cert_digest_type ); - if( md_info == MBEDTLS_MD_INVALID_HANDLE ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - if( session->peer_cert_digest_len != mbedtls_md_get_size( md_info ) ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - if( session->peer_cert_digest_len > (size_t)( end - p ) ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - session->peer_cert_digest = - mbedtls_calloc( 1, session->peer_cert_digest_len ); - if( session->peer_cert_digest == NULL ) - return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); - - mbedtls_platform_memcpy( session->peer_cert_digest, p, - session->peer_cert_digest_len ); - p += session->peer_cert_digest_len; - } -#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE && MBEDTLS_SSL_RENEGOTIATION */ -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - - /* - * Session ticket and associated data - */ -#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C) - if( 3 > (size_t)( end - p ) ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - session->ticket_len = mbedtls_platform_get_uint24_be( &p[0] ); - p += 3; - - if( session->ticket_len != 0 ) - { - if( session->ticket_len > (size_t)( end - p ) ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - session->ticket = mbedtls_calloc( 1, session->ticket_len ); - if( session->ticket == NULL ) - return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); - - mbedtls_platform_memcpy( session->ticket, p, session->ticket_len ); - p += session->ticket_len; - } - - if( 4 > (size_t)( end - p ) ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - session->ticket_lifetime = (uint32_t)mbedtls_platform_get_uint32_be( p ); - p += 4; -#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */ - - /* - * Misc extension-related info - */ -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) - if( 1 > (size_t)( end - p ) ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - session->mfl_code = *p++; -#endif - -#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) - if( 1 > (size_t)( end - p ) ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - session->trunc_hmac = *p++; -#endif - -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) - if( 1 > (size_t)( end - p ) ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - session->encrypt_then_mac = *p++; -#endif - - /* Done, should have consumed entire buffer */ - if( p != end ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - return( 0 ); -} - -/* - * Deserialize session: public wrapper for error cleaning - */ -int mbedtls_ssl_session_load( mbedtls_ssl_session *session, - const unsigned char *buf, - size_t len ) -{ - int ret = ssl_session_load( session, 0, buf, len ); - - if( ret != 0 ) - mbedtls_ssl_session_free( session ); - - return( ret ); -} - /* * Perform a single step of the SSL handshake */ @@ -11232,15 +6826,14 @@ int mbedtls_ssl_handshake_step( mbedtls_ssl_context *ssl ) return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); #if defined(MBEDTLS_SSL_CLI_C) - if( mbedtls_ssl_conf_get_endpoint( ssl->conf ) == MBEDTLS_SSL_IS_CLIENT ) + if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) ret = mbedtls_ssl_handshake_client_step( ssl ); #endif #if defined(MBEDTLS_SSL_SRV_C) - if( mbedtls_ssl_conf_get_endpoint( ssl->conf ) == MBEDTLS_SSL_IS_SERVER ) + if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) ret = mbedtls_ssl_handshake_server_step( ssl ); #endif - ssl_send_pending_fatal_alert( ssl ); return( ret ); } @@ -11284,9 +6877,9 @@ static int ssl_write_hello_request( mbedtls_ssl_context *ssl ) ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; ssl->out_msg[0] = MBEDTLS_SSL_HS_HELLO_REQUEST; - if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 ) + if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 ) { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret ); + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret ); return( ret ); } @@ -11317,18 +6910,13 @@ static int ssl_start_renegotiation( mbedtls_ssl_context *ssl ) /* RFC 6347 4.2.2: "[...] the HelloRequest will have message_seq = 0 and * the ServerHello will have message_seq = 1" */ #if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) && + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING ) { - if( mbedtls_ssl_conf_get_endpoint( ssl->conf ) == - MBEDTLS_SSL_IS_SERVER ) - { + if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) ssl->handshake->out_msg_seq = 1; - } else - { ssl->handshake->in_msg_seq = 1; - } } #endif @@ -11359,7 +6947,7 @@ int mbedtls_ssl_renegotiate( mbedtls_ssl_context *ssl ) #if defined(MBEDTLS_SSL_SRV_C) /* On server, just send the request */ - if( mbedtls_ssl_conf_get_endpoint( ssl->conf ) == MBEDTLS_SSL_IS_SERVER ) + if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) { if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); @@ -11414,15 +7002,14 @@ static int ssl_check_ctr_renegotiate( mbedtls_ssl_context *ssl ) if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER || ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING || - ! mbedtls_ssl_conf_is_renegotiation_enabled( ssl->conf ) ) + ssl->conf->disable_renegotiation == MBEDTLS_SSL_RENEGOTIATION_DISABLED ) { return( 0 ); } - // use regular memcmp as counters are public data in_ctr_cmp = memcmp( ssl->in_ctr + ep_len, ssl->conf->renego_period + ep_len, 8 - ep_len ); - out_ctr_cmp = memcmp( ssl->cur_out_ctr + ep_len, + out_ctr_cmp = memcmp( ssl->out_ctr + ep_len, ssl->conf->renego_period + ep_len, 8 - ep_len ); if( in_ctr_cmp <= 0 && out_ctr_cmp <= 0 ) @@ -11442,8 +7029,6 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) { int ret; size_t n; - volatile unsigned char *buf_dup = buf; - volatile size_t len_dup = len; if( ssl == NULL || ssl->conf == NULL ) return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); @@ -11451,7 +7036,7 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> read" ) ); #if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) ) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) { if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 ) return( ret ); @@ -11459,7 +7044,7 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) if( ssl->handshake != NULL && ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING ) { - if( ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 ) + if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 ) return( ret ); } } @@ -11498,18 +7083,16 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) } } - /* Loop as long as no application data record is available */ - while( ssl->in_offt == NULL ) + if( ssl->in_offt == NULL ) { /* Start timer if not already running */ - if( mbedtls_ssl_get_get_timer( ssl ) != NULL && - mbedtls_ssl_get_get_timer( ssl )( ssl->p_timer ) == -1 ) + if( ssl->f_get_timer != NULL && + ssl->f_get_timer( ssl->p_timer ) == -1 ) { - ssl_set_timer( ssl, - mbedtls_ssl_conf_get_read_timeout( ssl->conf ) ); + ssl_set_timer( ssl, ssl->conf->read_timeout ); } - if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 ) + if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 ) { if( ret == MBEDTLS_ERR_SSL_CONN_EOF ) return( 0 ); @@ -11524,7 +7107,7 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) /* * OpenSSL sends empty messages to randomize the IV */ - if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 ) + if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 ) { if( ret == MBEDTLS_ERR_SSL_CONN_EOF ) return( 0 ); @@ -11545,8 +7128,7 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) */ #if defined(MBEDTLS_SSL_CLI_C) - if( mbedtls_ssl_conf_get_endpoint( ssl->conf ) == - MBEDTLS_SSL_IS_CLIENT && + if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT && ( ssl->in_msg[0] != MBEDTLS_SSL_HS_HELLO_REQUEST || ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) ) ) { @@ -11554,40 +7136,25 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) /* With DTLS, drop the packet (probably from last handshake) */ #if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) ) - { - continue; - } - MBEDTLS_SSL_TRANSPORT_ELSE -#endif -#if defined(MBEDTLS_SSL_PROTO_TLS) - { - return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); - } + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + return( MBEDTLS_ERR_SSL_WANT_READ ); #endif + return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); } #endif /* MBEDTLS_SSL_CLI_C */ #if defined(MBEDTLS_SSL_SRV_C) - if( mbedtls_ssl_conf_get_endpoint( ssl->conf ) == - MBEDTLS_SSL_IS_SERVER && + if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_HELLO ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake received (not ClientHello)" ) ); /* With DTLS, drop the packet (probably from last handshake) */ #if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) ) - { - continue; - } - MBEDTLS_SSL_TRANSPORT_ELSE -#endif -#if defined(MBEDTLS_SSL_PROTO_TLS) - { - return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); - } + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + return( MBEDTLS_ERR_SSL_WANT_READ ); #endif + return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); } #endif /* MBEDTLS_SSL_SRV_C */ @@ -11595,7 +7162,7 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) /* Determine whether renegotiation attempt should be accepted */ if( ! ( ssl->conf->disable_renegotiation == MBEDTLS_SSL_RENEGOTIATION_DISABLED || ( ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && - mbedtls_ssl_conf_get_allow_legacy_renegotiation( ssl->conf ) == + ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION ) ) ) { /* @@ -11604,9 +7171,8 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) /* DTLS clients need to know renego is server-initiated */ #if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) && - mbedtls_ssl_conf_get_endpoint( ssl->conf ) == - MBEDTLS_SSL_IS_CLIENT ) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && + ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) { ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_PENDING; } @@ -11629,7 +7195,7 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) MBEDTLS_SSL_DEBUG_MSG( 3, ( "refusing renegotiation, sending alert" ) ); #if defined(MBEDTLS_SSL_PROTO_SSL3) - if( mbedtls_ssl_get_minor_ver( ssl ) == MBEDTLS_SSL_MINOR_VERSION_0 ) + if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) { /* SSLv3 does not have a "no_renegotiation" warning, so we send a fatal alert and abort the connection. */ @@ -11641,15 +7207,14 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) #endif /* MBEDTLS_SSL_PROTO_SSL3 */ #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( mbedtls_ssl_ver_geq( - mbedtls_ssl_get_minor_ver( ssl ), - MBEDTLS_SSL_MINOR_VERSION_1 ) ) + if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 ) { - ret = mbedtls_ssl_send_alert_message( ssl, - MBEDTLS_SSL_ALERT_LEVEL_WARNING, - MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION ); - if( ret != 0 ) + if( ( ret = mbedtls_ssl_send_alert_message( ssl, + MBEDTLS_SSL_ALERT_LEVEL_WARNING, + MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION ) ) != 0 ) + { return( ret ); + } } else #endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || @@ -11660,25 +7225,7 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) } } - /* At this point, we don't know whether the renegotiation has been - * completed or not. The cases to consider are the following: - * 1) The renegotiation is complete. In this case, no new record - * has been read yet. - * 2) The renegotiation is incomplete because the client received - * an application data record while awaiting the ServerHello. - * 3) The renegotiation is incomplete because the client received - * a non-handshake, non-application data message while awaiting - * the ServerHello. - * In each of these case, looping will be the proper action: - * - For 1), the next iteration will read a new record and check - * if it's application data. - * - For 2), the loop condition isn't satisfied as application data - * is present, hence continue is the same as break - * - For 3), the loop condition is satisfied and read_record - * will re-deliver the message that was held back by the client - * when expecting the ServerHello. - */ - continue; + return( MBEDTLS_ERR_SSL_WANT_READ ); } #if defined(MBEDTLS_SSL_RENEGOTIATION) else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING ) @@ -11720,8 +7267,7 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) * Do it now, after setting in_offt, to avoid taking this branch * again if ssl_write_hello_request() returns WANT_WRITE */ #if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION) - if( mbedtls_ssl_conf_get_endpoint( ssl->conf ) == - MBEDTLS_SSL_IS_SERVER && + if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING ) { if( ( ret = ssl_resend_hello_request( ssl ) ) != 0 ) @@ -11737,20 +7283,9 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) n = ( len < ssl->in_msglen ) ? len : ssl->in_msglen; - if( mbedtls_platform_memcpy( buf, ssl->in_offt, n ) != - buf ) - { - return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); - } + memcpy( buf, ssl->in_offt, n ); ssl->in_msglen -= n; - // clear incoming data after it's copied to buffer - if( mbedtls_platform_memset( ssl->in_offt, 0, n ) != - ssl->in_offt ) - { - return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); - } - if( ssl->in_msglen == 0 ) { /* all bytes consumed */ @@ -11765,12 +7300,7 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= read" ) ); - /* Secure against buffer substitution */ - if( buf_dup == buf && len_dup == len ) - { - return( (int) n ); - } - return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); + return( (int) n ); } /* @@ -11788,32 +7318,25 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) static int ssl_write_real( mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len ) { - volatile int ret = mbedtls_ssl_get_max_out_record_payload( ssl ); - const size_t max_len = (size_t) ret; - - if( ret < 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_get_max_out_record_payload", ret ); - return( ret ); - } - + int ret; +#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) + size_t max_len = mbedtls_ssl_get_max_frag_len( ssl ); +#else + size_t max_len = MBEDTLS_SSL_MAX_CONTENT_LEN; +#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ if( len > max_len ) { #if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) ) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "fragment larger than the (negotiated) " "maximum fragment length: %d > %d", len, max_len ) ); return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); } - MBEDTLS_SSL_TRANSPORT_ELSE + else #endif -#if defined(MBEDTLS_SSL_PROTO_TLS) - { len = max_len; - } -#endif } if( ssl->out_left != 0 ) @@ -11837,47 +7360,18 @@ static int ssl_write_real( mbedtls_ssl_context *ssl, * copy the data into the internal buffers and setup the data structure * to keep track of partial writes */ - ssl->out_msglen = len; + ssl->out_msglen = len; ssl->out_msgtype = MBEDTLS_SSL_MSG_APPLICATION_DATA; - if( mbedtls_platform_memcpy( ssl->out_msg, buf, len ) != ssl->out_msg ) + memcpy( ssl->out_msg, buf, len ); + + if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 ) { - return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret ); + return( ret ); } - -#if defined(MBEDTLS_FI_COUNTERMEASURES) && !defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) - /* - * Buffer pointer and size duplication cannot be supported with MBEDTLS_SSL_CBC_RECORD_SPLITTING. - * After splitting pointers and data size will not be the same as initaly provides by user. - */ - /* Secure against buffer substitution */ - if( buf == ssl->out_msg_dup && - ssl->out_msglen == ssl->out_msglen_dup && - ssl->out_msg_dup[0] == ssl->out_msg[0] ) - {/*write record only if data was copied from correct user pointer */ -#endif - if( ( ret = mbedtls_ssl_write_record( ssl, SSL_FORCE_FLUSH ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret ); - return( ret ); - } - -#if defined(MBEDTLS_FI_COUNTERMEASURES) && !defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) - } - else - { - return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); - } -#endif - } - if ( ret == 0 ) - { - return( (int) len ); - } - else - { - return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); } + return( (int) len ); } /* @@ -11896,16 +7390,9 @@ static int ssl_write_split( mbedtls_ssl_context *ssl, if( ssl->conf->cbc_record_splitting == MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED || len <= 1 || - mbedtls_ssl_ver_gt( - mbedtls_ssl_get_minor_ver( ssl ), - MBEDTLS_SSL_MINOR_VERSION_1 ) || -#if defined(MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS) - mbedtls_cipher_get_cipher_mode( &ssl->transform_out->cipher_ctx ) - != MBEDTLS_MODE_CBC ) -#else + ssl->minor_ver > MBEDTLS_SSL_MINOR_VERSION_1 || mbedtls_cipher_get_cipher_mode( &ssl->transform_out->cipher_ctx_enc ) != MBEDTLS_MODE_CBC ) -#endif { return( ssl_write_real( ssl, buf, len ) ); } @@ -11930,15 +7417,8 @@ static int ssl_write_split( mbedtls_ssl_context *ssl, */ int mbedtls_ssl_write( mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len ) { - int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; -#if defined(MBEDTLS_FI_COUNTERMEASURES) && !defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) - /* - * Buffer pointer and size duplication cannot be supported with MBEDTLS_SSL_CBC_RECORD_SPLITTING. - * After splitting pointers and data size will not be the same as initaly provides by user. - */ - volatile const unsigned char *buf_dup = buf; - volatile size_t len_dup = len; -#endif + int ret; + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write" ) ); if( ssl == NULL || ssl->conf == NULL ) @@ -11964,19 +7444,12 @@ int mbedtls_ssl_write( mbedtls_ssl_context *ssl, const unsigned char *buf, size_ #if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) ret = ssl_write_split( ssl, buf, len ); #else -#if defined(MBEDTLS_FI_COUNTERMEASURES) - /* Add const user pointers to context. We will be able to check its validity before copy to context */ - ssl->out_msg_dup = (unsigned char*)buf_dup; - ssl->out_msglen_dup = len_dup; -#endif //MBEDTLS_FI_COUNTERMEASURES ret = ssl_write_real( ssl, buf, len ); #endif MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write" ) ); - return( ret ); - } /* @@ -12019,22 +7492,14 @@ void mbedtls_ssl_transform_free( mbedtls_ssl_transform *transform ) deflateEnd( &transform->ctx_deflate ); inflateEnd( &transform->ctx_inflate ); #endif -#if defined(MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS) - mbedtls_cipher_free( &transform->cipher_ctx ); - if( transform->key_dec != NULL ) - mbedtls_free( transform->key_dec ); - if( transform->key_enc != NULL ) - mbedtls_free( transform->key_enc ); -#else + mbedtls_cipher_free( &transform->cipher_ctx_enc ); mbedtls_cipher_free( &transform->cipher_ctx_dec ); -#endif -#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC) + mbedtls_md_free( &transform->md_ctx_enc ); mbedtls_md_free( &transform->md_ctx_dec ); -#endif - mbedtls_platform_zeroize( transform, sizeof( mbedtls_ssl_transform ) ); + mbedtls_zeroize( transform, sizeof( mbedtls_ssl_transform ) ); } #if defined(MBEDTLS_X509_CRT_PARSE_C) @@ -12051,57 +7516,11 @@ static void ssl_key_cert_free( mbedtls_ssl_key_cert *key_cert ) } #endif /* MBEDTLS_X509_CRT_PARSE_C */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - -static void ssl_buffering_free( mbedtls_ssl_context *ssl ) +void mbedtls_ssl_handshake_free( mbedtls_ssl_handshake_params *handshake ) { - unsigned offset; - mbedtls_ssl_handshake_params * const hs = ssl->handshake; - - if( hs == NULL ) - return; - - ssl_free_buffered_record( ssl ); - - for( offset = 0; offset < MBEDTLS_SSL_MAX_BUFFERED_HS; offset++ ) - ssl_buffering_free_slot( ssl, offset ); -} - -static void ssl_buffering_free_slot( mbedtls_ssl_context *ssl, - uint8_t slot ) -{ - mbedtls_ssl_handshake_params * const hs = ssl->handshake; - mbedtls_ssl_hs_buffer * const hs_buf = &hs->buffering.hs[slot]; - - if( slot >= MBEDTLS_SSL_MAX_BUFFERED_HS ) - return; - - if( hs_buf->is_valid == 1 ) - { - hs->buffering.total_bytes_buffered -= hs_buf->data_len; - mbedtls_platform_zeroize( hs_buf->data, hs_buf->data_len ); - mbedtls_free( hs_buf->data ); - mbedtls_platform_memset( hs_buf, 0, sizeof( mbedtls_ssl_hs_buffer ) ); - } -} - -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - -void mbedtls_ssl_handshake_free( mbedtls_ssl_context *ssl ) -{ - mbedtls_ssl_handshake_params *handshake = ssl->handshake; - if( handshake == NULL ) return; -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) - if( ssl->conf->f_async_cancel != NULL && handshake->async_in_progress != 0 ) - { - ssl->conf->f_async_cancel( ssl ); - handshake->async_in_progress = 0; - } -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ - #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ defined(MBEDTLS_SSL_PROTO_TLS1_1) mbedtls_md5_free( &handshake->fin_md5 ); @@ -12116,19 +7535,6 @@ void mbedtls_ssl_handshake_free( mbedtls_ssl_context *ssl ) #endif #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ -#if defined(MBEDTLS_SSL_FREE_SERVER_CERTIFICATE) && \ - defined(MBEDTLS_X509_CRT_PARSE_C) && \ - defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - if( ssl->session_negotiate ) - { - ssl_clear_peer_cert( ssl->session_negotiate ); - } - if( ssl->session ) - { - ssl_clear_peer_cert( ssl->session ); - } -#endif /* MBEDTLS_SSL_FREE_SERVER_CERTIFICATE */ - #if defined(MBEDTLS_DHM_C) mbedtls_dhm_free( &handshake->dhm_ctx ); #endif @@ -12144,10 +7550,16 @@ void mbedtls_ssl_handshake_free( mbedtls_ssl_context *ssl ) #endif #endif +#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) + /* explicit void pointer cast for buggy MS compiler */ + mbedtls_free( (void *) handshake->curves ); +#endif + #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) if( handshake->psk != NULL ) { - mbedtls_platform_zeroize( handshake->psk, handshake->psk_len ); + mbedtls_zeroize( handshake->psk, handshake->psk_len ); mbedtls_free( handshake->psk ); } #endif @@ -12171,38 +7583,13 @@ void mbedtls_ssl_handshake_free( mbedtls_ssl_context *ssl ) } #endif /* MBEDTLS_X509_CRT_PARSE_C && MBEDTLS_SSL_SERVER_NAME_INDICATION */ -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - mbedtls_x509_crt_restart_free( &handshake->ecrs_ctx ); - if( handshake->ecrs_peer_cert != NULL ) - { - mbedtls_x509_crt_free( handshake->ecrs_peer_cert ); - mbedtls_free( handshake->ecrs_peer_cert ); - } -#endif - -#if defined(MBEDTLS_X509_CRT_PARSE_C) && \ - !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - mbedtls_pk_free( &handshake->peer_pubkey ); -#endif /* MBEDTLS_X509_CRT_PARSE_C && !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - #if defined(MBEDTLS_SSL_PROTO_DTLS) mbedtls_free( handshake->verify_cookie ); + mbedtls_free( handshake->hs_msg ); ssl_flight_free( handshake->flight ); - ssl_buffering_free( ssl ); #endif - mbedtls_platform_zeroize( handshake, - sizeof( mbedtls_ssl_handshake_params ) ); - -#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) - /* If the buffers are too big - reallocate. Because of the way Mbed TLS - * processes datagrams and the fact that a datagram is allowed to have - * several records in it, it is possible that the I/O buffers are not - * empty at this stage */ - handle_buffer_resizing( ssl, BUFFER_DOWNSIZING, - mbedtls_ssl_get_input_buflen( ssl ), - mbedtls_ssl_get_output_buflen( ssl ) ); -#endif + mbedtls_zeroize( handshake, sizeof( mbedtls_ssl_handshake_params ) ); } void mbedtls_ssl_session_free( mbedtls_ssl_session *session ) @@ -12211,601 +7598,20 @@ void mbedtls_ssl_session_free( mbedtls_ssl_session *session ) return; #if defined(MBEDTLS_X509_CRT_PARSE_C) - ssl_clear_peer_cert( session ); + if( session->peer_cert != NULL ) + { + mbedtls_x509_crt_free( session->peer_cert ); + mbedtls_free( session->peer_cert ); + } #endif #if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C) mbedtls_free( session->ticket ); #endif - mbedtls_platform_zeroize( session, sizeof( mbedtls_ssl_session ) ); + mbedtls_zeroize( session, sizeof( mbedtls_ssl_session ) ); } -#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION) - -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) -#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_CONNECTION_ID 1u -#else -#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_CONNECTION_ID 0u -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - -#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) -#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_BADMAC_LIMIT 1u -#else -#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_BADMAC_LIMIT 0u -#endif /* MBEDTLS_SSL_DTLS_BADMAC_LIMIT */ - -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) -#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_ANTI_REPLAY 1u -#else -#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_ANTI_REPLAY 0u -#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */ - -#if defined(MBEDTLS_SSL_ALPN) -#define SSL_SERIALIZED_CONTEXT_CONFIG_ALPN 1u -#else -#define SSL_SERIALIZED_CONTEXT_CONFIG_ALPN 0u -#endif /* MBEDTLS_SSL_ALPN */ - -#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_CONNECTION_ID_BIT 0 -#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_BADMAC_LIMIT_BIT 1 -#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_ANTI_REPLAY_BIT 2 -#define SSL_SERIALIZED_CONTEXT_CONFIG_ALPN_BIT 3 - -#define SSL_SERIALIZED_CONTEXT_CONFIG_BITFLAG \ - ( (uint32_t) ( \ - ( SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_CONNECTION_ID << SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_CONNECTION_ID_BIT ) | \ - ( SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_BADMAC_LIMIT << SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_BADMAC_LIMIT_BIT ) | \ - ( SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_ANTI_REPLAY << SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_ANTI_REPLAY_BIT ) | \ - ( SSL_SERIALIZED_CONTEXT_CONFIG_ALPN << SSL_SERIALIZED_CONTEXT_CONFIG_ALPN_BIT ) | \ - 0u ) ) - -static unsigned char ssl_serialized_context_header[] = { - MBEDTLS_VERSION_MAJOR, - MBEDTLS_VERSION_MINOR, - MBEDTLS_VERSION_PATCH, - ( SSL_SERIALIZED_SESSION_CONFIG_BITFLAG >> 8 ) & 0xFF, - ( SSL_SERIALIZED_SESSION_CONFIG_BITFLAG >> 0 ) & 0xFF, - ( SSL_SERIALIZED_CONTEXT_CONFIG_BITFLAG >> 16 ) & 0xFF, - ( SSL_SERIALIZED_CONTEXT_CONFIG_BITFLAG >> 8 ) & 0xFF, - ( SSL_SERIALIZED_CONTEXT_CONFIG_BITFLAG >> 0 ) & 0xFF, -}; - -/* - * Serialize a full SSL context - * - * The format of the serialized data is: - * (in the presentation language of TLS, RFC 8446 section 3) - * - * // header - * opaque mbedtls_version[3]; // major, minor, patch - * opaque context_format[5]; // version-specific field determining - * // the format of the remaining - * // serialized data. - * Note: When updating the format, remember to keep these - * version+format bytes. (We may make their size part of the API.) - * - * // session sub-structure - * opaque session<1..2^32-1>; // see mbedtls_ssl_session_save() - * // transform sub-structure - * uint8 random[64]; // ServerHello.random+ClientHello.random - * uint8 in_cid<0..2^8-1> // Connection ID: expected incoming value - * uint8 out_cid<0..2^8-1> // Connection ID: outgoing value to use - * // fields from ssl_context - * uint32 badmac_seen; // DTLS: number of records with failing MAC - * uint64 in_window_top; // DTLS: last validated record seq_num - * uint64 in_window; // DTLS: bitmask for replay protection - * uint8 disable_datagram_packing; // DTLS: only one record per datagram - * uint64 cur_out_ctr; // Record layer: outgoing sequence number - * uint16 mtu; // DTLS: path mtu (max outgoing fragment size) - * uint8 alpn_chosen<0..2^8-1> // ALPN: negotiated application protocol - * - * Note that many fields of the ssl_context or sub-structures are not - * serialized, as they fall in one of the following categories: - * - * 1. forced value (eg in_left must be 0) - * 2. pointer to dynamically-allocated memory (eg session, transform) - * 3. value can be re-derived from other data (eg session keys from MS) - * 4. value was temporary (eg content of input buffer) - * 5. value will be provided by the user again (eg I/O callbacks and context) - */ -int mbedtls_ssl_context_save( mbedtls_ssl_context *ssl, - unsigned char *buf, - size_t buf_len, - size_t *olen ) -{ - unsigned char *p = buf; - size_t used = 0; - size_t session_len; - int ret = 0; - - /* - * Enforce usage restrictions, see "return BAD_INPUT_DATA" in - * this function's documentation. - * - * These are due to assumptions/limitations in the implementation. Some of - * them are likely to stay (no handshake in progress) some might go away - * (only DTLS) but are currently used to simplify the implementation. - */ - /* The initial handshake must be over */ - if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - if( ssl->handshake != NULL ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - /* Double-check that sub-structures are indeed ready */ - if( ssl->transform == NULL || ssl->session == NULL ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - /* There must be no pending incoming or outgoing data */ - if( mbedtls_ssl_check_pending( ssl ) != 0 ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - if( ssl->out_left != 0 ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - /* Protocol must be DLTS, not TLS */ - if( MBEDTLS_SSL_TRANSPORT_IS_TLS( ssl->conf->transport ) ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - /* Version must be 1.2 */ - if( mbedtls_ssl_get_major_ver( ssl ) != MBEDTLS_SSL_MAJOR_VERSION_3 ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - if( mbedtls_ssl_get_minor_ver( ssl ) != MBEDTLS_SSL_MINOR_VERSION_3 ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - /* We must be using an AEAD ciphersuite */ - if( mbedtls_ssl_transform_uses_aead( ssl->transform ) != 1 ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - /* Renegotiation must not be enabled */ - if( mbedtls_ssl_conf_is_renegotiation_enabled( ssl->conf ) ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - /* - * Version and format identifier - */ - used += sizeof( ssl_serialized_context_header ); - - if( used <= buf_len ) - { - mbedtls_platform_memcpy( p, ssl_serialized_context_header, - sizeof( ssl_serialized_context_header ) ); - p += sizeof( ssl_serialized_context_header ); - } - - /* - * Session (length + data) - */ - ret = ssl_session_save( ssl->session, 1, NULL, 0, &session_len ); - if( ret != MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ) - return( ret ); - - used += 4 + session_len; - if( used <= buf_len ) - { - p = mbedtls_platform_put_uint32_be( p, session_len ); - - ret = ssl_session_save( ssl->session, 1, - p, session_len, &session_len ); - if( ret != 0 ) - return( ret ); - - p += session_len; - } - - /* - * Transform - */ - used += sizeof( ssl->transform->randbytes ); - if( used <= buf_len ) - { - mbedtls_platform_memcpy( p, ssl->transform->randbytes, - sizeof( ssl->transform->randbytes ) ); - p += sizeof( ssl->transform->randbytes ); - } - -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - used += 2 + ssl->transform->in_cid_len + ssl->transform->out_cid_len; - if( used <= buf_len ) - { - *p++ = ssl->transform->in_cid_len; - /* Not using more secure mbedtls_platform_memcpy as cid is public */ - memcpy( p, ssl->transform->in_cid, ssl->transform->in_cid_len ); - p += ssl->transform->in_cid_len; - - *p++ = ssl->transform->out_cid_len; - /* Not using more secure mbedtls_platform_memcpy as cid is public */ - memcpy( p, ssl->transform->out_cid, ssl->transform->out_cid_len ); - p += ssl->transform->out_cid_len; - } -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - - /* - * Saved fields from top-level ssl_context structure - */ -#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) - used += 4; - if( used <= buf_len ) - { - p = mbedtls_platform_put_uint32_be( p, ssl->badmac_seen ); - } -#endif /* MBEDTLS_SSL_DTLS_BADMAC_LIMIT */ - -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) - used += 16; - if( used <= buf_len ) - { - *p++ = (unsigned char)( ( ssl->in_window_top >> 56 ) & 0xFF ); - *p++ = (unsigned char)( ( ssl->in_window_top >> 48 ) & 0xFF ); - *p++ = (unsigned char)( ( ssl->in_window_top >> 40 ) & 0xFF ); - *p++ = (unsigned char)( ( ssl->in_window_top >> 32 ) & 0xFF ); - *p++ = (unsigned char)( ( ssl->in_window_top >> 24 ) & 0xFF ); - *p++ = (unsigned char)( ( ssl->in_window_top >> 16 ) & 0xFF ); - *p++ = (unsigned char)( ( ssl->in_window_top >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( ssl->in_window_top ) & 0xFF ); - - *p++ = (unsigned char)( ( ssl->in_window >> 56 ) & 0xFF ); - *p++ = (unsigned char)( ( ssl->in_window >> 48 ) & 0xFF ); - *p++ = (unsigned char)( ( ssl->in_window >> 40 ) & 0xFF ); - *p++ = (unsigned char)( ( ssl->in_window >> 32 ) & 0xFF ); - *p++ = (unsigned char)( ( ssl->in_window >> 24 ) & 0xFF ); - *p++ = (unsigned char)( ( ssl->in_window >> 16 ) & 0xFF ); - *p++ = (unsigned char)( ( ssl->in_window >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( ssl->in_window ) & 0xFF ); - } -#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */ - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - used += 1; - if( used <= buf_len ) - { - *p++ = ssl->disable_datagram_packing; - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - used += 8; - if( used <= buf_len ) - { - mbedtls_platform_memcpy( p, ssl->cur_out_ctr, 8 ); - p += 8; - } - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - used += 2; - if( used <= buf_len ) - { - p = mbedtls_platform_put_uint16_be( p, ssl->mtu ); - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - -#if defined(MBEDTLS_SSL_ALPN) - { - const uint8_t alpn_len = ssl->alpn_chosen - ? (uint8_t) strlen( ssl->alpn_chosen ) - : 0; - - used += 1 + alpn_len; - if( used <= buf_len ) - { - *p++ = alpn_len; - - if( ssl->alpn_chosen != NULL ) - { - mbedtls_platform_memcpy( p, ssl->alpn_chosen, alpn_len ); - p += alpn_len; - } - } - } -#endif /* MBEDTLS_SSL_ALPN */ - - /* - * Done - */ - *olen = used; - - if( used > buf_len ) - return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); - - MBEDTLS_SSL_DEBUG_BUF( 4, "saved context", buf, used ); - - return( ssl_session_reset_int( ssl, 0 ) ); -} - -/* - * Deserialize context, see mbedtls_ssl_context_save() for format. - * - * This internal version is wrapped by a public function that cleans up in - * case of error. - */ -static int ssl_context_load( mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len ) -{ - const unsigned char *p = buf; - const unsigned char * const end = buf + len; - size_t session_len; - int ret; - - /* - * The context should have been freshly setup or reset. - * Give the user an error in case of obvious misuse. - * (Checking session is useful because it won't be NULL if we're - * renegotiating, or if the user mistakenly loaded a session first.) - */ - if( ssl->state != MBEDTLS_SSL_HELLO_REQUEST || - ssl->session != NULL ) - { - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - } - - /* - * We can't check that the config matches the initial one, but we can at - * least check it matches the requirements for serializing. - */ - if( MBEDTLS_SSL_TRANSPORT_IS_TLS( ssl->conf->transport ) || - mbedtls_ssl_ver_lt( - mbedtls_ssl_conf_get_max_major_ver( ssl->conf ), - MBEDTLS_SSL_MAJOR_VERSION_3 ) || - mbedtls_ssl_ver_gt( - mbedtls_ssl_conf_get_min_major_ver( ssl->conf ), - MBEDTLS_SSL_MAJOR_VERSION_3 ) || - mbedtls_ssl_ver_lt( - mbedtls_ssl_conf_get_max_minor_ver( ssl->conf ), - MBEDTLS_SSL_MINOR_VERSION_3 ) || - mbedtls_ssl_ver_gt( - mbedtls_ssl_conf_get_min_minor_ver( ssl->conf ), - MBEDTLS_SSL_MINOR_VERSION_3 ) || - mbedtls_ssl_conf_is_renegotiation_enabled( ssl->conf ) ) - { - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - } - - MBEDTLS_SSL_DEBUG_BUF( 4, "context to load", buf, len ); - - /* - * Check version identifier - */ - if( (size_t)( end - p ) < sizeof( ssl_serialized_context_header ) ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - // use regular memcmp as header is not that critical - if( memcmp( p, ssl_serialized_context_header, - sizeof( ssl_serialized_context_header ) ) != 0 ) - { - return( MBEDTLS_ERR_SSL_VERSION_MISMATCH ); - } - p += sizeof( ssl_serialized_context_header ); - - /* - * Session - */ - if( (size_t)( end - p ) < 4 ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - session_len = mbedtls_platform_get_uint32_be( p ); - p += 4; - - /* This has been allocated by ssl_handshake_init(), called by - * by either ssl_session_reset_int() or mbedtls_ssl_setup(). */ - ssl->session = ssl->session_negotiate; - ssl->session_in = ssl->session; - ssl->session_out = ssl->session; - ssl->session_negotiate = NULL; - - if( (size_t)( end - p ) < session_len ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - ret = ssl_session_load( ssl->session, 1, p, session_len ); - if( ret != 0 ) - { - mbedtls_ssl_session_free( ssl->session ); - return( ret ); - } - - p += session_len; - - /* - * Transform - */ - - /* This has been allocated by ssl_handshake_init(), called by - * by either ssl_session_reset_int() or mbedtls_ssl_setup(). */ - ssl->transform = ssl->transform_negotiate; - ssl->transform_in = ssl->transform; - ssl->transform_out = ssl->transform; - ssl->transform_negotiate = NULL; - - /* Read random bytes and populate structure */ - if( (size_t)( end - p ) < sizeof( ssl->transform->randbytes ) ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - ret = ssl_populate_transform( ssl->transform, - mbedtls_ssl_session_get_ciphersuite( ssl->session ), - ssl->session->master, -#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC) -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) - ssl->session->encrypt_then_mac, -#endif -#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) - ssl->session->trunc_hmac, -#endif -#endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */ -#if defined(MBEDTLS_ZLIB_SUPPORT) - ssl->session->compression, -#endif - p, /* currently pointing to randbytes */ - MBEDTLS_SSL_MINOR_VERSION_3, /* (D)TLS 1.2 is forced */ - mbedtls_ssl_conf_get_endpoint( ssl->conf ), - ssl ); - if( ret != 0 ) - return( ret ); - - p += sizeof( ssl->transform->randbytes ); - -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - /* Read connection IDs and store them */ - if( (size_t)( end - p ) < 1 ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - ssl->transform->in_cid_len = *p++; - - if( (size_t)( end - p ) < ssl->transform->in_cid_len + 1u ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - /* Not using more secure mbedtls_platform_memcpy as cid is public */ - memcpy( ssl->transform->in_cid, p, ssl->transform->in_cid_len ); - p += ssl->transform->in_cid_len; - - ssl->transform->out_cid_len = *p++; - - if( (size_t)( end - p ) < ssl->transform->out_cid_len ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - /* Not using more secure mbedtls_platform_memcpy as cid is public */ - memcpy( ssl->transform->out_cid, p, ssl->transform->out_cid_len ); - p += ssl->transform->out_cid_len; -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - - /* - * Saved fields from top-level ssl_context structure - */ -#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) - if( (size_t)( end - p ) < 4 ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - ssl->badmac_seen = (unsigned)mbedtls_platform_get_uint32_be( p ); - p += 4; -#endif /* MBEDTLS_SSL_DTLS_BADMAC_LIMIT */ - -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) - if( (size_t)( end - p ) < 16 ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - ssl->in_window_top = ( (uint64_t) p[0] << 56 ) | - ( (uint64_t) p[1] << 48 ) | - ( (uint64_t) p[2] << 40 ) | - ( (uint64_t) p[3] << 32 ) | - ( (uint64_t) p[4] << 24 ) | - ( (uint64_t) p[5] << 16 ) | - ( (uint64_t) p[6] << 8 ) | - ( (uint64_t) p[7] ); - p += 8; - - ssl->in_window = ( (uint64_t) p[0] << 56 ) | - ( (uint64_t) p[1] << 48 ) | - ( (uint64_t) p[2] << 40 ) | - ( (uint64_t) p[3] << 32 ) | - ( (uint64_t) p[4] << 24 ) | - ( (uint64_t) p[5] << 16 ) | - ( (uint64_t) p[6] << 8 ) | - ( (uint64_t) p[7] ); - p += 8; -#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */ - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( (size_t)( end - p ) < 1 ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - ssl->disable_datagram_packing = *p++; -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - if( (size_t)( end - p ) < 8 ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - mbedtls_platform_memcpy( ssl->cur_out_ctr, p, 8 ); - p += 8; - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( (size_t)( end - p ) < 2 ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - ssl->mtu = (uint16_t)mbedtls_platform_get_uint16_be( p ); - p += 2; -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - -#if defined(MBEDTLS_SSL_ALPN) - { - uint8_t alpn_len; - const char **cur; - - if( (size_t)( end - p ) < 1 ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - alpn_len = *p++; - - if( alpn_len != 0 && ssl->conf->alpn_list != NULL ) - { - /* alpn_chosen should point to an item in the configured list */ - for( cur = ssl->conf->alpn_list; *cur != NULL; cur++ ) - { - if( strlen( *cur ) == alpn_len && - mbedtls_platform_memequal( p, cur, alpn_len ) == 0 ) - { - ssl->alpn_chosen = *cur; - break; - } - } - } - - /* can only happen on conf mismatch */ - if( alpn_len != 0 && ssl->alpn_chosen == NULL ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - p += alpn_len; - } -#endif /* MBEDTLS_SSL_ALPN */ - - /* - * Forced fields from top-level ssl_context structure - * - * Most of them already set to the correct value by mbedtls_ssl_init() and - * mbedtls_ssl_reset(), so we only need to set the remaining ones. - */ - ssl->state = MBEDTLS_SSL_HANDSHAKE_OVER; - -#if !defined(MBEDTLS_SSL_CONF_FIXED_MAJOR_VER) - ssl->major_ver = MBEDTLS_SSL_MAJOR_VERSION_3; -#endif /* !MBEDTLS_SSL_CONF_FIXED_MAJOR_VER */ -#if !defined(MBEDTLS_SSL_CONF_FIXED_MINOR_VER) - ssl->minor_ver = MBEDTLS_SSL_MINOR_VERSION_3; -#endif /* !MBEDTLS_SSL_CONF_FIXED_MINOR_VER */ - - /* Adjust pointers for header fields of outgoing records to - * the given transform, accounting for explicit IV and CID. */ - ssl_update_out_pointers( ssl, ssl->transform ); - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - ssl->in_epoch = 1; -#endif - - /* mbedtls_ssl_reset() leaves the handshake sub-structure allocated, - * which we don't want - otherwise we'd end up freeing the wrong transform - * by calling ssl_handshake_wrapup_free_hs_transform() inappropriately. */ - if( ssl->handshake != NULL ) - { - mbedtls_ssl_handshake_free( ssl ); - mbedtls_free( ssl->handshake ); - ssl->handshake = NULL; - } - - /* - * Done - should have consumed entire buffer - */ - if( p != end ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - return( 0 ); -} - -/* - * Deserialize context: public wrapper for error cleaning - */ -int mbedtls_ssl_context_load( mbedtls_ssl_context *context, - const unsigned char *buf, - size_t len ) -{ - int ret = ssl_context_load( context, buf, len ); - - if( ret != 0 ) - mbedtls_ssl_free( context ); - - return( ret ); -} -#endif /* MBEDTLS_SSL_CONTEXT_SERIALIZATION */ - /* * Free an SSL context */ @@ -12818,32 +7624,20 @@ void mbedtls_ssl_free( mbedtls_ssl_context *ssl ) if( ssl->out_buf != NULL ) { -#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) - size_t out_buf_len = ssl->out_buf_len; -#else - size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN; -#endif - mbedtls_platform_zeroize( ssl->out_buf, out_buf_len ); + mbedtls_zeroize( ssl->out_buf, MBEDTLS_SSL_BUFFER_LEN ); mbedtls_free( ssl->out_buf ); - ssl->out_buf = NULL; } if( ssl->in_buf != NULL ) { -#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) - size_t in_buf_len = ssl->in_buf_len; -#else - size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN; -#endif - mbedtls_platform_zeroize( ssl->in_buf, in_buf_len ); + mbedtls_zeroize( ssl->in_buf, MBEDTLS_SSL_BUFFER_LEN ); mbedtls_free( ssl->in_buf ); - ssl->in_buf = NULL; } #if defined(MBEDTLS_ZLIB_SUPPORT) if( ssl->compress_buf != NULL ) { - mbedtls_platform_zeroize( ssl->compress_buf, MBEDTLS_SSL_COMPRESS_BUFFER_LEN ); + mbedtls_zeroize( ssl->compress_buf, MBEDTLS_SSL_BUFFER_LEN ); mbedtls_free( ssl->compress_buf ); } #endif @@ -12856,7 +7650,7 @@ void mbedtls_ssl_free( mbedtls_ssl_context *ssl ) if( ssl->handshake ) { - mbedtls_ssl_handshake_free( ssl ); + mbedtls_ssl_handshake_free( ssl->handshake ); mbedtls_ssl_transform_free( ssl->transform_negotiate ); mbedtls_ssl_session_free( ssl->session_negotiate ); @@ -12871,10 +7665,10 @@ void mbedtls_ssl_free( mbedtls_ssl_context *ssl ) mbedtls_free( ssl->session ); } -#if defined(MBEDTLS_X509_CRT_PARSE_C) && !defined(MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION) +#if defined(MBEDTLS_X509_CRT_PARSE_C) if( ssl->hostname != NULL ) { - mbedtls_platform_zeroize( ssl->hostname, strlen( ssl->hostname ) ); + mbedtls_zeroize( ssl->hostname, strlen( ssl->hostname ) ); mbedtls_free( ssl->hostname ); } #endif @@ -12894,7 +7688,7 @@ void mbedtls_ssl_free( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= free" ) ); /* Actually clear after last debug message */ - mbedtls_platform_zeroize( ssl, sizeof( mbedtls_ssl_context ) ); + mbedtls_zeroize( ssl, sizeof( mbedtls_ssl_context ) ); } /* @@ -12903,16 +7697,9 @@ void mbedtls_ssl_free( mbedtls_ssl_context *ssl ) void mbedtls_ssl_config_init( mbedtls_ssl_config *conf ) { memset( conf, 0, sizeof( mbedtls_ssl_config ) ); - -#if !defined(MBEDTLS_SSL_PROTO_TLS) -#if !defined(MBEDTLS_SSL_CONF_TRANSPORT) - conf->transport = MBEDTLS_SSL_TRANSPORT_DATAGRAM; -#endif -#endif } #if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) -#if !defined(MBEDTLS_SSL_CONF_SINGLE_SIG_HASH) static int ssl_preset_default_hashes[] = { #if defined(MBEDTLS_SHA512_C) MBEDTLS_MD_SHA512, @@ -12928,34 +7715,25 @@ static int ssl_preset_default_hashes[] = { MBEDTLS_MD_NONE }; #endif -#endif -#if !defined(MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE) static int ssl_preset_suiteb_ciphersuites[] = { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 0 }; -#endif /* !MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE */ #if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) -#if !defined(MBEDTLS_SSL_CONF_SINGLE_SIG_HASH) static int ssl_preset_suiteb_hashes[] = { MBEDTLS_MD_SHA256, MBEDTLS_MD_SHA384, MBEDTLS_MD_NONE }; #endif -#endif -#if defined(MBEDTLS_ECP_C) && !defined(MBEDTLS_SSL_CONF_SINGLE_EC) +#if defined(MBEDTLS_ECP_C) static mbedtls_ecp_group_id ssl_preset_suiteb_curves[] = { -#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) MBEDTLS_ECP_DP_SECP256R1, -#endif -#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) MBEDTLS_ECP_DP_SECP384R1, -#endif MBEDTLS_ECP_DP_NONE }; #endif @@ -12972,14 +7750,8 @@ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf, /* Use the functions here so that they are covered in tests, * but otherwise access member directly for efficiency */ -#if !defined(MBEDTLS_SSL_CONF_ENDPOINT) mbedtls_ssl_conf_endpoint( conf, endpoint ); -#endif -#if !defined(MBEDTLS_SSL_CONF_TRANSPORT) mbedtls_ssl_conf_transport( conf, transport ); -#else - ((void) transport); -#endif /* * Things that are common to all presets @@ -12987,9 +7759,7 @@ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf, #if defined(MBEDTLS_SSL_CLI_C) if( endpoint == MBEDTLS_SSL_IS_CLIENT ) { -#if !defined(MBEDTLS_SSL_CONF_AUTHMODE) conf->authmode = MBEDTLS_SSL_VERIFY_REQUIRED; -#endif /* !MBEDTLS_SSL_CONF_AUTHMODE */ #if defined(MBEDTLS_SSL_SESSION_TICKETS) conf->session_tickets = MBEDTLS_SSL_SESSION_TICKETS_ENABLED; #endif @@ -13005,13 +7775,7 @@ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf, #endif #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) -#if !defined(MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET) conf->extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED; -#endif /* !MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET */ -#if !defined(MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET) - conf->enforce_extended_master_secret = - MBEDTLS_SSL_EXTENDED_MS_ENFORCE_DISABLED; -#endif /* !MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET */ #endif #if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) @@ -13023,30 +7787,23 @@ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf, conf->f_cookie_check = ssl_cookie_check_dummy; #endif -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) && \ - !defined(MBEDTLS_SSL_CONF_ANTI_REPLAY) +#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) conf->anti_replay = MBEDTLS_SSL_ANTI_REPLAY_ENABLED; #endif #if defined(MBEDTLS_SSL_SRV_C) -#if !defined(MBEDTLS_SSL_CONF_CERT_REQ_CA_LIST) conf->cert_req_ca_list = MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED; -#endif /* !MBEDTLS_SSL_CONF_CERT_REQ_CA_LIST */ -#endif /* MBEDTLS_SSL_SRV_C */ +#endif #if defined(MBEDTLS_SSL_PROTO_DTLS) -#if !defined(MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN) conf->hs_timeout_min = MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MIN; -#endif /* !MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN */ -#if !defined(MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX) conf->hs_timeout_max = MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MAX; -#endif /* !MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX */ -#endif /* MBEDTLS_SSL_PROTO_DTLS */ +#endif #if defined(MBEDTLS_SSL_RENEGOTIATION) conf->renego_max_records = MBEDTLS_SSL_RENEGO_MAX_RECORDS_DEFAULT; - mbedtls_platform_memset( conf->renego_period, 0x00, 2 ); - mbedtls_platform_memset( conf->renego_period + 2, 0xFF, 6 ); + memset( conf->renego_period, 0x00, 2 ); + memset( conf->renego_period + 2, 0xFF, 6 ); #endif #if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C) @@ -13075,41 +7832,27 @@ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf, * NSA Suite B */ case MBEDTLS_SSL_PRESET_SUITEB: -#if !defined(MBEDTLS_SSL_CONF_MIN_MAJOR_VER) conf->min_major_ver = MBEDTLS_SSL_MAJOR_VERSION_3; -#endif /* !MBEDTLS_SSL_CONF_MIN_MAJOR_VER */ -#if !defined(MBEDTLS_SSL_CONF_MIN_MINOR_VER) conf->min_minor_ver = MBEDTLS_SSL_MINOR_VERSION_3; /* TLS 1.2 */ -#endif /* !MBEDTLS_SSL_CONF_MIN_MINOR_VER */ -#if !defined(MBEDTLS_SSL_CONF_MAX_MAJOR_VER) conf->max_major_ver = MBEDTLS_SSL_MAX_MAJOR_VERSION; -#endif /* !MBEDTLS_SSL_CONF_MAX_MAJOR_VER */ -#if !defined(MBEDTLS_SSL_CONF_MAX_MINOR_VER) conf->max_minor_ver = MBEDTLS_SSL_MAX_MINOR_VERSION; -#endif /* !MBEDTLS_SSL_CONF_MAX_MINOR_VER */ -#if !defined(MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE) - conf->ciphersuite_list[0] = - conf->ciphersuite_list[1] = - conf->ciphersuite_list[2] = - conf->ciphersuite_list[3] = - ssl_preset_suiteb_ciphersuites; -#endif /* MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE */ + conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_0] = + conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_1] = + conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_2] = + conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_3] = + ssl_preset_suiteb_ciphersuites; #if defined(MBEDTLS_X509_CRT_PARSE_C) conf->cert_profile = &mbedtls_x509_crt_profile_suiteb; #endif #if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) -#if !defined(MBEDTLS_SSL_CONF_SINGLE_SIG_HASH) conf->sig_hashes = ssl_preset_suiteb_hashes; #endif -#endif #if defined(MBEDTLS_ECP_C) -#if !defined(MBEDTLS_SSL_CONF_SINGLE_EC) conf->curve_list = ssl_preset_suiteb_curves; -#endif #endif break; @@ -13117,52 +7860,39 @@ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf, * Default */ default: -#if !defined(MBEDTLS_SSL_CONF_MIN_MAJOR_VER) conf->min_major_ver = ( MBEDTLS_SSL_MIN_MAJOR_VERSION > MBEDTLS_SSL_MIN_VALID_MAJOR_VERSION ) ? MBEDTLS_SSL_MIN_MAJOR_VERSION : MBEDTLS_SSL_MIN_VALID_MAJOR_VERSION; -#endif /* !MBEDTLS_SSL_CONF_MIN_MAJOR_VER */ -#if !defined(MBEDTLS_SSL_CONF_MIN_MINOR_VER) conf->min_minor_ver = ( MBEDTLS_SSL_MIN_MINOR_VERSION > MBEDTLS_SSL_MIN_VALID_MINOR_VERSION ) ? MBEDTLS_SSL_MIN_MINOR_VERSION : MBEDTLS_SSL_MIN_VALID_MINOR_VERSION; + conf->max_major_ver = MBEDTLS_SSL_MAX_MAJOR_VERSION; + conf->max_minor_ver = MBEDTLS_SSL_MAX_MINOR_VERSION; + #if defined(MBEDTLS_SSL_PROTO_DTLS) - if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( transport ) ) + if( transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) conf->min_minor_ver = MBEDTLS_SSL_MINOR_VERSION_2; #endif -#endif /* !MBEDTLS_SSL_CONF_MIN_MINOR_VER */ -#if !defined(MBEDTLS_SSL_CONF_MAX_MAJOR_VER) - conf->max_major_ver = MBEDTLS_SSL_MAX_MAJOR_VERSION; -#endif /* !MBEDTLS_SSL_CONF_MAX_MAJOR_VER */ -#if !defined(MBEDTLS_SSL_CONF_MAX_MINOR_VER) - conf->max_minor_ver = MBEDTLS_SSL_MAX_MINOR_VERSION; -#endif /* !MBEDTLS_SSL_CONF_MAX_MINOR_VER */ -#if !defined(MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE) - conf->ciphersuite_list[0] = - conf->ciphersuite_list[1] = - conf->ciphersuite_list[2] = - conf->ciphersuite_list[3] = - mbedtls_ssl_list_ciphersuites(); -#endif /* MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE */ + conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_0] = + conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_1] = + conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_2] = + conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_3] = + mbedtls_ssl_list_ciphersuites(); #if defined(MBEDTLS_X509_CRT_PARSE_C) conf->cert_profile = &mbedtls_x509_crt_profile_default; #endif #if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) -#if !defined(MBEDTLS_SSL_CONF_SINGLE_SIG_HASH) conf->sig_hashes = ssl_preset_default_hashes; #endif -#endif #if defined(MBEDTLS_ECP_C) -#if !defined(MBEDTLS_SSL_CONF_SINGLE_EC) conf->curve_list = mbedtls_ecp_grp_id_list(); #endif -#endif #if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_CLI_C) conf->dhm_min_bitlen = 1024; @@ -13185,17 +7915,11 @@ void mbedtls_ssl_config_free( mbedtls_ssl_config *conf ) #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) if( conf->psk != NULL ) { - mbedtls_platform_zeroize( conf->psk, conf->psk_len ); + mbedtls_zeroize( conf->psk, conf->psk_len ); + mbedtls_zeroize( conf->psk_identity, conf->psk_identity_len ); mbedtls_free( conf->psk ); - conf->psk = NULL; - conf->psk_len = 0; - } - - if( conf->psk_identity != NULL ) - { - mbedtls_platform_zeroize( conf->psk_identity, conf->psk_identity_len ); mbedtls_free( conf->psk_identity ); - conf->psk_identity = NULL; + conf->psk_len = 0; conf->psk_identity_len = 0; } #endif @@ -13204,12 +7928,11 @@ void mbedtls_ssl_config_free( mbedtls_ssl_config *conf ) ssl_key_cert_free( conf->key_cert ); #endif - mbedtls_platform_zeroize( conf, sizeof( mbedtls_ssl_config ) ); + mbedtls_zeroize( conf, sizeof( mbedtls_ssl_config ) ); } #if defined(MBEDTLS_PK_C) && \ - ( defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECDSA_C) ) || \ - ( defined(MBEDTLS_USE_TINYCRYPT) ) + ( defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECDSA_C) ) /* * Convert between MBEDTLS_PK_XXX and SSL_SIG_XXX */ @@ -13219,7 +7942,7 @@ unsigned char mbedtls_ssl_sig_from_pk( mbedtls_pk_context *pk ) if( mbedtls_pk_can_do( pk, MBEDTLS_PK_RSA ) ) return( MBEDTLS_SSL_SIG_RSA ); #endif -#if defined(MBEDTLS_ECDSA_C) || defined(MBEDTLS_USE_TINYCRYPT) +#if defined(MBEDTLS_ECDSA_C) if( mbedtls_pk_can_do( pk, MBEDTLS_PK_ECDSA ) ) return( MBEDTLS_SSL_SIG_ECDSA ); #endif @@ -13247,7 +7970,7 @@ mbedtls_pk_type_t mbedtls_ssl_pk_alg_from_sig( unsigned char sig ) case MBEDTLS_SSL_SIG_RSA: return( MBEDTLS_PK_RSA ); #endif -#if defined(MBEDTLS_ECDSA_C) || defined(MBEDTLS_USE_TINYCRYPT) +#if defined(MBEDTLS_ECDSA_C) case MBEDTLS_SSL_SIG_ECDSA: return( MBEDTLS_PK_ECDSA ); #endif @@ -13372,35 +8095,21 @@ unsigned char mbedtls_ssl_hash_from_md_alg( int md ) } } -#if defined(MBEDTLS_USE_TINYCRYPT) -/* - * Check if a curve proposed by the peer is in our list. - * Return 0 if we're willing to use it, -1 otherwise. - */ -int mbedtls_ssl_check_curve_uecc( const mbedtls_ssl_context *ssl, - mbedtls_uecc_group_id grp_id ) -{ - MBEDTLS_SSL_BEGIN_FOR_EACH_SUPPORTED_UECC_GRP_ID( own_ec_id ) - if( own_ec_id == grp_id ) - return( 0 ); - MBEDTLS_SSL_END_FOR_EACH_SUPPORTED_UECC_GRP_ID - - return( -1 ); -} -#endif /* MBEDTLS_USE_TINYCRYPT */ - #if defined(MBEDTLS_ECP_C) /* * Check if a curve proposed by the peer is in our list. * Return 0 if we're willing to use it, -1 otherwise. */ -int mbedtls_ssl_check_curve( const mbedtls_ssl_context *ssl, - mbedtls_ecp_group_id grp_id ) +int mbedtls_ssl_check_curve( const mbedtls_ssl_context *ssl, mbedtls_ecp_group_id grp_id ) { - MBEDTLS_SSL_BEGIN_FOR_EACH_SUPPORTED_EC_GRP_ID( own_ec_id ) - if( own_ec_id == grp_id ) - return( 0 ); - MBEDTLS_SSL_END_FOR_EACH_SUPPORTED_EC_GRP_ID + const mbedtls_ecp_group_id *gid; + + if( ssl->conf->curve_list == NULL ) + return( -1 ); + + for( gid = ssl->conf->curve_list; *gid != MBEDTLS_ECP_DP_NONE; gid++ ) + if( *gid == grp_id ) + return( 0 ); return( -1 ); } @@ -13414,10 +8123,14 @@ int mbedtls_ssl_check_curve( const mbedtls_ssl_context *ssl, int mbedtls_ssl_check_sig_hash( const mbedtls_ssl_context *ssl, mbedtls_md_type_t md ) { - MBEDTLS_SSL_BEGIN_FOR_EACH_SIG_HASH( md_alg ) - if( md_alg == md ) - return( 0 ); - MBEDTLS_SSL_END_FOR_EACH_SIG_HASH + const int *cur; + + if( ssl->conf->sig_hashes == NULL ) + return( -1 ); + + for( cur = ssl->conf->sig_hashes; *cur != MBEDTLS_MD_NONE; cur++ ) + if( *cur == (int) md ) + return( 0 ); return( -1 ); } @@ -13425,7 +8138,7 @@ int mbedtls_ssl_check_sig_hash( const mbedtls_ssl_context *ssl, #if defined(MBEDTLS_X509_CRT_PARSE_C) int mbedtls_ssl_check_cert_usage( const mbedtls_x509_crt *cert, - mbedtls_ssl_ciphersuite_handle_t ciphersuite, + const mbedtls_ssl_ciphersuite_t *ciphersuite, int cert_endpoint, uint32_t *flags ) { @@ -13449,7 +8162,7 @@ int mbedtls_ssl_check_cert_usage( const mbedtls_x509_crt *cert, if( cert_endpoint == MBEDTLS_SSL_IS_SERVER ) { /* Server part of the key exchange */ - switch( mbedtls_ssl_suite_get_key_exchange( ciphersuite ) ) + switch( ciphersuite->key_exchange ) { case MBEDTLS_KEY_EXCHANGE_RSA: case MBEDTLS_KEY_EXCHANGE_RSA_PSK: @@ -13514,6 +8227,101 @@ int mbedtls_ssl_check_cert_usage( const mbedtls_x509_crt *cert, } #endif /* MBEDTLS_X509_CRT_PARSE_C */ +/* + * Convert version numbers to/from wire format + * and, for DTLS, to/from TLS equivalent. + * + * For TLS this is the identity. + * For DTLS, use 1's complement (v -> 255 - v, and then map as follows: + * 1.0 <-> 3.2 (DTLS 1.0 is based on TLS 1.1) + * 1.x <-> 3.x+1 for x != 0 (DTLS 1.2 based on TLS 1.2) + */ +void mbedtls_ssl_write_version( int major, int minor, int transport, + unsigned char ver[2] ) +{ +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + { + if( minor == MBEDTLS_SSL_MINOR_VERSION_2 ) + --minor; /* DTLS 1.0 stored as TLS 1.1 internally */ + + ver[0] = (unsigned char)( 255 - ( major - 2 ) ); + ver[1] = (unsigned char)( 255 - ( minor - 1 ) ); + } + else +#else + ((void) transport); +#endif + { + ver[0] = (unsigned char) major; + ver[1] = (unsigned char) minor; + } +} + +void mbedtls_ssl_read_version( int *major, int *minor, int transport, + const unsigned char ver[2] ) +{ +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + { + *major = 255 - ver[0] + 2; + *minor = 255 - ver[1] + 1; + + if( *minor == MBEDTLS_SSL_MINOR_VERSION_1 ) + ++*minor; /* DTLS 1.0 stored as TLS 1.1 internally */ + } + else +#else + ((void) transport); +#endif + { + *major = ver[0]; + *minor = ver[1]; + } +} + +int mbedtls_ssl_set_calc_verify_md( mbedtls_ssl_context *ssl, int md ) +{ +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) + if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 ) + return MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH; + + switch( md ) + { +#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) +#if defined(MBEDTLS_MD5_C) + case MBEDTLS_SSL_HASH_MD5: + return MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH; +#endif +#if defined(MBEDTLS_SHA1_C) + case MBEDTLS_SSL_HASH_SHA1: + ssl->handshake->calc_verify = ssl_calc_verify_tls; + break; +#endif +#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 */ +#if defined(MBEDTLS_SHA512_C) + case MBEDTLS_SSL_HASH_SHA384: + ssl->handshake->calc_verify = ssl_calc_verify_tls_sha384; + break; +#endif +#if defined(MBEDTLS_SHA256_C) + case MBEDTLS_SSL_HASH_SHA256: + ssl->handshake->calc_verify = ssl_calc_verify_tls_sha256; + break; +#endif + default: + return MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH; + } + + return 0; +#else /* !MBEDTLS_SSL_PROTO_TLS1_2 */ + (void) ssl; + (void) md; + + return MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH; +#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ +} + #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ defined(MBEDTLS_SSL_PROTO_TLS1_1) int mbedtls_ssl_get_key_exchange_md_ssl_tls( mbedtls_ssl_context *ssl, @@ -13591,8 +8399,8 @@ exit: mbedtls_sha1_free( &mbedtls_sha1 ); if( ret != 0 ) - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR ); return( ret ); @@ -13603,15 +8411,13 @@ exit: #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ defined(MBEDTLS_SSL_PROTO_TLS1_2) int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl, - unsigned char *hash, size_t *hashlen, - unsigned char *data, size_t data_len, - mbedtls_md_type_t md_alg ) + unsigned char *output, + unsigned char *data, size_t data_len, + mbedtls_md_type_t md_alg ) { int ret = 0; mbedtls_md_context_t ctx; - - mbedtls_md_handle_t md_info = mbedtls_md_info_from_type( md_alg ); - *hashlen = mbedtls_md_get_size( md_info ); + const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg ); mbedtls_md_init( &ctx ); @@ -13642,7 +8448,7 @@ int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_update", ret ); goto exit; } - if( ( ret = mbedtls_md_finish( &ctx, hash ) ) != 0 ) + if( ( ret = mbedtls_md_finish( &ctx, output ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_finish", ret ); goto exit; @@ -13652,8 +8458,8 @@ exit: mbedtls_md_free( &ctx ); if( ret != 0 ) - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR ); return( ret ); } diff --git a/APP_Framework/Framework/security/mbedtls/test.c b/APP_Framework/Framework/security/mbedtls/test.c new file mode 100644 index 000000000..2b6cd757b --- /dev/null +++ b/APP_Framework/Framework/security/mbedtls/test.c @@ -0,0 +1,129 @@ +#include +#include +#include +#include + +#include +#include "pk.h" +#include "sha256.h" +#include "sha1.h" +#include "aes.h" + + +void mbedtls_aes_ecb_test() { + int i; + mbedtls_aes_context aes_ctx; + + unsigned char key[16] = "ECBPASSWD1234"; + unsigned char plain[16] = "MbedTLS_AES"; + unsigned char decrypted_plain[16] = {0}; + unsigned char cipher[16] = {0}; + + mbedtls_aes_init(&aes_ctx); + + mbedtls_aes_setkey_enc(&aes_ctx, key, 128); + printf("\nAES ECB:\nBefore encrypt: %s\n", plain); + mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT, plain, cipher); + + printf("After encrypt: "); + for (i = 0; i < 16; ++i) { + printf("%c", cipher[i]); + } + printf(" -End\n"); + + mbedtls_aes_setkey_dec(&aes_ctx, key, 128); + mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_DECRYPT, cipher, decrypted_plain); + printf("After decrypt: %s\n", decrypted_plain); + mbedtls_aes_free(&aes_ctx); +}; + +void mbedtls_aes_cbc_test() { + int i; + mbedtls_aes_context aes_ctx; + + unsigned char key[16] = "CBCPASSWD4321"; + unsigned char iv[16]; + unsigned char plain[64] = "Port Mbed_TLS to XiUOS success."; + unsigned char decrypted_plain[64] = {0}; + unsigned char cipher[64] = {0}; + + mbedtls_aes_init(&aes_ctx); + + printf("AES CBC:\nBefore encrypt: %s\n", plain); + mbedtls_aes_setkey_enc(&aes_ctx, key, 128); + for (i = 0; i < 16; ++i) { + iv[i] = 0x01; + } + mbedtls_aes_crypt_cbc(&aes_ctx, MBEDTLS_AES_ENCRYPT, 64, iv, plain, cipher); + printf("After encrypt: "); + for (i = 0; i < 64; ++i) { + printf("%c", cipher[i]); + } + printf(" -End\n"); + + mbedtls_aes_setkey_dec(&aes_ctx, key, 128); + for (i = 0; i < 16; ++i) { + iv[i] = 0x01; + } + mbedtls_aes_crypt_cbc(&aes_ctx, MBEDTLS_AES_DECRYPT, 64, iv, cipher, decrypted_plain); + printf("After decrypt: %s\n", decrypted_plain); + mbedtls_aes_free(&aes_ctx); +}; + + +const char publickey[] = { + "-----BEGIN PUBLIC KEY----- \r\n" + "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE6NjtyqaRPShUnTn3OrM9CNnIxKHf3yWv4iFR/LPCcCTfnzGvIb3n/9REss3wjbeBNpZBFStPsYbY+iPWXA3ASw== \r\n" + "-----END PUBLIC KEY-----" +}; + +void mbedtls_init() { + mbedtls_pk_context ctx_pk; + mbedtls_pk_init(&ctx_pk); + + int ret = mbedtls_pk_parse_public_key(&ctx_pk, (uint8_t *)publickey, sizeof(publickey)); + if (ret != 0) { + printf("Can't import public key\n"); + } else { + printf("Imported public key:\n %s\n", publickey); + } +} + +int test() { + printf("test mbedtls ......\n"); + mbedtls_init(); + + int i; + unsigned char content_to_encrypt[] = "Hello Mbed-TLS"; + unsigned char content_encrypted[32]; + + mbedtls_sha1_context sha1_ctx; + mbedtls_sha1_init(&sha1_ctx); + mbedtls_sha1_starts(&sha1_ctx); + mbedtls_sha1_update(&sha1_ctx, content_to_encrypt, strlen((char *)content_to_encrypt)); + mbedtls_sha1_finish(&sha1_ctx, content_encrypted); + printf("\nOriginal Data: %s \nAfter encrypt by sha1:", content_to_encrypt); + mbedtls_sha1_free(&sha1_ctx); + for (i = 0; i < 20; ++i) { + printf("%02x", content_encrypted[i]); + } + printf("\n"); + + mbedtls_sha256_context sha256_ctx; + mbedtls_sha256_init(&sha256_ctx); + mbedtls_sha256_starts(&sha256_ctx, 0); + mbedtls_sha256_update(&sha256_ctx, content_to_encrypt, strlen((char *)content_to_encrypt)); + mbedtls_sha256_finish(&sha256_ctx, content_encrypted); + printf("\nOriginal Data: %s \nAfter encrypt by sha256:", content_to_encrypt); + mbedtls_sha256_free(&sha256_ctx); + for (i = 0; i < 32; ++i) { + printf("%02x", content_encrypted[i]); + } + printf("\n"); + + mbedtls_aes_ecb_test(); + mbedtls_aes_cbc_test(); +} + +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), + test_mbedtls, test, test_mbedtls); \ No newline at end of file diff --git a/APP_Framework/Framework/security/mbedtls/threading.c b/APP_Framework/Framework/security/mbedtls/threading.c new file mode 100644 index 000000000..82c6c1435 --- /dev/null +++ b/APP_Framework/Framework/security/mbedtls/threading.c @@ -0,0 +1,149 @@ +/* + * Threading abstraction layer + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_THREADING_C) + +#include "threading.h" + +#if defined(MBEDTLS_THREADING_PTHREAD) +static void threading_mutex_init_pthread( mbedtls_threading_mutex_t *mutex ) +{ + if( mutex == NULL ) + return; + + mutex->is_valid = pthread_mutex_init( &mutex->mutex, NULL ) == 0; +} + +static void threading_mutex_free_pthread( mbedtls_threading_mutex_t *mutex ) +{ + if( mutex == NULL || !mutex->is_valid ) + return; + + (void) pthread_mutex_destroy( &mutex->mutex ); + mutex->is_valid = 0; +} + +static int threading_mutex_lock_pthread( mbedtls_threading_mutex_t *mutex ) +{ + if( mutex == NULL || ! mutex->is_valid ) + return( MBEDTLS_ERR_THREADING_BAD_INPUT_DATA ); + + if( pthread_mutex_lock( &mutex->mutex ) != 0 ) + return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); + + return( 0 ); +} + +static int threading_mutex_unlock_pthread( mbedtls_threading_mutex_t *mutex ) +{ + if( mutex == NULL || ! mutex->is_valid ) + return( MBEDTLS_ERR_THREADING_BAD_INPUT_DATA ); + + if( pthread_mutex_unlock( &mutex->mutex ) != 0 ) + return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); + + return( 0 ); +} + +void (*mbedtls_mutex_init)( mbedtls_threading_mutex_t * ) = threading_mutex_init_pthread; +void (*mbedtls_mutex_free)( mbedtls_threading_mutex_t * ) = threading_mutex_free_pthread; +int (*mbedtls_mutex_lock)( mbedtls_threading_mutex_t * ) = threading_mutex_lock_pthread; +int (*mbedtls_mutex_unlock)( mbedtls_threading_mutex_t * ) = threading_mutex_unlock_pthread; + +/* + * With phtreads we can statically initialize mutexes + */ +#define MUTEX_INIT = { PTHREAD_MUTEX_INITIALIZER, 1 } + +#endif /* MBEDTLS_THREADING_PTHREAD */ + +#if defined(MBEDTLS_THREADING_ALT) +static int threading_mutex_fail( mbedtls_threading_mutex_t *mutex ) +{ + ((void) mutex ); + return( MBEDTLS_ERR_THREADING_BAD_INPUT_DATA ); +} +static void threading_mutex_dummy( mbedtls_threading_mutex_t *mutex ) +{ + ((void) mutex ); + return; +} + +void (*mbedtls_mutex_init)( mbedtls_threading_mutex_t * ) = threading_mutex_dummy; +void (*mbedtls_mutex_free)( mbedtls_threading_mutex_t * ) = threading_mutex_dummy; +int (*mbedtls_mutex_lock)( mbedtls_threading_mutex_t * ) = threading_mutex_fail; +int (*mbedtls_mutex_unlock)( mbedtls_threading_mutex_t * ) = threading_mutex_fail; + +/* + * Set functions pointers and initialize global mutexes + */ +void mbedtls_threading_set_alt( void (*mutex_init)( mbedtls_threading_mutex_t * ), + void (*mutex_free)( mbedtls_threading_mutex_t * ), + int (*mutex_lock)( mbedtls_threading_mutex_t * ), + int (*mutex_unlock)( mbedtls_threading_mutex_t * ) ) +{ + mbedtls_mutex_init = mutex_init; + mbedtls_mutex_free = mutex_free; + mbedtls_mutex_lock = mutex_lock; + mbedtls_mutex_unlock = mutex_unlock; + +#if defined(MBEDTLS_FS_IO) + mbedtls_mutex_init( &mbedtls_threading_readdir_mutex ); +#endif +#if defined(MBEDTLS_HAVE_TIME_DATE) + mbedtls_mutex_init( &mbedtls_threading_gmtime_mutex ); +#endif +} + +/* + * Free global mutexes + */ +void mbedtls_threading_free_alt( void ) +{ +#if defined(MBEDTLS_FS_IO) + mbedtls_mutex_free( &mbedtls_threading_readdir_mutex ); +#endif +#if defined(MBEDTLS_HAVE_TIME_DATE) + mbedtls_mutex_free( &mbedtls_threading_gmtime_mutex ); +#endif +} +#endif /* MBEDTLS_THREADING_ALT */ + +/* + * Define global mutexes + */ +#ifndef MUTEX_INIT +#define MUTEX_INIT +#endif +#if defined(MBEDTLS_FS_IO) +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; +#endif + +#endif /* MBEDTLS_THREADING_C */ diff --git a/APP_Framework/Framework/security/mbedtls/threading.h b/APP_Framework/Framework/security/mbedtls/threading.h index 92e6e6b98..aeea5d0e1 100644 --- a/APP_Framework/Framework/security/mbedtls/threading.h +++ b/APP_Framework/Framework/security/mbedtls/threading.h @@ -36,16 +36,13 @@ extern "C" { #endif -/* MBEDTLS_ERR_THREADING_FEATURE_UNAVAILABLE is deprecated and should not be - * used. */ #define MBEDTLS_ERR_THREADING_FEATURE_UNAVAILABLE -0x001A /**< The selected feature is not available. */ - #define MBEDTLS_ERR_THREADING_BAD_INPUT_DATA -0x001C /**< Bad input parameters to function. */ #define MBEDTLS_ERR_THREADING_MUTEX_ERROR -0x001E /**< Locking / unlocking / free failed with error code. */ #if defined(MBEDTLS_THREADING_PTHREAD) #include -typedef struct mbedtls_threading_mutex_t +typedef struct { pthread_mutex_t mutex; char is_valid; @@ -102,17 +99,9 @@ extern int (*mbedtls_mutex_unlock)( mbedtls_threading_mutex_t *mutex ); #if defined(MBEDTLS_FS_IO) extern mbedtls_threading_mutex_t mbedtls_threading_readdir_mutex; #endif - -#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_PLATFORM_GMTIME_R_ALT) -/* This mutex may or may not be used in the default definition of - * mbedtls_platform_gmtime_r(), but in order to determine that, - * we need to check POSIX features, hence modify _POSIX_C_SOURCE. - * With the current approach, this declaration is orphaned, lacking - * an accompanying definition, in case mbedtls_platform_gmtime_r() - * doesn't need it, but that's not a problem. */ +#if defined(MBEDTLS_HAVE_TIME_DATE) extern mbedtls_threading_mutex_t mbedtls_threading_gmtime_mutex; -#endif /* MBEDTLS_HAVE_TIME_DATE && !MBEDTLS_PLATFORM_GMTIME_R_ALT */ - +#endif #endif /* MBEDTLS_THREADING_C */ #ifdef __cplusplus diff --git a/APP_Framework/Framework/security/mbedtls/timing.c b/APP_Framework/Framework/security/mbedtls/timing.c new file mode 100644 index 000000000..7814f6d52 --- /dev/null +++ b/APP_Framework/Framework/security/mbedtls/timing.c @@ -0,0 +1,536 @@ +/* + * Portable interface to the CPU cycle counter + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_PLATFORM_C) +#include "platform.h" +#else +#include +#define mbedtls_printf printf +#endif + +#if defined(MBEDTLS_TIMING_C) + +#include "timing.h" + +#if !defined(MBEDTLS_TIMING_ALT) + +#if !defined(unix) && !defined(__unix__) && !defined(__unix) && \ + !defined(__APPLE__) && !defined(_WIN32) +#error "This module only works on Unix and Windows, see MBEDTLS_TIMING_C in config.h" +#endif + +#ifndef asm +#define asm __asm +#endif + +#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) + +#include +#include +#include + +struct _hr_time +{ + LARGE_INTEGER start; +}; + +#else + +#include +#include +#include +#include +#include + +struct _hr_time +{ + struct timeval start; +}; + +#endif /* _WIN32 && !EFIX64 && !EFI32 */ + +#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \ + ( defined(_MSC_VER) && defined(_M_IX86) ) || defined(__WATCOMC__) + +#define HAVE_HARDCLOCK + +unsigned long mbedtls_timing_hardclock( void ) +{ + unsigned long tsc; + __asm rdtsc + __asm mov [tsc], eax + return( tsc ); +} +#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM && + ( _MSC_VER && _M_IX86 ) || __WATCOMC__ */ + +/* some versions of mingw-64 have 32-bit longs even on x84_64 */ +#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \ + defined(__GNUC__) && ( defined(__i386__) || ( \ + ( defined(__amd64__) || defined( __x86_64__) ) && __SIZEOF_LONG__ == 4 ) ) + +#define HAVE_HARDCLOCK + +unsigned long mbedtls_timing_hardclock( void ) +{ + unsigned long lo, hi; + asm volatile( "rdtsc" : "=a" (lo), "=d" (hi) ); + return( lo ); +} +#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM && + __GNUC__ && __i386__ */ + +#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \ + defined(__GNUC__) && ( defined(__amd64__) || defined(__x86_64__) ) + +#define HAVE_HARDCLOCK + +unsigned long mbedtls_timing_hardclock( void ) +{ + unsigned long lo, hi; + asm volatile( "rdtsc" : "=a" (lo), "=d" (hi) ); + return( lo | ( hi << 32 ) ); +} +#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM && + __GNUC__ && ( __amd64__ || __x86_64__ ) */ + +#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \ + defined(__GNUC__) && ( defined(__powerpc__) || defined(__ppc__) ) + +#define HAVE_HARDCLOCK + +unsigned long mbedtls_timing_hardclock( void ) +{ + unsigned long tbl, tbu0, tbu1; + + do + { + asm volatile( "mftbu %0" : "=r" (tbu0) ); + asm volatile( "mftb %0" : "=r" (tbl ) ); + asm volatile( "mftbu %0" : "=r" (tbu1) ); + } + while( tbu0 != tbu1 ); + + return( tbl ); +} +#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM && + __GNUC__ && ( __powerpc__ || __ppc__ ) */ + +#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \ + defined(__GNUC__) && defined(__sparc64__) + +#if defined(__OpenBSD__) +#warning OpenBSD does not allow access to tick register using software version instead +#else +#define HAVE_HARDCLOCK + +unsigned long mbedtls_timing_hardclock( void ) +{ + unsigned long tick; + asm volatile( "rdpr %%tick, %0;" : "=&r" (tick) ); + return( tick ); +} +#endif /* __OpenBSD__ */ +#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM && + __GNUC__ && __sparc64__ */ + +#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \ + defined(__GNUC__) && defined(__sparc__) && !defined(__sparc64__) + +#define HAVE_HARDCLOCK + +unsigned long mbedtls_timing_hardclock( void ) +{ + unsigned long tick; + asm volatile( ".byte 0x83, 0x41, 0x00, 0x00" ); + asm volatile( "mov %%g1, %0" : "=r" (tick) ); + return( tick ); +} +#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM && + __GNUC__ && __sparc__ && !__sparc64__ */ + +#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \ + defined(__GNUC__) && defined(__alpha__) + +#define HAVE_HARDCLOCK + +unsigned long mbedtls_timing_hardclock( void ) +{ + unsigned long cc; + asm volatile( "rpcc %0" : "=r" (cc) ); + return( cc & 0xFFFFFFFF ); +} +#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM && + __GNUC__ && __alpha__ */ + +#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \ + defined(__GNUC__) && defined(__ia64__) + +#define HAVE_HARDCLOCK + +unsigned long mbedtls_timing_hardclock( void ) +{ + unsigned long itc; + asm volatile( "mov %0 = ar.itc" : "=r" (itc) ); + return( itc ); +} +#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM && + __GNUC__ && __ia64__ */ + +#if !defined(HAVE_HARDCLOCK) && defined(_MSC_VER) && \ + !defined(EFIX64) && !defined(EFI32) + +#define HAVE_HARDCLOCK + +unsigned long mbedtls_timing_hardclock( void ) +{ + LARGE_INTEGER offset; + + QueryPerformanceCounter( &offset ); + + return( (unsigned long)( offset.QuadPart ) ); +} +#endif /* !HAVE_HARDCLOCK && _MSC_VER && !EFIX64 && !EFI32 */ + +#if !defined(HAVE_HARDCLOCK) + +#define HAVE_HARDCLOCK + +static int hardclock_init = 0; +static struct timeval tv_init; + +unsigned long mbedtls_timing_hardclock( void ) +{ + struct timeval tv_cur; + + if( hardclock_init == 0 ) + { + gettimeofday( &tv_init, NULL ); + hardclock_init = 1; + } + + gettimeofday( &tv_cur, NULL ); + return( ( tv_cur.tv_sec - tv_init.tv_sec ) * 1000000 + + ( tv_cur.tv_usec - tv_init.tv_usec ) ); +} +#endif /* !HAVE_HARDCLOCK */ + +volatile int mbedtls_timing_alarmed = 0; + +#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) + +unsigned long mbedtls_timing_get_timer( struct mbedtls_timing_hr_time *val, int reset ) +{ + struct _hr_time *t = (struct _hr_time *) val; + + if( reset ) + { + 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 ); + } +} + +/* It's OK to use a global because alarm() is supposed to be global anyway */ +static DWORD alarmMs; + +static void TimerProc( void *TimerContext ) +{ + (void) TimerContext; + Sleep( alarmMs ); + mbedtls_timing_alarmed = 1; + /* _endthread will be called implicitly on return + * That ensures execution of thread funcition's epilogue */ +} + +void mbedtls_set_alarm( int seconds ) +{ + 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; + alarmMs = seconds * 1000; + (void) _beginthread( TimerProc, 0, NULL ); +} + +#else /* _WIN32 && !EFIX64 && !EFI32 */ + +unsigned long mbedtls_timing_get_timer( struct mbedtls_timing_hr_time *val, int reset ) +{ + struct _hr_time *t = (struct _hr_time *) val; + + if( reset ) + { + gettimeofday( &t->start, NULL ); + return( 0 ); + } + else + { + 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 ); + } +} + +static void sighandler( int signum ) +{ + mbedtls_timing_alarmed = 1; + signal( signum, sighandler ); +} + +void mbedtls_set_alarm( int seconds ) +{ + mbedtls_timing_alarmed = 0; + signal( SIGALRM, sighandler ); + 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 */ + +/* + * Set delays to watch + */ +void mbedtls_timing_set_delay( void *data, uint32_t int_ms, uint32_t fin_ms ) +{ + mbedtls_timing_delay_context *ctx = (mbedtls_timing_delay_context *) data; + + ctx->int_ms = int_ms; + ctx->fin_ms = fin_ms; + + if( fin_ms != 0 ) + (void) mbedtls_timing_get_timer( &ctx->timer, 1 ); +} + +/* + * Get number of delays expired + */ +int mbedtls_timing_get_delay( void *data ) +{ + mbedtls_timing_delay_context *ctx = (mbedtls_timing_delay_context *) data; + unsigned long elapsed_ms; + + if( ctx->fin_ms == 0 ) + return( -1 ); + + elapsed_ms = mbedtls_timing_get_timer( &ctx->timer, 0 ); + + if( elapsed_ms >= ctx->fin_ms ) + return( 2 ); + + if( elapsed_ms >= ctx->int_ms ) + return( 1 ); + + return( 0 ); +} + +#endif /* !MBEDTLS_TIMING_ALT */ + +#if defined(MBEDTLS_SELF_TEST) + +/* + * Busy-waits for the given number of milliseconds. + * Used for testing mbedtls_timing_hardclock. + */ +static void busy_msleep( unsigned long msec ) +{ + struct mbedtls_timing_hr_time hires; + unsigned long i = 0; /* for busy-waiting */ + volatile unsigned long j; /* to prevent optimisation */ + + (void) mbedtls_timing_get_timer( &hires, 1 ); + + while( mbedtls_timing_get_timer( &hires, 0 ) < msec ) + i++; + + j = i; + (void) j; +} + +#define FAIL do \ + { \ + if( verbose != 0 ) \ + { \ + 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 ); \ + } while( 0 ) + +/* + * Checkup routine + * + * Warning: this is work in progress, some tests may not be reliable enough + * yet! False positives may happen. + */ +int mbedtls_timing_self_test( int verbose ) +{ + unsigned long cycles = 0, ratio = 0; + unsigned long millisecs = 0, secs = 0; + int hardfail = 0; + struct mbedtls_timing_hr_time hires; + uint32_t a = 0, b = 0; + mbedtls_timing_delay_context ctx; + + if( verbose != 0 ) + mbedtls_printf( " TIMING tests note: will take some time!\n" ); + + if( verbose != 0 ) + mbedtls_printf( " TIMING test #1 (set_alarm / get_timer): " ); + + { + secs = 1; + + (void) mbedtls_timing_get_timer( &hires, 1 ); + + mbedtls_set_alarm( (int) secs ); + while( !mbedtls_timing_alarmed ) + ; + + millisecs = mbedtls_timing_get_timer( &hires, 0 ); + + /* For some reason on Windows it looks like alarm has an extra delay + * (maybe related to creating a new thread). Allow some room here. */ + if( millisecs < 800 * secs || millisecs > 1200 * secs + 300 ) + FAIL; + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + + if( verbose != 0 ) + mbedtls_printf( " TIMING test #2 (set/get_delay ): " ); + + { + a = 800; + b = 400; + mbedtls_timing_set_delay( &ctx, a, a + b ); /* T = 0 */ + + busy_msleep( a - a / 4 ); /* T = a - a/4 */ + if( mbedtls_timing_get_delay( &ctx ) != 0 ) + FAIL; + + busy_msleep( a / 4 + b / 4 ); /* T = a + b/4 */ + if( mbedtls_timing_get_delay( &ctx ) != 1 ) + FAIL; + + busy_msleep( b ); /* T = a + b + b/4 */ + if( mbedtls_timing_get_delay( &ctx ) != 2 ) + FAIL; + } + + mbedtls_timing_set_delay( &ctx, 0, 0 ); + busy_msleep( 200 ); + if( mbedtls_timing_get_delay( &ctx ) != -1 ) + FAIL; + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + + if( verbose != 0 ) + mbedtls_printf( " TIMING test #3 (hardclock / get_timer): " ); + + /* + * Allow one failure for possible counter wrapping. + * 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. + */ + +hard_test: + if( hardfail > 1 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed (ignored)\n" ); + + goto hard_test_done; + } + + /* Get a reference ratio cycles/ms */ + millisecs = 1; + cycles = mbedtls_timing_hardclock(); + busy_msleep( millisecs ); + cycles = mbedtls_timing_hardclock() - cycles; + ratio = cycles / millisecs; + + /* Check that the ratio is mostly constant */ + for( millisecs = 2; millisecs <= 4; millisecs++ ) + { + cycles = mbedtls_timing_hardclock(); + busy_msleep( millisecs ); + cycles = mbedtls_timing_hardclock() - cycles; + + /* Allow variation up to 20% */ + if( cycles / millisecs < ratio - ratio / 5 || + cycles / millisecs > ratio + ratio / 5 ) + { + hardfail++; + goto hard_test; + } + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + +hard_test_done: + + if( verbose != 0 ) + mbedtls_printf( "\n" ); + + return( 0 ); +} + +#endif /* MBEDTLS_SELF_TEST */ + +#endif /* MBEDTLS_TIMING_C */ diff --git a/APP_Framework/Framework/security/mbedtls/timing.h b/APP_Framework/Framework/security/mbedtls/timing.h index a965fe0d3..2c497bf4e 100644 --- a/APP_Framework/Framework/security/mbedtls/timing.h +++ b/APP_Framework/Framework/security/mbedtls/timing.h @@ -30,16 +30,16 @@ #include MBEDTLS_CONFIG_FILE #endif +#if !defined(MBEDTLS_TIMING_ALT) +// Regular implementation +// + #include #ifdef __cplusplus extern "C" { #endif -#if !defined(MBEDTLS_TIMING_ALT) -// Regular implementation -// - /** * \brief timer structure */ @@ -51,17 +51,13 @@ struct mbedtls_timing_hr_time /** * \brief Context for mbedtls_timing_set/get_delay() */ -typedef struct mbedtls_timing_delay_context +typedef struct { struct mbedtls_timing_hr_time timer; uint32_t int_ms; uint32_t fin_ms; } mbedtls_timing_delay_context; -#else /* MBEDTLS_TIMING_ALT */ -#include "timing_alt.h" -#endif /* MBEDTLS_TIMING_ALT */ - extern volatile int mbedtls_timing_alarmed; /** @@ -137,6 +133,18 @@ void mbedtls_timing_set_delay( void *data, uint32_t int_ms, uint32_t fin_ms ); */ int mbedtls_timing_get_delay( void *data ); +#ifdef __cplusplus +} +#endif + +#else /* MBEDTLS_TIMING_ALT */ +#include "timing_alt.h" +#endif /* MBEDTLS_TIMING_ALT */ + +#ifdef __cplusplus +extern "C" { +#endif + #if defined(MBEDTLS_SELF_TEST) /** * \brief Checkup routine diff --git a/APP_Framework/Framework/security/mbedtls/timing_alt.c b/APP_Framework/Framework/security/mbedtls/timing_alt.c new file mode 100644 index 000000000..ddc073db3 --- /dev/null +++ b/APP_Framework/Framework/security/mbedtls/timing_alt.c @@ -0,0 +1,153 @@ +/* + * Portable interface to the CPU cycle counter + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#define mbedtls_printf printf +#endif + +#if defined(MBEDTLS_TIMING_C) + +#include "timing_alt.h" +#include +#include +#include +#if RT_VER_NUM >= 0x40004 +#include +#include +#else +#include +#include +#endif + +#ifdef _WIN32 +#define SIGALRM 14 +#endif + +struct _hr_time +{ + struct timeval start; +}; + +static int hardclock_init = 0; +static struct timeval tv_init; + +unsigned long mbedtls_timing_hardclock( void ) +{ + struct timeval tv_cur; + + if( hardclock_init == 0 ) + { + gettimeofday( &tv_init, NULL ); + hardclock_init = 1; + } + + gettimeofday( &tv_cur, NULL ); + return( ( tv_cur.tv_sec - tv_init.tv_sec ) * 1000000 + + ( tv_cur.tv_usec - tv_init.tv_usec ) ); +} + +volatile int mbedtls_timing_alarmed = 0; + +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; + + gettimeofday( &offset, NULL ); + + if( reset ) + { + t->start.tv_sec = offset.tv_sec; + t->start.tv_usec = offset.tv_usec; + return( 0 ); + } + + delta = ( offset.tv_sec - t->start.tv_sec ) * 1000 + + ( offset.tv_usec - t->start.tv_usec ) / 1000; + + return( delta ); +} + +static void sighandler( int signum ) +{ + mbedtls_timing_alarmed = 1; + signal( signum, sighandler ); +} + +unsigned int alarm(unsigned int seconds) +{ + return 0; +} + +void mbedtls_set_alarm( int seconds ) +{ + mbedtls_timing_alarmed = 0; + signal( SIGALRM, sighandler ); + alarm( seconds ); +} + +/* + * Set delays to watch + */ +void mbedtls_timing_set_delay( void *data, uint32_t int_ms, uint32_t fin_ms ) +{ + mbedtls_timing_delay_context *ctx = (mbedtls_timing_delay_context *) data; + + ctx->int_ms = int_ms; + ctx->fin_ms = fin_ms; + + if( fin_ms != 0 ) + (void) mbedtls_timing_get_timer( &ctx->timer, 1 ); +} + +/* + * Get number of delays expired + */ +int mbedtls_timing_get_delay( void *data ) +{ + mbedtls_timing_delay_context *ctx = (mbedtls_timing_delay_context *) data; + unsigned long elapsed_ms; + + if( ctx->fin_ms == 0 ) + return( -1 ); + + elapsed_ms = mbedtls_timing_get_timer( &ctx->timer, 0 ); + + if( elapsed_ms >= ctx->fin_ms ) + return( 2 ); + + if( elapsed_ms >= ctx->int_ms ) + return( 1 ); + + return( 0 ); +} + +#endif /* MBEDTLS_TIMING_C */ diff --git a/APP_Framework/Framework/security/mbedtls/timing_alt.h b/APP_Framework/Framework/security/mbedtls/timing_alt.h new file mode 100644 index 000000000..70f220070 --- /dev/null +++ b/APP_Framework/Framework/security/mbedtls/timing_alt.h @@ -0,0 +1,139 @@ +/** + * \file timing_alt.h + * + * \brief Portable interface to the CPU cycle counter + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +#ifndef MBEDTLS_TIMING_ALT_H +#define MBEDTLS_TIMING_ALT_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_TIMING_ALT) +// Regular implementation +// + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief timer structure + */ +struct mbedtls_timing_hr_time +{ + unsigned char opaque[32]; +}; + +/** + * \brief Context for mbedtls_timing_set/get_delay() + */ +typedef struct +{ + struct mbedtls_timing_hr_time timer; + uint32_t int_ms; + uint32_t fin_ms; +} mbedtls_timing_delay_context; + +extern volatile int mbedtls_timing_alarmed; + +/** + * \brief Return the CPU cycle counter value + * + * \warning This is only a best effort! Do not rely on this! + * In particular, it is known to be unreliable on virtual + * machines. + */ +unsigned long mbedtls_timing_hardclock( void ); + +/** + * \brief Return the elapsed time in milliseconds + * + * \param val points to a timer structure + * \param reset if set to 1, the timer is restarted + */ +unsigned long mbedtls_timing_get_timer( struct mbedtls_timing_hr_time *val, int reset ); + +/** + * \brief Setup an alarm clock + * + * \param seconds delay before the "mbedtls_timing_alarmed" flag is set + * + * \warning Only one alarm at a time is supported. In a threaded + * context, this means one for the whole process, not one per + * thread. + */ +void mbedtls_set_alarm( int seconds ); + +/** + * \brief Set a pair of delays to watch + * (See \c mbedtls_timing_get_delay().) + * + * \param data Pointer to timing data + * Must point to a valid \c mbedtls_timing_delay_context struct. + * \param int_ms First (intermediate) delay in milliseconds. + * \param fin_ms Second (final) delay in milliseconds. + * Pass 0 to cancel the current delay. + */ +void mbedtls_timing_set_delay( void *data, uint32_t int_ms, uint32_t fin_ms ); + +/** + * \brief Get the status of delays + * (Memory helper: number of delays passed.) + * + * \param data Pointer to timing data + * Must point to a valid \c mbedtls_timing_delay_context struct. + * + * \return -1 if cancelled (fin_ms = 0) + * 0 if none of the delays are passed, + * 1 if only the intermediate delay is passed, + * 2 if the final delay is passed. + */ +int mbedtls_timing_get_delay( void *data ); + +#ifdef __cplusplus +} +#endif + +#endif /* MBEDTLS_TIMING_ALT */ + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(MBEDTLS_SELF_TEST) +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if a test failed + */ +int mbedtls_timing_self_test( int verbose ); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* timing.h */ diff --git a/APP_Framework/Framework/security/mbedtls/tls_hardware.c b/APP_Framework/Framework/security/mbedtls/tls_hardware.c new file mode 100644 index 000000000..44f7bb3f7 --- /dev/null +++ b/APP_Framework/Framework/security/mbedtls/tls_hardware.c @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include +#include +#include + +#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT) + +static int os_get_random(unsigned char *buf, size_t len) +{ + int i, j; + unsigned long tmp; + + for (i = 0; i < ((len + 3) & ~3) / 4; i++) + { + tmp = rand(); + + for (j = 0; j < 4; j++) + { + if ((i * 4 + j) < len) + { + buf[i * 4 + j] = (unsigned char)(tmp >> (j * 8)); + } + else + { + break; + } + } + } + + return 0; +} + +int mbedtls_hardware_poll( void *data, unsigned char *output, size_t len, size_t *olen ) +{ + os_get_random(output, len); + *olen = len; + + return 0; +} +#endif + diff --git a/APP_Framework/Framework/security/mbedtls/version.c b/APP_Framework/Framework/security/mbedtls/version.c new file mode 100644 index 000000000..9788e793b --- /dev/null +++ b/APP_Framework/Framework/security/mbedtls/version.c @@ -0,0 +1,50 @@ +/* + * Version information + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_VERSION_C) + +#include "version.h" +#include + +unsigned int mbedtls_version_get_number() +{ + return( MBEDTLS_VERSION_NUMBER ); +} + +void mbedtls_version_get_string( char *string ) +{ + memcpy( string, MBEDTLS_VERSION_STRING, + sizeof( MBEDTLS_VERSION_STRING ) ); +} + +void mbedtls_version_get_string_full( char *string ) +{ + memcpy( string, MBEDTLS_VERSION_STRING_FULL, + sizeof( MBEDTLS_VERSION_STRING_FULL ) ); +} + +#endif /* MBEDTLS_VERSION_C */ diff --git a/APP_Framework/Framework/security/mbedtls/version.h b/APP_Framework/Framework/security/mbedtls/version.h index e0a2e7f6d..715bf21a7 100644 --- a/APP_Framework/Framework/security/mbedtls/version.h +++ b/APP_Framework/Framework/security/mbedtls/version.h @@ -39,17 +39,17 @@ * Major, Minor, Patchlevel */ #define MBEDTLS_VERSION_MAJOR 2 -#define MBEDTLS_VERSION_MINOR 16 -#define MBEDTLS_VERSION_PATCH 6 +#define MBEDTLS_VERSION_MINOR 7 +#define MBEDTLS_VERSION_PATCH 10 /** * The single version number has the following structure: * MMNNPP00 * Major version | Minor version | Patch version */ -#define MBEDTLS_VERSION_NUMBER 0x02100600 -#define MBEDTLS_VERSION_STRING "2.16.6" -#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.16.6" +#define MBEDTLS_VERSION_NUMBER 0x02070A00 +#define MBEDTLS_VERSION_STRING "2.7.10" +#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.7.10" #if defined(MBEDTLS_VERSION_C) diff --git a/APP_Framework/Framework/security/mbedtls/version_features.c b/APP_Framework/Framework/security/mbedtls/version_features.c new file mode 100644 index 000000000..dd4cf03ad --- /dev/null +++ b/APP_Framework/Framework/security/mbedtls/version_features.c @@ -0,0 +1,722 @@ +/* + * Version feature information + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_VERSION_C) + +#include "version.h" + +#include + +static const char *features[] = { +#if defined(MBEDTLS_VERSION_FEATURES) +#if defined(MBEDTLS_HAVE_ASM) + "MBEDTLS_HAVE_ASM", +#endif /* MBEDTLS_HAVE_ASM */ +#if defined(MBEDTLS_NO_UDBL_DIVISION) + "MBEDTLS_NO_UDBL_DIVISION", +#endif /* MBEDTLS_NO_UDBL_DIVISION */ +#if defined(MBEDTLS_HAVE_SSE2) + "MBEDTLS_HAVE_SSE2", +#endif /* MBEDTLS_HAVE_SSE2 */ +#if defined(MBEDTLS_HAVE_TIME) + "MBEDTLS_HAVE_TIME", +#endif /* MBEDTLS_HAVE_TIME */ +#if defined(MBEDTLS_HAVE_TIME_DATE) + "MBEDTLS_HAVE_TIME_DATE", +#endif /* MBEDTLS_HAVE_TIME_DATE */ +#if defined(MBEDTLS_PLATFORM_MEMORY) + "MBEDTLS_PLATFORM_MEMORY", +#endif /* MBEDTLS_PLATFORM_MEMORY */ +#if defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) + "MBEDTLS_PLATFORM_NO_STD_FUNCTIONS", +#endif /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */ +#if defined(MBEDTLS_PLATFORM_EXIT_ALT) + "MBEDTLS_PLATFORM_EXIT_ALT", +#endif /* MBEDTLS_PLATFORM_EXIT_ALT */ +#if defined(MBEDTLS_PLATFORM_TIME_ALT) + "MBEDTLS_PLATFORM_TIME_ALT", +#endif /* MBEDTLS_PLATFORM_TIME_ALT */ +#if defined(MBEDTLS_PLATFORM_FPRINTF_ALT) + "MBEDTLS_PLATFORM_FPRINTF_ALT", +#endif /* MBEDTLS_PLATFORM_FPRINTF_ALT */ +#if defined(MBEDTLS_PLATFORM_PRINTF_ALT) + "MBEDTLS_PLATFORM_PRINTF_ALT", +#endif /* MBEDTLS_PLATFORM_PRINTF_ALT */ +#if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) + "MBEDTLS_PLATFORM_SNPRINTF_ALT", +#endif /* MBEDTLS_PLATFORM_SNPRINTF_ALT */ +#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT) + "MBEDTLS_PLATFORM_NV_SEED_ALT", +#endif /* MBEDTLS_PLATFORM_NV_SEED_ALT */ +#if defined(MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT) + "MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT", +#endif /* MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT */ +#if defined(MBEDTLS_DEPRECATED_WARNING) + "MBEDTLS_DEPRECATED_WARNING", +#endif /* MBEDTLS_DEPRECATED_WARNING */ +#if defined(MBEDTLS_DEPRECATED_REMOVED) + "MBEDTLS_DEPRECATED_REMOVED", +#endif /* MBEDTLS_DEPRECATED_REMOVED */ +#if defined(MBEDTLS_TIMING_ALT) + "MBEDTLS_TIMING_ALT", +#endif /* MBEDTLS_TIMING_ALT */ +#if defined(MBEDTLS_AES_ALT) + "MBEDTLS_AES_ALT", +#endif /* MBEDTLS_AES_ALT */ +#if defined(MBEDTLS_ARC4_ALT) + "MBEDTLS_ARC4_ALT", +#endif /* MBEDTLS_ARC4_ALT */ +#if defined(MBEDTLS_BLOWFISH_ALT) + "MBEDTLS_BLOWFISH_ALT", +#endif /* MBEDTLS_BLOWFISH_ALT */ +#if defined(MBEDTLS_CAMELLIA_ALT) + "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) + "MBEDTLS_DES_ALT", +#endif /* MBEDTLS_DES_ALT */ +#if defined(MBEDTLS_DHM_ALT) + "MBEDTLS_DHM_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) + "MBEDTLS_MD2_ALT", +#endif /* MBEDTLS_MD2_ALT */ +#if defined(MBEDTLS_MD4_ALT) + "MBEDTLS_MD4_ALT", +#endif /* MBEDTLS_MD4_ALT */ +#if defined(MBEDTLS_MD5_ALT) + "MBEDTLS_MD5_ALT", +#endif /* MBEDTLS_MD5_ALT */ +#if defined(MBEDTLS_RIPEMD160_ALT) + "MBEDTLS_RIPEMD160_ALT", +#endif /* MBEDTLS_RIPEMD160_ALT */ +#if defined(MBEDTLS_RSA_ALT) + "MBEDTLS_RSA_ALT", +#endif /* MBEDTLS_RSA_ALT */ +#if defined(MBEDTLS_SHA1_ALT) + "MBEDTLS_SHA1_ALT", +#endif /* MBEDTLS_SHA1_ALT */ +#if defined(MBEDTLS_SHA256_ALT) + "MBEDTLS_SHA256_ALT", +#endif /* MBEDTLS_SHA256_ALT */ +#if defined(MBEDTLS_SHA512_ALT) + "MBEDTLS_SHA512_ALT", +#endif /* MBEDTLS_SHA512_ALT */ +#if defined(MBEDTLS_XTEA_ALT) + "MBEDTLS_XTEA_ALT", +#endif /* MBEDTLS_XTEA_ALT */ +#if defined(MBEDTLS_ECP_ALT) + "MBEDTLS_ECP_ALT", +#endif /* MBEDTLS_ECP_ALT */ +#if defined(MBEDTLS_MD2_PROCESS_ALT) + "MBEDTLS_MD2_PROCESS_ALT", +#endif /* MBEDTLS_MD2_PROCESS_ALT */ +#if defined(MBEDTLS_MD4_PROCESS_ALT) + "MBEDTLS_MD4_PROCESS_ALT", +#endif /* MBEDTLS_MD4_PROCESS_ALT */ +#if defined(MBEDTLS_MD5_PROCESS_ALT) + "MBEDTLS_MD5_PROCESS_ALT", +#endif /* MBEDTLS_MD5_PROCESS_ALT */ +#if defined(MBEDTLS_RIPEMD160_PROCESS_ALT) + "MBEDTLS_RIPEMD160_PROCESS_ALT", +#endif /* MBEDTLS_RIPEMD160_PROCESS_ALT */ +#if defined(MBEDTLS_SHA1_PROCESS_ALT) + "MBEDTLS_SHA1_PROCESS_ALT", +#endif /* MBEDTLS_SHA1_PROCESS_ALT */ +#if defined(MBEDTLS_SHA256_PROCESS_ALT) + "MBEDTLS_SHA256_PROCESS_ALT", +#endif /* MBEDTLS_SHA256_PROCESS_ALT */ +#if defined(MBEDTLS_SHA512_PROCESS_ALT) + "MBEDTLS_SHA512_PROCESS_ALT", +#endif /* MBEDTLS_SHA512_PROCESS_ALT */ +#if defined(MBEDTLS_DES_SETKEY_ALT) + "MBEDTLS_DES_SETKEY_ALT", +#endif /* MBEDTLS_DES_SETKEY_ALT */ +#if defined(MBEDTLS_DES_CRYPT_ECB_ALT) + "MBEDTLS_DES_CRYPT_ECB_ALT", +#endif /* MBEDTLS_DES_CRYPT_ECB_ALT */ +#if defined(MBEDTLS_DES3_CRYPT_ECB_ALT) + "MBEDTLS_DES3_CRYPT_ECB_ALT", +#endif /* MBEDTLS_DES3_CRYPT_ECB_ALT */ +#if defined(MBEDTLS_AES_SETKEY_ENC_ALT) + "MBEDTLS_AES_SETKEY_ENC_ALT", +#endif /* MBEDTLS_AES_SETKEY_ENC_ALT */ +#if defined(MBEDTLS_AES_SETKEY_DEC_ALT) + "MBEDTLS_AES_SETKEY_DEC_ALT", +#endif /* MBEDTLS_AES_SETKEY_DEC_ALT */ +#if defined(MBEDTLS_AES_ENCRYPT_ALT) + "MBEDTLS_AES_ENCRYPT_ALT", +#endif /* MBEDTLS_AES_ENCRYPT_ALT */ +#if defined(MBEDTLS_AES_DECRYPT_ALT) + "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) + "MBEDTLS_ECP_INTERNAL_ALT", +#endif /* MBEDTLS_ECP_INTERNAL_ALT */ +#if defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT) + "MBEDTLS_ECP_RANDOMIZE_JAC_ALT", +#endif /* MBEDTLS_ECP_RANDOMIZE_JAC_ALT */ +#if defined(MBEDTLS_ECP_ADD_MIXED_ALT) + "MBEDTLS_ECP_ADD_MIXED_ALT", +#endif /* MBEDTLS_ECP_ADD_MIXED_ALT */ +#if defined(MBEDTLS_ECP_DOUBLE_JAC_ALT) + "MBEDTLS_ECP_DOUBLE_JAC_ALT", +#endif /* MBEDTLS_ECP_DOUBLE_JAC_ALT */ +#if defined(MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT) + "MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT", +#endif /* MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT */ +#if defined(MBEDTLS_ECP_NORMALIZE_JAC_ALT) + "MBEDTLS_ECP_NORMALIZE_JAC_ALT", +#endif /* MBEDTLS_ECP_NORMALIZE_JAC_ALT */ +#if defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT) + "MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT", +#endif /* MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT */ +#if defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT) + "MBEDTLS_ECP_RANDOMIZE_MXZ_ALT", +#endif /* MBEDTLS_ECP_RANDOMIZE_MXZ_ALT */ +#if defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT) + "MBEDTLS_ECP_NORMALIZE_MXZ_ALT", +#endif /* MBEDTLS_ECP_NORMALIZE_MXZ_ALT */ +#if defined(MBEDTLS_TEST_NULL_ENTROPY) + "MBEDTLS_TEST_NULL_ENTROPY", +#endif /* MBEDTLS_TEST_NULL_ENTROPY */ +#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT) + "MBEDTLS_ENTROPY_HARDWARE_ALT", +#endif /* MBEDTLS_ENTROPY_HARDWARE_ALT */ +#if defined(MBEDTLS_AES_ROM_TABLES) + "MBEDTLS_AES_ROM_TABLES", +#endif /* MBEDTLS_AES_ROM_TABLES */ +#if defined(MBEDTLS_CAMELLIA_SMALL_MEMORY) + "MBEDTLS_CAMELLIA_SMALL_MEMORY", +#endif /* MBEDTLS_CAMELLIA_SMALL_MEMORY */ +#if defined(MBEDTLS_CIPHER_MODE_CBC) + "MBEDTLS_CIPHER_MODE_CBC", +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#if defined(MBEDTLS_CIPHER_MODE_CFB) + "MBEDTLS_CIPHER_MODE_CFB", +#endif /* MBEDTLS_CIPHER_MODE_CFB */ +#if defined(MBEDTLS_CIPHER_MODE_CTR) + "MBEDTLS_CIPHER_MODE_CTR", +#endif /* MBEDTLS_CIPHER_MODE_CTR */ +#if defined(MBEDTLS_CIPHER_NULL_CIPHER) + "MBEDTLS_CIPHER_NULL_CIPHER", +#endif /* MBEDTLS_CIPHER_NULL_CIPHER */ +#if defined(MBEDTLS_CIPHER_PADDING_PKCS7) + "MBEDTLS_CIPHER_PADDING_PKCS7", +#endif /* MBEDTLS_CIPHER_PADDING_PKCS7 */ +#if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS) + "MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS", +#endif /* MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS */ +#if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN) + "MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN", +#endif /* MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN */ +#if defined(MBEDTLS_CIPHER_PADDING_ZEROS) + "MBEDTLS_CIPHER_PADDING_ZEROS", +#endif /* MBEDTLS_CIPHER_PADDING_ZEROS */ +#if defined(MBEDTLS_ENABLE_WEAK_CIPHERSUITES) + "MBEDTLS_ENABLE_WEAK_CIPHERSUITES", +#endif /* MBEDTLS_ENABLE_WEAK_CIPHERSUITES */ +#if defined(MBEDTLS_REMOVE_ARC4_CIPHERSUITES) + "MBEDTLS_REMOVE_ARC4_CIPHERSUITES", +#endif /* MBEDTLS_REMOVE_ARC4_CIPHERSUITES */ +#if defined(MBEDTLS_REMOVE_3DES_CIPHERSUITES) + "MBEDTLS_REMOVE_3DES_CIPHERSUITES", +#endif /* MBEDTLS_REMOVE_3DES_CIPHERSUITES */ +#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) + "MBEDTLS_ECP_DP_SECP192R1_ENABLED", +#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */ +#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) + "MBEDTLS_ECP_DP_SECP224R1_ENABLED", +#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */ +#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) + "MBEDTLS_ECP_DP_SECP256R1_ENABLED", +#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */ +#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) + "MBEDTLS_ECP_DP_SECP384R1_ENABLED", +#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */ +#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) + "MBEDTLS_ECP_DP_SECP521R1_ENABLED", +#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */ +#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) + "MBEDTLS_ECP_DP_SECP192K1_ENABLED", +#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */ +#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) + "MBEDTLS_ECP_DP_SECP224K1_ENABLED", +#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */ +#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) + "MBEDTLS_ECP_DP_SECP256K1_ENABLED", +#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */ +#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) + "MBEDTLS_ECP_DP_BP256R1_ENABLED", +#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */ +#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) + "MBEDTLS_ECP_DP_BP384R1_ENABLED", +#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */ +#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) + "MBEDTLS_ECP_DP_BP512R1_ENABLED", +#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */ +#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) + "MBEDTLS_ECP_DP_CURVE25519_ENABLED", +#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */ +#if defined(MBEDTLS_ECP_NIST_OPTIM) + "MBEDTLS_ECP_NIST_OPTIM", +#endif /* MBEDTLS_ECP_NIST_OPTIM */ +#if defined(MBEDTLS_ECDSA_DETERMINISTIC) + "MBEDTLS_ECDSA_DETERMINISTIC", +#endif /* MBEDTLS_ECDSA_DETERMINISTIC */ +#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) + "MBEDTLS_KEY_EXCHANGE_PSK_ENABLED", +#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */ +#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) + "MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED", +#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ +#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) + "MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED", +#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ +#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) + "MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED", +#endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ +#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) + "MBEDTLS_KEY_EXCHANGE_RSA_ENABLED", +#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */ +#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) + "MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED", +#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */ +#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) + "MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED", +#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED */ +#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) + "MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED", +#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ +#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) + "MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED", +#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ +#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) + "MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED", +#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED */ +#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) + "MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED", +#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ +#if defined(MBEDTLS_PK_PARSE_EC_EXTENDED) + "MBEDTLS_PK_PARSE_EC_EXTENDED", +#endif /* MBEDTLS_PK_PARSE_EC_EXTENDED */ +#if defined(MBEDTLS_ERROR_STRERROR_DUMMY) + "MBEDTLS_ERROR_STRERROR_DUMMY", +#endif /* MBEDTLS_ERROR_STRERROR_DUMMY */ +#if defined(MBEDTLS_GENPRIME) + "MBEDTLS_GENPRIME", +#endif /* MBEDTLS_GENPRIME */ +#if defined(MBEDTLS_FS_IO) + "MBEDTLS_FS_IO", +#endif /* MBEDTLS_FS_IO */ +#if defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES) + "MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES", +#endif /* MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES */ +#if defined(MBEDTLS_NO_PLATFORM_ENTROPY) + "MBEDTLS_NO_PLATFORM_ENTROPY", +#endif /* MBEDTLS_NO_PLATFORM_ENTROPY */ +#if defined(MBEDTLS_ENTROPY_FORCE_SHA256) + "MBEDTLS_ENTROPY_FORCE_SHA256", +#endif /* MBEDTLS_ENTROPY_FORCE_SHA256 */ +#if defined(MBEDTLS_ENTROPY_NV_SEED) + "MBEDTLS_ENTROPY_NV_SEED", +#endif /* MBEDTLS_ENTROPY_NV_SEED */ +#if defined(MBEDTLS_MEMORY_DEBUG) + "MBEDTLS_MEMORY_DEBUG", +#endif /* MBEDTLS_MEMORY_DEBUG */ +#if defined(MBEDTLS_MEMORY_BACKTRACE) + "MBEDTLS_MEMORY_BACKTRACE", +#endif /* MBEDTLS_MEMORY_BACKTRACE */ +#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) + "MBEDTLS_PK_RSA_ALT_SUPPORT", +#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */ +#if defined(MBEDTLS_PKCS1_V15) + "MBEDTLS_PKCS1_V15", +#endif /* MBEDTLS_PKCS1_V15 */ +#if defined(MBEDTLS_PKCS1_V21) + "MBEDTLS_PKCS1_V21", +#endif /* MBEDTLS_PKCS1_V21 */ +#if defined(MBEDTLS_RSA_NO_CRT) + "MBEDTLS_RSA_NO_CRT", +#endif /* MBEDTLS_RSA_NO_CRT */ +#if defined(MBEDTLS_SELF_TEST) + "MBEDTLS_SELF_TEST", +#endif /* MBEDTLS_SELF_TEST */ +#if defined(MBEDTLS_SHA256_SMALLER) + "MBEDTLS_SHA256_SMALLER", +#endif /* MBEDTLS_SHA256_SMALLER */ +#if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES) + "MBEDTLS_SSL_ALL_ALERT_MESSAGES", +#endif /* MBEDTLS_SSL_ALL_ALERT_MESSAGES */ +#if defined(MBEDTLS_SSL_DEBUG_ALL) + "MBEDTLS_SSL_DEBUG_ALL", +#endif /* MBEDTLS_SSL_DEBUG_ALL */ +#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) + "MBEDTLS_SSL_ENCRYPT_THEN_MAC", +#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ +#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) + "MBEDTLS_SSL_EXTENDED_MASTER_SECRET", +#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ +#if defined(MBEDTLS_SSL_FALLBACK_SCSV) + "MBEDTLS_SSL_FALLBACK_SCSV", +#endif /* MBEDTLS_SSL_FALLBACK_SCSV */ +#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) + "MBEDTLS_SSL_HW_RECORD_ACCEL", +#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */ +#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) + "MBEDTLS_SSL_CBC_RECORD_SPLITTING", +#endif /* MBEDTLS_SSL_CBC_RECORD_SPLITTING */ +#if defined(MBEDTLS_SSL_RENEGOTIATION) + "MBEDTLS_SSL_RENEGOTIATION", +#endif /* MBEDTLS_SSL_RENEGOTIATION */ +#if defined(MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO) + "MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO", +#endif /* MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO */ +#if defined(MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE) + "MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE", +#endif /* MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE */ +#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) + "MBEDTLS_SSL_MAX_FRAGMENT_LENGTH", +#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ +#if defined(MBEDTLS_SSL_PROTO_SSL3) + "MBEDTLS_SSL_PROTO_SSL3", +#endif /* MBEDTLS_SSL_PROTO_SSL3 */ +#if defined(MBEDTLS_SSL_PROTO_TLS1) + "MBEDTLS_SSL_PROTO_TLS1", +#endif /* MBEDTLS_SSL_PROTO_TLS1 */ +#if defined(MBEDTLS_SSL_PROTO_TLS1_1) + "MBEDTLS_SSL_PROTO_TLS1_1", +#endif /* MBEDTLS_SSL_PROTO_TLS1_1 */ +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) + "MBEDTLS_SSL_PROTO_TLS1_2", +#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ +#if defined(MBEDTLS_SSL_PROTO_DTLS) + "MBEDTLS_SSL_PROTO_DTLS", +#endif /* MBEDTLS_SSL_PROTO_DTLS */ +#if defined(MBEDTLS_SSL_ALPN) + "MBEDTLS_SSL_ALPN", +#endif /* MBEDTLS_SSL_ALPN */ +#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) + "MBEDTLS_SSL_DTLS_ANTI_REPLAY", +#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */ +#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) + "MBEDTLS_SSL_DTLS_HELLO_VERIFY", +#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */ +#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) + "MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE", +#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE */ +#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) + "MBEDTLS_SSL_DTLS_BADMAC_LIMIT", +#endif /* MBEDTLS_SSL_DTLS_BADMAC_LIMIT */ +#if defined(MBEDTLS_SSL_SESSION_TICKETS) + "MBEDTLS_SSL_SESSION_TICKETS", +#endif /* MBEDTLS_SSL_SESSION_TICKETS */ +#if defined(MBEDTLS_SSL_EXPORT_KEYS) + "MBEDTLS_SSL_EXPORT_KEYS", +#endif /* MBEDTLS_SSL_EXPORT_KEYS */ +#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) + "MBEDTLS_SSL_SERVER_NAME_INDICATION", +#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ +#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) + "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) + "MBEDTLS_THREADING_ALT", +#endif /* MBEDTLS_THREADING_ALT */ +#if defined(MBEDTLS_THREADING_PTHREAD) + "MBEDTLS_THREADING_PTHREAD", +#endif /* MBEDTLS_THREADING_PTHREAD */ +#if defined(MBEDTLS_VERSION_FEATURES) + "MBEDTLS_VERSION_FEATURES", +#endif /* MBEDTLS_VERSION_FEATURES */ +#if defined(MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3) + "MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3", +#endif /* MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3 */ +#if defined(MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION) + "MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION", +#endif /* MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION */ +#if defined(MBEDTLS_X509_CHECK_KEY_USAGE) + "MBEDTLS_X509_CHECK_KEY_USAGE", +#endif /* MBEDTLS_X509_CHECK_KEY_USAGE */ +#if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE) + "MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE", +#endif /* MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE */ +#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) + "MBEDTLS_X509_RSASSA_PSS_SUPPORT", +#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */ +#if defined(MBEDTLS_ZLIB_SUPPORT) + "MBEDTLS_ZLIB_SUPPORT", +#endif /* MBEDTLS_ZLIB_SUPPORT */ +#if defined(MBEDTLS_AESNI_C) + "MBEDTLS_AESNI_C", +#endif /* MBEDTLS_AESNI_C */ +#if defined(MBEDTLS_AES_C) + "MBEDTLS_AES_C", +#endif /* MBEDTLS_AES_C */ +#if defined(MBEDTLS_ARC4_C) + "MBEDTLS_ARC4_C", +#endif /* MBEDTLS_ARC4_C */ +#if defined(MBEDTLS_ASN1_PARSE_C) + "MBEDTLS_ASN1_PARSE_C", +#endif /* MBEDTLS_ASN1_PARSE_C */ +#if defined(MBEDTLS_ASN1_WRITE_C) + "MBEDTLS_ASN1_WRITE_C", +#endif /* MBEDTLS_ASN1_WRITE_C */ +#if defined(MBEDTLS_BASE64_C) + "MBEDTLS_BASE64_C", +#endif /* MBEDTLS_BASE64_C */ +#if defined(MBEDTLS_BIGNUM_C) + "MBEDTLS_BIGNUM_C", +#endif /* MBEDTLS_BIGNUM_C */ +#if defined(MBEDTLS_BLOWFISH_C) + "MBEDTLS_BLOWFISH_C", +#endif /* MBEDTLS_BLOWFISH_C */ +#if defined(MBEDTLS_CAMELLIA_C) + "MBEDTLS_CAMELLIA_C", +#endif /* MBEDTLS_CAMELLIA_C */ +#if defined(MBEDTLS_CCM_C) + "MBEDTLS_CCM_C", +#endif /* MBEDTLS_CCM_C */ +#if defined(MBEDTLS_CERTS_C) + "MBEDTLS_CERTS_C", +#endif /* MBEDTLS_CERTS_C */ +#if defined(MBEDTLS_CIPHER_C) + "MBEDTLS_CIPHER_C", +#endif /* MBEDTLS_CIPHER_C */ +#if defined(MBEDTLS_CMAC_C) + "MBEDTLS_CMAC_C", +#endif /* MBEDTLS_CMAC_C */ +#if defined(MBEDTLS_CTR_DRBG_C) + "MBEDTLS_CTR_DRBG_C", +#endif /* MBEDTLS_CTR_DRBG_C */ +#if defined(MBEDTLS_DEBUG_C) + "MBEDTLS_DEBUG_C", +#endif /* MBEDTLS_DEBUG_C */ +#if defined(MBEDTLS_DES_C) + "MBEDTLS_DES_C", +#endif /* MBEDTLS_DES_C */ +#if defined(MBEDTLS_DHM_C) + "MBEDTLS_DHM_C", +#endif /* MBEDTLS_DHM_C */ +#if defined(MBEDTLS_ECDH_C) + "MBEDTLS_ECDH_C", +#endif /* MBEDTLS_ECDH_C */ +#if defined(MBEDTLS_ECDSA_C) + "MBEDTLS_ECDSA_C", +#endif /* MBEDTLS_ECDSA_C */ +#if defined(MBEDTLS_ECJPAKE_C) + "MBEDTLS_ECJPAKE_C", +#endif /* MBEDTLS_ECJPAKE_C */ +#if defined(MBEDTLS_ECP_C) + "MBEDTLS_ECP_C", +#endif /* MBEDTLS_ECP_C */ +#if defined(MBEDTLS_ENTROPY_C) + "MBEDTLS_ENTROPY_C", +#endif /* MBEDTLS_ENTROPY_C */ +#if defined(MBEDTLS_ERROR_C) + "MBEDTLS_ERROR_C", +#endif /* MBEDTLS_ERROR_C */ +#if defined(MBEDTLS_GCM_C) + "MBEDTLS_GCM_C", +#endif /* MBEDTLS_GCM_C */ +#if defined(MBEDTLS_HAVEGE_C) + "MBEDTLS_HAVEGE_C", +#endif /* MBEDTLS_HAVEGE_C */ +#if defined(MBEDTLS_HMAC_DRBG_C) + "MBEDTLS_HMAC_DRBG_C", +#endif /* MBEDTLS_HMAC_DRBG_C */ +#if defined(MBEDTLS_MD_C) + "MBEDTLS_MD_C", +#endif /* MBEDTLS_MD_C */ +#if defined(MBEDTLS_MD2_C) + "MBEDTLS_MD2_C", +#endif /* MBEDTLS_MD2_C */ +#if defined(MBEDTLS_MD4_C) + "MBEDTLS_MD4_C", +#endif /* MBEDTLS_MD4_C */ +#if defined(MBEDTLS_MD5_C) + "MBEDTLS_MD5_C", +#endif /* MBEDTLS_MD5_C */ +#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) + "MBEDTLS_MEMORY_BUFFER_ALLOC_C", +#endif /* MBEDTLS_MEMORY_BUFFER_ALLOC_C */ +#if defined(MBEDTLS_NET_C) + "MBEDTLS_NET_C", +#endif /* MBEDTLS_NET_C */ +#if defined(MBEDTLS_OID_C) + "MBEDTLS_OID_C", +#endif /* MBEDTLS_OID_C */ +#if defined(MBEDTLS_PADLOCK_C) + "MBEDTLS_PADLOCK_C", +#endif /* MBEDTLS_PADLOCK_C */ +#if defined(MBEDTLS_PEM_PARSE_C) + "MBEDTLS_PEM_PARSE_C", +#endif /* MBEDTLS_PEM_PARSE_C */ +#if defined(MBEDTLS_PEM_WRITE_C) + "MBEDTLS_PEM_WRITE_C", +#endif /* MBEDTLS_PEM_WRITE_C */ +#if defined(MBEDTLS_PK_C) + "MBEDTLS_PK_C", +#endif /* MBEDTLS_PK_C */ +#if defined(MBEDTLS_PK_PARSE_C) + "MBEDTLS_PK_PARSE_C", +#endif /* MBEDTLS_PK_PARSE_C */ +#if defined(MBEDTLS_PK_WRITE_C) + "MBEDTLS_PK_WRITE_C", +#endif /* MBEDTLS_PK_WRITE_C */ +#if defined(MBEDTLS_PKCS5_C) + "MBEDTLS_PKCS5_C", +#endif /* MBEDTLS_PKCS5_C */ +#if defined(MBEDTLS_PKCS11_C) + "MBEDTLS_PKCS11_C", +#endif /* MBEDTLS_PKCS11_C */ +#if defined(MBEDTLS_PKCS12_C) + "MBEDTLS_PKCS12_C", +#endif /* MBEDTLS_PKCS12_C */ +#if defined(MBEDTLS_PLATFORM_C) + "MBEDTLS_PLATFORM_C", +#endif /* MBEDTLS_PLATFORM_C */ +#if defined(MBEDTLS_RIPEMD160_C) + "MBEDTLS_RIPEMD160_C", +#endif /* MBEDTLS_RIPEMD160_C */ +#if defined(MBEDTLS_RSA_C) + "MBEDTLS_RSA_C", +#endif /* MBEDTLS_RSA_C */ +#if defined(MBEDTLS_SHA1_C) + "MBEDTLS_SHA1_C", +#endif /* MBEDTLS_SHA1_C */ +#if defined(MBEDTLS_SHA256_C) + "MBEDTLS_SHA256_C", +#endif /* MBEDTLS_SHA256_C */ +#if defined(MBEDTLS_SHA512_C) + "MBEDTLS_SHA512_C", +#endif /* MBEDTLS_SHA512_C */ +#if defined(MBEDTLS_SSL_CACHE_C) + "MBEDTLS_SSL_CACHE_C", +#endif /* MBEDTLS_SSL_CACHE_C */ +#if defined(MBEDTLS_SSL_COOKIE_C) + "MBEDTLS_SSL_COOKIE_C", +#endif /* MBEDTLS_SSL_COOKIE_C */ +#if defined(MBEDTLS_SSL_TICKET_C) + "MBEDTLS_SSL_TICKET_C", +#endif /* MBEDTLS_SSL_TICKET_C */ +#if defined(MBEDTLS_SSL_CLI_C) + "MBEDTLS_SSL_CLI_C", +#endif /* MBEDTLS_SSL_CLI_C */ +#if defined(MBEDTLS_SSL_SRV_C) + "MBEDTLS_SSL_SRV_C", +#endif /* MBEDTLS_SSL_SRV_C */ +#if defined(MBEDTLS_SSL_TLS_C) + "MBEDTLS_SSL_TLS_C", +#endif /* MBEDTLS_SSL_TLS_C */ +#if defined(MBEDTLS_THREADING_C) + "MBEDTLS_THREADING_C", +#endif /* MBEDTLS_THREADING_C */ +#if defined(MBEDTLS_TIMING_C) + "MBEDTLS_TIMING_C", +#endif /* MBEDTLS_TIMING_C */ +#if defined(MBEDTLS_VERSION_C) + "MBEDTLS_VERSION_C", +#endif /* MBEDTLS_VERSION_C */ +#if defined(MBEDTLS_X509_USE_C) + "MBEDTLS_X509_USE_C", +#endif /* MBEDTLS_X509_USE_C */ +#if defined(MBEDTLS_X509_CRT_PARSE_C) + "MBEDTLS_X509_CRT_PARSE_C", +#endif /* MBEDTLS_X509_CRT_PARSE_C */ +#if defined(MBEDTLS_X509_CRL_PARSE_C) + "MBEDTLS_X509_CRL_PARSE_C", +#endif /* MBEDTLS_X509_CRL_PARSE_C */ +#if defined(MBEDTLS_X509_CSR_PARSE_C) + "MBEDTLS_X509_CSR_PARSE_C", +#endif /* MBEDTLS_X509_CSR_PARSE_C */ +#if defined(MBEDTLS_X509_CREATE_C) + "MBEDTLS_X509_CREATE_C", +#endif /* MBEDTLS_X509_CREATE_C */ +#if defined(MBEDTLS_X509_CRT_WRITE_C) + "MBEDTLS_X509_CRT_WRITE_C", +#endif /* MBEDTLS_X509_CRT_WRITE_C */ +#if defined(MBEDTLS_X509_CSR_WRITE_C) + "MBEDTLS_X509_CSR_WRITE_C", +#endif /* MBEDTLS_X509_CSR_WRITE_C */ +#if defined(MBEDTLS_XTEA_C) + "MBEDTLS_XTEA_C", +#endif /* MBEDTLS_XTEA_C */ +#endif /* MBEDTLS_VERSION_FEATURES */ + NULL +}; + +int mbedtls_version_check_feature( const char *feature ) +{ + const char **idx = features; + + if( *idx == NULL ) + return( -2 ); + + if( feature == NULL ) + return( -1 ); + + while( *idx != NULL ) + { + if( !strcmp( *idx, feature ) ) + return( 0 ); + idx++; + } + return( -1 ); +} + +#endif /* MBEDTLS_VERSION_C */ diff --git a/APP_Framework/Framework/security/mbedtls/x509.c b/APP_Framework/Framework/security/mbedtls/x509.c index 3493b712a..56de93e7d 100644 --- a/APP_Framework/Framework/security/mbedtls/x509.c +++ b/APP_Framework/Framework/security/mbedtls/x509.c @@ -38,22 +38,9 @@ #if defined(MBEDTLS_X509_USE_C) #include "x509.h" -#include "x509_internal.h" #include "asn1.h" #include "oid.h" -/* We include x509xxx.c files here so that x509.c is one compilation unit including - * all the x509 files. This is done because some of the internal functions are shared. - * For code size savings internal functions should be static so that compiler can do better job - * when optimizing. We don't wan't x509.c file to get too big so including .c files. - */ -#include "x509_crl.c" -#include "x509_crt.c" -#include "x509_csr.c" -#include "x509_create.c" -#include "x509write_crt.c" -#include "x509write_csr.c" - #include #include @@ -72,28 +59,24 @@ #define mbedtls_snprintf snprintf #endif + #if defined(MBEDTLS_HAVE_TIME) #include "platform_time.h" #endif -#if defined(MBEDTLS_HAVE_TIME_DATE) -#include "platform_util.h" + +#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) +#include +#else #include #endif -#define CHECK(code) if( ( ret = ( code ) ) != 0 ){ return( ret ); } -#define CHECK_RANGE(min, max, val) \ - do \ - { \ - if( ( val ) < ( min ) || ( val ) > ( max ) ) \ - { \ - return( ret ); \ - } \ - } while( 0 ) +#define CHECK(code) if( ( ret = code ) != 0 ){ return( ret ); } +#define CHECK_RANGE(min, max, val) if( val < min || val > max ){ return( ret ); } /* * CertificateSerialNumber ::= INTEGER */ -static int mbedtls_x509_get_serial( unsigned char **p, const unsigned char *end, +int mbedtls_x509_get_serial( unsigned char **p, const unsigned char *end, mbedtls_x509_buf *serial ) { int ret; @@ -118,32 +101,13 @@ static int mbedtls_x509_get_serial( unsigned char **p, const unsigned char *end, return( 0 ); } -#if defined(MBEDTLS_X509_CRL_PARSE_C) || defined(MBEDTLS_X509_CSR_PARSE_C) || \ - ( !defined(MBEDTLS_X509_ON_DEMAND_PARSING) && defined(MBEDTLS_X509_CRT_PARSE_C) ) -/* - * Parse an algorithm identifier with (optional) parameters - */ -static int mbedtls_x509_get_alg( unsigned char **p, const unsigned char *end, - mbedtls_x509_buf *alg, mbedtls_x509_buf *params ) -{ - int ret; - - if( ( ret = mbedtls_asn1_get_alg( p, end, alg, params ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); - - return( 0 ); -} -#endif /* defined(MBEDTLS_X509_CRL_PARSE_C) || defined(MBEDTLS_X509_CSR_PARSE_C) || - ( !defined(MBEDTLS_X509_ON_DEMAND_PARSING) && defined(MBEDTLS_X509_CRT_PARSE_C) ) */ - -#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) /* Get an algorithm identifier without parameters (eg for signatures) * * AlgorithmIdentifier ::= SEQUENCE { * algorithm OBJECT IDENTIFIER, * parameters ANY DEFINED BY algorithm OPTIONAL } */ -static int mbedtls_x509_get_alg_null( unsigned char **p, const unsigned char *end, +int mbedtls_x509_get_alg_null( unsigned char **p, const unsigned char *end, mbedtls_x509_buf *alg ) { int ret; @@ -154,6 +118,21 @@ static int mbedtls_x509_get_alg_null( unsigned char **p, const unsigned char *en return( 0 ); } +/* + * Parse an algorithm identifier with (optional) paramaters + */ +int mbedtls_x509_get_alg( unsigned char **p, const unsigned char *end, + mbedtls_x509_buf *alg, mbedtls_x509_buf *params ) +{ + int ret; + + if( ( ret = mbedtls_asn1_get_alg( p, end, alg, params ) ) != 0 ) + return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); + + return( 0 ); +} + +#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) /* * HashAlgorithm ::= AlgorithmIdentifier * @@ -176,7 +155,7 @@ static int x509_get_hash_alg( const mbedtls_x509_buf *alg, mbedtls_md_type_t *md return( MBEDTLS_ERR_X509_INVALID_ALG + MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); - p = alg->p; + p = (unsigned char *) alg->p; end = p + alg->len; if( p >= end ) @@ -222,7 +201,7 @@ static int x509_get_hash_alg( const mbedtls_x509_buf *alg, mbedtls_md_type_t *md * of trailerField MUST be 1, and PKCS#1 v2.2 doesn't even define any other * option. Enfore this at parsing time. */ -static int mbedtls_x509_get_rsassa_pss_params( const mbedtls_x509_buf *params, +int mbedtls_x509_get_rsassa_pss_params( const mbedtls_x509_buf *params, mbedtls_md_type_t *md_alg, mbedtls_md_type_t *mgf_md, int *salt_len ) { @@ -364,59 +343,56 @@ static int mbedtls_x509_get_rsassa_pss_params( const mbedtls_x509_buf *params, * AttributeType ::= OBJECT IDENTIFIER * * AttributeValue ::= ANY DEFINED BY AttributeType - * - * NOTE: This function returns an ASN.1 low-level error code. */ static int x509_get_attr_type_value( unsigned char **p, const unsigned char *end, - mbedtls_x509_buf *oid, - mbedtls_x509_buf *val ) + mbedtls_x509_name *cur ) { int ret; size_t len; + mbedtls_x509_buf *oid; + mbedtls_x509_buf *val; - ret = mbedtls_asn1_get_tag( p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE ); - if( ret != 0 ) - goto exit; + if( ( ret = mbedtls_asn1_get_tag( p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) + return( MBEDTLS_ERR_X509_INVALID_NAME + ret ); - end = *p + len; + if( ( end - *p ) < 1 ) + return( MBEDTLS_ERR_X509_INVALID_NAME + + MBEDTLS_ERR_ASN1_OUT_OF_DATA ); - ret = mbedtls_asn1_get_tag( p, end, &oid->len, MBEDTLS_ASN1_OID ); - if( ret != 0 ) - goto exit; + oid = &cur->oid; + oid->tag = **p; + + if( ( ret = mbedtls_asn1_get_tag( p, end, &oid->len, MBEDTLS_ASN1_OID ) ) != 0 ) + return( MBEDTLS_ERR_X509_INVALID_NAME + ret ); - oid->tag = MBEDTLS_ASN1_OID; oid->p = *p; *p += oid->len; - if( *p == end ) - { - ret = MBEDTLS_ERR_ASN1_OUT_OF_DATA; - goto exit; - } + if( ( end - *p ) < 1 ) + return( MBEDTLS_ERR_X509_INVALID_NAME + + MBEDTLS_ERR_ASN1_OUT_OF_DATA ); - if( !MBEDTLS_ASN1_IS_STRING_TAG( **p ) ) - { - ret = MBEDTLS_ERR_ASN1_UNEXPECTED_TAG; - goto exit; - } + if( **p != MBEDTLS_ASN1_BMP_STRING && **p != MBEDTLS_ASN1_UTF8_STRING && + **p != MBEDTLS_ASN1_T61_STRING && **p != MBEDTLS_ASN1_PRINTABLE_STRING && + **p != MBEDTLS_ASN1_IA5_STRING && **p != MBEDTLS_ASN1_UNIVERSAL_STRING && + **p != MBEDTLS_ASN1_BIT_STRING ) + return( MBEDTLS_ERR_X509_INVALID_NAME + + MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); + val = &cur->val; val->tag = *(*p)++; - ret = mbedtls_asn1_get_len( p, end, &val->len ); - if( ret != 0 ) - goto exit; + if( ( ret = mbedtls_asn1_get_len( p, end, &val->len ) ) != 0 ) + return( MBEDTLS_ERR_X509_INVALID_NAME + ret ); val->p = *p; *p += val->len; - if( *p != end ) - ret = MBEDTLS_ERR_ASN1_LENGTH_MISMATCH; + cur->next = NULL; -exit: - return( ret ); + return( 0 ); } /* @@ -441,239 +417,60 @@ exit: * For the general case we still use a flat list, but we mark elements of the * same set so that they are "merged" together in the functions that consume * this list, eg mbedtls_x509_dn_gets(). - * - * NOTE: This function returns an ASN.1 low-level error code. */ -static int x509_set_sequence_iterate( unsigned char **p, - unsigned char const **end_set, - unsigned char const *end, - mbedtls_x509_buf *oid, - mbedtls_x509_buf *val ) +int mbedtls_x509_get_name( unsigned char **p, const unsigned char *end, + mbedtls_x509_name *cur ) { int ret; size_t set_len; + const unsigned char *end_set; - if( *p == *end_set ) - { - /* Parse next TLV of ASN.1 SET structure. */ - ret = mbedtls_asn1_get_tag( p, end, &set_len, - MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SET ); - if( ret != 0 ) - goto exit; - - *end_set = *p + set_len; - } - - /* x509_get_attr_type_value() returns ASN.1 low-level error codes. */ - ret = x509_get_attr_type_value( p, *end_set, oid, val ); - -exit: - return( ret ); -} - -/* - * Like memcmp, but case-insensitive and always returns -1 if different - */ -static int mbedtls_x509_memcasecmp( const void *s1, const void *s2, - size_t len1, size_t len2 ) -{ - size_t i; - unsigned char diff; - const unsigned char *n1 = s1, *n2 = s2; - - if( len1 != len2 ) - return( -1 ); - - for( i = 0; i < len1; i++ ) - { - diff = n1[i] ^ n2[i]; - - if( diff == 0 ) - continue; - - if( diff == 32 && - ( ( n1[i] >= 'a' && n1[i] <= 'z' ) || - ( n1[i] >= 'A' && n1[i] <= 'Z' ) ) ) - { - continue; - } - - return( -1 ); - } - - return( 0 ); -} - -/* - * Compare two X.509 strings, case-insensitive, and allowing for some encoding - * variations (but not all). - * - * Return 0 if equal, -1 otherwise. - */ -static int x509_string_cmp( const mbedtls_x509_buf *a, - const mbedtls_x509_buf *b ) -{ - if( a->tag == b->tag && - a->len == b->len && - mbedtls_platform_memequal( a->p, b->p, b->len ) == 0 ) - { - return( 0 ); - } - - if( ( a->tag == MBEDTLS_ASN1_UTF8_STRING || a->tag == MBEDTLS_ASN1_PRINTABLE_STRING ) && - ( b->tag == MBEDTLS_ASN1_UTF8_STRING || b->tag == MBEDTLS_ASN1_PRINTABLE_STRING ) && - mbedtls_x509_memcasecmp( a->p, b->p, - a->len, b->len ) == 0 ) - { - return( 0 ); - } - - return( -1 ); -} - -/* - * Compare two X.509 Names (aka rdnSequence) given as raw ASN.1 data. - * - * See RFC 5280 section 7.1, though we don't implement the whole algorithm: - * We sometimes return unequal when the full algorithm would return equal, - * but never the other way. (In particular, we don't do Unicode normalisation - * or space folding.) - * - * Further, this function allows to pass a callback to be triggered for every - * pair of well-formed and equal entries in the two input name lists. - * - * Returns: - * - 0 if both sequences are well-formed, present the same X.509 name, - * and the callback (if provided) hasn't returned a non-zero value - * on any of the name components. - * - 1 if a difference was detected in the name components. - * - A non-zero error code if the abort callback returns a non-zero value. - * In this case, the returned error code is the error code from the callback. - * - A negative error code if a parsing error occurred in either - * of the two buffers. - * - * This function can be used to verify that a buffer contains a well-formed - * ASN.1 encoded X.509 name by calling it with equal parameters. - */ -static int mbedtls_x509_name_cmp_raw( mbedtls_x509_buf_raw const *a, - mbedtls_x509_buf_raw const *b, - int (*abort_check)( void *ctx, - mbedtls_x509_buf *oid, - mbedtls_x509_buf *val, - int next_merged ), - void *abort_check_ctx ) -{ - int ret; - size_t idx; - unsigned char *p[2], *end[2], *set[2]; - - p[0] = a->p; - p[1] = b->p; - end[0] = p[0] + a->len; - end[1] = p[1] + b->len; - - for( idx = 0; idx < 2; idx++ ) - { - size_t len; - ret = mbedtls_asn1_get_tag( &p[idx], end[idx], &len, - MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE ); - - if( end[idx] != p[idx] + len ) - { - return( MBEDTLS_ERR_X509_INVALID_NAME + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - } - - set[idx] = p[idx]; - } - + /* don't use recursion, we'd risk stack overflow if not optimized */ while( 1 ) { - int next_merged; - mbedtls_x509_buf oid[2], val[2]; + /* + * parse SET + */ + if( ( ret = mbedtls_asn1_get_tag( p, end, &set_len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET ) ) != 0 ) + return( MBEDTLS_ERR_X509_INVALID_NAME + ret ); - ret = x509_set_sequence_iterate( &p[0], (const unsigned char **) &set[0], - end[0], &oid[0], &val[0] ); - if( ret != 0 ) - goto exit; + end_set = *p + set_len; - ret = x509_set_sequence_iterate( &p[1], (const unsigned char **) &set[1], - end[1], &oid[1], &val[1] ); - if( ret != 0 ) - goto exit; - - if( oid[0].len != oid[1].len || - mbedtls_platform_memequal( oid[0].p, oid[1].p, oid[1].len ) != 0 ) + while( 1 ) { - return( 1 ); - } - - if( x509_string_cmp( &val[0], &val[1] ) != 0 ) - return( 1 ); - - next_merged = ( set[0] != p[0] ); - if( next_merged != ( set[1] != p[1] ) ) - return( 1 ); - - if( abort_check != NULL ) - { - ret = abort_check( abort_check_ctx, &oid[0], &val[0], - next_merged ); - if( ret != 0 ) + if( ( ret = x509_get_attr_type_value( p, end_set, cur ) ) != 0 ) return( ret ); + + if( *p == end_set ) + break; + + /* Mark this item as being no the only one in a set */ + cur->next_merged = 1; + + cur->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_name ) ); + + if( cur->next == NULL ) + return( MBEDTLS_ERR_X509_ALLOC_FAILED ); + + cur = cur->next; } - if( p[0] == end[0] && p[1] == end[1] ) - break; - } + /* + * continue until end of SEQUENCE is reached + */ + if( *p == end ) + return( 0 ); -exit: - if( ret < 0 ) - ret += MBEDTLS_ERR_X509_INVALID_NAME; - - return( ret ); -} - -static int x509_get_name_cb( void *ctx, - mbedtls_x509_buf *oid, - mbedtls_x509_buf *val, - int next_merged ) -{ - mbedtls_x509_name **cur_ptr = (mbedtls_x509_name**) ctx; - mbedtls_x509_name *cur = *cur_ptr; - - if( cur->oid.p != NULL ) - { cur->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_name ) ); + if( cur->next == NULL ) - return( MBEDTLS_ERR_ASN1_ALLOC_FAILED ); + return( MBEDTLS_ERR_X509_ALLOC_FAILED ); cur = cur->next; } - - cur->oid = *oid; - cur->val = *val; - cur->next_merged = next_merged; - - *cur_ptr = cur; - return( 0 ); } -static int mbedtls_x509_get_name( unsigned char *p, - size_t len, - mbedtls_x509_name *cur ) -{ - mbedtls_x509_buf_raw name_buf = { p, len }; - mbedtls_platform_memset( cur, 0, sizeof( mbedtls_x509_name ) ); - return( mbedtls_x509_name_cmp_raw( &name_buf, &name_buf, - x509_get_name_cb, - &cur ) ); -} - -#if ( !defined(MBEDTLS_X509_CRT_REMOVE_TIME) && defined(MBEDTLS_X509_CRT_PARSE_C) ) || \ - defined(MBEDTLS_X509_CRL_PARSE_C) static int x509_parse_int( unsigned char **p, size_t n, int *res ) { *res = 0; @@ -792,7 +589,7 @@ static int x509_parse_time( unsigned char **p, size_t len, size_t yearlen, * utcTime UTCTime, * generalTime GeneralizedTime } */ -static int mbedtls_x509_get_time( unsigned char **p, const unsigned char *end, +int mbedtls_x509_get_time( unsigned char **p, const unsigned char *end, mbedtls_x509_time *tm ) { int ret; @@ -821,10 +618,8 @@ static int mbedtls_x509_get_time( unsigned char **p, const unsigned char *end, return x509_parse_time( p, len, year_len, tm ); } -#endif /* ( !defined(MBEDTLS_X509_CRT_REMOVE_TIME) && defined(MBEDTLS_X509_CRT_PARSE_C) ) || - defined(MBEDTLS_X509_CRL_PARSE_C) */ -static int mbedtls_x509_get_sig( unsigned char **p, const unsigned char *end, mbedtls_x509_buf *sig ) +int mbedtls_x509_get_sig( unsigned char **p, const unsigned char *end, mbedtls_x509_buf *sig ) { int ret; size_t len; @@ -848,30 +643,18 @@ static int mbedtls_x509_get_sig( unsigned char **p, const unsigned char *end, mb return( 0 ); } -static int mbedtls_x509_get_sig_alg_raw( unsigned char **p, unsigned char const *end, - mbedtls_md_type_t *md_alg, - mbedtls_pk_type_t *pk_alg, - void **sig_opts ) -{ - int ret; - mbedtls_asn1_buf alg, params; - ret = mbedtls_asn1_get_alg( p, end, &alg, ¶ms ); - if( ret != 0 ) - return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); - - return( mbedtls_x509_get_sig_alg( &alg, ¶ms, md_alg, - pk_alg, sig_opts ) ); -} - /* * Get signature algorithm from alg OID and optional parameters */ -static int mbedtls_x509_get_sig_alg( const mbedtls_x509_buf *sig_oid, const mbedtls_x509_buf *sig_params, +int mbedtls_x509_get_sig_alg( const mbedtls_x509_buf *sig_oid, const mbedtls_x509_buf *sig_params, mbedtls_md_type_t *md_alg, mbedtls_pk_type_t *pk_alg, void **sig_opts ) { int ret; + if( *sig_opts != NULL ) + return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); + if( ( ret = mbedtls_oid_get_sig_alg( sig_oid, md_alg, pk_alg ) ) != 0 ) return( MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG + ret ); @@ -894,10 +677,7 @@ static int mbedtls_x509_get_sig_alg( const mbedtls_x509_buf *sig_oid, const mbed return( ret ); } - if( sig_opts != NULL ) - *sig_opts = (void *) pss_opts; - else - mbedtls_free( pss_opts ); + *sig_opts = (void *) pss_opts; } else #endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */ @@ -905,40 +685,41 @@ static int mbedtls_x509_get_sig_alg( const mbedtls_x509_buf *sig_oid, const mbed /* Make sure parameters are absent or NULL */ if( ( sig_params->tag != MBEDTLS_ASN1_NULL && sig_params->tag != 0 ) || sig_params->len != 0 ) - return( MBEDTLS_ERR_X509_INVALID_ALG ); - - if( sig_opts != NULL ) - *sig_opts = NULL; + return( MBEDTLS_ERR_X509_INVALID_ALG ); } return( 0 ); } -#if defined(MBEDTLS_X509_CRL_PARSE_C) /* * X.509 Extensions (No parsing of extensions, pointer should * be either manually updated or extensions should be parsed!) */ -static int mbedtls_x509_get_ext( unsigned char **p, const unsigned char *end, - mbedtls_x509_buf *ext, int tag ) +int mbedtls_x509_get_ext( unsigned char **p, const unsigned char *end, + mbedtls_x509_buf *ext, int tag ) { int ret; size_t len; - /* Extension structure use EXPLICIT tagging. That is, the actual - * `Extensions` structure is wrapped by a tag-length pair using - * the respective context-specific tag. */ - ret = mbedtls_asn1_get_tag( p, end, &ext->len, - MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | tag ); - if( ret != 0 ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); + if( *p == end ) + return( 0 ); - ext->tag = MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | tag; - ext->p = *p; - end = *p + ext->len; + ext->tag = **p; + + if( ( ret = mbedtls_asn1_get_tag( p, end, &ext->len, + MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | tag ) ) != 0 ) + return( ret ); + + ext->p = *p; + end = *p + ext->len; /* * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension + * + * Extension ::= SEQUENCE { + * extnID OBJECT IDENTIFIER, + * critical BOOLEAN DEFAULT FALSE, + * extnValue OCTET STRING } */ if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) @@ -950,7 +731,7 @@ static int mbedtls_x509_get_ext( unsigned char **p, const unsigned char *end, return( 0 ); } -#endif /* defined(MBEDTLS_X509_CRL_PARSE_C) */ + /* * Store the name in printable form into buf; no more * than size characters will be written @@ -1048,45 +829,30 @@ int mbedtls_x509_serial_gets( char *buf, size_t size, const mbedtls_x509_buf *se return( (int) ( size - n ) ); } -#if !defined(MBEDTLS_X509_REMOVE_INFO) /* * Helper for writing signature algorithms */ -static int mbedtls_x509_sig_alg_gets( char *buf, size_t size, mbedtls_pk_type_t pk_alg, - mbedtls_md_type_t md_alg, const void *sig_opts ) +int mbedtls_x509_sig_alg_gets( char *buf, size_t size, const mbedtls_x509_buf *sig_oid, + mbedtls_pk_type_t pk_alg, mbedtls_md_type_t md_alg, + const void *sig_opts ) { int ret; char *p = buf; size_t n = size; const char *desc = NULL; - mbedtls_x509_buf sig_oid; - mbedtls_md_type_t tmp_md_alg = md_alg; -#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) - /* The hash for RSASSA is determined by the algorithm parameters; - * in the OID list, the hash is set to MBEDTLS_MD_NONE. */ - if( pk_alg == MBEDTLS_PK_RSASSA_PSS ) - tmp_md_alg = MBEDTLS_MD_NONE; -#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */ - - sig_oid.tag = MBEDTLS_ASN1_OID; - ret = mbedtls_oid_get_oid_by_sig_alg( pk_alg, tmp_md_alg, - (const char**) &sig_oid.p, - &sig_oid.len ); - if( ret == 0 && - mbedtls_oid_get_sig_alg_desc( &sig_oid, &desc ) == 0 ) - { - ret = mbedtls_snprintf( p, n, "%s", desc ); - } + ret = mbedtls_oid_get_sig_alg_desc( sig_oid, &desc ); + if( ret != 0 ) + ret = mbedtls_snprintf( p, n, "???" ); else - ret = mbedtls_snprintf( p, n, "???" ); + ret = mbedtls_snprintf( p, n, "%s", desc ); MBEDTLS_X509_SAFE_SNPRINTF; #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) if( pk_alg == MBEDTLS_PK_RSASSA_PSS ) { const mbedtls_pk_rsassa_pss_options *pss_opts; - mbedtls_md_handle_t md_info, mgf_md_info; + const mbedtls_md_info_t *md_info, *mgf_md_info; pss_opts = (const mbedtls_pk_rsassa_pss_options *) sig_opts; @@ -1111,7 +877,7 @@ static int mbedtls_x509_sig_alg_gets( char *buf, size_t size, mbedtls_pk_type_t /* * Helper for writing "RSA key size", "EC key size", etc */ -static int mbedtls_x509_key_size_helper( char *buf, size_t buf_size, const char *name ) +int mbedtls_x509_key_size_helper( char *buf, size_t buf_size, const char *name ) { char *p = buf; size_t n = buf_size; @@ -1122,21 +888,42 @@ static int mbedtls_x509_key_size_helper( char *buf, size_t buf_size, const char return( 0 ); } -#endif /* !MBEDTLS_X509_REMOVE_INFO */ #if defined(MBEDTLS_HAVE_TIME_DATE) /* * Set the time structure to the current time. * Return 0 on success, non-zero on failure. */ +#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) static int x509_get_current_time( mbedtls_x509_time *now ) { - struct tm *lt, tm_buf; + SYSTEMTIME st; + + GetSystemTime( &st ); + + now->year = st.wYear; + now->mon = st.wMonth; + now->day = st.wDay; + now->hour = st.wHour; + now->min = st.wMinute; + now->sec = st.wSecond; + + return( 0 ); +} +#else +static int x509_get_current_time( mbedtls_x509_time *now ) +{ + struct tm *lt; mbedtls_time_t tt; int ret = 0; +#if defined(MBEDTLS_THREADING_C) + if( mbedtls_mutex_lock( &mbedtls_threading_gmtime_mutex ) != 0 ) + return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); +#endif + tt = mbedtls_time( NULL ); - lt = mbedtls_platform_gmtime_r( &tt, &tm_buf ); + lt = gmtime( &tt ); if( lt == NULL ) ret = -1; @@ -1150,8 +937,14 @@ static int x509_get_current_time( mbedtls_x509_time *now ) now->sec = lt->tm_sec; } +#if defined(MBEDTLS_THREADING_C) + if( mbedtls_mutex_unlock( &mbedtls_threading_gmtime_mutex ) != 0 ) + return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); +#endif + return( ret ); } +#endif /* _WIN32 && !EFIX64 && !EFI32 */ /* * Return 0 if before <= after, 1 otherwise @@ -1213,19 +1006,22 @@ int mbedtls_x509_time_is_future( const mbedtls_x509_time *from ) return( x509_check_time( from, &now ) ); } -#endif /* MBEDTLS_HAVE_TIME_DATE */ -void mbedtls_x509_name_free( mbedtls_x509_name *name ) +#else /* MBEDTLS_HAVE_TIME_DATE */ + +int mbedtls_x509_time_is_past( const mbedtls_x509_time *to ) { - while( name != NULL ) - { - mbedtls_x509_name *next = name->next; - mbedtls_platform_zeroize( name, sizeof( *name ) ); - mbedtls_free( name ); - name = next; - } + ((void) to); + return( 0 ); } +int mbedtls_x509_time_is_future( const mbedtls_x509_time *from ) +{ + ((void) from); + return( 0 ); +} +#endif /* MBEDTLS_HAVE_TIME_DATE */ + #if defined(MBEDTLS_SELF_TEST) #include "x509_crt.h" @@ -1236,8 +1032,8 @@ void mbedtls_x509_name_free( mbedtls_x509_name *name ) */ int mbedtls_x509_self_test( int verbose ) { - int ret = 0; #if defined(MBEDTLS_CERTS_C) && defined(MBEDTLS_SHA256_C) + int ret; uint32_t flags; mbedtls_x509_crt cacert; mbedtls_x509_crt clicert; @@ -1245,7 +1041,6 @@ int mbedtls_x509_self_test( int verbose ) if( verbose != 0 ) mbedtls_printf( " X.509 certificate load: " ); - mbedtls_x509_crt_init( &cacert ); mbedtls_x509_crt_init( &clicert ); ret = mbedtls_x509_crt_parse( &clicert, (const unsigned char *) mbedtls_test_cli_crt, @@ -1255,9 +1050,11 @@ int mbedtls_x509_self_test( int verbose ) if( verbose != 0 ) mbedtls_printf( "failed\n" ); - goto cleanup; + return( ret ); } + mbedtls_x509_crt_init( &cacert ); + ret = mbedtls_x509_crt_parse( &cacert, (const unsigned char *) mbedtls_test_ca_crt, mbedtls_test_ca_crt_len ); if( ret != 0 ) @@ -1265,40 +1062,32 @@ int mbedtls_x509_self_test( int verbose ) if( verbose != 0 ) mbedtls_printf( "failed\n" ); - goto cleanup; + return( ret ); } if( verbose != 0 ) mbedtls_printf( "passed\n X.509 signature verify: "); - ret = mbedtls_x509_crt_verify( &clicert, &cacert, NULL, -#if !defined(MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION) - NULL, -#endif /* !MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION */ - &flags -#if !defined(MBEDTLS_X509_REMOVE_VERIFY_CALLBACK) - , NULL, NULL -#endif - ); - + ret = mbedtls_x509_crt_verify( &clicert, &cacert, NULL, NULL, &flags, NULL, NULL ); if( ret != 0 ) { if( verbose != 0 ) mbedtls_printf( "failed\n" ); - goto cleanup; + return( ret ); } if( verbose != 0 ) mbedtls_printf( "passed\n\n"); -cleanup: mbedtls_x509_crt_free( &cacert ); mbedtls_x509_crt_free( &clicert ); + + return( 0 ); #else ((void) verbose); -#endif /* MBEDTLS_CERTS_C && MBEDTLS_SHA256_C */ - return( ret ); + return( 0 ); +#endif /* MBEDTLS_CERTS_C && MBEDTLS_SHA1_C */ } #endif /* MBEDTLS_SELF_TEST */ diff --git a/APP_Framework/Framework/security/mbedtls/x509.h b/APP_Framework/Framework/security/mbedtls/x509.h index b2ad182f2..d6db9c6e3 100644 --- a/APP_Framework/Framework/security/mbedtls/x509.h +++ b/APP_Framework/Framework/security/mbedtls/x509.h @@ -77,7 +77,7 @@ #define MBEDTLS_ERR_X509_ALLOC_FAILED -0x2880 /**< Allocation of memory failed. */ #define MBEDTLS_ERR_X509_FILE_IO_ERROR -0x2900 /**< Read/write of file failed. */ #define MBEDTLS_ERR_X509_BUFFER_TOO_SMALL -0x2980 /**< Destination buffer is too small. */ -#define MBEDTLS_ERR_X509_FATAL_ERROR -0x3000 /**< A fatal error occurred, eg the chain is too long or the vrfy callback failed. */ +#define MBEDTLS_ERR_X509_FATAL_ERROR -0x3000 /**< A fatal error occured, eg the chain is too long or the vrfy callback failed. */ /* \} name */ /** @@ -85,8 +85,6 @@ * \{ */ /* Reminder: update x509_crt_verify_strings[] in library/x509_crt.c */ -/* Reminder: update X509_BADCERT_FI_EXTRA in library/x509_crt.c if using more - * that 24 bits */ #define MBEDTLS_X509_BADCERT_EXPIRED 0x01 /**< The certificate validity has expired. */ #define MBEDTLS_X509_BADCERT_REVOKED 0x02 /**< The certificate has been revoked (is on a CRL). */ #define MBEDTLS_X509_BADCERT_CN_MISMATCH 0x04 /**< The certificate Common Name (CN) does not match with the expected CN. */ @@ -185,15 +183,6 @@ extern "C" { * \{ */ -/** - * Basic length-value buffer structure - */ -typedef struct mbedtls_x509_buf_raw -{ - unsigned char *p; /*!< The address of the first byte in the buffer. */ - size_t len; /*!< The number of Bytes in the buffer. */ -} mbedtls_x509_buf_raw; - /** * Type-length-value structure that allows for ASN1 using DER. */ @@ -252,7 +241,6 @@ int mbedtls_x509_dn_gets( char *buf, size_t size, const mbedtls_x509_name *dn ); */ int mbedtls_x509_serial_gets( char *buf, size_t size, const mbedtls_x509_buf *serial ); -#if defined(MBEDTLS_HAVE_TIME_DATE) /** * \brief Check a given mbedtls_x509_time against the system time * and tell if it's in the past. @@ -262,7 +250,7 @@ int mbedtls_x509_serial_gets( char *buf, size_t size, const mbedtls_x509_buf *se * * \param to mbedtls_x509_time to check * - * \return 1 if the given time is in the past or an error occurred, + * \return 1 if the given time is in the past or an error occured, * 0 otherwise. */ int mbedtls_x509_time_is_past( const mbedtls_x509_time *to ); @@ -276,50 +264,10 @@ int mbedtls_x509_time_is_past( const mbedtls_x509_time *to ); * * \param from mbedtls_x509_time to check * - * \return 1 if the given time is in the future or an error occurred, + * \return 1 if the given time is in the future or an error occured, * 0 otherwise. */ int mbedtls_x509_time_is_future( const mbedtls_x509_time *from ); -#endif /* MBEDTLS_HAVE_TIME_DATE */ - -/** - * \brief Free a dynamic linked list presentation of an X.509 name - * as returned e.g. by mbedtls_x509_crt_get_subject(). - * - * \param name The address of the first name component. This may - * be \c NULL, in which case this functions returns - * immediately. - */ -void mbedtls_x509_name_free( mbedtls_x509_name *name ); - -/** - * \brief Free a dynamic linked list presentation of an X.509 sequence - * as returned e.g. by mbedtls_x509_crt_get_subject_alt_name(). - * - * \param seq The address of the first sequence component. This may - * be \c NULL, in which case this functions returns - * immediately. - */ -static inline void mbedtls_x509_sequence_free( mbedtls_x509_sequence *seq ) -{ - mbedtls_asn1_sequence_free( (mbedtls_asn1_sequence*) seq ); -} - -#if !defined(MBEDTLS_HAVE_TIME_DATE) -static inline int mbedtls_x509_time_is_past( const mbedtls_x509_time *to ) -{ - ((void) to); - return( 0 ); -} - -static inline int mbedtls_x509_time_is_future( const mbedtls_x509_time *from ) -{ - ((void) from); - return( 0 ); -} -#endif /* !MBEDTLS_HAVE_TIME_DATE */ - -#if defined(MBEDTLS_SELF_TEST) /** * \brief Checkup routine @@ -328,7 +276,46 @@ static inline int mbedtls_x509_time_is_future( const mbedtls_x509_time *from ) */ int mbedtls_x509_self_test( int verbose ); -#endif /* MBEDTLS_SELF_TEST */ +/* + * Internal module functions. You probably do not want to use these unless you + * know you do. + */ +int mbedtls_x509_get_name( unsigned char **p, const unsigned char *end, + mbedtls_x509_name *cur ); +int mbedtls_x509_get_alg_null( unsigned char **p, const unsigned char *end, + mbedtls_x509_buf *alg ); +int mbedtls_x509_get_alg( unsigned char **p, const unsigned char *end, + mbedtls_x509_buf *alg, mbedtls_x509_buf *params ); +#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) +int mbedtls_x509_get_rsassa_pss_params( const mbedtls_x509_buf *params, + mbedtls_md_type_t *md_alg, mbedtls_md_type_t *mgf_md, + int *salt_len ); +#endif +int mbedtls_x509_get_sig( unsigned char **p, const unsigned char *end, mbedtls_x509_buf *sig ); +int mbedtls_x509_get_sig_alg( const mbedtls_x509_buf *sig_oid, const mbedtls_x509_buf *sig_params, + mbedtls_md_type_t *md_alg, mbedtls_pk_type_t *pk_alg, + void **sig_opts ); +int mbedtls_x509_get_time( unsigned char **p, const unsigned char *end, + mbedtls_x509_time *t ); +int mbedtls_x509_get_serial( unsigned char **p, const unsigned char *end, + mbedtls_x509_buf *serial ); +int mbedtls_x509_get_ext( unsigned char **p, const unsigned char *end, + mbedtls_x509_buf *ext, int tag ); +int mbedtls_x509_sig_alg_gets( char *buf, size_t size, const mbedtls_x509_buf *sig_oid, + mbedtls_pk_type_t pk_alg, mbedtls_md_type_t md_alg, + const void *sig_opts ); +int mbedtls_x509_key_size_helper( char *buf, size_t buf_size, const char *name ); +int mbedtls_x509_string_to_names( mbedtls_asn1_named_data **head, const char *name ); +int mbedtls_x509_set_extension( mbedtls_asn1_named_data **head, const char *oid, size_t oid_len, + int critical, const unsigned char *val, + size_t val_len ); +int mbedtls_x509_write_extensions( unsigned char **p, unsigned char *start, + mbedtls_asn1_named_data *first ); +int mbedtls_x509_write_names( unsigned char **p, unsigned char *start, + mbedtls_asn1_named_data *first ); +int mbedtls_x509_write_sig( unsigned char **p, unsigned char *start, + const char *oid, size_t oid_len, + unsigned char *sig, size_t size ); #define MBEDTLS_X509_SAFE_SNPRINTF \ do { \ @@ -339,18 +326,6 @@ int mbedtls_x509_self_test( int verbose ); p += (size_t) ret; \ } while( 0 ) -#define MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP \ - do { \ - if( ret < 0 || (size_t) ret >= n ) \ - { \ - ret = MBEDTLS_ERR_X509_BUFFER_TOO_SMALL; \ - goto cleanup; \ - } \ - \ - n -= (size_t) ret; \ - p += (size_t) ret; \ - } while( 0 ) - #ifdef __cplusplus } #endif diff --git a/APP_Framework/Framework/security/mbedtls/x509_create.c b/APP_Framework/Framework/security/mbedtls/x509_create.c index 8771ba3b6..a9bf80cc4 100644 --- a/APP_Framework/Framework/security/mbedtls/x509_create.c +++ b/APP_Framework/Framework/security/mbedtls/x509_create.c @@ -28,90 +28,53 @@ #if defined(MBEDTLS_X509_CREATE_C) #include "x509.h" -#include "x509_internal.h" #include "asn1write.h" #include "oid.h" #include -/* Structure linking OIDs for X.509 DN AttributeTypes to their - * string representations and default string encodings used by Mbed TLS. */ typedef struct { - const char *name; /* String representation of AttributeType, e.g. - * "CN" or "emailAddress". */ - size_t name_len; /* Length of 'name', without trailing 0 byte. */ - const char *oid; /* String representation of OID of AttributeType, - * as per RFC 5280, Appendix A.1. */ - int default_tag; /* The default character encoding used for the - * given attribute type, e.g. - * MBEDTLS_ASN1_UTF8_STRING for UTF-8. */ + const char *name; + size_t name_len; + const char*oid; } x509_attr_descriptor_t; #define ADD_STRLEN( s ) s, sizeof( s ) - 1 -/* X.509 DN attributes from RFC 5280, Appendix A.1. */ static const x509_attr_descriptor_t x509_attrs[] = { - { ADD_STRLEN( "CN" ), - MBEDTLS_OID_AT_CN, MBEDTLS_ASN1_UTF8_STRING }, - { ADD_STRLEN( "commonName" ), - MBEDTLS_OID_AT_CN, MBEDTLS_ASN1_UTF8_STRING }, - { ADD_STRLEN( "C" ), - MBEDTLS_OID_AT_COUNTRY, MBEDTLS_ASN1_PRINTABLE_STRING }, - { ADD_STRLEN( "countryName" ), - MBEDTLS_OID_AT_COUNTRY, MBEDTLS_ASN1_PRINTABLE_STRING }, - { ADD_STRLEN( "O" ), - MBEDTLS_OID_AT_ORGANIZATION, MBEDTLS_ASN1_UTF8_STRING }, - { ADD_STRLEN( "organizationName" ), - MBEDTLS_OID_AT_ORGANIZATION, MBEDTLS_ASN1_UTF8_STRING }, - { ADD_STRLEN( "L" ), - MBEDTLS_OID_AT_LOCALITY, MBEDTLS_ASN1_UTF8_STRING }, - { ADD_STRLEN( "locality" ), - MBEDTLS_OID_AT_LOCALITY, MBEDTLS_ASN1_UTF8_STRING }, - { ADD_STRLEN( "R" ), - MBEDTLS_OID_PKCS9_EMAIL, MBEDTLS_ASN1_IA5_STRING }, - { ADD_STRLEN( "OU" ), - MBEDTLS_OID_AT_ORG_UNIT, MBEDTLS_ASN1_UTF8_STRING }, - { ADD_STRLEN( "organizationalUnitName" ), - MBEDTLS_OID_AT_ORG_UNIT, MBEDTLS_ASN1_UTF8_STRING }, - { ADD_STRLEN( "ST" ), - MBEDTLS_OID_AT_STATE, MBEDTLS_ASN1_UTF8_STRING }, - { ADD_STRLEN( "stateOrProvinceName" ), - MBEDTLS_OID_AT_STATE, MBEDTLS_ASN1_UTF8_STRING }, - { ADD_STRLEN( "emailAddress" ), - MBEDTLS_OID_PKCS9_EMAIL, MBEDTLS_ASN1_IA5_STRING }, - { ADD_STRLEN( "serialNumber" ), - MBEDTLS_OID_AT_SERIAL_NUMBER, MBEDTLS_ASN1_PRINTABLE_STRING }, - { ADD_STRLEN( "postalAddress" ), - MBEDTLS_OID_AT_POSTAL_ADDRESS, MBEDTLS_ASN1_PRINTABLE_STRING }, - { ADD_STRLEN( "postalCode" ), - MBEDTLS_OID_AT_POSTAL_CODE, MBEDTLS_ASN1_PRINTABLE_STRING }, - { ADD_STRLEN( "dnQualifier" ), - MBEDTLS_OID_AT_DN_QUALIFIER, MBEDTLS_ASN1_PRINTABLE_STRING }, - { ADD_STRLEN( "title" ), - MBEDTLS_OID_AT_TITLE, MBEDTLS_ASN1_UTF8_STRING }, - { ADD_STRLEN( "surName" ), - MBEDTLS_OID_AT_SUR_NAME, MBEDTLS_ASN1_UTF8_STRING }, - { ADD_STRLEN( "SN" ), - MBEDTLS_OID_AT_SUR_NAME, MBEDTLS_ASN1_UTF8_STRING }, - { ADD_STRLEN( "givenName" ), - MBEDTLS_OID_AT_GIVEN_NAME, MBEDTLS_ASN1_UTF8_STRING }, - { ADD_STRLEN( "GN" ), - MBEDTLS_OID_AT_GIVEN_NAME, MBEDTLS_ASN1_UTF8_STRING }, - { ADD_STRLEN( "initials" ), - MBEDTLS_OID_AT_INITIALS, MBEDTLS_ASN1_UTF8_STRING }, - { ADD_STRLEN( "pseudonym" ), - MBEDTLS_OID_AT_PSEUDONYM, MBEDTLS_ASN1_UTF8_STRING }, - { ADD_STRLEN( "generationQualifier" ), - MBEDTLS_OID_AT_GENERATION_QUALIFIER, MBEDTLS_ASN1_UTF8_STRING }, - { ADD_STRLEN( "domainComponent" ), - MBEDTLS_OID_DOMAIN_COMPONENT, MBEDTLS_ASN1_IA5_STRING }, - { ADD_STRLEN( "DC" ), - MBEDTLS_OID_DOMAIN_COMPONENT, MBEDTLS_ASN1_IA5_STRING }, - { NULL, 0, NULL, MBEDTLS_ASN1_NULL } + { ADD_STRLEN( "CN" ), MBEDTLS_OID_AT_CN }, + { ADD_STRLEN( "commonName" ), MBEDTLS_OID_AT_CN }, + { ADD_STRLEN( "C" ), MBEDTLS_OID_AT_COUNTRY }, + { ADD_STRLEN( "countryName" ), MBEDTLS_OID_AT_COUNTRY }, + { ADD_STRLEN( "O" ), MBEDTLS_OID_AT_ORGANIZATION }, + { ADD_STRLEN( "organizationName" ), MBEDTLS_OID_AT_ORGANIZATION }, + { ADD_STRLEN( "L" ), MBEDTLS_OID_AT_LOCALITY }, + { ADD_STRLEN( "locality" ), MBEDTLS_OID_AT_LOCALITY }, + { ADD_STRLEN( "R" ), MBEDTLS_OID_PKCS9_EMAIL }, + { ADD_STRLEN( "OU" ), MBEDTLS_OID_AT_ORG_UNIT }, + { ADD_STRLEN( "organizationalUnitName" ), MBEDTLS_OID_AT_ORG_UNIT }, + { ADD_STRLEN( "ST" ), MBEDTLS_OID_AT_STATE }, + { ADD_STRLEN( "stateOrProvinceName" ), MBEDTLS_OID_AT_STATE }, + { ADD_STRLEN( "emailAddress" ), MBEDTLS_OID_PKCS9_EMAIL }, + { ADD_STRLEN( "serialNumber" ), MBEDTLS_OID_AT_SERIAL_NUMBER }, + { ADD_STRLEN( "postalAddress" ), MBEDTLS_OID_AT_POSTAL_ADDRESS }, + { ADD_STRLEN( "postalCode" ), MBEDTLS_OID_AT_POSTAL_CODE }, + { ADD_STRLEN( "dnQualifier" ), MBEDTLS_OID_AT_DN_QUALIFIER }, + { ADD_STRLEN( "title" ), MBEDTLS_OID_AT_TITLE }, + { ADD_STRLEN( "surName" ), MBEDTLS_OID_AT_SUR_NAME }, + { ADD_STRLEN( "SN" ), MBEDTLS_OID_AT_SUR_NAME }, + { ADD_STRLEN( "givenName" ), MBEDTLS_OID_AT_GIVEN_NAME }, + { ADD_STRLEN( "GN" ), MBEDTLS_OID_AT_GIVEN_NAME }, + { ADD_STRLEN( "initials" ), MBEDTLS_OID_AT_INITIALS }, + { ADD_STRLEN( "pseudonym" ), MBEDTLS_OID_AT_PSEUDONYM }, + { ADD_STRLEN( "generationQualifier" ), MBEDTLS_OID_AT_GENERATION_QUALIFIER }, + { ADD_STRLEN( "domainComponent" ), MBEDTLS_OID_DOMAIN_COMPONENT }, + { ADD_STRLEN( "DC" ), MBEDTLS_OID_DOMAIN_COMPONENT }, + { NULL, 0, NULL } }; -static const x509_attr_descriptor_t *x509_attr_descr_from_name( const char *name, size_t name_len ) +static const char *x509_at_oid_from_name( const char *name, size_t name_len ) { const x509_attr_descriptor_t *cur; @@ -120,19 +83,15 @@ static const x509_attr_descriptor_t *x509_attr_descr_from_name( const char *name strncmp( cur->name, name, name_len ) == 0 ) break; - if ( cur->name == NULL ) - return( NULL ); - - return( cur ); + return( cur->oid ); } -static int mbedtls_x509_string_to_names( mbedtls_asn1_named_data **head, const char *name ) +int mbedtls_x509_string_to_names( mbedtls_asn1_named_data **head, const char *name ) { int ret = 0; const char *s = name, *c = s; const char *end = s + strlen( s ); const char *oid = NULL; - const x509_attr_descriptor_t* attr_descr = NULL; int in_tag = 1; char data[MBEDTLS_X509_MAX_DN_NAME_SIZE]; char *d = data; @@ -144,13 +103,12 @@ static int mbedtls_x509_string_to_names( mbedtls_asn1_named_data **head, const c { if( in_tag && *c == '=' ) { - if( ( attr_descr = x509_attr_descr_from_name( s, c - s ) ) == NULL ) + if( ( oid = x509_at_oid_from_name( s, c - s ) ) == NULL ) { ret = MBEDTLS_ERR_X509_UNKNOWN_OID; goto exit; } - oid = attr_descr->oid; s = c + 1; in_tag = 0; d = data; @@ -169,19 +127,13 @@ static int mbedtls_x509_string_to_names( mbedtls_asn1_named_data **head, const c } else if( !in_tag && ( *c == ',' || c == end ) ) { - mbedtls_asn1_named_data* cur = - mbedtls_asn1_store_named_data( head, oid, strlen( oid ), - (unsigned char *) data, - d - data ); - - if(cur == NULL ) + if( mbedtls_asn1_store_named_data( head, oid, strlen( oid ), + (unsigned char *) data, + d - data ) == NULL ) { return( MBEDTLS_ERR_X509_ALLOC_FAILED ); } - // set tagType - cur->val.tag = attr_descr->default_tag; - while( c < end && *(c + 1) == ' ' ) c++; @@ -211,7 +163,7 @@ exit: /* The first byte of the value in the mbedtls_asn1_named_data structure is reserved * to store the critical boolean for us */ -static int mbedtls_x509_set_extension( mbedtls_asn1_named_data **head, const char *oid, size_t oid_len, +int mbedtls_x509_set_extension( mbedtls_asn1_named_data **head, const char *oid, size_t oid_len, int critical, const unsigned char *val, size_t val_len ) { mbedtls_asn1_named_data *cur; @@ -223,7 +175,7 @@ static int mbedtls_x509_set_extension( mbedtls_asn1_named_data **head, const cha } cur->val.p[0] = critical; - mbedtls_platform_memcpy( cur->val.p + 1, val, val_len ); + memcpy( cur->val.p + 1, val, val_len ); return( 0 ); } @@ -240,40 +192,46 @@ static int mbedtls_x509_set_extension( mbedtls_asn1_named_data **head, const cha * * AttributeValue ::= ANY DEFINED BY AttributeType */ -static int x509_write_name( unsigned char **p, unsigned char *start, mbedtls_asn1_named_data* cur_name) +static int x509_write_name( unsigned char **p, unsigned char *start, + const char *oid, size_t oid_len, + const unsigned char *name, size_t name_len ) { int ret; size_t len = 0; - const char *oid = (const char*)cur_name->oid.p; - size_t oid_len = cur_name->oid.len; - const unsigned char *name = cur_name->val.p; - size_t name_len = cur_name->val.len; - // Write correct string tag and value - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tagged_string( p, start, - cur_name->val.tag, - (const char *) name, - name_len ) ); + // Write PrintableString for all except MBEDTLS_OID_PKCS9_EMAIL + // + if( MBEDTLS_OID_SIZE( MBEDTLS_OID_PKCS9_EMAIL ) == oid_len && + memcmp( oid, MBEDTLS_OID_PKCS9_EMAIL, oid_len ) == 0 ) + { + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_ia5_string( p, start, + (const char *) name, + name_len ) ); + } + else + { + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_printable_string( p, start, + (const char *) name, + name_len ) ); + } + // Write OID // - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_oid( p, start, oid, - oid_len ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_oid( p, start, oid, oid_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_SEQUENCE ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_CONSTRUCTED | + MBEDTLS_ASN1_SEQUENCE ) ); 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 | MBEDTLS_ASN1_SET ) ); return( (int) len ); } int mbedtls_x509_write_names( unsigned char **p, unsigned char *start, - mbedtls_asn1_named_data *first ) + mbedtls_asn1_named_data *first ) { int ret; size_t len = 0; @@ -281,7 +239,9 @@ int mbedtls_x509_write_names( unsigned char **p, unsigned char *start, while( cur != NULL ) { - MBEDTLS_ASN1_CHK_ADD( len, x509_write_name( p, start, cur ) ); + MBEDTLS_ASN1_CHK_ADD( len, x509_write_name( p, start, (char *) cur->oid.p, + cur->oid.len, + cur->val.p, cur->val.len ) ); cur = cur->next; } @@ -292,7 +252,7 @@ int mbedtls_x509_write_names( unsigned char **p, unsigned char *start, return( (int) len ); } -static int mbedtls_x509_write_sig( unsigned char **p, unsigned char *start, +int mbedtls_x509_write_sig( unsigned char **p, unsigned char *start, const char *oid, size_t oid_len, unsigned char *sig, size_t size ) { @@ -304,7 +264,7 @@ static int mbedtls_x509_write_sig( unsigned char **p, unsigned char *start, len = size; (*p) -= len; - mbedtls_platform_memcpy( *p, sig, len ); + memcpy( *p, sig, len ); if( *p - start < 1 ) return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); @@ -361,7 +321,7 @@ static int x509_write_extension( unsigned char **p, unsigned char *start, * -- by extnID * } */ -static int mbedtls_x509_write_extensions( unsigned char **p, unsigned char *start, +int mbedtls_x509_write_extensions( unsigned char **p, unsigned char *start, mbedtls_asn1_named_data *first ) { int ret; diff --git a/APP_Framework/Framework/security/mbedtls/x509_crl.c b/APP_Framework/Framework/security/mbedtls/x509_crl.c index 8ee5e63d1..d3bccaa9e 100644 --- a/APP_Framework/Framework/security/mbedtls/x509_crl.c +++ b/APP_Framework/Framework/security/mbedtls/x509_crl.c @@ -38,9 +38,7 @@ #if defined(MBEDTLS_X509_CRL_PARSE_C) #include "x509_crl.h" -#include "x509_internal.h" #include "oid.h" -#include "platform_util.h" #include @@ -68,6 +66,11 @@ #include #endif +/* 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; +} + /* * Version ::= INTEGER { v1(0), v2(1) } */ @@ -104,17 +107,17 @@ static int x509_get_crl_ext( unsigned char **p, { int ret; - if( *p == end ) - return( 0 ); - /* * crlExtensions [0] EXPLICIT Extensions OPTIONAL * -- if present, version MUST be v2 */ if( ( ret = mbedtls_x509_get_ext( p, end, ext, 0 ) ) != 0 ) - return( ret ); + { + if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) + return( 0 ); - end = ext->p + ext->len; + return( ret ); + } while( *p < end ) { @@ -313,9 +316,9 @@ int mbedtls_x509_crl_parse_der( mbedtls_x509_crl *chain, if( crl == NULL || buf == NULL ) return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); - mbedtls_platform_memset( &sig_params1, 0, sizeof( mbedtls_x509_buf ) ); - mbedtls_platform_memset( &sig_params2, 0, sizeof( mbedtls_x509_buf ) ); - mbedtls_platform_memset( &sig_oid2, 0, sizeof( mbedtls_x509_buf ) ); + memset( &sig_params1, 0, sizeof( mbedtls_x509_buf ) ); + memset( &sig_params2, 0, sizeof( mbedtls_x509_buf ) ); + memset( &sig_oid2, 0, sizeof( mbedtls_x509_buf ) ); /* * Add new CRL on the end of the chain if needed. @@ -347,7 +350,7 @@ int mbedtls_x509_crl_parse_der( mbedtls_x509_crl *chain, if( p == NULL ) return( MBEDTLS_ERR_X509_ALLOC_FAILED ); - mbedtls_platform_memcpy( p, buf, buflen ); + memcpy( p, buf, buflen ); crl->raw.p = p; crl->raw.len = buflen; @@ -429,17 +432,15 @@ int mbedtls_x509_crl_parse_der( mbedtls_x509_crl *chain, mbedtls_x509_crl_free( crl ); return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); } - p += len; - crl->issuer_raw.len = p - crl->issuer_raw.p; - if( ( ret = mbedtls_x509_get_name( crl->issuer_raw.p, - crl->issuer_raw.len, - &crl->issuer ) ) != 0 ) + if( ( ret = mbedtls_x509_get_name( &p, p + len, &crl->issuer ) ) != 0 ) { mbedtls_x509_crl_free( crl ); return( ret ); } + crl->issuer_raw.len = p - crl->issuer_raw.p; + /* * thisUpdate Time * nextUpdate Time OPTIONAL @@ -511,10 +512,10 @@ int mbedtls_x509_crl_parse_der( mbedtls_x509_crl *chain, } if( crl->sig_oid.len != sig_oid2.len || - mbedtls_platform_memequal( crl->sig_oid.p, sig_oid2.p, crl->sig_oid.len ) != 0 || + memcmp( crl->sig_oid.p, sig_oid2.p, crl->sig_oid.len ) != 0 || sig_params1.len != sig_params2.len || ( sig_params1.len != 0 && - mbedtls_platform_memequal( sig_params1.p, sig_params2.p, sig_params1.len ) != 0 ) ) + memcmp( sig_params1.p, sig_params2.p, sig_params1.len ) != 0 ) ) { mbedtls_x509_crl_free( crl ); return( MBEDTLS_ERR_X509_SIG_MISMATCH ); @@ -615,14 +616,18 @@ int mbedtls_x509_crl_parse_file( mbedtls_x509_crl *chain, const char *path ) ret = mbedtls_x509_crl_parse( chain, buf, n ); - mbedtls_platform_zeroize( buf, n ); + mbedtls_zeroize( buf, n ); mbedtls_free( buf ); return( ret ); } #endif /* MBEDTLS_FS_IO */ -#if !defined(MBEDTLS_X509_REMOVE_INFO) +/* + * Return an informational string about the certificate. + */ +#define BEFORE_COLON 14 +#define BC "14" /* * Return an informational string about the CRL. */ @@ -688,8 +693,8 @@ int mbedtls_x509_crl_info( char *buf, size_t size, const char *prefix, ret = mbedtls_snprintf( p, n, "\n%ssigned using : ", prefix ); MBEDTLS_X509_SAFE_SNPRINTF; - ret = mbedtls_x509_sig_alg_gets( p, n, crl->sig_pk, - crl->sig_md, crl->sig_opts ); + ret = mbedtls_x509_sig_alg_gets( p, n, &crl->sig_oid, crl->sig_pk, crl->sig_md, + crl->sig_opts ); MBEDTLS_X509_SAFE_SNPRINTF; ret = mbedtls_snprintf( p, n, "\n" ); @@ -697,14 +702,13 @@ int mbedtls_x509_crl_info( char *buf, size_t size, const char *prefix, return( (int) ( size - n ) ); } -#endif /* !MBEDTLS_X509_REMOVE_INFO */ /* * Initialize a CRL chain */ void mbedtls_x509_crl_init( mbedtls_x509_crl *crl ) { - mbedtls_platform_memset( crl, 0, sizeof(mbedtls_x509_crl) ); + memset( crl, 0, sizeof(mbedtls_x509_crl) ); } /* @@ -733,7 +737,7 @@ void mbedtls_x509_crl_free( mbedtls_x509_crl *crl ) { name_prv = name_cur; name_cur = name_cur->next; - mbedtls_platform_zeroize( name_prv, sizeof( mbedtls_x509_name ) ); + mbedtls_zeroize( name_prv, sizeof( mbedtls_x509_name ) ); mbedtls_free( name_prv ); } @@ -742,14 +746,13 @@ void mbedtls_x509_crl_free( mbedtls_x509_crl *crl ) { entry_prv = entry_cur; entry_cur = entry_cur->next; - mbedtls_platform_zeroize( entry_prv, - sizeof( mbedtls_x509_crl_entry ) ); + mbedtls_zeroize( entry_prv, sizeof( mbedtls_x509_crl_entry ) ); mbedtls_free( entry_prv ); } if( crl_cur->raw.p != NULL ) { - mbedtls_platform_zeroize( crl_cur->raw.p, crl_cur->raw.len ); + mbedtls_zeroize( crl_cur->raw.p, crl_cur->raw.len ); mbedtls_free( crl_cur->raw.p ); } @@ -763,7 +766,7 @@ void mbedtls_x509_crl_free( mbedtls_x509_crl *crl ) crl_prv = crl_cur; crl_cur = crl_cur->next; - mbedtls_platform_zeroize( crl_prv, sizeof( mbedtls_x509_crl ) ); + mbedtls_zeroize( crl_prv, sizeof( mbedtls_x509_crl ) ); if( crl_prv != crl ) mbedtls_free( crl_prv ); } diff --git a/APP_Framework/Framework/security/mbedtls/x509_crl.h b/APP_Framework/Framework/security/mbedtls/x509_crl.h index e4e22332a..08a4283a6 100644 --- a/APP_Framework/Framework/security/mbedtls/x509_crl.h +++ b/APP_Framework/Framework/security/mbedtls/x509_crl.h @@ -69,22 +69,14 @@ mbedtls_x509_crl_entry; */ typedef struct mbedtls_x509_crl { - mbedtls_md_type_t sig_md; /**< Internal representation of the MD algorithm of the signature algorithm, e.g. MBEDTLS_MD_SHA256 */ - mbedtls_pk_type_t sig_pk; /**< Internal representation of the Public Key algorithm of the signature algorithm, e.g. MBEDTLS_PK_RSA */ - - int version; /**< CRL version (1=v1, 2=v2) */ - void *sig_opts; /**< Signature options to be passed to mbedtls_pk_verify_ext(), e.g. for RSASSA-PSS */ - - struct mbedtls_x509_crl *next; - - mbedtls_x509_buf_raw issuer_raw; /**< The raw issuer data (DER). */ - mbedtls_x509_buf raw; /**< The raw certificate data (DER). */ mbedtls_x509_buf tbs; /**< The raw certificate body (DER). The part that is To Be Signed. */ - + int version; /**< CRL version (1=v1, 2=v2) */ mbedtls_x509_buf sig_oid; /**< CRL signature type identifier */ + mbedtls_x509_buf issuer_raw; /**< The raw issuer data (DER). */ + mbedtls_x509_name issuer; /**< The parsed issuer data (named information object). */ mbedtls_x509_time this_update; @@ -96,6 +88,11 @@ typedef struct mbedtls_x509_crl mbedtls_x509_buf sig_oid2; mbedtls_x509_buf sig; + mbedtls_md_type_t sig_md; /**< Internal representation of the MD algorithm of the signature algorithm, e.g. MBEDTLS_MD_SHA256 */ + mbedtls_pk_type_t sig_pk; /**< Internal representation of the Public Key algorithm of the signature algorithm, e.g. MBEDTLS_PK_RSA */ + void *sig_opts; /**< Signature options to be passed to mbedtls_pk_verify_ext(), e.g. for RSASSA-PSS */ + + struct mbedtls_x509_crl *next; } mbedtls_x509_crl; @@ -114,7 +111,7 @@ int mbedtls_x509_crl_parse_der( mbedtls_x509_crl *chain, /** * \brief Parse one or more CRLs and append them to the chained list * - * \note Multiple CRLs are accepted only if using PEM format + * \note Mutliple CRLs are accepted only if using PEM format * * \param chain points to the start of the chain * \param buf buffer holding the CRL data in PEM or DER format @@ -129,7 +126,7 @@ int mbedtls_x509_crl_parse( mbedtls_x509_crl *chain, const unsigned char *buf, s /** * \brief Load one or more CRLs and append them to the chained list * - * \note Multiple CRLs are accepted only if using PEM format + * \note Mutliple CRLs are accepted only if using PEM format * * \param chain points to the start of the chain * \param path filename to read the CRLs from (in PEM or DER encoding) @@ -139,7 +136,6 @@ int mbedtls_x509_crl_parse( mbedtls_x509_crl *chain, const unsigned char *buf, s int mbedtls_x509_crl_parse_file( mbedtls_x509_crl *chain, const char *path ); #endif /* MBEDTLS_FS_IO */ -#if !defined(MBEDTLS_X509_REMOVE_INFO) /** * \brief Returns an informational string about the CRL. * @@ -153,7 +149,6 @@ int mbedtls_x509_crl_parse_file( mbedtls_x509_crl *chain, const char *path ); */ int mbedtls_x509_crl_info( char *buf, size_t size, const char *prefix, const mbedtls_x509_crl *crl ); -#endif /* !MBEDTLS_X509_REMOVE_INFO */ /** * \brief Initialize a CRL (chain) diff --git a/APP_Framework/Framework/security/mbedtls/x509_crt.c b/APP_Framework/Framework/security/mbedtls/x509_crt.c index ed2a89f7d..e1ea1f735 100644 --- a/APP_Framework/Framework/security/mbedtls/x509_crt.c +++ b/APP_Framework/Framework/security/mbedtls/x509_crt.c @@ -27,8 +27,6 @@ * * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf - * - * [SIRO] https://cabforum.org/wp-content/uploads/Chunghwatelecom201503cabforumV4.pdf */ #if !defined(MBEDTLS_CONFIG_FILE) @@ -40,10 +38,7 @@ #if defined(MBEDTLS_X509_CRT_PARSE_C) #include "x509_crt.h" -#include "x509_internal.h" #include "oid.h" -#include "platform_util.h" -#include "platform.h" #include @@ -80,408 +75,11 @@ #endif /* !_WIN32 || EFIX64 || EFI32 */ #endif -#if !defined(MBEDTLS_X509_ON_DEMAND_PARSING) -static void x509_buf_to_buf_raw( mbedtls_x509_buf_raw *dst, - mbedtls_x509_buf const *src ) -{ - dst->p = src->p; - dst->len = src->len; +/* 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; } -static void x509_buf_raw_to_buf( mbedtls_x509_buf *dst, - mbedtls_x509_buf_raw const *src ) -{ - dst->p = src->p; - dst->len = src->len; -} -#endif /* MBEDTLS_X509_ON_DEMAND_PARSING */ - -static int x509_crt_parse_frame( unsigned char *start, - unsigned char *end, - mbedtls_x509_crt_frame *frame ); -static int x509_crt_subject_from_frame( mbedtls_x509_crt_frame const *frame, - mbedtls_x509_name *subject ); -static int x509_crt_issuer_from_frame( mbedtls_x509_crt_frame const *frame, - mbedtls_x509_name *issuer ); -#if !defined(MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION) -static int x509_crt_subject_alt_from_frame( mbedtls_x509_crt_frame const *frame, - mbedtls_x509_sequence *subject_alt ); -#endif /* !MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION */ -static int x509_crt_ext_key_usage_from_frame( mbedtls_x509_crt_frame const *frame, - mbedtls_x509_sequence *ext_key_usage ); - -static int mbedtls_x509_crt_flush_cache_pk( mbedtls_x509_crt const *crt ) -{ -#if defined(MBEDTLS_THREADING_C) - if( mbedtls_mutex_lock( &crt->cache->pk_mutex ) != 0 ) - return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); -#endif - -#if !defined(MBEDTLS_X509_ALWAYS_FLUSH) || \ - defined(MBEDTLS_THREADING_C) - /* Can only free the PK context if nobody is using it. - * If MBEDTLS_X509_ALWAYS_FLUSH is set, nested uses - * of xxx_acquire() are prohibited, and no reference - * counting is needed. Also, notice that the code-path - * below is safe if the cache isn't filled. */ - if( crt->cache->pk_readers == 0 ) -#endif /* !MBEDTLS_X509_ALWAYS_FLUSH || - MBEDTLS_THREADING_C */ - { -#if !defined(MBEDTLS_X509_ON_DEMAND_PARSING) - /* The cache holds a shallow copy of the PK context - * in the legacy struct, so don't free PK context. */ - mbedtls_free( crt->cache->pk ); -#else - mbedtls_pk_free( crt->cache->pk ); - mbedtls_free( crt->cache->pk ); -#endif /* MBEDTLS_X509_ON_DEMAND_PARSING */ - crt->cache->pk = NULL; - } - -#if defined(MBEDTLS_THREADING_C) - if( mbedtls_mutex_unlock( &crt->cache->pk_mutex ) != 0 ) - return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); -#endif - return( 0 ); -} - -static int mbedtls_x509_crt_flush_cache_frame( mbedtls_x509_crt const *crt ) -{ -#if defined(MBEDTLS_THREADING_C) - if( mbedtls_mutex_lock( &crt->cache->frame_mutex ) != 0 ) - return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); -#endif - -#if !defined(MBEDTLS_X509_ALWAYS_FLUSH) || \ - defined(MBEDTLS_THREADING_C) - /* Can only free the PK context if nobody is using it. - * If MBEDTLS_X509_ALWAYS_FLUSH is set, nested uses - * of xxx_acquire() are prohibited, and no reference - * counting is needed. Also, notice that the code-path - * below is safe if the cache isn't filled. */ - if( crt->cache->frame_readers == 0 ) -#endif /* !MBEDTLS_X509_ALWAYS_FLUSH || - MBEDTLS_THREADING_C */ - { - mbedtls_free( crt->cache->frame ); - crt->cache->frame = NULL; - } - -#if defined(MBEDTLS_THREADING_C) - if( mbedtls_mutex_unlock( &crt->cache->frame_mutex ) != 0 ) - return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); -#endif - return( 0 ); -} - -int mbedtls_x509_crt_flush_cache( mbedtls_x509_crt const *crt ) -{ - int ret; - ret = mbedtls_x509_crt_flush_cache_frame( crt ); - if( ret != 0 ) - return( ret ); - ret = mbedtls_x509_crt_flush_cache_pk( crt ); - if( ret != 0 ) - return( ret ); - return( 0 ); -} - -static int x509_crt_frame_parse_ext( mbedtls_x509_crt_frame *frame ); - -static int mbedtls_x509_crt_cache_provide_frame( mbedtls_x509_crt const *crt ) -{ - mbedtls_x509_crt_cache *cache = crt->cache; - mbedtls_x509_crt_frame *frame; - - if( cache->frame != NULL ) - { -#if !defined(MBEDTLS_X509_ALWAYS_FLUSH) || \ - defined(MBEDTLS_THREADING_C) - return( 0 ); -#else - /* If MBEDTLS_X509_ALWAYS_FLUSH is set, we don't - * allow nested uses of acquire. */ - return( MBEDTLS_ERR_X509_FATAL_ERROR ); -#endif - } - - frame = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt_frame ) ); - if( frame == NULL ) - return( MBEDTLS_ERR_X509_ALLOC_FAILED ); - cache->frame = frame; - -#if defined(MBEDTLS_X509_ON_DEMAND_PARSING) - /* This would work with !MBEDTLS_X509_ON_DEMAND_PARSING, too, - * but is inefficient compared to copying the respective fields - * from the legacy mbedtls_x509_crt. */ - return( x509_crt_parse_frame( crt->raw.p, - crt->raw.p + crt->raw.len, - frame ) ); -#else /* MBEDTLS_X509_ON_DEMAND_PARSING */ - /* Make sure all extension related fields are properly initialized. */ - frame->ca_istrue = 0; - frame->max_pathlen = 0; - frame->ext_types = 0; - frame->version = crt->version; - frame->sig_md = crt->sig_md; - frame->sig_pk = crt->sig_pk; - -#if !defined(MBEDTLS_X509_CRT_REMOVE_TIME) - frame->valid_from = crt->valid_from; - frame->valid_to = crt->valid_to; -#endif /* !MBEDTLS_X509_CRT_REMOVE_TIME */ - - x509_buf_to_buf_raw( &frame->raw, &crt->raw ); - x509_buf_to_buf_raw( &frame->tbs, &crt->tbs ); - x509_buf_to_buf_raw( &frame->serial, &crt->serial ); - x509_buf_to_buf_raw( &frame->pubkey_raw, &crt->pk_raw ); - x509_buf_to_buf_raw( &frame->issuer_raw, &crt->issuer_raw ); - x509_buf_to_buf_raw( &frame->subject_raw, &crt->subject_raw ); -#if !defined(MBEDTLS_X509_CRT_REMOVE_SUBJECT_ISSUER_ID) - x509_buf_to_buf_raw( &frame->subject_id, &crt->subject_id ); - x509_buf_to_buf_raw( &frame->issuer_id, &crt->issuer_id ); -#endif /* !MBEDTLS_X509_CRT_REMOVE_SUBJECT_ISSUER_ID */ - x509_buf_to_buf_raw( &frame->sig, &crt->sig ); - x509_buf_to_buf_raw( &frame->v3_ext, &crt->v3_ext ); - - /* The legacy CRT structure doesn't explicitly contain - * the `AlgorithmIdentifier` bounds; however, those can - * be inferred from the surrounding (mandatory) `SerialNumber` - * and `Issuer` fields. */ - frame->sig_alg.p = crt->serial.p + crt->serial.len; - frame->sig_alg.len = crt->issuer_raw.p - frame->sig_alg.p; - - return( x509_crt_frame_parse_ext( frame ) ); -#endif /* !MBEDTLS_X509_ON_DEMAND_PARSING */ -} - -static int mbedtls_x509_crt_cache_provide_pk( mbedtls_x509_crt const *crt ) -{ - mbedtls_x509_crt_cache *cache = crt->cache; - mbedtls_pk_context *pk; - - if( cache->pk != NULL ) - { -#if !defined(MBEDTLS_X509_ALWAYS_FLUSH) || \ - defined(MBEDTLS_THREADING_C) - return( 0 ); -#else - /* If MBEDTLS_X509_ALWAYS_FLUSH is set, we don't - * allow nested uses of acquire. */ - return( MBEDTLS_ERR_X509_FATAL_ERROR ); -#endif - } - - pk = mbedtls_calloc( 1, sizeof( mbedtls_pk_context ) ); - if( pk == NULL ) - return( MBEDTLS_ERR_X509_ALLOC_FAILED ); - cache->pk = pk; - -#if !defined(MBEDTLS_X509_ON_DEMAND_PARSING) - *pk = crt->pk; - return( 0 ); -#else - { - mbedtls_x509_buf_raw pk_raw = cache->pk_raw; - return( mbedtls_pk_parse_subpubkey( &pk_raw.p, - pk_raw.p + pk_raw.len, - pk ) ); - } -#endif /* MBEDTLS_X509_ON_DEMAND_PARSING */ -} - -static void x509_crt_cache_init( mbedtls_x509_crt_cache *cache ) -{ - memset( cache, 0, sizeof( *cache ) ); -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_init( &cache->frame_mutex ); - mbedtls_mutex_init( &cache->pk_mutex ); -#endif -} - -static void x509_crt_cache_clear_pk( mbedtls_x509_crt_cache *cache ) -{ -#if !defined(MBEDTLS_X509_ON_DEMAND_PARSING) - /* The cache holds a shallow copy of the PK context - * in the legacy struct, so don't free PK context. */ - mbedtls_free( cache->pk ); -#else - mbedtls_pk_free( cache->pk ); - mbedtls_free( cache->pk ); -#endif /* MBEDTLS_X509_ON_DEMAND_PARSING */ - - cache->pk = NULL; -} - -static void x509_crt_cache_clear_frame( mbedtls_x509_crt_cache *cache ) -{ - mbedtls_free( cache->frame ); - cache->frame = NULL; -} - -static void x509_crt_cache_free( mbedtls_x509_crt_cache *cache ) -{ - if( cache == NULL ) - return; - -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_free( &cache->frame_mutex ); - mbedtls_mutex_free( &cache->pk_mutex ); -#endif - - x509_crt_cache_clear_frame( cache ); - x509_crt_cache_clear_pk( cache ); - - mbedtls_platform_memset( cache, 0, sizeof( *cache ) ); -} - -#if !defined(MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION) -int mbedtls_x509_crt_get_subject_alt_names( mbedtls_x509_crt const *crt, - mbedtls_x509_sequence **subj_alt ) -{ - int ret; - mbedtls_x509_crt_frame const *frame; - mbedtls_x509_sequence *seq; - - ret = mbedtls_x509_crt_frame_acquire( crt, &frame ); - if( ret != 0 ) - return( ret ); - - seq = mbedtls_calloc( 1, sizeof( mbedtls_x509_sequence ) ); - if( seq == NULL ) - ret = MBEDTLS_ERR_X509_ALLOC_FAILED; - else - ret = x509_crt_subject_alt_from_frame( frame, seq ); - - mbedtls_x509_crt_frame_release( crt ); - - *subj_alt = seq; - return( ret ); -} -#endif /* !MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION */ - -int mbedtls_x509_crt_get_ext_key_usage( mbedtls_x509_crt const *crt, - mbedtls_x509_sequence **ext_key_usage ) -{ - int ret; - mbedtls_x509_crt_frame const *frame; - mbedtls_x509_sequence *seq; - - ret = mbedtls_x509_crt_frame_acquire( crt, &frame ); - if( ret != 0 ) - return( ret ); - - seq = mbedtls_calloc( 1, sizeof( mbedtls_x509_sequence ) ); - if( seq == NULL ) - ret = MBEDTLS_ERR_X509_ALLOC_FAILED; - else - ret = x509_crt_ext_key_usage_from_frame( frame, seq ); - - mbedtls_x509_crt_frame_release( crt ); - - *ext_key_usage = seq; - return( ret ); -} - -int mbedtls_x509_crt_get_subject( mbedtls_x509_crt const *crt, - mbedtls_x509_name **subject ) -{ - int ret; - mbedtls_x509_crt_frame const *frame; - mbedtls_x509_name *name; - - ret = mbedtls_x509_crt_frame_acquire( crt, &frame ); - if( ret != 0 ) - return( ret ); - - name = mbedtls_calloc( 1, sizeof( mbedtls_x509_name ) ); - if( name == NULL ) - ret = MBEDTLS_ERR_X509_ALLOC_FAILED; - else - ret = x509_crt_subject_from_frame( frame, name ); - - mbedtls_x509_crt_frame_release( crt ); - - *subject = name; - return( ret ); -} - -int mbedtls_x509_crt_get_issuer( mbedtls_x509_crt const *crt, - mbedtls_x509_name **issuer ) -{ - int ret; - mbedtls_x509_crt_frame const *frame; - mbedtls_x509_name *name; - - ret = mbedtls_x509_crt_frame_acquire( crt, &frame ); - if( ret != 0 ) - return( ret ); - - name = mbedtls_calloc( 1, sizeof( mbedtls_x509_name ) ); - if( name == NULL ) - ret = MBEDTLS_ERR_X509_ALLOC_FAILED; - else - ret = x509_crt_issuer_from_frame( frame, name ); - - mbedtls_x509_crt_frame_release( crt ); - - *issuer = name; - return( ret ); -} - -int mbedtls_x509_crt_get_frame( mbedtls_x509_crt const *crt, - mbedtls_x509_crt_frame *dst ) -{ - int ret; - mbedtls_x509_crt_frame const *frame; - ret = mbedtls_x509_crt_frame_acquire( crt, &frame ); - if( ret != 0 ) - return( ret ); - *dst = *frame; - mbedtls_x509_crt_frame_release( crt ); - return( 0 ); -} - -int mbedtls_x509_crt_get_pk( mbedtls_x509_crt const *crt, - mbedtls_pk_context *dst ) -{ -#if !defined(MBEDTLS_X509_ON_DEMAND_PARSING) - mbedtls_x509_buf_raw pk_raw = crt->cache->pk_raw; - return( mbedtls_pk_parse_subpubkey( &pk_raw.p, - pk_raw.p + pk_raw.len, - dst ) ); -#else /* !MBEDTLS_X509_ON_DEMAND_PARSING */ - int ret; - mbedtls_pk_context *pk; - ret = mbedtls_x509_crt_pk_acquire( crt, &pk ); - if( ret != 0 ) - return( ret ); - - /* Move PK from CRT cache to destination pointer - * to avoid a copy. */ - *dst = *pk; - mbedtls_free( crt->cache->pk ); - crt->cache->pk = NULL; - - mbedtls_x509_crt_pk_release( crt ); - return( 0 ); -#endif /* MBEDTLS_X509_ON_DEMAND_PARSING */ -} - -/* - * Item in a verification chain: cert and flags for it - */ -typedef struct { - mbedtls_x509_crt *crt; - uint32_t flags; -} x509_crt_verify_chain_item; - -/* - * Max size of verification chain: end-entity + intermediates + trusted root - */ -#define X509_MAX_VERIFY_CHAIN_SIZE ( MBEDTLS_X509_MAX_INTERMEDIATE_CA + 2 ) - /* * Default profile */ @@ -511,9 +109,7 @@ const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_next = MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ) | MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA512 ), 0xFFFFFFF, /* Any PK alg */ -#if defined(MBEDTLS_USE_TINYCRYPT) - MBEDTLS_X509_ID_FLAG( MBEDTLS_UECC_DP_SECP256R1 ), -#elif defined(MBEDTLS_ECP_C) +#if defined(MBEDTLS_ECP_C) /* Curves at or above 128-bit security level */ MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256R1 ) | MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP384R1 ) | @@ -539,9 +135,7 @@ const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_suiteb = /* Only ECDSA */ MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_ECDSA ) | MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_ECKEY ), -#if defined(MBEDTLS_USE_TINYCRYPT) - MBEDTLS_X509_ID_FLAG( MBEDTLS_UECC_DP_SECP256R1 ), -#elif defined(MBEDTLS_ECP_C) +#if defined(MBEDTLS_ECP_C) /* Only NIST P-256 and P-384 */ MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256R1 ) | MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP384R1 ), @@ -553,7 +147,7 @@ const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_suiteb = /* * Check md_alg against profile - * Return 0 if md_alg is acceptable for this profile, -1 otherwise + * Return 0 if md_alg acceptable for this profile, -1 otherwise */ static int x509_profile_check_md_alg( const mbedtls_x509_crt_profile *profile, mbedtls_md_type_t md_alg ) @@ -569,7 +163,7 @@ static int x509_profile_check_md_alg( const mbedtls_x509_crt_profile *profile, /* * Check pk_alg against profile - * Return 0 if pk_alg is acceptable for this profile, -1 otherwise + * Return 0 if pk_alg acceptable for this profile, -1 otherwise */ static int x509_profile_check_pk_alg( const mbedtls_x509_crt_profile *profile, mbedtls_pk_type_t pk_alg ) @@ -585,13 +179,12 @@ static int x509_profile_check_pk_alg( const mbedtls_x509_crt_profile *profile, /* * Check key against profile - * Return 0 if pk is acceptable for this profile, -1 otherwise + * Return 0 if pk_alg acceptable for this profile, -1 otherwise */ static int x509_profile_check_key( const mbedtls_x509_crt_profile *profile, + mbedtls_pk_type_t pk_alg, const mbedtls_pk_context *pk ) { - const mbedtls_pk_type_t pk_alg = mbedtls_pk_get_type( pk ); - #if defined(MBEDTLS_RSA_C) if( pk_alg == MBEDTLS_PK_RSA || pk_alg == MBEDTLS_PK_RSASSA_PSS ) { @@ -602,22 +195,12 @@ static int x509_profile_check_key( const mbedtls_x509_crt_profile *profile, } #endif -#if defined(MBEDTLS_USE_TINYCRYPT) - if( pk_alg == MBEDTLS_PK_ECKEY ) - { - if( ( profile->allowed_curves & MBEDTLS_UECC_DP_SECP256R1 ) != 0 ) - return( 0 ); - - return( -1 ); - } -#endif /* MBEDTLS_USE_TINYCRYPT */ - #if defined(MBEDTLS_ECP_C) if( pk_alg == MBEDTLS_PK_ECDSA || pk_alg == MBEDTLS_PK_ECKEY || pk_alg == MBEDTLS_PK_ECKEY_DH ) { - const 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 ); @@ -632,44 +215,6 @@ static int x509_profile_check_key( const mbedtls_x509_crt_profile *profile, return( -1 ); } -#if !defined(MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION) -/* - * Return 0 if name matches wildcard, -1 otherwise - */ -static int x509_check_wildcard( char const *cn, - size_t cn_len, - unsigned char const *buf, - size_t buf_len ) -{ - size_t i; - size_t cn_idx = 0; - - /* We can't have a match if there is no wildcard to match */ - if( buf_len < 3 || buf[0] != '*' || buf[1] != '.' ) - return( -1 ); - - for( i = 0; i < cn_len; ++i ) - { - if( cn[i] == '.' ) - { - cn_idx = i; - break; - } - } - - if( cn_idx == 0 ) - return( -1 ); - - if( mbedtls_x509_memcasecmp( buf + 1, cn + cn_idx, - buf_len - 1, cn_len - cn_idx ) == 0 ) - { - return( 0 ); - } - - return( -1 ); -} -#endif /* !MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION */ - /* * Version ::= INTEGER { v1(0), v2(1), v3(2) } */ @@ -689,7 +234,7 @@ static int x509_get_version( unsigned char **p, return( 0 ); } - return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); + return( ret ); } end = *p + len; @@ -704,7 +249,6 @@ static int x509_get_version( unsigned char **p, return( 0 ); } -#if !defined(MBEDTLS_X509_CRT_REMOVE_TIME) /* * Validity ::= SEQUENCE { * notBefore Time, @@ -736,44 +280,28 @@ static int x509_get_dates( unsigned char **p, return( 0 ); } -#else /* !MBEDTLS_X509_CRT_REMOVE_TIME */ -static int x509_skip_dates( unsigned char **p, - const unsigned char *end ) -{ - int ret; - size_t len; - if( ( ret = mbedtls_asn1_get_tag( p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_DATE + ret ); - - /* skip contents of the sequence */ - *p += len; - - return( 0 ); -} -#endif /* MBEDTLS_X509_CRT_REMOVE_TIME */ - -#if !defined(MBEDTLS_X509_CRT_REMOVE_SUBJECT_ISSUER_ID) /* * X.509 v2/v3 unique identifier (not parsed) */ static int x509_get_uid( unsigned char **p, const unsigned char *end, - mbedtls_x509_buf_raw *uid, int n ) + mbedtls_x509_buf *uid, int n ) { int ret; if( *p == end ) return( 0 ); + uid->tag = **p; + if( ( ret = mbedtls_asn1_get_tag( p, end, &uid->len, MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | n ) ) != 0 ) { if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) return( 0 ); - return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); + return( ret ); } uid->p = *p; @@ -781,30 +309,6 @@ static int x509_get_uid( unsigned char **p, return( 0 ); } -#else /* !MBEDTLS_X509_CRT_REMOVE_SUBJECT_ISSUER_ID */ -static int x509_skip_uid( unsigned char **p, - const unsigned char *end, - int n ) -{ - int ret; - size_t len; - - if( *p == end ) - return( 0 ); - - if( ( ret = mbedtls_asn1_get_tag( p, end, &len, - MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | n ) ) != 0 ) - { - if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) - return( 0 ); - - return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); - } - - *p += len; - return( 0 ); -} -#endif /* MBEDTLS_X509_CRT_REMOVE_SUBJECT_ISSUER_ID */ static int x509_get_basic_constraints( unsigned char **p, const unsigned char *end, @@ -824,7 +328,7 @@ static int x509_get_basic_constraints( unsigned char **p, if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - return( ret ); + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); if( *p == end ) return( 0 ); @@ -835,7 +339,7 @@ static int x509_get_basic_constraints( unsigned char **p, ret = mbedtls_asn1_get_int( p, end, ca_istrue ); if( ret != 0 ) - return( ret ); + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); if( *ca_istrue != 0 ) *ca_istrue = 1; @@ -845,15 +349,11 @@ static int x509_get_basic_constraints( unsigned char **p, return( 0 ); if( ( ret = mbedtls_asn1_get_int( p, end, max_pathlen ) ) != 0 ) - return( ret ); + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); if( *p != end ) - return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - /* Do not accept max_pathlen equal to INT_MAX to avoid a signed integer - * overflow, which is an undefined behavior. */ - if( *max_pathlen == INT_MAX ) - return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); (*max_pathlen)++; @@ -868,10 +368,11 @@ static int x509_get_ns_cert_type( unsigned char **p, mbedtls_x509_bitstring bs = { 0, 0, NULL }; if( ( ret = mbedtls_asn1_get_bitstring( p, end, &bs ) ) != 0 ) - return( ret ); + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); if( bs.len != 1 ) - return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + + MBEDTLS_ERR_ASN1_INVALID_LENGTH ); /* Get actual bitstring */ *ns_cert_type = *bs.p; @@ -880,53 +381,29 @@ static int x509_get_ns_cert_type( unsigned char **p, static int x509_get_key_usage( unsigned char **p, const unsigned char *end, - uint16_t *key_usage) + unsigned int *key_usage) { int ret; size_t i; mbedtls_x509_bitstring bs = { 0, 0, NULL }; if( ( ret = mbedtls_asn1_get_bitstring( p, end, &bs ) ) != 0 ) - return( ret ); + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); if( bs.len < 1 ) - return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + + MBEDTLS_ERR_ASN1_INVALID_LENGTH ); /* Get actual bitstring */ *key_usage = 0; - for( i = 0; i < bs.len && i < sizeof( *key_usage ); i++ ) + for( i = 0; i < bs.len && i < sizeof( unsigned int ); i++ ) { - *key_usage |= (uint16_t) bs.p[i] << ( 8*i ); + *key_usage |= (unsigned int) bs.p[i] << (8*i); } return( 0 ); } -static int asn1_build_sequence_cb( void *ctx, - int tag, - unsigned char *data, - size_t data_len ) -{ - mbedtls_asn1_sequence **cur_ptr = (mbedtls_asn1_sequence **) ctx; - mbedtls_asn1_sequence *cur = *cur_ptr; - - /* Allocate and assign next pointer */ - if( cur->buf.p != NULL ) - { - cur->next = mbedtls_calloc( 1, sizeof( mbedtls_asn1_sequence ) ); - if( cur->next == NULL ) - return( MBEDTLS_ERR_ASN1_ALLOC_FAILED ); - cur = cur->next; - } - - cur->buf.tag = tag; - cur->buf.p = data; - cur->buf.len = data_len; - - *cur_ptr = cur; - return( 0 ); -} - /* * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId * @@ -936,14 +413,19 @@ static int x509_get_ext_key_usage( unsigned char **p, const unsigned char *end, mbedtls_x509_sequence *ext_key_usage) { - return( mbedtls_asn1_traverse_sequence_of( p, end, - 0xFF, MBEDTLS_ASN1_OID, - 0, 0, - asn1_build_sequence_cb, - (void *) &ext_key_usage ) ); + int ret; + + if( ( ret = mbedtls_asn1_get_sequence_of( p, end, ext_key_usage, MBEDTLS_ASN1_OID ) ) != 0 ) + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); + + /* Sequence length must be >= 1 */ + if( ext_key_usage->buf.p == NULL ) + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + + MBEDTLS_ERR_ASN1_INVALID_LENGTH ); + + return( 0 ); } -#if !defined(MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION) /* * SubjectAltName ::= GeneralNames * @@ -970,769 +452,483 @@ static int x509_get_ext_key_usage( unsigned char **p, * * NOTE: we only parse and use dNSName at this point. */ -static int x509_get_subject_alt_name( unsigned char *p, +static int x509_get_subject_alt_name( unsigned char **p, const unsigned char *end, mbedtls_x509_sequence *subject_alt_name ) { - return( mbedtls_asn1_traverse_sequence_of( &p, end, - MBEDTLS_ASN1_TAG_CLASS_MASK, - MBEDTLS_ASN1_CONTEXT_SPECIFIC, - MBEDTLS_ASN1_TAG_VALUE_MASK, - 2 /* SubjectAlt DNS */, - asn1_build_sequence_cb, - (void *) &subject_alt_name ) ); + int ret; + size_t len, tag_len; + mbedtls_asn1_buf *buf; + unsigned char tag; + mbedtls_asn1_sequence *cur = subject_alt_name; + + /* Get main sequence tag */ + if( ( ret = mbedtls_asn1_get_tag( p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); + + if( *p + len != end ) + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + + while( *p < end ) + { + if( ( end - *p ) < 1 ) + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + + MBEDTLS_ERR_ASN1_OUT_OF_DATA ); + + tag = **p; + (*p)++; + if( ( ret = mbedtls_asn1_get_len( p, end, &tag_len ) ) != 0 ) + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); + + if( ( tag & MBEDTLS_ASN1_TAG_CLASS_MASK ) != + MBEDTLS_ASN1_CONTEXT_SPECIFIC ) + { + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + + MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); + } + + /* Skip everything but DNS name */ + if( tag != ( MBEDTLS_ASN1_CONTEXT_SPECIFIC | 2 ) ) + { + *p += tag_len; + continue; + } + + /* Allocate and assign next pointer */ + if( cur->buf.p != NULL ) + { + if( cur->next != NULL ) + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS ); + + cur->next = mbedtls_calloc( 1, sizeof( mbedtls_asn1_sequence ) ); + + if( cur->next == NULL ) + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + + MBEDTLS_ERR_ASN1_ALLOC_FAILED ); + + cur = cur->next; + } + + buf = &(cur->buf); + buf->tag = tag; + buf->p = *p; + buf->len = tag_len; + *p += buf->len; + } + + /* Set final sequence entry's next pointer to NULL */ + cur->next = NULL; + + if( *p != end ) + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + + return( 0 ); } -#endif /* !MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION */ /* * X.509 v3 extensions * */ -static int x509_crt_get_ext_cb( void *ctx, - int tag, - unsigned char *p, - size_t ext_len ) +static int x509_get_crt_ext( unsigned char **p, + const unsigned char *end, + mbedtls_x509_crt *crt ) { int ret; - mbedtls_x509_crt_frame *frame = (mbedtls_x509_crt_frame *) ctx; size_t len; - unsigned char *end, *end_ext_octet; - mbedtls_x509_buf extn_oid = { 0, 0, NULL }; - int is_critical = 0; /* DEFAULT FALSE */ - int ext_type = 0; + unsigned char *end_ext_data, *end_ext_octet; - ((void) tag); - - /* - * Extension ::= SEQUENCE { - * extnID OBJECT IDENTIFIER, - * critical BOOLEAN DEFAULT FALSE, - * extnValue OCTET STRING } - */ - - end = p + ext_len; - - /* Get extension ID */ - if( ( ret = mbedtls_asn1_get_tag( &p, end, &extn_oid.len, - MBEDTLS_ASN1_OID ) ) != 0 ) - goto err; - - extn_oid.tag = MBEDTLS_ASN1_OID; - extn_oid.p = p; - p += extn_oid.len; - - /* Get optional critical */ - if( ( ret = mbedtls_asn1_get_bool( &p, end, &is_critical ) ) != 0 && - ( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) ) - goto err; - - /* Data should be octet string type */ - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ) - goto err; - - end_ext_octet = p + len; - if( end_ext_octet != end ) + if( ( ret = mbedtls_x509_get_ext( p, end, &crt->v3_ext, 3 ) ) != 0 ) { - ret = MBEDTLS_ERR_ASN1_LENGTH_MISMATCH; - goto err; + if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) + return( 0 ); + + return( ret ); } - /* - * Detect supported extensions - */ - ret = mbedtls_oid_get_x509_ext_type( &extn_oid, &ext_type ); - if( ret != 0 ) + while( *p < end ) { + /* + * Extension ::= SEQUENCE { + * extnID OBJECT IDENTIFIER, + * critical BOOLEAN DEFAULT FALSE, + * extnValue OCTET STRING } + */ + mbedtls_x509_buf extn_oid = {0, 0, NULL}; + int is_critical = 0; /* DEFAULT FALSE */ + int ext_type = 0; + + if( ( ret = mbedtls_asn1_get_tag( p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); + + end_ext_data = *p + len; + + /* Get extension ID */ + if( ( ret = mbedtls_asn1_get_tag( p, end_ext_data, &extn_oid.len, + MBEDTLS_ASN1_OID ) ) != 0 ) + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); + + extn_oid.tag = MBEDTLS_ASN1_OID; + extn_oid.p = *p; + *p += extn_oid.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 ); + + end_ext_octet = *p + len; + + if( end_ext_octet != end_ext_data ) + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + + /* + * Detect supported extensions + */ + ret = mbedtls_oid_get_x509_ext_type( &extn_oid, &ext_type ); + + if( ret != 0 ) + { + /* No parser found, skip extension */ + *p = end_ext_octet; + #if !defined(MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION) - if( is_critical ) - { - /* Data is marked as critical: fail */ - ret = MBEDTLS_ERR_ASN1_UNEXPECTED_TAG; - goto err; + if( is_critical ) + { + /* Data is marked as critical: fail */ + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + + MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); + } +#endif + continue; } -#endif /* MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION */ - return( 0 ); - } - /* Forbid repeated extensions */ - if( ( frame->ext_types & ext_type ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS ); + /* Forbid repeated extensions */ + if( ( crt->ext_types & ext_type ) != 0 ) + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS ); - frame->ext_types |= ext_type; - switch( ext_type ) - { + crt->ext_types |= ext_type; + + switch( ext_type ) + { case MBEDTLS_X509_EXT_BASIC_CONSTRAINTS: - { - int ca_istrue; - int max_pathlen; - /* Parse basic constraints */ - ret = x509_get_basic_constraints( &p, end_ext_octet, - &ca_istrue, - &max_pathlen ); - if( ret != 0 ) - goto err; - - frame->ca_istrue = ca_istrue; - frame->max_pathlen = max_pathlen; + if( ( ret = x509_get_basic_constraints( p, end_ext_octet, + &crt->ca_istrue, &crt->max_pathlen ) ) != 0 ) + return( ret ); break; - } case MBEDTLS_X509_EXT_KEY_USAGE: /* Parse key usage */ - ret = x509_get_key_usage( &p, end_ext_octet, - &frame->key_usage ); - if( ret != 0 ) - goto err; - break; - - case MBEDTLS_X509_EXT_SUBJECT_ALT_NAME: -#if !defined(MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION) - /* Copy reference to raw subject alt name data. */ - frame->subject_alt_raw.p = p; - frame->subject_alt_raw.len = end_ext_octet - p; - ret = mbedtls_asn1_traverse_sequence_of( &p, end_ext_octet, - MBEDTLS_ASN1_TAG_CLASS_MASK, - MBEDTLS_ASN1_CONTEXT_SPECIFIC, - MBEDTLS_ASN1_TAG_VALUE_MASK, - 2 /* SubjectAlt DNS */, - NULL, NULL ); - if( ret != 0 ) - goto err; -#endif /* !MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION */ + if( ( ret = x509_get_key_usage( p, end_ext_octet, + &crt->key_usage ) ) != 0 ) + return( ret ); break; case MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE: /* Parse extended key usage */ - frame->ext_key_usage_raw.p = p; - frame->ext_key_usage_raw.len = end_ext_octet - p; - if( frame->ext_key_usage_raw.len == 0 ) - { - ret = MBEDTLS_ERR_ASN1_INVALID_LENGTH; - goto err; - } - - /* Check structural sanity of extension. */ - ret = mbedtls_asn1_traverse_sequence_of( &p, end_ext_octet, - 0xFF, MBEDTLS_ASN1_OID, - 0, 0, NULL, NULL ); - if( ret != 0 ) - goto err; + if( ( ret = x509_get_ext_key_usage( p, end_ext_octet, + &crt->ext_key_usage ) ) != 0 ) + return( ret ); + break; + case MBEDTLS_X509_EXT_SUBJECT_ALT_NAME: + /* Parse subject alt name */ + if( ( ret = x509_get_subject_alt_name( p, end_ext_octet, + &crt->subject_alt_names ) ) != 0 ) + return( ret ); break; case MBEDTLS_X509_EXT_NS_CERT_TYPE: /* Parse netscape certificate type */ - ret = x509_get_ns_cert_type( &p, end_ext_octet, - &frame->ns_cert_type ); - if( ret != 0 ) - goto err; + if( ( ret = x509_get_ns_cert_type( p, end_ext_octet, + &crt->ns_cert_type ) ) != 0 ) + return( ret ); break; default: - /* - * If this is a non-critical extension, which the oid layer - * supports, but there isn't an X.509 parser for it, - * skip the extension. - */ -#if !defined(MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION) - if( is_critical ) - return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE ); -#endif - p = end_ext_octet; - } - - return( 0 ); - -err: - return( ret ); -} - -static int x509_crt_frame_parse_ext( mbedtls_x509_crt_frame *frame ) -{ - int ret; - unsigned char *p = frame->v3_ext.p; - unsigned char *end = p + frame->v3_ext.len; - - if( p == end ) - return( 0 ); - - ret = mbedtls_asn1_traverse_sequence_of( &p, end, - 0xFF, MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED, - 0, 0, x509_crt_get_ext_cb, frame ); - - if( ret == MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE ) - return( ret ); - if( ret == MBEDTLS_ERR_X509_INVALID_EXTENSIONS ) - return( ret ); - - if( ret != 0 ) - ret += MBEDTLS_ERR_X509_INVALID_EXTENSIONS; - - return( ret ); -} - -static int x509_crt_parse_frame( unsigned char *start, - unsigned char *end, - mbedtls_x509_crt_frame *frame ) -{ - int ret; - unsigned char *p; - size_t len; - - mbedtls_x509_buf tmp; - unsigned char *tbs_start; - - mbedtls_x509_buf outer_sig_alg; - size_t inner_sig_alg_len; - unsigned char *inner_sig_alg_start; - - mbedtls_platform_memset( frame, 0, sizeof( *frame ) ); - - /* - * Certificate ::= SEQUENCE { - * tbsCertificate TBSCertificate, - * signatureAlgorithm AlgorithmIdentifier, - * signatureValue BIT STRING - * } - * - */ - p = start; - - frame->raw.p = p; - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - { - return( MBEDTLS_ERR_X509_INVALID_FORMAT ); - } - - /* NOTE: We are currently not checking that the `Certificate` - * structure spans the entire buffer. */ - end = p + len; - frame->raw.len = end - frame->raw.p; - - /* - * TBSCertificate ::= SEQUENCE { ... - */ - frame->tbs.p = p; - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - { - return( ret + MBEDTLS_ERR_X509_INVALID_FORMAT ); - } - tbs_start = p; - - /* Breadth-first parsing: Jump over TBS for now. */ - p += len; - frame->tbs.len = p - frame->tbs.p; - - /* - * AlgorithmIdentifier ::= SEQUENCE { ... - */ - outer_sig_alg.p = p; - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - { - return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); - } - p += len; - outer_sig_alg.len = p - outer_sig_alg.p; - - /* - * signatureValue BIT STRING - */ - ret = mbedtls_x509_get_sig( &p, end, &tmp ); - if( ret != 0 ) - return( ret ); - frame->sig.p = tmp.p; - frame->sig.len = tmp.len; - - /* Check that we consumed the entire `Certificate` structure. */ - if( p != end ) - { - return( MBEDTLS_ERR_X509_INVALID_FORMAT + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - } - - /* Parse TBSCertificate structure - * - * TBSCertificate ::= SEQUENCE { - * version [0] EXPLICIT Version DEFAULT v1, - * serialNumber CertificateSerialNumber, - * signature AlgorithmIdentifier, - * issuer Name, - * validity Validity, - * subject Name, - * subjectPublicKeyInfo SubjectPublicKeyInfo, - * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, - * -- If present, version MUST be v2 or v3 - * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, - * -- If present, version MUST be v2 or v3 - * extensions [3] EXPLICIT Extensions OPTIONAL - * -- If present, version MUST be v3 - * } - */ - end = frame->tbs.p + frame->tbs.len; - p = tbs_start; - - /* - * Version ::= INTEGER { v1(0), v2(1), v3(2) } - */ - { - int version; - ret = x509_get_version( &p, end, &version ); - if( ret != 0 ) - return( ret ); - - if( version < 0 || version > 2 ) - return( MBEDTLS_ERR_X509_UNKNOWN_VERSION ); - - frame->version = version + 1; - } - - /* - * CertificateSerialNumber ::= INTEGER - */ - ret = mbedtls_x509_get_serial( &p, end, &tmp ); - if( ret != 0 ) - return( ret ); - - frame->serial.p = tmp.p; - frame->serial.len = tmp.len; - - /* - * signature AlgorithmIdentifier - */ - inner_sig_alg_start = p; - ret = mbedtls_x509_get_sig_alg_raw( &p, end, &frame->sig_md, - &frame->sig_pk, NULL ); - if( ret != 0 ) - return( ret ); - inner_sig_alg_len = p - inner_sig_alg_start; - - frame->sig_alg.p = inner_sig_alg_start; - frame->sig_alg.len = inner_sig_alg_len; - - /* Consistency check: - * Inner and outer AlgorithmIdentifier structures must coincide: - * - * Quoting RFC 5280, Section 4.1.1.2: - * This field MUST contain the same algorithm identifier as the - * signature field in the sequence tbsCertificate (Section 4.1.2.3). - */ - if( outer_sig_alg.len != inner_sig_alg_len || - mbedtls_platform_memequal( outer_sig_alg.p, inner_sig_alg_start, inner_sig_alg_len ) != 0 ) - { - return( MBEDTLS_ERR_X509_SIG_MISMATCH ); - } - - /* - * issuer Name - * - * Name ::= CHOICE { -- only one possibility for now -- - * rdnSequence RDNSequence } - * - * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName - */ - frame->issuer_raw.p = p; - - ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ); - if( ret != 0 ) - return( ret + MBEDTLS_ERR_X509_INVALID_FORMAT ); - p += len; - frame->issuer_raw.len = p - frame->issuer_raw.p; - - /* Comparing the raw buffer to itself amounts to structural validation. */ - ret = mbedtls_x509_name_cmp_raw( &frame->issuer_raw, - &frame->issuer_raw, - NULL, NULL ); - if( ret != 0 ) - return( ret ); - - /* - * Validity ::= SEQUENCE { ... - */ -#if !defined(MBEDTLS_X509_CRT_REMOVE_TIME) - ret = x509_get_dates( &p, end, &frame->valid_from, &frame->valid_to ); - if( ret != 0 ) - return( ret ); -#else /* !MBEDTLS_X509_CRT_REMOVE_TIME */ - ret = x509_skip_dates( &p, end ); - if( ret != 0 ) - return( ret ); -#endif /* MBEDTLS_X509_CRT_REMOVE_TIME */ - - /* - * subject Name - * - * Name ::= CHOICE { -- only one possibility for now -- - * rdnSequence RDNSequence } - * - * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName - */ - frame->subject_raw.p = p; - - ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ); - if( ret != 0 ) - return( ret + MBEDTLS_ERR_X509_INVALID_FORMAT ); - p += len; - frame->subject_raw.len = p - frame->subject_raw.p; - - /* Comparing the raw buffer to itself amounts to structural validation. */ - ret = mbedtls_x509_name_cmp_raw( &frame->subject_raw, - &frame->subject_raw, - NULL, NULL ); - if( ret != 0 ) - return( ret ); - - /* - * SubjectPublicKeyInfo - */ - frame->pubkey_raw.p = p; - ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ); - if( ret != 0 ) - return( ret + MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); - p += len; - frame->pubkey_raw.len = p - frame->pubkey_raw.p; - - if( frame->version != 1 ) - { -#if !defined(MBEDTLS_X509_CRT_REMOVE_SUBJECT_ISSUER_ID) - /* - * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, - * -- If present, version shall be v2 or v3 - */ - ret = x509_get_uid( &p, end, &frame->issuer_id, 1 /* implicit tag */ ); - if( ret != 0 ) - return( ret ); - - /* - * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, - * -- If present, version shall be v2 or v3 - */ - ret = x509_get_uid( &p, end, &frame->subject_id, 2 /* implicit tag */ ); - if( ret != 0 ) - return( ret ); -#else /* !MBEDTLS_X509_CRT_REMOVE_SUBJECT_ISSUER_ID */ - ret = x509_skip_uid( &p, end, 1 /* implicit tag */ ); - if( ret != 0 ) - return( ret ); - ret = x509_skip_uid( &p, end, 2 /* implicit tag */ ); - if( ret != 0 ) - return( ret ); -#endif /* MBEDTLS_X509_CRT_REMOVE_SUBJECT_ISSUER_ID */ - } - - /* - * extensions [3] EXPLICIT Extensions OPTIONAL - * -- If present, version shall be v3 - */ -#if !defined(MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3) - if( frame->version == 3 ) -#endif - { - if( p != end ) - { - ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONTEXT_SPECIFIC | - MBEDTLS_ASN1_CONSTRUCTED | 3 ); - if( len == 0 ) - ret = MBEDTLS_ERR_ASN1_OUT_OF_DATA; - if( ret != 0 ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); - - frame->v3_ext.p = p; - frame->v3_ext.len = len; - - p += len; + return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE ); } - - ret = x509_crt_frame_parse_ext( frame ); - if( ret != 0 ) - return( ret ); } - /* Wrapup: Check that we consumed the entire `TBSCertificate` structure. */ - if( p != end ) - { - return( MBEDTLS_ERR_X509_INVALID_FORMAT + + if( *p != end ) + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - } return( 0 ); } -static int x509_crt_subject_from_frame( mbedtls_x509_crt_frame const *frame, - mbedtls_x509_name *subject ) -{ - return( mbedtls_x509_get_name( frame->subject_raw.p, - frame->subject_raw.len, - subject ) ); -} - -static int x509_crt_issuer_from_frame( mbedtls_x509_crt_frame const *frame, - mbedtls_x509_name *issuer ) -{ - return( mbedtls_x509_get_name( frame->issuer_raw.p, - frame->issuer_raw.len, - issuer ) ); -} - -#if !defined(MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION) -static int x509_crt_subject_alt_from_frame( mbedtls_x509_crt_frame const *frame, - mbedtls_x509_sequence *subject_alt ) -{ - int ret; - unsigned char *p = frame->subject_alt_raw.p; - unsigned char *end = p + frame->subject_alt_raw.len; - - mbedtls_platform_memset( subject_alt, 0, sizeof( *subject_alt ) ); - - if( ( frame->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME ) == 0 ) - return( 0 ); - - ret = x509_get_subject_alt_name( p, end, subject_alt ); - if( ret != 0 ) - ret += MBEDTLS_ERR_X509_INVALID_EXTENSIONS; - return( ret ); -} -#endif /* !MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION */ - -static int x509_crt_ext_key_usage_from_frame( mbedtls_x509_crt_frame const *frame, - mbedtls_x509_sequence *ext_key_usage ) -{ - int ret; - unsigned char *p = frame->ext_key_usage_raw.p; - unsigned char *end = p + frame->ext_key_usage_raw.len; - - mbedtls_platform_memset( ext_key_usage, 0, sizeof( *ext_key_usage ) ); - - if( ( frame->ext_types & MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE ) == 0 ) - return( 0 ); - - ret = x509_get_ext_key_usage( &p, end, ext_key_usage ); - if( ret != 0 ) - { - ret += MBEDTLS_ERR_X509_INVALID_EXTENSIONS; - return( ret ); - } - - return( 0 ); -} - -#if !defined(MBEDTLS_X509_ON_DEMAND_PARSING) -static int x509_crt_pk_from_frame( mbedtls_x509_crt_frame *frame, - mbedtls_pk_context *pk ) -{ - unsigned char *p = frame->pubkey_raw.p; - unsigned char *end = p + frame->pubkey_raw.len; - return( mbedtls_pk_parse_subpubkey( &p, end, pk ) ); -} -#endif /* !MBEDTLS_X509_ON_DEMAND_PARSING */ - /* * Parse and fill a single X.509 certificate in DER format */ -static int x509_crt_parse_der_core( mbedtls_x509_crt *crt, - const unsigned char *buf, - size_t buflen, - int make_copy ) +static int x509_crt_parse_der_core( mbedtls_x509_crt *crt, const unsigned char *buf, + size_t buflen ) { int ret; - mbedtls_x509_crt_frame *frame; - mbedtls_x509_crt_cache *cache; + size_t len; + unsigned char *p, *end, *crt_end; + mbedtls_x509_buf sig_params1, sig_params2, sig_oid2; + memset( &sig_params1, 0, sizeof( mbedtls_x509_buf ) ); + memset( &sig_params2, 0, sizeof( mbedtls_x509_buf ) ); + memset( &sig_oid2, 0, sizeof( mbedtls_x509_buf ) ); + + /* + * Check for valid input + */ if( crt == NULL || buf == NULL ) return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); - if( make_copy == 0 ) - { - crt->raw.p = (unsigned char*) buf; - crt->raw.len = buflen; - crt->own_buffer = 0; - } - else - { - /* Call mbedtls_calloc with buflen + 1 in order to avoid potential - * return of NULL in case of length 0 certificates, which we want - * to cleanly fail with MBEDTLS_ERR_X509_INVALID_FORMAT in the - * core parsing routine, but not here. */ - crt->raw.p = mbedtls_calloc( 1, buflen + 1 ); - if( crt->raw.p == NULL ) - return( MBEDTLS_ERR_X509_ALLOC_FAILED ); - crt->raw.len = buflen; - mbedtls_platform_memcpy( crt->raw.p, buf, buflen ); - - crt->own_buffer = 1; - } - - cache = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt_cache ) ); - if( cache == NULL ) - { - ret = MBEDTLS_ERR_X509_ALLOC_FAILED; - goto exit; - } - crt->cache = cache; - x509_crt_cache_init( cache ); - -#if defined(MBEDTLS_X509_ON_DEMAND_PARSING) - - ret = mbedtls_x509_crt_cache_provide_frame( crt ); - if( ret != 0 ) - goto exit; - - frame = crt->cache->frame; - -#else /* MBEDTLS_X509_ON_DEMAND_PARSING */ - - frame = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt_frame ) ); - if( frame == NULL ) - { - ret = MBEDTLS_ERR_X509_ALLOC_FAILED; - goto exit; - } - cache->frame = frame; - - ret = x509_crt_parse_frame( crt->raw.p, - crt->raw.p + crt->raw.len, - frame ); - if( ret != 0 ) - goto exit; - - /* Copy frame to legacy CRT structure -- that's inefficient, but if - * memory matters, the new CRT structure should be used anyway. */ - x509_buf_raw_to_buf( &crt->tbs, &frame->tbs ); - x509_buf_raw_to_buf( &crt->serial, &frame->serial ); - x509_buf_raw_to_buf( &crt->issuer_raw, &frame->issuer_raw ); - x509_buf_raw_to_buf( &crt->subject_raw, &frame->subject_raw ); -#if !defined(MBEDTLS_X509_CRT_REMOVE_SUBJECT_ISSUER_ID) - x509_buf_raw_to_buf( &crt->issuer_id, &frame->issuer_id ); - x509_buf_raw_to_buf( &crt->subject_id, &frame->subject_id ); -#endif /* !MBEDTLS_X509_CRT_REMOVE_SUBJECT_ISSUER_ID */ - x509_buf_raw_to_buf( &crt->pk_raw, &frame->pubkey_raw ); - x509_buf_raw_to_buf( &crt->sig, &frame->sig ); - x509_buf_raw_to_buf( &crt->v3_ext, &frame->v3_ext ); - -#if !defined(MBEDTLS_X509_CRT_REMOVE_TIME) - crt->valid_from = frame->valid_from; - crt->valid_to = frame->valid_to; -#endif /* !MBEDTLS_X509_CRT_REMOVE_TIME */ - - crt->version = frame->version; - crt->ca_istrue = frame->ca_istrue; - crt->max_pathlen = frame->max_pathlen; - crt->ext_types = frame->ext_types; - crt->key_usage = frame->key_usage; - crt->ns_cert_type = frame->ns_cert_type; + // Use the original buffer until we figure out actual length + p = (unsigned char*) buf; + len = buflen; + end = p + len; /* - * Obtain the remaining fields from the frame. + * Certificate ::= SEQUENCE { + * tbsCertificate TBSCertificate, + * signatureAlgorithm AlgorithmIdentifier, + * signatureValue BIT STRING } */ - + if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) { - /* sig_oid: Previously, needed for convenience in - * mbedtls_x509_crt_info(), now pure legacy burden. */ - unsigned char *tmp = frame->sig_alg.p; - unsigned char *end = tmp + frame->sig_alg.len; - mbedtls_x509_buf sig_oid, sig_params; + mbedtls_x509_crt_free( crt ); + return( MBEDTLS_ERR_X509_INVALID_FORMAT ); + } - ret = mbedtls_x509_get_alg( &tmp, end, - &sig_oid, &sig_params ); + if( len > (size_t) ( end - p ) ) + { + mbedtls_x509_crt_free( crt ); + return( MBEDTLS_ERR_X509_INVALID_FORMAT + + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + } + crt_end = p + len; + + // Create and populate a new buffer for the raw field + crt->raw.len = crt_end - buf; + crt->raw.p = p = mbedtls_calloc( 1, crt->raw.len ); + if( p == NULL ) + return( MBEDTLS_ERR_X509_ALLOC_FAILED ); + + memcpy( p, buf, crt->raw.len ); + + // Direct pointers to the new buffer + p += crt->raw.len - len; + end = crt_end = p + len; + + /* + * TBSCertificate ::= SEQUENCE { + */ + crt->tbs.p = p; + + if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) + { + mbedtls_x509_crt_free( crt ); + return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); + } + + end = p + len; + crt->tbs.len = end - crt->tbs.p; + + /* + * Version ::= INTEGER { v1(0), v2(1), v3(2) } + * + * CertificateSerialNumber ::= INTEGER + * + * signature AlgorithmIdentifier + */ + if( ( ret = x509_get_version( &p, end, &crt->version ) ) != 0 || + ( ret = mbedtls_x509_get_serial( &p, end, &crt->serial ) ) != 0 || + ( ret = mbedtls_x509_get_alg( &p, end, &crt->sig_oid, + &sig_params1 ) ) != 0 ) + { + mbedtls_x509_crt_free( crt ); + return( ret ); + } + + if( crt->version < 0 || crt->version > 2 ) + { + mbedtls_x509_crt_free( crt ); + return( MBEDTLS_ERR_X509_UNKNOWN_VERSION ); + } + + crt->version++; + + if( ( ret = mbedtls_x509_get_sig_alg( &crt->sig_oid, &sig_params1, + &crt->sig_md, &crt->sig_pk, + &crt->sig_opts ) ) != 0 ) + { + mbedtls_x509_crt_free( crt ); + return( ret ); + } + + /* + * issuer Name + */ + crt->issuer_raw.p = p; + + if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) + { + mbedtls_x509_crt_free( crt ); + return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); + } + + if( ( ret = mbedtls_x509_get_name( &p, p + len, &crt->issuer ) ) != 0 ) + { + mbedtls_x509_crt_free( crt ); + return( ret ); + } + + crt->issuer_raw.len = p - crt->issuer_raw.p; + + /* + * Validity ::= SEQUENCE { + * notBefore Time, + * notAfter Time } + * + */ + if( ( ret = x509_get_dates( &p, end, &crt->valid_from, + &crt->valid_to ) ) != 0 ) + { + mbedtls_x509_crt_free( crt ); + return( ret ); + } + + /* + * subject Name + */ + crt->subject_raw.p = p; + + if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) + { + mbedtls_x509_crt_free( crt ); + return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); + } + + if( len && ( ret = mbedtls_x509_get_name( &p, p + len, &crt->subject ) ) != 0 ) + { + mbedtls_x509_crt_free( crt ); + return( ret ); + } + + crt->subject_raw.len = p - crt->subject_raw.p; + + /* + * SubjectPublicKeyInfo + */ + if( ( ret = mbedtls_pk_parse_subpubkey( &p, end, &crt->pk ) ) != 0 ) + { + mbedtls_x509_crt_free( crt ); + return( ret ); + } + + /* + * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, + * -- If present, version shall be v2 or v3 + * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, + * -- If present, version shall be v2 or v3 + * extensions [3] EXPLICIT Extensions OPTIONAL + * -- If present, version shall be v3 + */ + if( crt->version == 2 || crt->version == 3 ) + { + ret = x509_get_uid( &p, end, &crt->issuer_id, 1 ); if( ret != 0 ) { - /* This should never happen, because we check - * the sanity of the AlgorithmIdentifier structure - * during frame parsing. */ - ret = MBEDTLS_ERR_X509_FATAL_ERROR; - goto exit; - } - crt->sig_oid = sig_oid; - - /* Signature parameters */ - tmp = frame->sig_alg.p; - ret = mbedtls_x509_get_sig_alg_raw( &tmp, end, - &crt->sig_md, &crt->sig_pk, - &crt->sig_opts ); - if( ret != 0 ) - { - /* Again, this should never happen. */ - ret = MBEDTLS_ERR_X509_FATAL_ERROR; - goto exit; + mbedtls_x509_crt_free( crt ); + return( ret ); } } - ret = x509_crt_pk_from_frame( frame, &crt->pk ); - if( ret != 0 ) - goto exit; + if( crt->version == 2 || crt->version == 3 ) + { + ret = x509_get_uid( &p, end, &crt->subject_id, 2 ); + if( ret != 0 ) + { + mbedtls_x509_crt_free( crt ); + return( ret ); + } + } - ret = x509_crt_subject_from_frame( frame, &crt->subject ); - if( ret != 0 ) - goto exit; +#if !defined(MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3) + if( crt->version == 3 ) +#endif + { + ret = x509_get_crt_ext( &p, end, crt ); + if( ret != 0 ) + { + mbedtls_x509_crt_free( crt ); + return( ret ); + } + } - ret = x509_crt_issuer_from_frame( frame, &crt->issuer ); - if( ret != 0 ) - goto exit; - -#if !defined(MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION) - ret = x509_crt_subject_alt_from_frame( frame, &crt->subject_alt_names ); - if( ret != 0 ) - goto exit; -#endif /* !MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION */ - - ret = x509_crt_ext_key_usage_from_frame( frame, &crt->ext_key_usage ); - if( ret != 0 ) - goto exit; -#endif /* !MBEDTLS_X509_ON_DEMAND_PARSING */ - - /* Currently, we accept DER encoded CRTs with trailing garbage - * and promise to not account for the garbage in the `raw` field. - * - * Note that this means that `crt->raw.len` is not necessarily the - * full size of the heap buffer allocated at `crt->raw.p` in case - * of copy-mode, but this is not a problem: freeing the buffer doesn't - * need the size, and the garbage data doesn't need zeroization. */ - crt->raw.len = frame->raw.len; - - cache->pk_raw = frame->pubkey_raw; - - /* Free the frame before parsing the public key to - * keep peak RAM usage low. This is slightly inefficient - * because the frame will need to be parsed again on the - * first usage of the CRT, but that seems acceptable. - * As soon as the frame gets used multiple times, it - * will be cached by default. */ - x509_crt_cache_clear_frame( crt->cache ); - - /* The cache just references the PK structure from the legacy - * implementation, so set up the latter first before setting up - * the cache. - * - * We're not actually using the parsed PK context here; - * we just parse it to check that it's well-formed. */ - ret = mbedtls_x509_crt_cache_provide_pk( crt ); - if( ret != 0 ) - goto exit; - x509_crt_cache_clear_pk( crt->cache ); - -exit: - if( ret != 0 ) + if( p != end ) + { mbedtls_x509_crt_free( crt ); + return( MBEDTLS_ERR_X509_INVALID_FORMAT + + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + } - return( ret ); + end = crt_end; + + /* + * } + * -- end of TBSCertificate + * + * signatureAlgorithm AlgorithmIdentifier, + * signatureValue BIT STRING + */ + if( ( ret = mbedtls_x509_get_alg( &p, end, &sig_oid2, &sig_params2 ) ) != 0 ) + { + mbedtls_x509_crt_free( crt ); + return( ret ); + } + + if( crt->sig_oid.len != sig_oid2.len || + memcmp( crt->sig_oid.p, sig_oid2.p, crt->sig_oid.len ) != 0 || + sig_params1.len != sig_params2.len || + ( sig_params1.len != 0 && + memcmp( sig_params1.p, sig_params2.p, sig_params1.len ) != 0 ) ) + { + mbedtls_x509_crt_free( crt ); + return( MBEDTLS_ERR_X509_SIG_MISMATCH ); + } + + if( ( ret = mbedtls_x509_get_sig( &p, end, &crt->sig ) ) != 0 ) + { + mbedtls_x509_crt_free( crt ); + return( ret ); + } + + if( p != end ) + { + mbedtls_x509_crt_free( crt ); + return( MBEDTLS_ERR_X509_INVALID_FORMAT + + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + } + + return( 0 ); } /* * Parse one X.509 certificate in DER format from a buffer and add them to a * chained list */ -static int mbedtls_x509_crt_parse_der_internal( mbedtls_x509_crt *chain, - const unsigned char *buf, - size_t buflen, - int make_copy ) +int mbedtls_x509_crt_parse_der( mbedtls_x509_crt *chain, const unsigned char *buf, + size_t buflen ) { int ret; mbedtls_x509_crt *crt = chain, *prev = NULL; @@ -1743,7 +939,7 @@ static int mbedtls_x509_crt_parse_der_internal( mbedtls_x509_crt *chain, if( crt == NULL || buf == NULL ) return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); - while( crt->raw.p != NULL && crt->next != NULL ) + while( crt->version != 0 && crt->next != NULL ) { prev = crt; crt = crt->next; @@ -1752,7 +948,7 @@ static int mbedtls_x509_crt_parse_der_internal( mbedtls_x509_crt *chain, /* * Add new certificate on the end of the chain if needed. */ - if( crt->raw.p != NULL && crt->next == NULL ) + if( crt->version != 0 && crt->next == NULL ) { crt->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt ) ); @@ -1764,7 +960,7 @@ static int mbedtls_x509_crt_parse_der_internal( mbedtls_x509_crt *chain, crt = crt->next; } - if( ( ret = x509_crt_parse_der_core( crt, buf, buflen, make_copy ) ) != 0 ) + if( ( ret = x509_crt_parse_der_core( crt, buf, buflen ) ) != 0 ) { if( prev ) prev->next = NULL; @@ -1778,27 +974,11 @@ static int mbedtls_x509_crt_parse_der_internal( mbedtls_x509_crt *chain, return( 0 ); } -int mbedtls_x509_crt_parse_der_nocopy( mbedtls_x509_crt *chain, - const unsigned char *buf, - size_t buflen ) -{ - return( mbedtls_x509_crt_parse_der_internal( chain, buf, buflen, 0 ) ); -} - -int mbedtls_x509_crt_parse_der( mbedtls_x509_crt *chain, - const unsigned char *buf, - size_t buflen ) -{ - return( mbedtls_x509_crt_parse_der_internal( chain, buf, buflen, 1 ) ); -} - /* * Parse one or more PEM certificates from a buffer and add them to the chained * list */ -int mbedtls_x509_crt_parse( mbedtls_x509_crt *chain, - const unsigned char *buf, - size_t buflen ) +int mbedtls_x509_crt_parse( mbedtls_x509_crt *chain, const unsigned char *buf, size_t buflen ) { #if defined(MBEDTLS_PEM_PARSE_C) int success = 0, first_error = 0, total_failed = 0; @@ -1924,7 +1104,7 @@ int mbedtls_x509_crt_parse_file( mbedtls_x509_crt *chain, const char *path ) ret = mbedtls_x509_crt_parse( chain, buf, n ); - mbedtls_platform_zeroize( buf, n ); + mbedtls_zeroize( buf, n ); mbedtls_free( buf ); return( ret ); @@ -1946,9 +1126,9 @@ int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path ) if( len > MAX_PATH - 3 ) return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); - mbedtls_platform_memset( szDir, 0, sizeof(szDir) ); - mbedtls_platform_memset( filename, 0, MAX_PATH ); - mbedtls_platform_memcpy( filename, path, len ); + memset( szDir, 0, sizeof(szDir) ); + memset( filename, 0, MAX_PATH ); + memcpy( filename, path, len ); filename[len++] = '\\'; p = filename + len; filename[len++] = '*'; @@ -1965,7 +1145,7 @@ int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path ) len = MAX_PATH - len; do { - mbedtls_platform_memset( p, 0, len ); + memset( p, 0, len ); if( file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) continue; @@ -2054,73 +1234,6 @@ cleanup: } #endif /* MBEDTLS_FS_IO */ -typedef struct mbedtls_x509_crt_sig_info -{ - mbedtls_md_type_t sig_md; - mbedtls_pk_type_t sig_pk; - void *sig_opts; - size_t crt_hash_len; - mbedtls_x509_buf_raw sig; - mbedtls_x509_buf_raw issuer_raw; - uint8_t crt_hash[MBEDTLS_MD_MAX_SIZE]; -} mbedtls_x509_crt_sig_info; - -static void x509_crt_free_sig_info( mbedtls_x509_crt_sig_info *info ) -{ -#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) - mbedtls_free( info->sig_opts ); -#else - ((void) info); -#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */ -} - -static int x509_crt_get_sig_info( mbedtls_x509_crt_frame const *frame, - mbedtls_x509_crt_sig_info *info ) -{ - mbedtls_md_handle_t md_info; - - md_info = mbedtls_md_info_from_type( frame->sig_md ); - if( mbedtls_md( md_info, frame->tbs.p, frame->tbs.len, - info->crt_hash ) != 0 ) - { - /* Note: this can't happen except after an internal error */ - return( -1 ); - } - - info->crt_hash_len = mbedtls_md_get_size( md_info ); - - /* Make sure that this function leaves the target structure - * ready to be freed, regardless of success of failure. */ - info->sig_opts = NULL; - -#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) - { - int ret; - unsigned char *alg_start = frame->sig_alg.p; - unsigned char *alg_end = alg_start + frame->sig_alg.len; - - /* Get signature options -- currently only - * necessary for RSASSA-PSS. */ - ret = mbedtls_x509_get_sig_alg_raw( &alg_start, alg_end, &info->sig_md, - &info->sig_pk, &info->sig_opts ); - if( ret != 0 ) - { - /* Note: this can't happen except after an internal error */ - return( -1 ); - } - } -#else /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */ - info->sig_md = frame->sig_md; - info->sig_pk = frame->sig_pk; -#endif /* !MBEDTLS_X509_RSASSA_PSS_SUPPORT */ - - info->issuer_raw = frame->issuer_raw; - info->sig = frame->sig; - return( 0 ); -} - -#if !defined(MBEDTLS_X509_REMOVE_INFO) -#if !defined(MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION) static int x509_info_subject_alt_name( char **buf, size_t *size, const mbedtls_x509_sequence *subject_alt_name ) { @@ -2158,7 +1271,6 @@ static int x509_info_subject_alt_name( char **buf, size_t *size, return( 0 ); } -#endif /* !MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION */ #define PRINT_ITEM(i) \ { \ @@ -2168,7 +1280,7 @@ static int x509_info_subject_alt_name( char **buf, size_t *size, } #define CERT_TYPE(type,name) \ - if( ns_cert_type & (type) ) \ + if( ns_cert_type & type ) \ PRINT_ITEM( name ); static int x509_info_cert_type( char **buf, size_t *size, @@ -2195,7 +1307,7 @@ static int x509_info_cert_type( char **buf, size_t *size, } #define KEY_USAGE(code,name) \ - if( key_usage & (code) ) \ + if( key_usage & code ) \ PRINT_ITEM( name ); static int x509_info_key_usage( char **buf, size_t *size, @@ -2251,227 +1363,270 @@ static int x509_info_ext_key_usage( char **buf, size_t *size, return( 0 ); } +/* + * Like memcmp, but case-insensitive and always returns -1 if different + */ +static int x509_memcasecmp( const void *s1, const void *s2, size_t len ) +{ + size_t i; + unsigned char diff; + const unsigned char *n1 = s1, *n2 = s2; + + for( i = 0; i < len; i++ ) + { + diff = n1[i] ^ n2[i]; + + if( diff == 0 ) + continue; + + if( diff == 32 && + ( ( n1[i] >= 'a' && n1[i] <= 'z' ) || + ( n1[i] >= 'A' && n1[i] <= 'Z' ) ) ) + { + continue; + } + + return( -1 ); + } + + return( 0 ); +} + +/* + * Return 0 if name matches wildcard, -1 otherwise + */ +static int x509_check_wildcard( const char *cn, mbedtls_x509_buf *name ) +{ + size_t i; + size_t cn_idx = 0, cn_len = strlen( cn ); + + if( name->len < 3 || name->p[0] != '*' || name->p[1] != '.' ) + return( 0 ); + + for( i = 0; i < cn_len; ++i ) + { + if( cn[i] == '.' ) + { + cn_idx = i; + break; + } + } + + if( cn_idx == 0 ) + return( -1 ); + + if( cn_len - cn_idx == name->len - 1 && + x509_memcasecmp( name->p + 1, cn + cn_idx, name->len - 1 ) == 0 ) + { + return( 0 ); + } + + return( -1 ); +} + +/* + * Compare two X.509 strings, case-insensitive, and allowing for some encoding + * variations (but not all). + * + * Return 0 if equal, -1 otherwise. + */ +static int x509_string_cmp( const mbedtls_x509_buf *a, const mbedtls_x509_buf *b ) +{ + if( a->tag == b->tag && + a->len == b->len && + memcmp( a->p, b->p, b->len ) == 0 ) + { + return( 0 ); + } + + if( ( a->tag == MBEDTLS_ASN1_UTF8_STRING || a->tag == MBEDTLS_ASN1_PRINTABLE_STRING ) && + ( b->tag == MBEDTLS_ASN1_UTF8_STRING || b->tag == MBEDTLS_ASN1_PRINTABLE_STRING ) && + a->len == b->len && + x509_memcasecmp( a->p, b->p, b->len ) == 0 ) + { + return( 0 ); + } + + return( -1 ); +} + +/* + * Compare two X.509 Names (aka rdnSequence). + * + * See RFC 5280 section 7.1, though we don't implement the whole algorithm: + * we sometimes return unequal when the full algorithm would return equal, + * but never the other way. (In particular, we don't do Unicode normalisation + * or space folding.) + * + * Return 0 if equal, -1 otherwise. + */ +static int x509_name_cmp( const mbedtls_x509_name *a, const mbedtls_x509_name *b ) +{ + /* Avoid recursion, it might not be optimised by the compiler */ + while( a != NULL || b != NULL ) + { + if( a == NULL || b == NULL ) + return( -1 ); + + /* type */ + if( a->oid.tag != b->oid.tag || + a->oid.len != b->oid.len || + memcmp( a->oid.p, b->oid.p, b->oid.len ) != 0 ) + { + return( -1 ); + } + + /* value */ + if( x509_string_cmp( &a->val, &b->val ) != 0 ) + return( -1 ); + + /* structure of the list of sets */ + if( a->next_merged != b->next_merged ) + return( -1 ); + + a = a->next; + b = b->next; + } + + /* a == NULL == b */ + return( 0 ); +} + /* * Return an informational string about the certificate. */ -#define BEFORE_COLON_CRT 18 -#define BC_CRT "18" +#define BEFORE_COLON 18 +#define BC "18" int mbedtls_x509_crt_info( char *buf, size_t size, const char *prefix, - const mbedtls_x509_crt *crt ) + const mbedtls_x509_crt *crt ) { int ret; size_t n; char *p; - char key_size_str[BEFORE_COLON_CRT]; - mbedtls_x509_crt_frame frame; - mbedtls_pk_context pk; - - mbedtls_x509_name *issuer = NULL, *subject = NULL; - mbedtls_x509_sequence *ext_key_usage = NULL; -#if !defined(MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION) - mbedtls_x509_sequence *subject_alt_names = NULL; -#endif /* !MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION */ - - mbedtls_x509_crt_sig_info sig_info; + char key_size_str[BEFORE_COLON]; p = buf; n = size; - memset( &sig_info, 0, sizeof( mbedtls_x509_crt_sig_info ) ); - mbedtls_pk_init( &pk ); - if( NULL == crt ) { ret = mbedtls_snprintf( p, n, "\nCertificate is uninitialised!\n" ); - MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP; + MBEDTLS_X509_SAFE_SNPRINTF; return( (int) ( size - n ) ); } - ret = mbedtls_x509_crt_get_frame( crt, &frame ); - if( ret != 0 ) - { - ret = MBEDTLS_ERR_X509_FATAL_ERROR; - goto cleanup; - } - - ret = mbedtls_x509_crt_get_subject( crt, &subject ); - if( ret != 0 ) - { - ret = MBEDTLS_ERR_X509_FATAL_ERROR; - goto cleanup; - } - - ret = mbedtls_x509_crt_get_issuer( crt, &issuer ); - if( ret != 0 ) - { - ret = MBEDTLS_ERR_X509_FATAL_ERROR; - goto cleanup; - } - -#if !defined(MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION) - ret = mbedtls_x509_crt_get_subject_alt_names( crt, &subject_alt_names ); - if( ret != 0 ) - { - ret = MBEDTLS_ERR_X509_FATAL_ERROR; - goto cleanup; - } -#endif /* !MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION */ - - ret = mbedtls_x509_crt_get_ext_key_usage( crt, &ext_key_usage ); - if( ret != 0 ) - { - ret = MBEDTLS_ERR_X509_FATAL_ERROR; - goto cleanup; - } - - ret = mbedtls_x509_crt_get_pk( crt, &pk ); - if( ret != 0 ) - { - ret = MBEDTLS_ERR_X509_FATAL_ERROR; - goto cleanup; - } - - ret = x509_crt_get_sig_info( &frame, &sig_info ); - if( ret != 0 ) - { - ret = MBEDTLS_ERR_X509_FATAL_ERROR; - goto cleanup; - } - ret = mbedtls_snprintf( p, n, "%scert. version : %d\n", - prefix, frame.version ); - MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP; + prefix, crt->version ); + MBEDTLS_X509_SAFE_SNPRINTF; + ret = mbedtls_snprintf( p, n, "%sserial number : ", + prefix ); + MBEDTLS_X509_SAFE_SNPRINTF; - { - mbedtls_x509_buf serial; - serial.p = frame.serial.p; - serial.len = frame.serial.len; - ret = mbedtls_snprintf( p, n, "%sserial number : ", - prefix ); - MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP; - ret = mbedtls_x509_serial_gets( p, n, &serial ); - MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP; - } + ret = mbedtls_x509_serial_gets( p, n, &crt->serial ); + MBEDTLS_X509_SAFE_SNPRINTF; ret = mbedtls_snprintf( p, n, "\n%sissuer name : ", prefix ); - MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP; - ret = mbedtls_x509_dn_gets( p, n, issuer ); - MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP; + MBEDTLS_X509_SAFE_SNPRINTF; + ret = mbedtls_x509_dn_gets( p, n, &crt->issuer ); + MBEDTLS_X509_SAFE_SNPRINTF; ret = mbedtls_snprintf( p, n, "\n%ssubject name : ", prefix ); - MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP; - ret = mbedtls_x509_dn_gets( p, n, subject ); - MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP; + MBEDTLS_X509_SAFE_SNPRINTF; + ret = mbedtls_x509_dn_gets( p, n, &crt->subject ); + MBEDTLS_X509_SAFE_SNPRINTF; -#if !defined(MBEDTLS_X509_CRT_REMOVE_TIME) ret = mbedtls_snprintf( p, n, "\n%sissued on : " \ "%04d-%02d-%02d %02d:%02d:%02d", prefix, - frame.valid_from.year, frame.valid_from.mon, - frame.valid_from.day, frame.valid_from.hour, - frame.valid_from.min, frame.valid_from.sec ); - MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP; + crt->valid_from.year, crt->valid_from.mon, + crt->valid_from.day, crt->valid_from.hour, + crt->valid_from.min, crt->valid_from.sec ); + MBEDTLS_X509_SAFE_SNPRINTF; ret = mbedtls_snprintf( p, n, "\n%sexpires on : " \ "%04d-%02d-%02d %02d:%02d:%02d", prefix, - frame.valid_to.year, frame.valid_to.mon, - frame.valid_to.day, frame.valid_to.hour, - frame.valid_to.min, frame.valid_to.sec ); - MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP; -#endif /* MBEDTLS_X509_CRT_REMOVE_TIME */ + crt->valid_to.year, crt->valid_to.mon, + crt->valid_to.day, crt->valid_to.hour, + crt->valid_to.min, crt->valid_to.sec ); + MBEDTLS_X509_SAFE_SNPRINTF; ret = mbedtls_snprintf( p, n, "\n%ssigned using : ", prefix ); - MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP; + MBEDTLS_X509_SAFE_SNPRINTF; - ret = mbedtls_x509_sig_alg_gets( p, n, sig_info.sig_pk, - sig_info.sig_md, sig_info.sig_opts ); - MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP; + ret = mbedtls_x509_sig_alg_gets( p, n, &crt->sig_oid, crt->sig_pk, + crt->sig_md, crt->sig_opts ); + MBEDTLS_X509_SAFE_SNPRINTF; /* Key size */ - if( ( ret = mbedtls_x509_key_size_helper( key_size_str, BEFORE_COLON_CRT, - mbedtls_pk_get_name( &pk ) ) ) != 0 ) + if( ( ret = mbedtls_x509_key_size_helper( key_size_str, BEFORE_COLON, + mbedtls_pk_get_name( &crt->pk ) ) ) != 0 ) { return( ret ); } - ret = mbedtls_snprintf( p, n, "\n%s%-" BC_CRT "s: %d bits", prefix, key_size_str, - (int) mbedtls_pk_get_bitlen( &pk ) ); - MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP; + ret = mbedtls_snprintf( p, n, "\n%s%-" BC "s: %d bits", prefix, key_size_str, + (int) mbedtls_pk_get_bitlen( &crt->pk ) ); + MBEDTLS_X509_SAFE_SNPRINTF; /* * Optional extensions */ - if( frame.ext_types & MBEDTLS_X509_EXT_BASIC_CONSTRAINTS ) + if( crt->ext_types & MBEDTLS_X509_EXT_BASIC_CONSTRAINTS ) { ret = mbedtls_snprintf( p, n, "\n%sbasic constraints : CA=%s", prefix, - frame.ca_istrue ? "true" : "false" ); - MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP; + crt->ca_istrue ? "true" : "false" ); + MBEDTLS_X509_SAFE_SNPRINTF; - if( frame.max_pathlen > 0 ) + if( crt->max_pathlen > 0 ) { - ret = mbedtls_snprintf( p, n, ", max_pathlen=%d", frame.max_pathlen - 1 ); - MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP; + ret = mbedtls_snprintf( p, n, ", max_pathlen=%d", crt->max_pathlen - 1 ); + MBEDTLS_X509_SAFE_SNPRINTF; } } -#if !defined(MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION) - if( frame.ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME ) + if( crt->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME ) { ret = mbedtls_snprintf( p, n, "\n%ssubject alt name : ", prefix ); - MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP; + MBEDTLS_X509_SAFE_SNPRINTF; if( ( ret = x509_info_subject_alt_name( &p, &n, - subject_alt_names ) ) != 0 ) + &crt->subject_alt_names ) ) != 0 ) return( ret ); } -#endif /* !MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION */ - if( frame.ext_types & MBEDTLS_X509_EXT_NS_CERT_TYPE ) + if( crt->ext_types & MBEDTLS_X509_EXT_NS_CERT_TYPE ) { ret = mbedtls_snprintf( p, n, "\n%scert. type : ", prefix ); - MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP; + MBEDTLS_X509_SAFE_SNPRINTF; - if( ( ret = x509_info_cert_type( &p, &n, frame.ns_cert_type ) ) != 0 ) + if( ( ret = x509_info_cert_type( &p, &n, crt->ns_cert_type ) ) != 0 ) return( ret ); } - if( frame.ext_types & MBEDTLS_X509_EXT_KEY_USAGE ) + if( crt->ext_types & MBEDTLS_X509_EXT_KEY_USAGE ) { ret = mbedtls_snprintf( p, n, "\n%skey usage : ", prefix ); - MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP; + MBEDTLS_X509_SAFE_SNPRINTF; - if( ( ret = x509_info_key_usage( &p, &n, frame.key_usage ) ) != 0 ) + if( ( ret = x509_info_key_usage( &p, &n, crt->key_usage ) ) != 0 ) return( ret ); } - if( frame.ext_types & MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE ) + if( crt->ext_types & MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE ) { ret = mbedtls_snprintf( p, n, "\n%sext key usage : ", prefix ); - MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP; + MBEDTLS_X509_SAFE_SNPRINTF; if( ( ret = x509_info_ext_key_usage( &p, &n, - ext_key_usage ) ) != 0 ) + &crt->ext_key_usage ) ) != 0 ) return( ret ); } ret = mbedtls_snprintf( p, n, "\n" ); - MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP; + MBEDTLS_X509_SAFE_SNPRINTF; - ret = (int) ( size - n ); - -cleanup: - - x509_crt_free_sig_info( &sig_info ); - mbedtls_pk_free( &pk ); - mbedtls_x509_name_free( issuer ); - mbedtls_x509_name_free( subject ); - mbedtls_x509_sequence_free( ext_key_usage ); -#if !defined(MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION) - mbedtls_x509_sequence_free( subject_alt_names ); -#endif /* !MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION */ - - return( ret ); + return( (int) ( size - n ) ); } struct x509_crt_verify_string { @@ -2530,11 +1685,10 @@ int mbedtls_x509_crt_verify_info( char *buf, size_t size, const char *prefix, return( (int) ( size - n ) ); } -#endif /* !MBEDTLS_X509_REMOVE_INFO */ #if defined(MBEDTLS_X509_CHECK_KEY_USAGE) -static int x509_crt_check_key_usage_frame( const mbedtls_x509_crt_frame *crt, - unsigned int usage ) +int mbedtls_x509_crt_check_key_usage( const mbedtls_x509_crt *crt, + unsigned int usage ) { unsigned int usage_must, usage_may; unsigned int may_mask = MBEDTLS_X509_KU_ENCIPHER_ONLY @@ -2555,87 +1709,37 @@ static int x509_crt_check_key_usage_frame( const mbedtls_x509_crt_frame *crt, return( 0 ); } - -int mbedtls_x509_crt_check_key_usage( const mbedtls_x509_crt *crt, - unsigned int usage ) -{ - int ret; - mbedtls_x509_crt_frame const *frame; - ret = mbedtls_x509_crt_frame_acquire( crt, &frame ); - if( ret != 0 ) - return( MBEDTLS_ERR_X509_FATAL_ERROR ); - - ret = x509_crt_check_key_usage_frame( frame, usage ); - mbedtls_x509_crt_frame_release( crt ); - - return( ret ); -} #endif #if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE) -typedef struct -{ - const char *oid; - size_t oid_len; -} x509_crt_check_ext_key_usage_cb_ctx_t; - -static int x509_crt_check_ext_key_usage_cb( void *ctx, - int tag, - unsigned char *data, - size_t data_len ) -{ - x509_crt_check_ext_key_usage_cb_ctx_t *cb_ctx = - (x509_crt_check_ext_key_usage_cb_ctx_t *) ctx; - ((void) tag); - - if( MBEDTLS_OID_CMP_RAW( MBEDTLS_OID_ANY_EXTENDED_KEY_USAGE, - data, data_len ) == 0 ) - { - return( 1 ); - } - - if( data_len == cb_ctx->oid_len && mbedtls_platform_memequal( data, cb_ctx->oid, - data_len ) == 0 ) - { - return( 1 ); - } - - return( 0 ); -} - int mbedtls_x509_crt_check_extended_key_usage( const mbedtls_x509_crt *crt, - const char *usage_oid, - size_t usage_len ) + const char *usage_oid, + size_t usage_len ) { - int ret; - mbedtls_x509_crt_frame const *frame; - unsigned ext_types; - unsigned char *p, *end; - x509_crt_check_ext_key_usage_cb_ctx_t cb_ctx = { usage_oid, usage_len }; - - ret = mbedtls_x509_crt_frame_acquire( crt, &frame ); - if( ret != 0 ) - return( MBEDTLS_ERR_X509_FATAL_ERROR ); + const mbedtls_x509_sequence *cur; /* Extension is not mandatory, absent means no restriction */ - ext_types = frame->ext_types; - if( ( ext_types & MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE ) != 0 ) - { - p = frame->ext_key_usage_raw.p; - end = p + frame->ext_key_usage_raw.len; + if( ( crt->ext_types & MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE ) == 0 ) + return( 0 ); - ret = mbedtls_asn1_traverse_sequence_of( &p, end, - 0xFF, MBEDTLS_ASN1_OID, 0, 0, - x509_crt_check_ext_key_usage_cb, - &cb_ctx ); - if( ret == 1 ) - ret = 0; - else - ret = MBEDTLS_ERR_X509_BAD_INPUT_DATA; + /* + * Look for the requested usage (or wildcard ANY) in our list + */ + for( cur = &crt->ext_key_usage; cur != NULL; cur = cur->next ) + { + const mbedtls_x509_buf *cur_oid = &cur->buf; + + if( cur_oid->len == usage_len && + memcmp( cur_oid->p, usage_oid, usage_len ) == 0 ) + { + return( 0 ); + } + + if( MBEDTLS_OID_CMP( MBEDTLS_OID_ANY_EXTENDED_KEY_USAGE, cur_oid ) == 0 ) + return( 0 ); } - mbedtls_x509_crt_frame_release( crt ); - return( ret ); + return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); } #endif /* MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE */ @@ -2643,16 +1747,14 @@ int mbedtls_x509_crt_check_extended_key_usage( const mbedtls_x509_crt *crt, /* * Return 1 if the certificate is revoked, or 0 otherwise. */ -static int x509_serial_is_revoked( unsigned char const *serial, - size_t serial_len, - const mbedtls_x509_crl *crl ) +int mbedtls_x509_crt_is_revoked( const mbedtls_x509_crt *crt, const mbedtls_x509_crl *crl ) { const mbedtls_x509_crl_entry *cur = &crl->entry; while( cur != NULL && cur->serial.len != 0 ) { - if( serial_len == cur->serial.len && - mbedtls_platform_memequal( serial, cur->serial.p, serial_len ) == 0 ) + if( crt->serial.len == cur->serial.len && + memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 ) { if( mbedtls_x509_time_is_past( &cur->revocation_date ) ) return( 1 ); @@ -2664,71 +1766,25 @@ static int x509_serial_is_revoked( unsigned char const *serial, return( 0 ); } -int mbedtls_x509_crt_is_revoked( const mbedtls_x509_crt *crt, - const mbedtls_x509_crl *crl ) -{ - int ret; - mbedtls_x509_crt_frame const *frame; - - ret = mbedtls_x509_crt_frame_acquire( crt, &frame ); - if( ret != 0 ) - return( MBEDTLS_ERR_X509_FATAL_ERROR ); - - ret = x509_serial_is_revoked( frame->serial.p, - frame->serial.len, - crl ); - mbedtls_x509_crt_frame_release( crt ); - return( ret ); -} - /* * Check that the given certificate is not revoked according to the CRL. * Skip validation if no CRL for the given CA is present. */ -static int x509_crt_verifycrl( unsigned char *crt_serial, - size_t crt_serial_len, - mbedtls_x509_crt *ca_crt, +static int x509_crt_verifycrl( mbedtls_x509_crt *crt, mbedtls_x509_crt *ca, mbedtls_x509_crl *crl_list, const mbedtls_x509_crt_profile *profile ) { - int ret; int flags = 0; unsigned char hash[MBEDTLS_MD_MAX_SIZE]; - mbedtls_md_handle_t md_info; - mbedtls_x509_buf_raw ca_subject; - mbedtls_pk_context *pk; - int can_sign; + const mbedtls_md_info_t *md_info; - if( ca_crt == NULL ) + if( ca == NULL ) return( flags ); - { - mbedtls_x509_crt_frame const *ca; - ret = mbedtls_x509_crt_frame_acquire( ca_crt, &ca ); - if( ret != 0 ) - return( MBEDTLS_X509_BADCRL_NOT_TRUSTED ); - - ca_subject = ca->subject_raw; - - can_sign = 0; - if( x509_crt_check_key_usage_frame( ca, - MBEDTLS_X509_KU_CRL_SIGN ) == 0 ) - { - can_sign = 1; - } - - mbedtls_x509_crt_frame_release( ca_crt ); - } - - ret = mbedtls_x509_crt_pk_acquire( ca_crt, &pk ); - if( ret != 0 ) - return( MBEDTLS_X509_BADCRL_NOT_TRUSTED ); - while( crl_list != NULL ) { if( crl_list->version == 0 || - mbedtls_x509_name_cmp_raw( &crl_list->issuer_raw, - &ca_subject, NULL, NULL ) != 0 ) + x509_name_cmp( &crl_list->issuer, &ca->subject ) != 0 ) { crl_list = crl_list->next; continue; @@ -2738,7 +1794,8 @@ static int x509_crt_verifycrl( unsigned char *crt_serial, * Check if the CA is configured to sign CRLs */ #if defined(MBEDTLS_X509_CHECK_KEY_USAGE) - if( !can_sign ) + if( mbedtls_x509_crt_check_key_usage( ca, + MBEDTLS_X509_KU_CRL_SIGN ) != 0 ) { flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED; break; @@ -2762,10 +1819,10 @@ static int x509_crt_verifycrl( unsigned char *crt_serial, break; } - if( x509_profile_check_key( profile, pk ) != 0 ) + if( x509_profile_check_key( profile, crl_list->sig_pk, &ca->pk ) != 0 ) flags |= MBEDTLS_X509_BADCERT_BAD_KEY; - if( mbedtls_pk_verify_ext( crl_list->sig_pk, crl_list->sig_opts, pk, + if( mbedtls_pk_verify_ext( crl_list->sig_pk, crl_list->sig_opts, &ca->pk, crl_list->sig_md, hash, mbedtls_md_get_size( md_info ), crl_list->sig.p, crl_list->sig.len ) != 0 ) { @@ -2785,8 +1842,7 @@ static int x509_crt_verifycrl( unsigned char *crt_serial, /* * Check if certificate is revoked */ - if( x509_serial_is_revoked( crt_serial, crt_serial_len, - crl_list ) ) + if( mbedtls_x509_crt_is_revoked( crt, crl_list ) ) { flags |= MBEDTLS_X509_BADCERT_REVOKED; break; @@ -2795,78 +1851,26 @@ static int x509_crt_verifycrl( unsigned char *crt_serial, crl_list = crl_list->next; } - mbedtls_x509_crt_pk_release( ca_crt ); return( flags ); } #endif /* MBEDTLS_X509_CRL_PARSE_C */ -/* - * Check the signature of a certificate by its parent - */ -static int x509_crt_check_signature( const mbedtls_x509_crt_sig_info *sig_info, - mbedtls_x509_crt *parent, - mbedtls_x509_crt_restart_ctx *rs_ctx ) -{ - int ret; - mbedtls_pk_context *pk; - - ret = mbedtls_x509_crt_pk_acquire( parent, &pk ); - if( ret != 0 ) - return( MBEDTLS_ERR_X509_FATAL_ERROR ); - - /* Skip expensive computation on obvious mismatch */ - if( ! mbedtls_pk_can_do( pk, sig_info->sig_pk ) ) - { - ret = -1; - goto exit; - } - -#if !( defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) ) - ((void) rs_ctx); -#else - if( rs_ctx != NULL && sig_info->sig_pk == MBEDTLS_PK_ECDSA ) - { - ret = mbedtls_pk_verify_restartable( pk, - sig_info->sig_md, - sig_info->crt_hash, sig_info->crt_hash_len, - sig_info->sig.p, sig_info->sig.len, - &rs_ctx->pk ); - } - else -#endif - { - ret = mbedtls_pk_verify_ext( sig_info->sig_pk, - sig_info->sig_opts, - pk, - sig_info->sig_md, - sig_info->crt_hash, sig_info->crt_hash_len, - sig_info->sig.p, sig_info->sig.len ); - } - -exit: - mbedtls_x509_crt_pk_release( parent ); - return( ret ); -} - /* * Check if 'parent' is a suitable parent (signing CA) for 'child'. * Return 0 if yes, -1 if not. * * top means parent is a locally-trusted certificate + * bottom means child is the end entity cert */ -static int x509_crt_check_parent( const mbedtls_x509_crt_sig_info *sig_info, - const mbedtls_x509_crt_frame *parent, - int top ) +static int x509_crt_check_parent( const mbedtls_x509_crt *child, + const mbedtls_x509_crt *parent, + int top, int bottom ) { int need_ca_bit; /* Parent must be the issuer */ - if( mbedtls_x509_name_cmp_raw( &sig_info->issuer_raw, - &parent->subject_raw, - NULL, NULL ) != 0 ) - { + if( x509_name_cmp( &child->issuer, &parent->subject ) != 0 ) return( -1 ); - } /* Parent must have the basicConstraints CA bit set as a general rule */ need_ca_bit = 1; @@ -2875,13 +1879,20 @@ static int x509_crt_check_parent( const mbedtls_x509_crt_sig_info *sig_info, if( top && parent->version < 3 ) need_ca_bit = 0; + /* Exception: self-signed end-entity certs that are locally trusted. */ + if( top && bottom && + child->raw.len == parent->raw.len && + memcmp( child->raw.p, parent->raw.p, child->raw.len ) == 0 ) + { + need_ca_bit = 0; + } + if( need_ca_bit && ! parent->ca_istrue ) return( -1 ); #if defined(MBEDTLS_X509_CHECK_KEY_USAGE) if( need_ca_bit && - x509_crt_check_key_usage_frame( parent, - MBEDTLS_X509_KU_KEY_CERT_SIGN ) != 0 ) + mbedtls_x509_crt_check_key_usage( parent, MBEDTLS_X509_KU_KEY_CERT_SIGN ) != 0 ) { return( -1 ); } @@ -2890,909 +1901,363 @@ static int x509_crt_check_parent( const mbedtls_x509_crt_sig_info *sig_info, return( 0 ); } -/* This value is different enough from 0 that it's hard for an active physical - * attacker to reach it just by flipping a few bits. */ -#define X509_SIGNATURE_IS_GOOD 0x7f5a5a5a - /* - * Find a suitable parent for child in candidates, or return NULL. + * Verify a certificate with no parent inside the chain + * (either the parent is a trusted root, or there is no parent) * - * Here suitable is defined as: - * 1. subject name matches child's issuer - * 2. if necessary, the CA bit is set and key usage allows signing certs - * 3. for trusted roots, the signature is correct - * (for intermediates, the signature is checked and the result reported) - * 4. pathlen constraints are satisfied + * See comments for mbedtls_x509_crt_verify_with_profile() + * (also for notation used below) * - * If there's a suitable candidate which is also time-valid, return the first - * such. Otherwise, return the first suitable candidate (or NULL if there is - * none). + * 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() * - * The rationale for this rule is that someone could have a list of trusted - * roots with two versions on the same root with different validity periods. - * (At least one user reported having such a list and wanted it to just work.) - * The reason we don't just require time-validity is that generally there is - * only one version, and if it's expired we want the flags to state that - * rather than NOT_TRUSTED, as would be the case if we required it here. - * - * The rationale for rule 3 (signature for trusted roots) is that users might - * have two versions of the same CA with different keys in their list, and the - * way we select the correct one is by checking the signature (as we don't - * rely on key identifier extensions). (This is one way users might choose to - * handle key rollover, another relies on self-issued certs, see [SIRO].) - * - * Arguments: - * - [in] child: certificate for which we're looking for a parent - * - [in] candidates: chained list of potential parents - * - [out] r_parent: parent found (or NULL) - * - [out] r_signature_is_good: set to X509_SIGNATURE_IS_GOOD if - * child signature by parent is valid, or to 0 - * - [in] top: 1 if candidates consists of trusted roots, ie we're at the top - * of the chain, 0 otherwise - * - [in] path_cnt: number of intermediates seen so far - * - [in] self_cnt: number of self-signed intermediates seen so far - * (will never be greater than path_cnt) - * - [in-out] rs_ctx: context for restarting operations - * - * Return value: - * - 0 on success - * - MBEDTLS_ERR_ECP_IN_PROGRESS or MBEDTLS_ERR_PLATFORM_FAULT_DETECTED otherwise + * 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_find_parent_in( - mbedtls_x509_crt_sig_info const *child_sig, - mbedtls_x509_crt *candidates, - mbedtls_x509_crt **r_parent, - int *r_signature_is_good, - int top, - unsigned path_cnt, - unsigned self_cnt, - mbedtls_x509_crt_restart_ctx *rs_ctx ) +static int x509_crt_verify_top( + mbedtls_x509_crt *child, mbedtls_x509_crt *trust_ca, + mbedtls_x509_crl *ca_crl, + const mbedtls_x509_crt_profile *profile, + int path_cnt, int self_cnt, uint32_t *flags, + int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), + void *p_vrfy ) { int ret; - volatile int ret_fi = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; - mbedtls_x509_crt *parent_crt; - int signature_is_good = 0; + uint32_t ca_flags = 0; + int check_path_cnt; + unsigned char hash[MBEDTLS_MD_MAX_SIZE]; + const mbedtls_md_info_t *md_info; + mbedtls_x509_crt *future_past_ca = NULL; -#if defined(MBEDTLS_HAVE_TIME_DATE) - mbedtls_x509_crt *fallback_parent; - int fallback_signature_is_good; -#endif /* MBEDTLS_HAVE_TIME_DATE */ + if( mbedtls_x509_time_is_past( &child->valid_to ) ) + *flags |= MBEDTLS_X509_BADCERT_EXPIRED; -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - /* did we have something in progress? */ - if( rs_ctx != NULL && rs_ctx->parent != NULL ) + if( mbedtls_x509_time_is_future( &child->valid_from ) ) + *flags |= MBEDTLS_X509_BADCERT_FUTURE; + + if( x509_profile_check_md_alg( profile, child->sig_md ) != 0 ) + *flags |= MBEDTLS_X509_BADCERT_BAD_MD; + + if( x509_profile_check_pk_alg( profile, child->sig_pk ) != 0 ) + *flags |= MBEDTLS_X509_BADCERT_BAD_PK; + + /* + * Child is the top of the chain. Check against the trust_ca list. + */ + *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED; + + md_info = mbedtls_md_info_from_type( child->sig_md ); + if( mbedtls_md( md_info, child->tbs.p, child->tbs.len, hash ) != 0 ) { - /* restore saved state */ - parent_crt = rs_ctx->parent; -#if defined(MBEDTLS_HAVE_TIME_DATE) - fallback_parent = rs_ctx->fallback_parent; - fallback_signature_is_good = rs_ctx->fallback_signature_is_good; -#endif /* MBEDTLS_HAVE_TIME_DATE */ - - /* clear saved state */ - rs_ctx->parent = NULL; -#if defined(MBEDTLS_HAVE_TIME_DATE) - rs_ctx->fallback_parent = NULL; - rs_ctx->fallback_signature_is_good = 0; -#endif /* MBEDTLS_HAVE_TIME_DATE */ - - /* resume where we left */ - goto check_signature; + /* Note: this can't happen except after an internal error */ + /* Cannot check signature, no need to try any CA */ + trust_ca = NULL; } -#endif -#if defined(MBEDTLS_HAVE_TIME_DATE) - fallback_parent = NULL; - fallback_signature_is_good = 0; -#endif /* MBEDTLS_HAVE_TIME_DATE */ - - for( parent_crt = candidates; parent_crt != NULL; - parent_crt = parent_crt->next ) + for( /* trust_ca */ ; trust_ca != NULL; trust_ca = trust_ca->next ) { - volatile int parent_valid, parent_match, path_len_ok; - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) -check_signature: -#endif - - parent_valid = parent_match = path_len_ok = 0; - { - mbedtls_x509_crt_frame const *parent; - - ret = mbedtls_x509_crt_frame_acquire( parent_crt, &parent ); - if( ret != 0 ) - return( MBEDTLS_ERR_X509_FATAL_ERROR ); - -#if !defined(MBEDTLS_X509_CRT_REMOVE_TIME) - if( !mbedtls_x509_time_is_past( &parent->valid_to ) && - !mbedtls_x509_time_is_future( &parent->valid_from ) ) -#endif /* !MBEDTLS_X509_CRT_REMOVE_TIME */ - { - parent_valid = 1; - } - - /* basic parenting skills (name, CA bit, key usage) */ - if( x509_crt_check_parent( child_sig, parent, top ) == 0 ) - parent_match = 1; - - /* +1 because the stored max_pathlen is 1 higher - * than the actual value */ - if( !( parent->max_pathlen > 0 && - (size_t) parent->max_pathlen < 1 + path_cnt - self_cnt ) ) - { - path_len_ok = 1; - } - - mbedtls_x509_crt_frame_release( parent_crt ); - } - - if( parent_match == 0 || path_len_ok == 0 ) + if( x509_crt_check_parent( child, trust_ca, 1, path_cnt == 0 ) != 0 ) continue; - /* Signature */ - ret_fi = x509_crt_check_signature( child_sig, parent_crt, rs_ctx ); + check_path_cnt = path_cnt + 1; -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && ret_fi == MBEDTLS_ERR_ECP_IN_PROGRESS ) + /* + * Reduce check_path_cnt to check against if top of the chain is + * the same as the trusted CA + */ + if( child->subject_raw.len == trust_ca->subject_raw.len && + memcmp( child->subject_raw.p, trust_ca->subject_raw.p, + child->subject_raw.len ) == 0 ) { - /* save state */ - rs_ctx->parent = parent_crt; -#if defined(MBEDTLS_HAVE_TIME_DATE) - rs_ctx->fallback_parent = fallback_parent; - rs_ctx->fallback_signature_is_good = fallback_signature_is_good; -#endif /* MBEDTLS_HAVE_TIME_DATE */ - - return( ret_fi ); - } -#endif - - if( ret_fi == 0 ) - { - mbedtls_platform_random_delay(); - if( ret_fi == 0 ) - signature_is_good = X509_SIGNATURE_IS_GOOD; - else - return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); + check_path_cnt--; } - if( top && ! signature_is_good ) - continue; - - /* optional time check */ - if( !parent_valid ) + /* Self signed certificates do not count towards the limit */ + if( trust_ca->max_pathlen > 0 && + trust_ca->max_pathlen < check_path_cnt - self_cnt ) { -#if defined(MBEDTLS_HAVE_TIME_DATE) - if( fallback_parent == NULL ) - { - fallback_parent = parent_crt; - fallback_signature_is_good = signature_is_good; - } -#endif /* MBEDTLS_HAVE_TIME_DATE */ - continue; } - *r_parent = parent_crt; - *r_signature_is_good = signature_is_good; + if( mbedtls_pk_verify_ext( child->sig_pk, child->sig_opts, &trust_ca->pk, + child->sig_md, hash, mbedtls_md_get_size( md_info ), + child->sig.p, child->sig.len ) != 0 ) + { + continue; + } + + if( mbedtls_x509_time_is_past( &trust_ca->valid_to ) || + mbedtls_x509_time_is_future( &trust_ca->valid_from ) ) + { + if ( future_past_ca == NULL ) + future_past_ca = trust_ca; + + continue; + } break; } - if( parent_crt == NULL ) + if( trust_ca != NULL || ( trust_ca = future_past_ca ) != NULL ) { -#if defined(MBEDTLS_HAVE_TIME_DATE) - *r_parent = fallback_parent; - *r_signature_is_good = fallback_signature_is_good; -#else /* MBEDTLS_HAVE_TIME_DATE */ - *r_parent = NULL; -#endif /* !MBEDTLS_HAVE_TIME_DATE */ + /* + * Top of chain is signed by a trusted CA + */ + *flags &= ~MBEDTLS_X509_BADCERT_NOT_TRUSTED; + + if( x509_profile_check_key( profile, child->sig_pk, &trust_ca->pk ) != 0 ) + *flags |= MBEDTLS_X509_BADCERT_BAD_KEY; } - return( 0 ); -} - -/* - * Find a parent in trusted CAs or the provided chain, or return NULL. - * - * Searches in trusted CAs first, and return the first suitable parent found - * (see find_parent_in() for definition of suitable). - * - * Arguments: - * - [in] child: certificate for which we're looking for a parent, followed - * by a chain of possible intermediates - * - [in] trust_ca: list of locally trusted certificates - * - [out] parent: parent found (or NULL) - * - [out] parent_is_trusted: 1 if returned `parent` is trusted, or 0 - * - [out] signature_is_good: 1 if child signature by parent is valid, or 0 - * - [in] path_cnt: number of links in the chain so far (EE -> ... -> child) - * - [in] self_cnt: number of self-signed certs in the chain so far - * (will always be no greater than path_cnt) - * - [in-out] rs_ctx: context for restarting operations - * - * Return value: - * - 0 on success - * - MBEDTLS_ERR_ECP_IN_PROGRESS otherwise - */ -static int x509_crt_find_parent( - mbedtls_x509_crt_sig_info const *child_sig, - mbedtls_x509_crt *rest, - mbedtls_x509_crt *trust_ca, - mbedtls_x509_crt **parent, - int *parent_is_trusted, - int *signature_is_good, - unsigned path_cnt, - unsigned self_cnt, - mbedtls_x509_crt_restart_ctx *rs_ctx ) -{ - int ret; - mbedtls_x509_crt *search_list; - - *parent_is_trusted = 1; - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - /* restore then clear saved state if we have some stored */ - if( rs_ctx != NULL && rs_ctx->parent_is_trusted != -1 ) + /* + * If top of chain is not the same as the trusted CA send a verify request + * to the callback for any issues with validity and CRL presence for the + * trusted CA certificate. + */ + if( trust_ca != NULL && + ( child->subject_raw.len != trust_ca->subject_raw.len || + memcmp( child->subject_raw.p, trust_ca->subject_raw.p, + child->subject_raw.len ) != 0 ) ) { - *parent_is_trusted = rs_ctx->parent_is_trusted; - rs_ctx->parent_is_trusted = -1; - } -#endif - - while( 1 ) { - search_list = *parent_is_trusted ? trust_ca : rest; - - ret = x509_crt_find_parent_in( child_sig, search_list, - parent, signature_is_good, - *parent_is_trusted, - path_cnt, self_cnt, rs_ctx ); - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) - { - /* save state */ - rs_ctx->parent_is_trusted = *parent_is_trusted; - return( ret ); - } +#if defined(MBEDTLS_X509_CRL_PARSE_C) + /* Check trusted CA's CRL for the chain's top crt */ + *flags |= x509_crt_verifycrl( child, trust_ca, ca_crl, profile ); #else - (void) ret; + ((void) ca_crl); #endif - /* stop here if found or already in second iteration */ - if( *parent != NULL || *parent_is_trusted == 0 ) - break; + if( mbedtls_x509_time_is_past( &trust_ca->valid_to ) ) + ca_flags |= MBEDTLS_X509_BADCERT_EXPIRED; - /* prepare second iteration */ - *parent_is_trusted = 0; - } - - /* extra precaution against mistakes in the caller */ - if( *parent == NULL ) - { - *parent_is_trusted = 0; - *signature_is_good = 0; - } - - return( 0 ); -} - -/* - * Check if an end-entity certificate is locally trusted - * - * Currently we require such certificates to be self-signed (actually only - * check for self-issued as self-signatures are not checked) - */ -static int x509_crt_check_ee_locally_trusted( - mbedtls_x509_crt_frame const *crt, - mbedtls_x509_crt const *trust_ca ) -{ - mbedtls_x509_crt const *cur; - - /* look for an exact match with trusted cert */ - for( cur = trust_ca; cur != NULL; cur = cur->next ) - { - if( crt->raw.len == cur->raw.len && - mbedtls_platform_memequal( crt->raw.p, cur->raw.p, crt->raw.len ) == 0 ) - { - return( 0 ); - } - } - - /* too bad */ - return( -1 ); -} - -#if !defined(MBEDTLS_X509_REMOVE_VERIFY_CALLBACK) - -/* - * Reset (init or clear) a verify_chain - */ -static void x509_crt_verify_chain_reset( - mbedtls_x509_crt_verify_chain *ver_chain ) -{ - size_t i; - - for( i = 0; i < MBEDTLS_X509_MAX_VERIFY_CHAIN_SIZE; i++ ) - { - ver_chain->items[i].crt = NULL; - ver_chain->items[i].flags = (uint32_t) -1; - } - - ver_chain->len = 0; -} - -/* - * Merge the flags for all certs in the chain, after calling callback - */ -static int x509_crt_verify_chain_get_flags( - const mbedtls_x509_crt_verify_chain *ver_chain, - uint32_t *flags, - int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), - void *p_vrfy ) -{ - int ret; - unsigned i; - uint32_t cur_flags; - const mbedtls_x509_crt_verify_chain_item *cur; - - for( i = ver_chain->len; i != 0; --i ) - { - cur = &ver_chain->items[i-1]; - cur_flags = cur->flags; + if( mbedtls_x509_time_is_future( &trust_ca->valid_from ) ) + ca_flags |= MBEDTLS_X509_BADCERT_FUTURE; if( NULL != f_vrfy ) - if( ( ret = f_vrfy( p_vrfy, cur->crt, (int) i-1, &cur_flags ) ) != 0 ) - return( ret ); - - *flags |= cur_flags; - } - - return( 0 ); -} - -static void x509_crt_verify_chain_add_ee_flags( - mbedtls_x509_crt_verify_chain *chain, - uint32_t ee_flags ) -{ - chain->items[0].flags |= ee_flags; -} - -static void x509_crt_verify_chain_add_crt( - mbedtls_x509_crt_verify_chain *chain, - mbedtls_x509_crt *crt ) -{ - mbedtls_x509_crt_verify_chain_item *cur; - cur = &chain->items[chain->len]; - cur->crt = crt; - cur->flags = 0; - chain->len++; -} - -static uint32_t* x509_crt_verify_chain_get_cur_flags( - mbedtls_x509_crt_verify_chain *chain ) -{ - return( &chain->items[chain->len - 1].flags ); -} - -static unsigned x509_crt_verify_chain_len( - mbedtls_x509_crt_verify_chain const *chain ) -{ - return( chain->len ); -} - -#else /* !MBEDTLS_X509_REMOVE_VERIFY_CALLBACK */ - -/* - * Reset (init or clear) a verify_chain - */ -static void x509_crt_verify_chain_reset( - mbedtls_x509_crt_verify_chain *ver_chain ) -{ - ver_chain->len = 0; - ver_chain->flags = 0; -} - -/* - * Merge the flags for all certs in the chain, after calling callback - */ -static int x509_crt_verify_chain_get_flags( - const mbedtls_x509_crt_verify_chain *ver_chain, - uint32_t *flags, - int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), - void *p_vrfy ) -{ - ((void) f_vrfy); - ((void) p_vrfy); - *flags = ver_chain->flags; - return( 0 ); -} - -static void x509_crt_verify_chain_add_ee_flags( - mbedtls_x509_crt_verify_chain *chain, - uint32_t ee_flags ) -{ - chain->flags |= ee_flags; -} - -static void x509_crt_verify_chain_add_crt( - mbedtls_x509_crt_verify_chain *chain, - mbedtls_x509_crt *crt ) -{ - ((void) crt); - chain->len++; -} - -static uint32_t* x509_crt_verify_chain_get_cur_flags( - mbedtls_x509_crt_verify_chain *chain ) -{ - return( &chain->flags ); -} - -static unsigned x509_crt_verify_chain_len( - mbedtls_x509_crt_verify_chain const *chain ) -{ - return( chain->len ); -} - -#endif /* MBEDTLS_X509_REMOVE_VERIFY_CALLBACK */ - -/* - * This is used in addition to the flag for a specific issue, to ensure that - * it is not possible for an active physical attacker to entirely clear the - * flags just by flipping a single bit. Take advantage of the fact that all - * values defined in include/x509.h so far are 24-bit or less, so the - * top byte is free. - * - * Currently this protection is not compatible with the vrfy callback (as it - * can observ and modify flags freely), so it's only enabled when the callback - * is disabled. - */ -#if defined(MBEDTLS_X509_REMOVE_VERIFY_CALLBACK) -#define X509_BADCERT_FI_EXTRA 0xff000000u -#else -#define X509_BADCERT_FI_EXTRA 0u -#endif - -/* - * Build and verify a certificate chain - * - * Given a peer-provided list of certificates EE, C1, ..., Cn and - * a list of trusted certs R1, ... Rp, try to build and verify a chain - * EE, Ci1, ... Ciq [, Rj] - * such that every cert in the chain is a child of the next one, - * jumping to a trusted root as early as possible. - * - * Verify that chain and return it with flags for all issues found. - * - * Special cases: - * - EE == Rj -> return a one-element list containing it - * - EE, Ci1, ..., Ciq cannot be continued with a trusted root - * -> return that chain with NOT_TRUSTED set on Ciq - * - * Tests for (aspects of) this function should include at least: - * - trusted EE - * - EE -> trusted root - * - EE -> intermediate CA -> trusted root - * - if relevant: EE untrusted - * - if relevant: EE -> intermediate, untrusted - * with the aspect under test checked at each relevant level (EE, int, root). - * For some aspects longer chains are required, but usually length 2 is - * enough (but length 1 is not in general). - * - * Arguments: - * - [in] crt: the cert list EE, C1, ..., Cn - * - [in] trust_ca: the trusted list R1, ..., Rp - * - [in] ca_crl, profile: as in verify_with_profile() - * - [out] ver_chain: the built and verified chain - * Only valid when return value is 0, may contain garbage otherwise! - * Restart note: need not be the same when calling again to resume. - * - [in-out] rs_ctx: context for restarting operations - * - * Return value: - * - non-zero if the chain could not be fully built and examined - * - 0 is the chain was successfully built and examined, - * even if it was found to be invalid - */ -static int x509_crt_verify_chain( - mbedtls_x509_crt *crt, - mbedtls_x509_crt *trust_ca, - mbedtls_x509_crl *ca_crl, - const mbedtls_x509_crt_profile *profile, - mbedtls_x509_crt_verify_chain *ver_chain, - mbedtls_x509_crt_restart_ctx *rs_ctx ) -{ - /* Don't initialize any of those variables here, so that the compiler can - * catch potential issues with jumping ahead when restarting */ - int ret; - uint32_t *flags; - mbedtls_x509_crt *child_crt; - mbedtls_x509_crt *parent_crt; - int parent_is_trusted; - int child_is_trusted; - int signature_is_good; - volatile int signature_is_good_fi; - unsigned self_cnt; - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - /* resume if we had an operation in progress */ - if( rs_ctx != NULL && rs_ctx->in_progress == x509_crt_rs_find_parent ) - { - /* restore saved state */ - *ver_chain = rs_ctx->ver_chain; /* struct copy */ - self_cnt = rs_ctx->self_cnt; - child_crt = rs_ctx->cur_crt; - - child_is_trusted = 0; - goto find_parent; - } -#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - - child_crt = crt; - self_cnt = 0; - parent_is_trusted = 0; - child_is_trusted = 0; - - while( 1 ) { -#if defined(MBEDTLS_X509_CRL_PARSE_C) - mbedtls_x509_buf_raw child_serial; -#endif /* MBEDTLS_X509_CRL_PARSE_C */ - int self_issued; - - /* Add certificate to the verification chain */ - x509_crt_verify_chain_add_crt( ver_chain, child_crt ); - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) -find_parent: -#endif - - flags = x509_crt_verify_chain_get_cur_flags( ver_chain ); - { - mbedtls_x509_crt_sig_info child_sig; + if( ( ret = f_vrfy( p_vrfy, trust_ca, path_cnt + 1, + &ca_flags ) ) != 0 ) { - mbedtls_x509_crt_frame const *child; - - ret = mbedtls_x509_crt_frame_acquire( child_crt, &child ); - if( ret != 0 ) - return( MBEDTLS_ERR_X509_FATAL_ERROR ); - -#if !defined(MBEDTLS_X509_CRT_REMOVE_TIME) - /* Check time-validity (all certificates) */ - if( mbedtls_x509_time_is_past( &child->valid_to ) ) - *flags |= MBEDTLS_X509_BADCERT_EXPIRED | X509_BADCERT_FI_EXTRA; - if( mbedtls_x509_time_is_future( &child->valid_from ) ) - *flags |= MBEDTLS_X509_BADCERT_FUTURE | X509_BADCERT_FI_EXTRA; -#endif /* !MBEDTLS_X509_CRT_REMOVE_TIME */ - - /* Stop here for trusted roots (but not for trusted EE certs) */ - if( child_is_trusted ) - { - mbedtls_x509_crt_frame_release( child_crt ); - return( 0 ); - } - - self_issued = 0; - if( mbedtls_x509_name_cmp_raw( &child->issuer_raw, - &child->subject_raw, - NULL, NULL ) == 0 ) - { - self_issued = 1; - } - - /* Check signature algorithm: MD & PK algs */ - if( x509_profile_check_md_alg( profile, child->sig_md ) != 0 ) - *flags |= MBEDTLS_X509_BADCERT_BAD_MD | X509_BADCERT_FI_EXTRA; - - if( x509_profile_check_pk_alg( profile, child->sig_pk ) != 0 ) - *flags |= MBEDTLS_X509_BADCERT_BAD_PK | X509_BADCERT_FI_EXTRA; - - /* Special case: EE certs that are locally trusted */ - if( x509_crt_verify_chain_len( ver_chain ) == 1 && self_issued && - x509_crt_check_ee_locally_trusted( child, trust_ca ) == 0 ) - { - mbedtls_x509_crt_frame_release( child_crt ); - return( 0 ); - } - -#if defined(MBEDTLS_X509_CRL_PARSE_C) - child_serial = child->serial; -#endif /* MBEDTLS_X509_CRL_PARSE_C */ - - ret = x509_crt_get_sig_info( child, &child_sig ); - mbedtls_x509_crt_frame_release( child_crt ); - - if( ret != 0 ) - return( MBEDTLS_ERR_X509_FATAL_ERROR ); + return( ret ); } - - /* Look for a parent in trusted CAs or up the chain */ - ret = x509_crt_find_parent( &child_sig, child_crt->next, - trust_ca, &parent_crt, - &parent_is_trusted, &signature_is_good, - x509_crt_verify_chain_len( ver_chain ) - 1, - self_cnt, rs_ctx ); - - x509_crt_free_sig_info( &child_sig ); } + } -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) - { - /* save state */ - rs_ctx->in_progress = x509_crt_rs_find_parent; - rs_ctx->self_cnt = self_cnt; - rs_ctx->ver_chain = *ver_chain; /* struct copy */ - rs_ctx->cur_crt = child_crt; + /* Call callback on top cert */ + if( NULL != f_vrfy ) + { + if( ( ret = f_vrfy( p_vrfy, child, path_cnt, flags ) ) != 0 ) return( ret ); - } -#else - (void) ret; -#endif - - /* No parent? We're done here */ - if( parent_crt == NULL ) - { - *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED | X509_BADCERT_FI_EXTRA; - return( 0 ); - } - - /* Count intermediate self-issued (not necessarily self-signed) certs. - * These can occur with some strategies for key rollover, see [SIRO], - * and should be excluded from max_pathlen checks. */ - if( x509_crt_verify_chain_len( ver_chain ) != 1 && self_issued ) - self_cnt++; - - /* path_cnt is 0 for the first intermediate CA, - * and if parent is trusted it's not an intermediate CA */ - if( ! parent_is_trusted && - x509_crt_verify_chain_len( ver_chain ) > - MBEDTLS_X509_MAX_INTERMEDIATE_CA ) - { - /* return immediately to avoid overflow the chain array */ - return( MBEDTLS_ERR_X509_FATAL_ERROR ); - } - - /* signature was checked while searching parent */ - signature_is_good_fi = signature_is_good; - if( signature_is_good_fi != X509_SIGNATURE_IS_GOOD ) - *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED | X509_BADCERT_FI_EXTRA; - - mbedtls_platform_random_delay(); - if( signature_is_good_fi != X509_SIGNATURE_IS_GOOD ) - *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED | X509_BADCERT_FI_EXTRA; - - { - mbedtls_pk_context *parent_pk; - ret = mbedtls_x509_crt_pk_acquire( parent_crt, &parent_pk ); - if( ret != 0 ) - return( MBEDTLS_ERR_X509_FATAL_ERROR ); - - /* check size of signing key */ - if( x509_profile_check_key( profile, parent_pk ) != 0 ) - *flags |= MBEDTLS_X509_BADCERT_BAD_KEY | X509_BADCERT_FI_EXTRA; - - mbedtls_x509_crt_pk_release( parent_crt ); - } - -#if defined(MBEDTLS_X509_CRL_PARSE_C) - /* Check trusted CA's CRL for the given crt */ - *flags |= x509_crt_verifycrl( child_serial.p, - child_serial.len, - parent_crt, ca_crl, profile ); -#else - (void) ca_crl; -#endif - - /* prepare for next iteration */ - child_crt = parent_crt; - parent_crt = NULL; - child_is_trusted = parent_is_trusted; - signature_is_good = 0; - } -} - -#if !defined(MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION) -/* - * Check for CN match - */ -static int x509_crt_check_cn( unsigned char const *buf, - size_t buflen, - const char *cn, - size_t cn_len ) -{ - /* Try exact match */ - if( mbedtls_x509_memcasecmp( cn, buf, buflen, cn_len ) == 0 ) - return( 0 ); - - /* try wildcard match */ - if( x509_check_wildcard( cn, cn_len, buf, buflen ) == 0 ) - { - return( 0 ); } - return( -1 ); -} - -/* Returns 1 on a match and 0 on a mismatch. - * This is because this function is used as a callback for - * mbedtls_x509_name_cmp_raw(), which continues the name - * traversal as long as the callback returns 0. */ -static int x509_crt_check_name( void *ctx, - mbedtls_x509_buf *oid, - mbedtls_x509_buf *val, - int next_merged ) -{ - char const *cn = (char const*) ctx; - size_t cn_len = strlen( cn ); - ((void) next_merged); - - if( MBEDTLS_OID_CMP( MBEDTLS_OID_AT_CN, oid ) == 0 && - x509_crt_check_cn( val->p, val->len, cn, cn_len ) == 0 ) - { - return( 1 ); - } - - return( 0 ); -} - -/* Returns 1 on a match and 0 on a mismatch. - * This is because this function is used as a callback for - * mbedtls_asn1_traverse_sequence_of(), which continues the - * traversal as long as the callback returns 0. */ -static int x509_crt_subject_alt_check_name( void *ctx, - int tag, - unsigned char *data, - size_t data_len ) -{ - char const *cn = (char const*) ctx; - size_t cn_len = strlen( cn ); - ((void) tag); - - if( x509_crt_check_cn( data, data_len, cn, cn_len ) == 0 ) - return( 1 ); + *flags |= ca_flags; return( 0 ); } /* - * Verify the requested CN - only call this if cn is not NULL! + * Verify a certificate with a parent inside the chain + * + * See comments for mbedtls_x509_crt_verify_with_profile() */ -static int x509_crt_verify_name( const mbedtls_x509_crt *crt, - const char *cn, - uint32_t *flags ) +static int x509_crt_verify_child( + mbedtls_x509_crt *child, mbedtls_x509_crt *parent, + mbedtls_x509_crt *trust_ca, mbedtls_x509_crl *ca_crl, + const mbedtls_x509_crt_profile *profile, + int path_cnt, int self_cnt, uint32_t *flags, + int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), + void *p_vrfy ) { int ret; - mbedtls_x509_crt_frame const *frame; + uint32_t parent_flags = 0; + unsigned char hash[MBEDTLS_MD_MAX_SIZE]; + mbedtls_x509_crt *grandparent; + const mbedtls_md_info_t *md_info; - ret = mbedtls_x509_crt_frame_acquire( crt, &frame ); - if( ret != 0 ) - return( MBEDTLS_ERR_X509_FATAL_ERROR ); + /* Counting intermediate self signed certificates */ + if( ( path_cnt != 0 ) && x509_name_cmp( &child->issuer, &child->subject ) == 0 ) + self_cnt++; - if( frame->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME ) + /* path_cnt is 0 for the first intermediate CA */ + if( 1 + path_cnt > MBEDTLS_X509_MAX_INTERMEDIATE_CA ) { - unsigned char *p = - frame->subject_alt_raw.p; - const unsigned char *end = - frame->subject_alt_raw.p + frame->subject_alt_raw.len; + /* return immediately as the goal is to avoid unbounded recursion */ + return( MBEDTLS_ERR_X509_FATAL_ERROR ); + } - ret = mbedtls_asn1_traverse_sequence_of( &p, end, - MBEDTLS_ASN1_TAG_CLASS_MASK, - MBEDTLS_ASN1_CONTEXT_SPECIFIC, - MBEDTLS_ASN1_TAG_VALUE_MASK, - 2 /* SubjectAlt DNS */, - x509_crt_subject_alt_check_name, - (void *) cn ); + if( mbedtls_x509_time_is_past( &child->valid_to ) ) + *flags |= MBEDTLS_X509_BADCERT_EXPIRED; + + if( mbedtls_x509_time_is_future( &child->valid_from ) ) + *flags |= MBEDTLS_X509_BADCERT_FUTURE; + + if( x509_profile_check_md_alg( profile, child->sig_md ) != 0 ) + *flags |= MBEDTLS_X509_BADCERT_BAD_MD; + + if( x509_profile_check_pk_alg( profile, child->sig_pk ) != 0 ) + *flags |= MBEDTLS_X509_BADCERT_BAD_PK; + + md_info = mbedtls_md_info_from_type( child->sig_md ); + if( mbedtls_md( md_info, child->tbs.p, child->tbs.len, hash ) != 0 ) + { + /* Note: this can't happen except after an internal error */ + *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED; } else { - ret = mbedtls_x509_name_cmp_raw( &frame->subject_raw, - &frame->subject_raw, - x509_crt_check_name, (void *) cn ); + if( x509_profile_check_key( profile, child->sig_pk, &parent->pk ) != 0 ) + *flags |= MBEDTLS_X509_BADCERT_BAD_KEY; + + if( mbedtls_pk_verify_ext( child->sig_pk, child->sig_opts, &parent->pk, + child->sig_md, hash, mbedtls_md_get_size( md_info ), + child->sig.p, child->sig.len ) != 0 ) + { + *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED; + } } - mbedtls_x509_crt_frame_release( crt ); +#if defined(MBEDTLS_X509_CRL_PARSE_C) + /* Check trusted CA's CRL for the given crt */ + *flags |= x509_crt_verifycrl(child, parent, ca_crl, profile ); +#endif - /* x509_crt_check_name() and x509_crt_subject_alt_check_name() - * return 1 when finding a name component matching `cn`. */ - if( ret == 1 ) - return( 0 ); + /* Look for a grandparent in trusted CAs */ + for( grandparent = trust_ca; + grandparent != NULL; + grandparent = grandparent->next ) + { + if( x509_crt_check_parent( parent, grandparent, + 0, path_cnt == 0 ) == 0 ) + break; + } - if( ret != 0 ) - ret = MBEDTLS_ERR_X509_FATAL_ERROR; + if( grandparent != NULL ) + { + ret = x509_crt_verify_top( parent, grandparent, ca_crl, profile, + path_cnt + 1, self_cnt, &parent_flags, f_vrfy, p_vrfy ); + if( ret != 0 ) + return( ret ); + } + else + { + /* Look for a grandparent upwards the chain */ + for( grandparent = parent->next; + grandparent != NULL; + grandparent = grandparent->next ) + { + /* +2 because the current step is not yet accounted for + * and because max_pathlen is one higher than it should be. + * Also self signed certificates do not count to the limit. */ + if( grandparent->max_pathlen > 0 && + grandparent->max_pathlen < 2 + path_cnt - self_cnt ) + { + continue; + } - *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH | X509_BADCERT_FI_EXTRA; - return( ret ); + if( x509_crt_check_parent( parent, grandparent, + 0, path_cnt == 0 ) == 0 ) + break; + } + + /* Is our parent part of the chain or at the top? */ + if( grandparent != NULL ) + { + ret = x509_crt_verify_child( parent, grandparent, trust_ca, ca_crl, + profile, path_cnt + 1, self_cnt, &parent_flags, + f_vrfy, p_vrfy ); + if( ret != 0 ) + return( ret ); + } + else + { + ret = x509_crt_verify_top( parent, trust_ca, ca_crl, profile, + path_cnt + 1, self_cnt, &parent_flags, + f_vrfy, p_vrfy ); + if( ret != 0 ) + return( ret ); + } + } + + /* child is verified to be a child of the parent, call verify callback */ + if( NULL != f_vrfy ) + if( ( ret = f_vrfy( p_vrfy, child, path_cnt, flags ) ) != 0 ) + return( ret ); + + *flags |= parent_flags; + + return( 0 ); } -#endif /* !MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION */ /* - * Verify the certificate validity (default profile, not restartable) + * Verify the certificate validity */ int mbedtls_x509_crt_verify( mbedtls_x509_crt *crt, mbedtls_x509_crt *trust_ca, mbedtls_x509_crl *ca_crl, -#if !defined(MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION) - const char *cn, -#endif /* !MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION */ - uint32_t *flags -#if !defined(MBEDTLS_X509_REMOVE_VERIFY_CALLBACK) - , int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *) - , void *p_vrfy -#endif /* MBEDTLS_X509_REMOVE_VERIFY_CALLBACK */ - ) + const char *cn, uint32_t *flags, + int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), + void *p_vrfy ) { - return( mbedtls_x509_crt_verify_restartable( crt, trust_ca, ca_crl, - &mbedtls_x509_crt_profile_default, -#if !defined(MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION) - cn, -#endif /* !MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION */ - flags, -#if !defined(MBEDTLS_X509_REMOVE_VERIFY_CALLBACK) - f_vrfy, p_vrfy, -#endif /* !MBEDTLS_X509_REMOVE_VERIFY_CALLBACK */ - NULL ) ); + return( mbedtls_x509_crt_verify_with_profile( crt, trust_ca, ca_crl, + &mbedtls_x509_crt_profile_default, cn, flags, f_vrfy, p_vrfy ) ); } + /* - * Verify the certificate validity (user-chosen profile, not restartable) + * 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, mbedtls_x509_crt *trust_ca, mbedtls_x509_crl *ca_crl, const mbedtls_x509_crt_profile *profile, -#if !defined(MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION) - const char *cn, -#endif /* !MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION */ - uint32_t *flags -#if !defined(MBEDTLS_X509_REMOVE_VERIFY_CALLBACK) - , int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *) - , void *p_vrfy -#endif /* MBEDTLS_X509_REMOVE_VERIFY_CALLBACK */ - ) -{ - return( mbedtls_x509_crt_verify_restartable( crt, trust_ca, ca_crl, - profile, -#if !defined(MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION) - cn, -#endif /* !MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION */ - flags, -#if !defined(MBEDTLS_X509_REMOVE_VERIFY_CALLBACK) - f_vrfy, p_vrfy, -#endif /* !MBEDTLS_X509_REMOVE_VERIFY_CALLBACK */ - NULL ) ); -} - -/* - * Verify the certificate validity, with profile, restartable version - * - * This function: - * - checks the requested CN (if any) - * - checks the type and size of the EE cert's key, - * as that isn't done as part of chain building/verification currently - * - builds and verifies the chain - * - then calls the callback and merges the flags - */ -int mbedtls_x509_crt_verify_restartable( mbedtls_x509_crt *crt, - mbedtls_x509_crt *trust_ca, - mbedtls_x509_crl *ca_crl, - const mbedtls_x509_crt_profile *profile, -#if !defined(MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION) - const char *cn, -#endif /* !MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION */ - uint32_t *flags, -#if !defined(MBEDTLS_X509_REMOVE_VERIFY_CALLBACK) + const char *cn, uint32_t *flags, int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), - void *p_vrfy, -#endif /* !MBEDTLS_X509_REMOVE_VERIFY_CALLBACK */ - mbedtls_x509_crt_restart_ctx *rs_ctx ) + void *p_vrfy ) { + size_t cn_len; int ret; - mbedtls_x509_crt_verify_chain ver_chain; - uint32_t ee_flags; - volatile uint32_t flags_fi = (uint32_t) -1; + int pathlen = 0, selfsigned = 0; + mbedtls_x509_crt *parent; + mbedtls_x509_name *name; + mbedtls_x509_sequence *cur = NULL; + mbedtls_pk_type_t pk_type; *flags = 0; - ee_flags = 0; - x509_crt_verify_chain_reset( &ver_chain ); if( profile == NULL ) { @@ -3800,59 +2265,106 @@ int mbedtls_x509_crt_verify_restartable( mbedtls_x509_crt *crt, goto exit; } -#if !defined(MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION) - /* check name if requested */ if( cn != NULL ) { - ret = x509_crt_verify_name( crt, cn, &ee_flags ); - if( ret != 0 ) - return( ret ); - } -#endif /* !MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION */ + name = &crt->subject; + cn_len = strlen( cn ); + if( crt->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME ) + { + cur = &crt->subject_alt_names; + + while( cur != NULL ) + { + if( cur->buf.len == cn_len && + x509_memcasecmp( cn, cur->buf.p, cn_len ) == 0 ) + break; + + if( cur->buf.len > 2 && + memcmp( cur->buf.p, "*.", 2 ) == 0 && + x509_check_wildcard( cn, &cur->buf ) == 0 ) + { + break; + } + + cur = cur->next; + } + + if( cur == NULL ) + *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH; + } + else + { + while( name != NULL ) + { + if( MBEDTLS_OID_CMP( MBEDTLS_OID_AT_CN, &name->oid ) == 0 ) + { + if( name->val.len == cn_len && + x509_memcasecmp( name->val.p, cn, cn_len ) == 0 ) + break; + + if( name->val.len > 2 && + memcmp( name->val.p, "*.", 2 ) == 0 && + x509_check_wildcard( cn, &name->val ) == 0 ) + break; + } + + name = name->next; + } + + if( name == NULL ) + *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH; + } + } + + /* Check the type and size of the key */ + pk_type = mbedtls_pk_get_type( &crt->pk ); + + if( x509_profile_check_pk_alg( profile, pk_type ) != 0 ) + *flags |= MBEDTLS_X509_BADCERT_BAD_PK; + + if( x509_profile_check_key( profile, pk_type, &crt->pk ) != 0 ) + *flags |= MBEDTLS_X509_BADCERT_BAD_KEY; + + /* Look for a parent in trusted CAs */ + for( parent = trust_ca; parent != NULL; parent = parent->next ) { - mbedtls_pk_context *pk; - mbedtls_pk_type_t pk_type; - - ret = mbedtls_x509_crt_pk_acquire( crt, &pk ); - if( ret != 0 ) - return( MBEDTLS_ERR_X509_FATAL_ERROR ); - - /* Check the type and size of the key */ - pk_type = mbedtls_pk_get_type( pk ); - - if( x509_profile_check_pk_alg( profile, pk_type ) != 0 ) - ee_flags |= MBEDTLS_X509_BADCERT_BAD_PK | X509_BADCERT_FI_EXTRA; - - if( x509_profile_check_key( profile, pk ) != 0 ) - ee_flags |= MBEDTLS_X509_BADCERT_BAD_KEY | X509_BADCERT_FI_EXTRA; - - mbedtls_x509_crt_pk_release( crt ); + if( x509_crt_check_parent( crt, parent, 0, pathlen == 0 ) == 0 ) + break; } - /* Check the chain */ - ret = x509_crt_verify_chain( crt, trust_ca, ca_crl, profile, - &ver_chain, rs_ctx ); + if( parent != NULL ) + { + ret = x509_crt_verify_top( crt, parent, ca_crl, profile, + pathlen, selfsigned, flags, f_vrfy, p_vrfy ); + if( ret != 0 ) + goto exit; + } + else + { + /* Look for a parent upwards the chain */ + for( parent = crt->next; parent != NULL; parent = parent->next ) + if( x509_crt_check_parent( crt, parent, 0, pathlen == 0 ) == 0 ) + break; - if( ret != 0 ) - goto exit; - - /* Merge end-entity flags */ - x509_crt_verify_chain_add_ee_flags( &ver_chain, ee_flags ); - - /* Build final flags, calling callback on the way if any */ -#if !defined(MBEDTLS_X509_REMOVE_VERIFY_CALLBACK) - ret = x509_crt_verify_chain_get_flags( &ver_chain, flags, f_vrfy, p_vrfy ); -#else - ret = x509_crt_verify_chain_get_flags( &ver_chain, flags, NULL, NULL ); -#endif /* MBEDTLS_X509_REMOVE_VERIFY_CALLBACK */ + /* Are we part of the chain or at the top? */ + if( parent != NULL ) + { + ret = x509_crt_verify_child( crt, parent, trust_ca, ca_crl, profile, + pathlen, selfsigned, flags, f_vrfy, p_vrfy ); + if( ret != 0 ) + goto exit; + } + else + { + ret = x509_crt_verify_top( crt, trust_ca, ca_crl, profile, + pathlen, selfsigned, flags, f_vrfy, p_vrfy ); + if( ret != 0 ) + goto exit; + } + } exit: -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && ret != MBEDTLS_ERR_ECP_IN_PROGRESS ) - mbedtls_x509_crt_restart_free( rs_ctx ); -#endif - /* prevent misuse of the vrfy callback - VERIFY_FAILED would be ignored by * the SSL module for authmode optional, but non-zero return from the * callback means a fatal error so it shouldn't be ignored */ @@ -3865,21 +2377,10 @@ exit: return( ret ); } - flags_fi = *flags; - if( flags_fi == 0 ) - { - mbedtls_platform_random_delay(); - if( flags_fi == 0 ) - return( 0 ); - else - return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); - } + if( *flags != 0 ) + return( MBEDTLS_ERR_X509_CERT_VERIFY_FAILED ); - /* Preserve the API by removing internal extra bits - from now on the - * fact that flags is non-zero is also redundantly encoded by the - * non-zero return value from this function. */ - *flags &= ~ X509_BADCERT_FI_EXTRA; - return( MBEDTLS_ERR_X509_CERT_VERIFY_FAILED ); + return( 0 ); } /* @@ -3893,39 +2394,65 @@ void mbedtls_x509_crt_init( mbedtls_x509_crt *crt ) /* * Unallocate all certificate data */ - void mbedtls_x509_crt_free( mbedtls_x509_crt *crt ) { mbedtls_x509_crt *cert_cur = crt; mbedtls_x509_crt *cert_prv; + mbedtls_x509_name *name_cur; + mbedtls_x509_name *name_prv; + mbedtls_x509_sequence *seq_cur; + mbedtls_x509_sequence *seq_prv; if( crt == NULL ) return; do { - x509_crt_cache_free( cert_cur->cache ); - mbedtls_free( cert_cur->cache ); - -#if !defined(MBEDTLS_X509_ON_DEMAND_PARSING) mbedtls_pk_free( &cert_cur->pk ); #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) mbedtls_free( cert_cur->sig_opts ); #endif - mbedtls_x509_name_free( cert_cur->issuer.next ); - mbedtls_x509_name_free( cert_cur->subject.next ); - mbedtls_x509_sequence_free( cert_cur->ext_key_usage.next ); -#if !defined(MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION) - mbedtls_x509_sequence_free( cert_cur->subject_alt_names.next ); -#endif /* !MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION */ - -#endif /* !MBEDTLS_X509_ON_DEMAND_PARSING */ - - if( cert_cur->raw.p != NULL && cert_cur->own_buffer ) + name_cur = cert_cur->issuer.next; + while( name_cur != NULL ) { - mbedtls_platform_zeroize( cert_cur->raw.p, cert_cur->raw.len ); + name_prv = name_cur; + name_cur = name_cur->next; + mbedtls_zeroize( name_prv, sizeof( mbedtls_x509_name ) ); + mbedtls_free( name_prv ); + } + + name_cur = cert_cur->subject.next; + while( name_cur != NULL ) + { + name_prv = name_cur; + name_cur = name_cur->next; + mbedtls_zeroize( name_prv, sizeof( mbedtls_x509_name ) ); + mbedtls_free( name_prv ); + } + + seq_cur = cert_cur->ext_key_usage.next; + while( seq_cur != NULL ) + { + seq_prv = seq_cur; + seq_cur = seq_cur->next; + mbedtls_zeroize( seq_prv, sizeof( mbedtls_x509_sequence ) ); + mbedtls_free( seq_prv ); + } + + seq_cur = cert_cur->subject_alt_names.next; + while( seq_cur != NULL ) + { + seq_prv = seq_cur; + seq_cur = seq_cur->next; + mbedtls_zeroize( seq_prv, sizeof( mbedtls_x509_sequence ) ); + mbedtls_free( seq_prv ); + } + + if( cert_cur->raw.p != NULL ) + { + mbedtls_zeroize( cert_cur->raw.p, cert_cur->raw.len ); mbedtls_free( cert_cur->raw.p ); } @@ -3939,170 +2466,11 @@ void mbedtls_x509_crt_free( mbedtls_x509_crt *crt ) cert_prv = cert_cur; cert_cur = cert_cur->next; - mbedtls_platform_zeroize( cert_prv, sizeof( mbedtls_x509_crt ) ); + mbedtls_zeroize( cert_prv, sizeof( mbedtls_x509_crt ) ); if( cert_prv != crt ) mbedtls_free( cert_prv ); } while( cert_cur != NULL ); } -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) -/* - * Initialize a restart context - */ -void mbedtls_x509_crt_restart_init( mbedtls_x509_crt_restart_ctx *ctx ) -{ - mbedtls_pk_restart_init( &ctx->pk ); - - ctx->parent = NULL; -#if defined(MBEDTLS_HAVE_TIME_DATE) - ctx->fallback_parent = NULL; - ctx->fallback_signature_is_good = 0; -#endif /* MBEDTLS_HAVE_TIME_DATE */ - - ctx->parent_is_trusted = -1; - - ctx->in_progress = x509_crt_rs_none; - ctx->self_cnt = 0; - x509_crt_verify_chain_reset( &ctx->ver_chain ); -} - -/* - * Free the components of a restart context - */ -void mbedtls_x509_crt_restart_free( mbedtls_x509_crt_restart_ctx *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_pk_restart_free( &ctx->pk ); - mbedtls_x509_crt_restart_init( ctx ); -} -#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - -int mbedtls_x509_crt_frame_acquire( mbedtls_x509_crt const *crt, - mbedtls_x509_crt_frame const **dst ) -{ - int ret = 0; -#if defined(MBEDTLS_THREADING_C) - if( mbedtls_mutex_lock( &crt->cache->frame_mutex ) != 0 ) - return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); -#endif /* MBEDTLS_THREADING_C */ - -#if !defined(MBEDTLS_X509_ALWAYS_FLUSH) || \ - defined(MBEDTLS_THREADING_C) - if( crt->cache->frame_readers == 0 ) -#endif - ret = mbedtls_x509_crt_cache_provide_frame( crt ); - -#if !defined(MBEDTLS_X509_ALWAYS_FLUSH) || \ - defined(MBEDTLS_THREADING_C) - if( crt->cache->frame_readers == MBEDTLS_X509_CACHE_FRAME_READERS_MAX ) - return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); - - crt->cache->frame_readers++; -#endif - -#if defined(MBEDTLS_THREADING_C) - if( mbedtls_mutex_unlock( &crt->cache->frame_mutex ) != 0 ) - return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); -#endif /* MBEDTLS_THREADING_C */ - - *dst = crt->cache->frame; - return( ret ); -} - -int mbedtls_x509_crt_frame_release( mbedtls_x509_crt const *crt ) -{ -#if defined(MBEDTLS_THREADING_C) - if( mbedtls_mutex_lock( &crt->cache->frame_mutex ) != 0 ) - return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); -#endif /* MBEDTLS_THREADING_C */ - -#if !defined(MBEDTLS_X509_ALWAYS_FLUSH) || \ - defined(MBEDTLS_THREADING_C) - if( crt->cache->frame_readers == 0 ) - return( MBEDTLS_ERR_X509_FATAL_ERROR ); - - crt->cache->frame_readers--; -#endif - -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_unlock( &crt->cache->frame_mutex ); -#endif /* MBEDTLS_THREADING_C */ - -#if defined(MBEDTLS_X509_ALWAYS_FLUSH) - (void) mbedtls_x509_crt_flush_cache_frame( crt ); -#endif /* MBEDTLS_X509_ALWAYS_FLUSH */ - -#if !defined(MBEDTLS_X509_ALWAYS_FLUSH) && \ - !defined(MBEDTLS_THREADING_C) - ((void) crt); -#endif - - return( 0 ); -} - -int mbedtls_x509_crt_pk_acquire( mbedtls_x509_crt const *crt, - mbedtls_pk_context **dst ) -{ - int ret = 0; -#if defined(MBEDTLS_THREADING_C) - if( mbedtls_mutex_lock( &crt->cache->pk_mutex ) != 0 ) - return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); -#endif /* MBEDTLS_THREADING_C */ - -#if !defined(MBEDTLS_X509_ALWAYS_FLUSH) || \ - defined(MBEDTLS_THREADING_C) - if( crt->cache->pk_readers == 0 ) -#endif - ret = mbedtls_x509_crt_cache_provide_pk( crt ); - -#if !defined(MBEDTLS_X509_ALWAYS_FLUSH) || \ - defined(MBEDTLS_THREADING_C) - if( crt->cache->pk_readers == MBEDTLS_X509_CACHE_PK_READERS_MAX ) - return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); - - crt->cache->pk_readers++; -#endif - -#if defined(MBEDTLS_THREADING_C) - if( mbedtls_mutex_unlock( &crt->cache->pk_mutex ) != 0 ) - return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); -#endif /* MBEDTLS_THREADING_C */ - - *dst = crt->cache->pk; - return( ret ); -} - -int mbedtls_x509_crt_pk_release( mbedtls_x509_crt const *crt ) -{ -#if defined(MBEDTLS_THREADING_C) - if( mbedtls_mutex_lock( &crt->cache->pk_mutex ) != 0 ) - return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); -#endif /* MBEDTLS_THREADING_C */ - -#if !defined(MBEDTLS_X509_ALWAYS_FLUSH) || \ - defined(MBEDTLS_THREADING_C) - if( crt->cache->pk_readers == 0 ) - return( MBEDTLS_ERR_X509_FATAL_ERROR ); - - crt->cache->pk_readers--; -#endif - -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_unlock( &crt->cache->pk_mutex ); -#endif /* MBEDTLS_THREADING_C */ - -#if defined(MBEDTLS_X509_ALWAYS_FLUSH) - (void) mbedtls_x509_crt_flush_cache_pk( crt ); -#endif /* MBEDTLS_X509_ALWAYS_FLUSH */ - -#if !defined(MBEDTLS_X509_ALWAYS_FLUSH) && \ - !defined(MBEDTLS_THREADING_C) - ((void) crt); -#endif - - return( 0 ); -} #endif /* MBEDTLS_X509_CRT_PARSE_C */ diff --git a/APP_Framework/Framework/security/mbedtls/x509_crt.h b/APP_Framework/Framework/security/mbedtls/x509_crt.h index f0eed056f..2c3c758e9 100644 --- a/APP_Framework/Framework/security/mbedtls/x509_crt.h +++ b/APP_Framework/Framework/security/mbedtls/x509_crt.h @@ -47,90 +47,12 @@ extern "C" { * \{ */ -typedef struct mbedtls_x509_crt_cache -{ -#if !defined(MBEDTLS_X509_ALWAYS_FLUSH) || \ - defined(MBEDTLS_THREADING_C) - uint32_t frame_readers; - uint32_t pk_readers; -#endif /* !MBEDTLS_X509_ALWAYS_FLUSH || MBEDTLS_THREADING_C */ -#if defined(MBEDTLS_THREADING_C) - mbedtls_threading_mutex_t frame_mutex; - mbedtls_threading_mutex_t pk_mutex; -#endif - mbedtls_x509_buf_raw pk_raw; - struct mbedtls_x509_crt_frame *frame; - struct mbedtls_pk_context *pk; -} mbedtls_x509_crt_cache; - -typedef struct mbedtls_x509_crt_frame -{ - /* Keep these 8-bit fields at the front of the structure to allow them to - * be fetched in a single instruction on Thumb2; putting them at the back - * requires an intermediate address calculation. */ - - uint8_t version; /**< The X.509 version. (1=v1, 2=v2, 3=v3) */ - uint8_t ca_istrue; /**< Optional Basic Constraint extension value: - * 1 if this certificate belongs to a CA, 0 otherwise. */ - uint8_t max_pathlen; /**< Optional Basic Constraint extension value: - * The maximum path length to the root certificate. - * Path length is 1 higher than RFC 5280 'meaning', so 1+ */ - uint8_t ns_cert_type; /**< Optional Netscape certificate type extension value: - * See the values in x509.h */ - - mbedtls_md_type_t sig_md; /**< The hash algorithm used to hash CRT before signing. */ - mbedtls_pk_type_t sig_pk; /**< The signature algorithm used to sign the CRT hash. */ - - uint16_t key_usage; /**< Optional key usage extension value: See the values in x509.h */ - uint32_t ext_types; /**< Bitfield indicating which extensions are present. - * See the values in x509.h. */ - -#if !defined(MBEDTLS_X509_CRT_REMOVE_TIME) - mbedtls_x509_time valid_from; /**< The start time of certificate validity. */ - mbedtls_x509_time valid_to; /**< The end time of certificate validity. */ -#endif /* !MBEDTLS_X509_CRT_REMOVE_TIME */ - - mbedtls_x509_buf_raw raw; /**< The raw certificate data in DER. */ - mbedtls_x509_buf_raw tbs; /**< The part of the CRT that is [T]o [B]e [S]igned. */ - - mbedtls_x509_buf_raw serial; /**< The unique ID for certificate issued by a specific CA. */ - - mbedtls_x509_buf_raw pubkey_raw; /**< The raw public key data (DER). */ - -#if !defined(MBEDTLS_X509_CRT_REMOVE_SUBJECT_ISSUER_ID) - mbedtls_x509_buf_raw issuer_id; /**< Optional X.509 v2/v3 issuer unique identifier. */ - mbedtls_x509_buf_raw subject_id; /**< Optional X.509 v2/v3 subject unique identifier. */ -#endif /* !MBEDTLS_X509_CRT_REMOVE_SUBJECT_ISSUER_ID */ - - mbedtls_x509_buf_raw issuer_raw; /**< The raw issuer data (DER). Used for quick comparison. */ - mbedtls_x509_buf_raw subject_raw; /**< The raw subject data (DER). Used for quick comparison. */ - - mbedtls_x509_buf_raw sig; /**< Signature: hash of the tbs part signed with the private key. */ - mbedtls_x509_buf_raw sig_alg; /**< The signature algorithm used for \p sig. */ - - mbedtls_x509_buf_raw v3_ext; /**< The raw data for the extension list in the certificate. - * Might be useful for manual inspection of extensions that - * Mbed TLS doesn't yet support. */ -#if !defined(MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION) - mbedtls_x509_buf_raw subject_alt_raw; /**< The raw data for the SubjectAlternativeNames extension. */ -#endif /* !MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION */ - mbedtls_x509_buf_raw ext_key_usage_raw; /**< The raw data for the ExtendedKeyUsage extension. */ -} mbedtls_x509_crt_frame; - /** * Container for an X.509 certificate. The certificate may be chained. */ typedef struct mbedtls_x509_crt { - int own_buffer; /**< Indicates if \c raw is owned - * by the structure or not. */ - mbedtls_x509_buf raw; /**< The raw certificate data (DER). */ - mbedtls_x509_crt_cache *cache; /**< Internal parsing cache. */ - - struct mbedtls_x509_crt *next; /**< Next certificate in the CA-chain. */ - - /* Legacy fields */ -#if !defined(MBEDTLS_X509_ON_DEMAND_PARSING) + mbedtls_x509_buf raw; /**< The raw certificate data (DER). */ mbedtls_x509_buf tbs; /**< The raw certificate body (DER). The part that is To Be Signed. */ int version; /**< The X.509 version. (1=v1, 2=v2, 3=v3) */ @@ -143,22 +65,15 @@ typedef struct mbedtls_x509_crt mbedtls_x509_name issuer; /**< The parsed issuer data (named information object). */ mbedtls_x509_name subject; /**< The parsed subject data (named information object). */ -#if !defined(MBEDTLS_X509_CRT_REMOVE_TIME) mbedtls_x509_time valid_from; /**< Start time of certificate validity. */ mbedtls_x509_time valid_to; /**< End time of certificate validity. */ -#endif /* !MBEDTLS_X509_CRT_REMOVE_TIME */ - mbedtls_x509_buf pk_raw; mbedtls_pk_context pk; /**< Container for the public key context. */ -#if !defined(MBEDTLS_X509_CRT_REMOVE_SUBJECT_ISSUER_ID) mbedtls_x509_buf issuer_id; /**< Optional X.509 v2/v3 issuer unique identifier. */ mbedtls_x509_buf subject_id; /**< Optional X.509 v2/v3 subject unique identifier. */ -#endif /* !MBEDTLS_X509_CRT_REMOVE_SUBJECT_ISSUER_ID */ mbedtls_x509_buf v3_ext; /**< Optional X.509 v3 extensions. */ -#if !defined(MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION) mbedtls_x509_sequence subject_alt_names; /**< Optional list of Subject Alternative Names (Only dNSName supported). */ -#endif /* !MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION */ int ext_types; /**< Bit string containing detected and parsed extensions */ int ca_istrue; /**< Optional Basic Constraint extension value: 1 if this certificate belongs to a CA, 0 otherwise. */ @@ -166,7 +81,7 @@ typedef struct mbedtls_x509_crt unsigned int key_usage; /**< Optional key usage extension value: See the values in x509.h */ - mbedtls_x509_sequence ext_key_usage; /**< Optional list of extended key usage OIDs. */ + mbedtls_x509_sequence ext_key_usage; /**< Optional list of extended key usage OIDs. */ unsigned char ns_cert_type; /**< Optional Netscape certificate type extension value: See the values in x509.h */ @@ -174,7 +89,8 @@ typedef struct mbedtls_x509_crt mbedtls_md_type_t sig_md; /**< Internal representation of the MD algorithm of the signature algorithm, e.g. MBEDTLS_MD_SHA256 */ mbedtls_pk_type_t sig_pk; /**< Internal representation of the Public Key algorithm of the signature algorithm, e.g. MBEDTLS_PK_RSA */ void *sig_opts; /**< Signature options to be passed to mbedtls_pk_verify_ext(), e.g. for RSASSA-PSS */ -#endif /* !MBEDTLS_X509_ON_DEMAND_PARSING */ + + struct mbedtls_x509_crt *next; /**< Next certificate in the CA-chain. */ } mbedtls_x509_crt; @@ -182,14 +98,14 @@ mbedtls_x509_crt; * Build flag from an algorithm/curve identifier (pk, md, ecp) * Since 0 is always XXX_NONE, ignore it. */ -#define MBEDTLS_X509_ID_FLAG( id ) ( 1 << ( (id) - 1 ) ) +#define MBEDTLS_X509_ID_FLAG( id ) ( 1 << ( id - 1 ) ) /** * Security profile for certificate verification. * * All lists are bitfields, built by ORing flags from MBEDTLS_X509_ID_FLAG(). */ -typedef struct mbedtls_x509_crt_profile +typedef struct { uint32_t allowed_mds; /**< MDs for signatures */ uint32_t allowed_pks; /**< PK algs for signatures */ @@ -209,7 +125,6 @@ mbedtls_x509_crt_profile; #define MBEDTLS_X509_MAX_FILE_PATH_LEN 512 #endif -#if defined(MBEDTLS_X509_CRT_WRITE_C) /** * Container for writing a certificate (CRT) */ @@ -227,82 +142,6 @@ typedef struct mbedtls_x509write_cert mbedtls_asn1_named_data *extensions; } mbedtls_x509write_cert; -#endif /* MBEDTLS_X509_CRT_WRITE_C */ - -#if !defined(MBEDTLS_X509_REMOVE_VERIFY_CALLBACK) - -/** - * Item in a verification chain: cert and flags for it - */ -typedef struct { - mbedtls_x509_crt *crt; - uint32_t flags; -} mbedtls_x509_crt_verify_chain_item; - -/** - * Max size of verification chain: end-entity + intermediates + trusted root - */ -#define MBEDTLS_X509_MAX_VERIFY_CHAIN_SIZE ( MBEDTLS_X509_MAX_INTERMEDIATE_CA + 2 ) - -/** - * Verification chain as built by \c mbedtls_crt_verify_chain() - */ -typedef struct -{ - mbedtls_x509_crt_verify_chain_item items[MBEDTLS_X509_MAX_VERIFY_CHAIN_SIZE]; - unsigned len; -} mbedtls_x509_crt_verify_chain; - -#else /* !MBEDTLS_X509_REMOVE_VERIFY_CALLBACK */ - -typedef struct -{ - unsigned len; - uint32_t flags; -} mbedtls_x509_crt_verify_chain; - -#endif /* !MBEDTLS_X509_REMOVE_VERIFY_CALLBACK */ - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - -/** - * \brief Context for resuming X.509 verify operations - */ -typedef struct -{ - /* for check_signature() */ - mbedtls_pk_restart_ctx pk; - - /* for find_parent_in() */ - mbedtls_x509_crt *parent; /* non-null iff parent_in in progress */ - - /* current child CRT */ - mbedtls_x509_crt *cur_crt; - -#if defined(MBEDTLS_HAVE_TIME_DATE) - mbedtls_x509_crt *fallback_parent; - int fallback_signature_is_good; -#endif /* MBEDTLS_HAVE_TIME_DATE */ - - /* for find_parent() */ - int parent_is_trusted; /* -1 if find_parent is not in progress */ - - /* for verify_chain() */ - enum { - x509_crt_rs_none, - x509_crt_rs_find_parent, - } in_progress; /* none if no operation is in progress */ - int self_cnt; - mbedtls_x509_crt_verify_chain ver_chain; - -} mbedtls_x509_crt_restart_ctx; - -#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - -/* Now we can declare functions that take a pointer to that */ -typedef void mbedtls_x509_crt_restart_ctx; - -#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ #if defined(MBEDTLS_X509_CRT_PARSE_C) /** @@ -324,58 +163,16 @@ extern const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_suiteb; /** * \brief Parse a single DER formatted certificate and add it - * to the end of the provided chained list. + * to the chained list. * - * \param chain The pointer to the start of the CRT chain to attach to. - * When parsing the first CRT in a chain, this should point - * to an instance of ::mbedtls_x509_crt initialized through - * mbedtls_x509_crt_init(). - * \param buf The buffer holding the DER encoded certificate. - * \param buflen The size in Bytes of \p buf. + * \param chain points to the start of the chain + * \param buf buffer holding the certificate DER data + * \param buflen size of the buffer * - * \note This function makes an internal copy of the CRT buffer - * \p buf. In particular, \p buf may be destroyed or reused - * after this call returns. To avoid duplicating the CRT - * buffer (at the cost of stricter lifetime constraints), - * use mbedtls_x509_crt_parse_der_nocopy() instead. - * - * \return \c 0 if successful. - * \return A negative error code on failure. + * \return 0 if successful, or a specific X509 or PEM error code */ -int mbedtls_x509_crt_parse_der( mbedtls_x509_crt *chain, - const unsigned char *buf, - size_t buflen ); - -/** - * \brief Parse a single DER formatted certificate and add it - * to the end of the provided chained list. This is a - * variant of mbedtls_x509_crt_parse_der() which takes - * temporary ownership of the CRT buffer until the CRT - * is destroyed. - * - * \param chain The pointer to the start of the CRT chain to attach to. - * When parsing the first CRT in a chain, this should point - * to an instance of ::mbedtls_x509_crt initialized through - * mbedtls_x509_crt_init(). - * \param buf The address of the readable buffer holding the DER encoded - * certificate to use. On success, this buffer must be - * retained and not be changed for the liftetime of the - * CRT chain \p chain, that is, until \p chain is destroyed - * through a call to mbedtls_x509_crt_free(). - * \param buflen The size in Bytes of \p buf. - * - * \note This call is functionally equivalent to - * mbedtls_x509_crt_parse_der(), but it avoids creating a - * copy of the input buffer at the cost of stronger lifetime - * constraints. This is useful in constrained environments - * where duplication of the CRT cannot be tolerated. - * - * \return \c 0 if successful. - * \return A negative error code on failure. - */ -int mbedtls_x509_crt_parse_der_nocopy( mbedtls_x509_crt *chain, - const unsigned char *buf, - size_t buflen ); +int mbedtls_x509_crt_parse_der( mbedtls_x509_crt *chain, const unsigned char *buf, + size_t buflen ); /** * \brief Parse one DER-encoded or one or more concatenated PEM-encoded @@ -441,7 +238,6 @@ int mbedtls_x509_crt_parse_file( mbedtls_x509_crt *chain, const char *path ); int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path ); #endif /* MBEDTLS_FS_IO */ -#if !defined(MBEDTLS_X509_REMOVE_INFO) /** * \brief Returns an informational string about the * certificate. @@ -471,7 +267,6 @@ int mbedtls_x509_crt_info( char *buf, size_t size, const char *prefix, */ int mbedtls_x509_crt_verify_info( char *buf, size_t size, const char *prefix, uint32_t flags ); -#endif /* !MBEDTLS_X509_REMOVE_INFO */ /** * \brief Verify the certificate signature @@ -532,17 +327,11 @@ int mbedtls_x509_crt_verify_info( char *buf, size_t size, const char *prefix, * verification process. */ int mbedtls_x509_crt_verify( mbedtls_x509_crt *crt, - mbedtls_x509_crt *trust_ca, - mbedtls_x509_crl *ca_crl, -#if !defined(MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION) || defined(DOXYGEN_ONLY) - const char *cn, -#endif /* !MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION || DOXYGEN_ONLY */ - uint32_t *flags -#if !defined(MBEDTLS_X509_REMOVE_VERIFY_CALLBACK) || defined(DOXYGEN_ONLY) - , int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), - void *p_vrfy -#endif /* !MBEDTLS_X509_REMOVE_VERIFY_CALLBACK || DOXYGEN_ONLY */ - ); + mbedtls_x509_crt *trust_ca, + mbedtls_x509_crl *ca_crl, + const char *cn, uint32_t *flags, + int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), + void *p_vrfy ); /** * \brief Verify the certificate signature according to profile @@ -575,51 +364,9 @@ int mbedtls_x509_crt_verify_with_profile( mbedtls_x509_crt *crt, mbedtls_x509_crt *trust_ca, mbedtls_x509_crl *ca_crl, const mbedtls_x509_crt_profile *profile, -#if !defined(MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION) || defined(DOXYGEN_ONLY) - const char *cn, -#endif /* !MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION || DOXYGEN_ONLY */ - uint32_t *flags -#if !defined(MBEDTLS_X509_REMOVE_VERIFY_CALLBACK) || defined(DOXYGEN_ONLY) - , int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), - void *p_vrfy -#endif /* !MBEDTLS_X509_REMOVE_VERIFY_CALLBACK || DOXYGEN_ONLY */ - ); - -/** - * \brief Restartable version of \c mbedtls_crt_verify_with_profile() - * - * \note Performs the same job as \c mbedtls_crt_verify_with_profile() - * but can return early and restart according to the limit - * set with \c mbedtls_ecp_set_max_ops() to reduce blocking. - * - * \param crt a certificate (chain) to be verified - * \param trust_ca the list of trusted CAs - * \param ca_crl the list of CRLs for trusted CAs - * \param profile security profile for verification - * \param cn expected Common Name (can be set to - * NULL if the CN must not be verified) - * \param flags result of the verification - * \param f_vrfy verification function - * \param p_vrfy verification parameter - * \param rs_ctx restart context (NULL to disable restart) - * - * \return See \c mbedtls_crt_verify_with_profile(), or - * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of - * operations was reached: see \c mbedtls_ecp_set_max_ops(). - */ -int mbedtls_x509_crt_verify_restartable( mbedtls_x509_crt *crt, - mbedtls_x509_crt *trust_ca, - mbedtls_x509_crl *ca_crl, - const mbedtls_x509_crt_profile *profile, -#if !defined(MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION) || defined(DOXYGEN_ONLY) - const char *cn, -#endif /* !MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION || DOXYGEN_ONLY */ - uint32_t *flags, -#if !defined(MBEDTLS_X509_REMOVE_VERIFY_CALLBACK) || defined(DOXYGEN_ONLY) - int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), - void *p_vrfy, -#endif /* !MBEDTLS_X509_REMOVE_VERIFY_CALLBACK || DOXYGEN_ONLY */ - mbedtls_x509_crt_restart_ctx *rs_ctx ); + const char *cn, uint32_t *flags, + int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), + void *p_vrfy ); #if defined(MBEDTLS_X509_CHECK_KEY_USAGE) /** @@ -692,264 +439,6 @@ void mbedtls_x509_crt_init( mbedtls_x509_crt *crt ); * \param crt Certificate chain to free */ void mbedtls_x509_crt_free( mbedtls_x509_crt *crt ); - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) -/** - * \brief Initialize a restart context - */ -void mbedtls_x509_crt_restart_init( mbedtls_x509_crt_restart_ctx *ctx ); - -/** - * \brief Free the components of a restart context - */ -void mbedtls_x509_crt_restart_free( mbedtls_x509_crt_restart_ctx *ctx ); -#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - -/** - * \brief Request CRT frame giving access to basic CRT fields - * and raw ASN.1 data of complex fields. - * - * \param crt The CRT to use. This must be initialized and set up. - * \param dst The address of the destination frame structure. - * This need not be initialized. - * - * \note ::mbedtls_x509_crt_frame does not contain pointers to - * dynamically allocated memory, and hence need not be freed. - * Users may e.g. allocate an instance of - * ::mbedtls_x509_crt_frame on the stack and call this function - * on it, in which case no allocation/freeing has to be done. - * - * \note You may also use mbedtls_x509_crt_frame_acquire() and - * mbedtls_x509_crt_frame_release() for copy-less variants - * of this function. - * - * \return \c 0 on success. In this case, \p dst is updated - * to hold the frame for the given CRT. - * \return A negative error code on failure. - */ -int mbedtls_x509_crt_get_frame( mbedtls_x509_crt const *crt, - mbedtls_x509_crt_frame *dst ); - -/** - * \brief Set up a PK context with the public key in a certificate. - * - * \param crt The certificate to use. This must be initialized and set up. - * \param pk The address of the destination PK context to fill. - * This must be initialized via mbedtls_pk_init(). - * - * \note You may also use mbedtls_x509_crt_pk_acquire() and - * mbedtls_x509_crt_pk_release() for copy-less variants - * of this function. - * - * \return \c 0 on success. In this case, the user takes ownership - * of the destination PK context, and is responsible for - * calling mbedtls_pk_free() on it once it's no longer needed. - * \return A negative error code on failure. - */ -int mbedtls_x509_crt_get_pk( mbedtls_x509_crt const *crt, - mbedtls_pk_context *pk ); - -/** - * \brief Request the subject name of a CRT, presented - * as a dynamically allocated linked list. - * - * \param crt The CRT to use. This must be initialized and set up. - * \param subject The address at which to store the address of the - * first entry of the generated linked list holding - * the subject name. - * - * \note Depending on your use case, consider using the raw ASN.1 - * describing the subject name instead of the heap-allocated - * linked list generated by this call. The pointers to the - * raw ASN.1 data are part of the CRT frame that can be queried - * via mbedtls_x509_crt_get_frame(), and they can be traversed - * via mbedtls_asn1_traverse_sequence_of(). - * - * \return \c 0 on success. In this case, the user takes ownership - * of the name context, and is responsible for freeing it - * through a call to mbedtls_x509_name_free() once it's no - * longer needed. - * \return A negative error code on failure. - */ -int mbedtls_x509_crt_get_subject( mbedtls_x509_crt const *crt, - mbedtls_x509_name **subject ); - -/** - * \brief Request the subject name of a CRT, presented - * as a dynamically allocated linked list. - * - * \param crt The CRT to use. This must be initialized and set up. - * \param issuer The address at which to store the address of the - * first entry of the generated linked list holding - * the subject name. - * - * \note Depending on your use case, consider using the raw ASN.1 - * describing the issuer name instead of the heap-allocated - * linked list generated by this call. The pointers to the - * raw ASN.1 data are part of the CRT frame that can be queried - * via mbedtls_x509_crt_get_frame(), and they can be traversed - * via mbedtls_asn1_traverse_sequence_of(). - * - * \return \c 0 on success. In this case, the user takes ownership - * of the name context, and is responsible for freeing it - * through a call to mbedtls_x509_name_free() once it's no - * longer needed. - * \return A negative error code on failure. - */ -int mbedtls_x509_crt_get_issuer( mbedtls_x509_crt const *crt, - mbedtls_x509_name **issuer ); - -#if !defined(MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION) -/** - * \brief Request the subject alternative name of a CRT, presented - * as a dynamically allocated linked list. - * - * \param crt The CRT to use. This must be initialized and set up. - * \param subj_alt The address at which to store the address of the - * first component of the subject alternative names list. - * - * \note Depending in your use case, consider using the raw ASN.1 - * describing the subject alternative names extension - * instead of the heap-allocated linked list generated by this - * call. The pointers to the raw ASN.1 data are part of the CRT - * frame that can be queried via mbedtls_x509_crt_get_frame(), - * and mbedtls_asn1_traverse_sequence_of() can be used to - * traverse the list of subject alternative names. - * - * \return \c 0 on success. In this case, the user takes ownership - * of the name context, and is responsible for freeing it - * through a call to mbedtls_x509_sequence_free() once it's - * no longer needed. - * \return A negative error code on failure. - */ -int mbedtls_x509_crt_get_subject_alt_names( mbedtls_x509_crt const *crt, - mbedtls_x509_sequence **subj_alt ); -#endif /* !MBEDTLS_X509_REMOVE_HOSTNAME_VERIFICATION */ - -/** - * \brief Request the ExtendedKeyUsage extension of a CRT, - * presented as a dynamically allocated linked list. - * - * \param crt The CRT to use. This must be initialized and set up. - * \param ext_key_usage The address at which to store the address of the - * first entry of the ExtendedKeyUsage extension. - * - * \note Depending in your use case, consider using the raw ASN.1 - * describing the extended key usage extension instead of - * the heap-allocated linked list generated by this call. - * The pointers to the raw ASN.1 data are part of the CRT - * frame that can be queried via mbedtls_x509_crt_get_frame(), - * and mbedtls_asn1_traverse_sequence_of() can be used to - * traverse the entries in the extended key usage extension. - * - * \return \c 0 on success. In this case, the user takes ownership - * of the name context, and is responsible for freeing it - * through a call to mbedtls_x509_sequence_free() once it's - * no longer needed. - * \return A negative error code on failure. - */ -int mbedtls_x509_crt_get_ext_key_usage( mbedtls_x509_crt const *crt, - mbedtls_x509_sequence **ext_key_usage ); - -/** - * \brief Flush internal X.509 CRT parsing cache, if present. - * - * \param crt The CRT structure whose cache to flush. - * - * \note Calling this function frequently reduces RAM usage - * at the cost of performance. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_x509_crt_flush_cache( mbedtls_x509_crt const *crt ); - -/** - * \brief Request temporary read-access to a certificate frame - * for a given certificate. - * - * Once no longer needed, the frame must be released - * through a call to mbedtls_x509_crt_frame_release(). - * - * This is a copy-less version of mbedtls_x509_crt_get_frame(). - * See there for more information. - * - * \param crt The certificate to use. This must be initialized and set up. - * \param dst The address at which to store the address of a readable - * certificate frame for the input certificate \p crt which the - * caller can use until calling mbedtls_x509_crt_frame_release(). - * - * \note The certificate frame `**frame_ptr` returned by this function - * is owned by the X.509 module and must not be freed or modified - * by the caller. The X.509 module guarantees its validity as long - * as \p crt is valid and mbedtls_x509_crt_frame_release() hasn't - * been issued. - * - * \note In a single-threaded application using - * MBEDTLS_X509_ALWAYS_FLUSH, nested calls to this function - * are not allowed and will fail gracefully with - * MBEDTLS_ERR_X509_FATAL_ERROR. - * - * \return \c 0 on success. In this case, `*frame_ptr` is updated - * to hold the address of a frame for the given CRT. - * \return A negative error code on failure. - */ -int mbedtls_x509_crt_frame_acquire( mbedtls_x509_crt const *crt, - mbedtls_x509_crt_frame const **dst ); - -/** - * \brief Release access to a certificate frame acquired - * through a prior call to mbedtls_x509_crt_frame_acquire(). - * - * \param crt The certificate for which a certificate frame has - * previously been acquired. - */ -int mbedtls_x509_crt_frame_release( mbedtls_x509_crt const *crt ); - -/** - * \brief Request temporary access to a public key context - * for a given certificate. - * - * Once no longer needed, the frame must be released - * through a call to mbedtls_x509_crt_pk_release(). - * - * This is a copy-less version of mbedtls_x509_crt_get_pk(). - * See there for more information. - * - * \param crt The certificate to use. This must be initialized and set up. - * \param dst The address at which to store the address of a public key - * context for the public key in the input certificate \p crt. - * - * \warning The public key context `**pk_ptr` returned by this function - * is owned by the X.509 module and must be used by the caller - * in a thread-safe way. In particular, the caller must only - * use the context with functions which are `const` on the input - * context, or those which are known to be thread-safe. The latter - * for example includes mbedtls_pk_verify() for ECC or RSA public - * key contexts. - * - * \note In a single-threaded application using - * MBEDTLS_X509_ALWAYS_FLUSH, nested calls to this function - * are not allowed and will fail gracefully with - * MBEDTLS_ERR_X509_FATAL_ERROR. - * - * \return \c 0 on success. In this case, `*pk_ptr` is updated - * to hold the address of a public key context for the given - * certificate. - * \return A negative error code on failure. - */ -int mbedtls_x509_crt_pk_acquire( mbedtls_x509_crt const *crt, - mbedtls_pk_context **dst ); - -/** - * \brief Release access to a public key context acquired - * through a prior call to mbedtls_x509_crt_frame_acquire(). - * - * \param crt The certificate for which a certificate frame has - * previously been acquired. - */ -int mbedtls_x509_crt_pk_release( mbedtls_x509_crt const *crt ); - #endif /* MBEDTLS_X509_CRT_PARSE_C */ /* \} name */ diff --git a/APP_Framework/Framework/security/mbedtls/x509_csr.c b/APP_Framework/Framework/security/mbedtls/x509_csr.c index a06c04879..39ad87a83 100644 --- a/APP_Framework/Framework/security/mbedtls/x509_csr.c +++ b/APP_Framework/Framework/security/mbedtls/x509_csr.c @@ -38,9 +38,7 @@ #if defined(MBEDTLS_X509_CSR_PARSE_C) #include "x509_csr.h" -#include "x509_internal.h" #include "oid.h" -#include "platform_util.h" #include @@ -62,6 +60,11 @@ #include #endif +/* 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; +} + /* * Version ::= INTEGER { v1(0) } */ @@ -96,7 +99,7 @@ int mbedtls_x509_csr_parse_der( mbedtls_x509_csr *csr, unsigned char *p, *end; mbedtls_x509_buf sig_params; - mbedtls_platform_memset( &sig_params, 0, sizeof( mbedtls_x509_buf ) ); + memset( &sig_params, 0, sizeof( mbedtls_x509_buf ) ); /* * Check for valid input @@ -114,7 +117,7 @@ int mbedtls_x509_csr_parse_der( mbedtls_x509_csr *csr, if( p == NULL ) return( MBEDTLS_ERR_X509_ALLOC_FAILED ); - mbedtls_platform_memcpy( p, buf, buflen ); + memcpy( p, buf, buflen ); csr->raw.p = p; csr->raw.len = len; @@ -184,17 +187,15 @@ int mbedtls_x509_csr_parse_der( mbedtls_x509_csr *csr, mbedtls_x509_csr_free( csr ); return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); } - p += len; - csr->subject_raw.len = p - csr->subject_raw.p; - if( ( ret = mbedtls_x509_get_name( csr->subject_raw.p, - csr->subject_raw.len, - &csr->subject ) ) != 0 ) + if( ( ret = mbedtls_x509_get_name( &p, p + len, &csr->subject ) ) != 0 ) { mbedtls_x509_csr_free( csr ); return( ret ); } + csr->subject_raw.len = p - csr->subject_raw.p; + /* * subjectPKInfo SubjectPublicKeyInfo */ @@ -324,16 +325,15 @@ int mbedtls_x509_csr_parse_file( mbedtls_x509_csr *csr, const char *path ) ret = mbedtls_x509_csr_parse( csr, buf, n ); - mbedtls_platform_zeroize( buf, n ); + mbedtls_zeroize( buf, n ); mbedtls_free( buf ); return( ret ); } #endif /* MBEDTLS_FS_IO */ -#if !defined(MBEDTLS_X509_REMOVE_INFO) -#define BEFORE_COLON_CSR 14 -#define BC_CSR "14" +#define BEFORE_COLON 14 +#define BC "14" /* * Return an informational string about the CSR. */ @@ -343,7 +343,7 @@ int mbedtls_x509_csr_info( char *buf, size_t size, const char *prefix, int ret; size_t n; char *p; - char key_size_str[BEFORE_COLON_CSR]; + char key_size_str[BEFORE_COLON]; p = buf; n = size; @@ -360,30 +360,29 @@ int mbedtls_x509_csr_info( char *buf, size_t size, const char *prefix, ret = mbedtls_snprintf( p, n, "\n%ssigned using : ", prefix ); MBEDTLS_X509_SAFE_SNPRINTF; - ret = mbedtls_x509_sig_alg_gets( p, n, csr->sig_pk, - csr->sig_md, csr->sig_opts ); + ret = mbedtls_x509_sig_alg_gets( p, n, &csr->sig_oid, csr->sig_pk, csr->sig_md, + csr->sig_opts ); MBEDTLS_X509_SAFE_SNPRINTF; - if( ( ret = mbedtls_x509_key_size_helper( key_size_str, BEFORE_COLON_CSR, + if( ( ret = mbedtls_x509_key_size_helper( key_size_str, BEFORE_COLON, mbedtls_pk_get_name( &csr->pk ) ) ) != 0 ) { return( ret ); } - ret = mbedtls_snprintf( p, n, "\n%s%-" BC_CSR "s: %d bits\n", prefix, key_size_str, + ret = mbedtls_snprintf( p, n, "\n%s%-" BC "s: %d bits\n", prefix, key_size_str, (int) mbedtls_pk_get_bitlen( &csr->pk ) ); MBEDTLS_X509_SAFE_SNPRINTF; return( (int) ( size - n ) ); } -#endif /* !MBEDTLS_X509_REMOVE_INFO */ /* * Initialize a CSR */ void mbedtls_x509_csr_init( mbedtls_x509_csr *csr ) { - mbedtls_platform_memset( csr, 0, sizeof(mbedtls_x509_csr) ); + memset( csr, 0, sizeof(mbedtls_x509_csr) ); } /* @@ -408,17 +407,17 @@ void mbedtls_x509_csr_free( mbedtls_x509_csr *csr ) { name_prv = name_cur; name_cur = name_cur->next; - mbedtls_platform_zeroize( name_prv, sizeof( mbedtls_x509_name ) ); + mbedtls_zeroize( name_prv, sizeof( mbedtls_x509_name ) ); mbedtls_free( name_prv ); } if( csr->raw.p != NULL ) { - mbedtls_platform_zeroize( csr->raw.p, csr->raw.len ); + mbedtls_zeroize( csr->raw.p, csr->raw.len ); mbedtls_free( csr->raw.p ); } - mbedtls_platform_zeroize( csr, sizeof( mbedtls_x509_csr ) ); + mbedtls_zeroize( csr, sizeof( mbedtls_x509_csr ) ); } #endif /* MBEDTLS_X509_CSR_PARSE_C */ diff --git a/APP_Framework/Framework/security/mbedtls/x509_csr.h b/APP_Framework/Framework/security/mbedtls/x509_csr.h index 8ad2be8d5..a3c28048e 100644 --- a/APP_Framework/Framework/security/mbedtls/x509_csr.h +++ b/APP_Framework/Framework/security/mbedtls/x509_csr.h @@ -123,7 +123,6 @@ int mbedtls_x509_csr_parse( mbedtls_x509_csr *csr, const unsigned char *buf, siz int mbedtls_x509_csr_parse_file( mbedtls_x509_csr *csr, const char *path ); #endif /* MBEDTLS_FS_IO */ -#if !defined(MBEDTLS_X509_REMOVE_INFO) /** * \brief Returns an informational string about the * CSR. @@ -138,7 +137,6 @@ int mbedtls_x509_csr_parse_file( mbedtls_x509_csr *csr, const char *path ); */ int mbedtls_x509_csr_info( char *buf, size_t size, const char *prefix, const mbedtls_x509_csr *csr ); -#endif /* !MBEDTLS_X509_REMOVE_INFO */ /** * \brief Initialize a CSR diff --git a/APP_Framework/Framework/security/mbedtls/x509_internal.h b/APP_Framework/Framework/security/mbedtls/x509_internal.h deleted file mode 100644 index 668d8fba0..000000000 --- a/APP_Framework/Framework/security/mbedtls/x509_internal.h +++ /dev/null @@ -1,124 +0,0 @@ -/** - * \file x509_internal.h - * - * \brief Internal X.509 functions - */ -/* - * Copyright (C) 2006-2019, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * This file is part of Mbed TLS (https://tls.mbed.org) - * - */ -#ifndef MBEDTLS_X509_INTERNAL_H -#define MBEDTLS_X509_INTERNAL_H - -#if defined(MBEDTLS_X509_USE_C) - -#include "x509.h" -#include "threading.h" - -/* Internal structure used for caching parsed data from an X.509 CRT. */ - -struct mbedtls_x509_crt; -struct mbedtls_pk_context; -struct mbedtls_x509_crt_frame; -#define MBEDTLS_X509_CACHE_PK_READERS_MAX ((uint32_t) -1) -#define MBEDTLS_X509_CACHE_FRAME_READERS_MAX ((uint32_t) -1) - -/* Internal X.509 CRT cache handling functions. */ -#if defined(MBEDTLS_X509_CRT_PARSE_C) -static int mbedtls_x509_crt_flush_cache_frame( struct mbedtls_x509_crt const *crt ); -static int mbedtls_x509_crt_flush_cache_pk( struct mbedtls_x509_crt const *crt ); - -static int mbedtls_x509_crt_cache_provide_frame( struct mbedtls_x509_crt const *crt ); -static int mbedtls_x509_crt_cache_provide_pk( struct mbedtls_x509_crt const *crt ); -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -/* Uncategorized internal X.509 functions */ -static int mbedtls_x509_get_name( unsigned char *p, size_t len, - mbedtls_x509_name *cur ); - -#if defined(MBEDTLS_X509_CRL_PARSE_C) || defined(MBEDTLS_X509_CSR_PARSE_C) || \ - ( !defined(MBEDTLS_X509_ON_DEMAND_PARSING) && defined(MBEDTLS_X509_CRT_PARSE_C) ) -static int mbedtls_x509_get_alg( unsigned char **p, const unsigned char *end, - mbedtls_x509_buf *alg, mbedtls_x509_buf *params ); -#endif /* defined(MBEDTLS_X509_CRL_PARSE_C) || defined(MBEDTLS_X509_CSR_PARSE_C) || - ( !defined(MBEDTLS_X509_ON_DEMAND_PARSING) && defined(MBEDTLS_X509_CRT_PARSE_C) ) */ - -#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) -static int mbedtls_x509_get_alg_null( unsigned char **p, const unsigned char *end, - mbedtls_x509_buf *alg ); -static int mbedtls_x509_get_rsassa_pss_params( const mbedtls_x509_buf *params, - mbedtls_md_type_t *md_alg, mbedtls_md_type_t *mgf_md, - int *salt_len ); -#endif -static int mbedtls_x509_get_sig( unsigned char **p, const unsigned char *end, mbedtls_x509_buf *sig ); -static int mbedtls_x509_get_sig_alg_raw( unsigned char **p, unsigned char const *end, - mbedtls_md_type_t *md_alg, - mbedtls_pk_type_t *pk_alg, - void **sig_opts ); -static int mbedtls_x509_get_sig_alg( const mbedtls_x509_buf *sig_oid, const mbedtls_x509_buf *sig_params, - mbedtls_md_type_t *md_alg, mbedtls_pk_type_t *pk_alg, - void **sig_opts ); - -#if ( !defined(MBEDTLS_X509_CRT_REMOVE_TIME) && defined(MBEDTLS_X509_CRT_PARSE_C) ) || \ - defined(MBEDTLS_X509_CRL_PARSE_C) -static int mbedtls_x509_get_time( unsigned char **p, const unsigned char *end, - mbedtls_x509_time *t ); -#endif /* ( !defined(MBEDTLS_X509_CRT_REMOVE_TIME) && defined(MBEDTLS_X509_CRT_PARSE_C) ) || - defined(MBEDTLS_X509_CRL_PARSE_C) */ - -static int mbedtls_x509_get_serial( unsigned char **p, const unsigned char *end, - mbedtls_x509_buf *serial ); -static int mbedtls_x509_name_cmp_raw( mbedtls_x509_buf_raw const *a, - mbedtls_x509_buf_raw const *b, - int (*check)( void *ctx, - mbedtls_x509_buf *oid, - mbedtls_x509_buf *val, - int next_merged ), - void *check_ctx ); -static int mbedtls_x509_memcasecmp( const void *s1, const void *s2, - size_t len1, size_t len2 ); - -#if defined(MBEDTLS_X509_CRL_PARSE_C) -static int mbedtls_x509_get_ext( unsigned char **p, const unsigned char *end, - mbedtls_x509_buf *ext, int tag ); -#endif /* defined(MBEDTLS_X509_CRL_PARSE_C) */ - -#if !defined(MBEDTLS_X509_REMOVE_INFO) -static int mbedtls_x509_sig_alg_gets( char *buf, size_t size, - mbedtls_pk_type_t pk_alg, mbedtls_md_type_t md_alg, - const void *sig_opts ); -#endif -#if !defined(MBEDTLS_X509_REMOVE_INFO) -static int mbedtls_x509_key_size_helper( char *buf, size_t buf_size, const char *name ); -#endif /* !defined(MBEDTLS_X509_REMOVE_INFO) */ - -#if defined(MBEDTLS_X509_CREATE_C) -static int mbedtls_x509_string_to_names( mbedtls_asn1_named_data **head, const char *name ); -static int mbedtls_x509_set_extension( mbedtls_asn1_named_data **head, const char *oid, size_t oid_len, - int critical, const unsigned char *val, - size_t val_len ); -static int mbedtls_x509_write_extensions( unsigned char **p, unsigned char *start, - mbedtls_asn1_named_data *first ); -int mbedtls_x509_write_names( unsigned char **p, unsigned char *start, - mbedtls_asn1_named_data *first ); -static int mbedtls_x509_write_sig( unsigned char **p, unsigned char *start, - const char *oid, size_t oid_len, - unsigned char *sig, size_t size ); -#endif /* MBEDTLS_X509_CREATE_C */ -#endif /* MBEDTLS_X509_USE_C */ -#endif /* MBEDTLS_X509_INTERNAL_H */ diff --git a/APP_Framework/Framework/security/mbedtls/x509write_crt.c b/APP_Framework/Framework/security/mbedtls/x509write_crt.c index 044040cb0..180a1fdaf 100644 --- a/APP_Framework/Framework/security/mbedtls/x509write_crt.c +++ b/APP_Framework/Framework/security/mbedtls/x509write_crt.c @@ -34,11 +34,9 @@ #if defined(MBEDTLS_X509_CRT_WRITE_C) #include "x509_crt.h" -#include "x509_internal.h" #include "oid.h" #include "asn1write.h" #include "sha1.h" -#include "platform_util.h" #include @@ -46,19 +44,14 @@ #include "pem.h" #endif /* MBEDTLS_PEM_WRITE_C */ -/* - * For the currently used signature algorithms the buffer to store any signature - * must be at least of size MAX(MBEDTLS_ECDSA_MAX_LEN, MBEDTLS_MPI_MAX_SIZE) - */ -#if MBEDTLS_ECDSA_MAX_LEN > MBEDTLS_MPI_MAX_SIZE -#define SIGNATURE_MAX_SIZE MBEDTLS_ECDSA_MAX_LEN -#else -#define SIGNATURE_MAX_SIZE MBEDTLS_MPI_MAX_SIZE -#endif +/* 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; +} void mbedtls_x509write_crt_init( mbedtls_x509write_cert *ctx ) { - mbedtls_platform_memset( ctx, 0, sizeof( mbedtls_x509write_cert ) ); + memset( ctx, 0, sizeof( mbedtls_x509write_cert ) ); mbedtls_mpi_init( &ctx->serial ); ctx->version = MBEDTLS_X509_CRT_VERSION_3; @@ -72,7 +65,7 @@ void mbedtls_x509write_crt_free( mbedtls_x509write_cert *ctx ) mbedtls_asn1_free_named_data_list( &ctx->issuer ); mbedtls_asn1_free_named_data_list( &ctx->extensions ); - mbedtls_platform_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 ) @@ -150,7 +143,7 @@ int mbedtls_x509write_crt_set_basic_constraints( mbedtls_x509write_cert *ctx, unsigned char *c = buf + sizeof(buf); size_t len = 0; - mbedtls_platform_memset( buf, 0, sizeof(buf) ); + memset( buf, 0, sizeof(buf) ); if( is_ca && max_pathlen > 127 ) return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); @@ -181,7 +174,7 @@ int mbedtls_x509write_crt_set_subject_key_identifier( mbedtls_x509write_cert *ct unsigned char *c = buf + sizeof(buf); size_t len = 0; - mbedtls_platform_memset( buf, 0, sizeof(buf) ); + memset( buf, 0, sizeof(buf) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_pk_write_pubkey( &c, buf, ctx->subject_key ) ); ret = mbedtls_sha1_ret( buf + sizeof( buf ) - len, len, @@ -206,7 +199,7 @@ int mbedtls_x509write_crt_set_authority_key_identifier( mbedtls_x509write_cert * unsigned char *c = buf + sizeof( buf ); size_t len = 0; - mbedtls_platform_memset( buf, 0, sizeof(buf) ); + memset( buf, 0, sizeof(buf) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_pk_write_pubkey( &c, buf, ctx->issuer_key ) ); ret = mbedtls_sha1_ret( buf + sizeof( buf ) - len, len, @@ -345,7 +338,7 @@ int mbedtls_x509write_crt_der( mbedtls_x509write_cert *ctx, unsigned char *buf, size_t sig_oid_len = 0; unsigned char *c, *c2; unsigned char hash[64]; - unsigned char sig[SIGNATURE_MAX_SIZE]; + unsigned char sig[MBEDTLS_MPI_MAX_SIZE]; unsigned char tmp_buf[2048]; size_t sub_len = 0, pub_len = 0, sig_and_oid_len = 0, sig_len; size_t len = 0; @@ -481,7 +474,7 @@ int mbedtls_x509write_crt_der( mbedtls_x509write_cert *ctx, unsigned char *buf, return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); c2 -= len; - mbedtls_platform_memcpy( c2, c, len ); + memcpy( c2, c, len ); len += sig_and_oid_len; MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c2, buf, len ) ); diff --git a/APP_Framework/Framework/security/mbedtls/x509write_csr.c b/APP_Framework/Framework/security/mbedtls/x509write_csr.c index a52fc411b..f67f3413c 100644 --- a/APP_Framework/Framework/security/mbedtls/x509write_csr.c +++ b/APP_Framework/Framework/security/mbedtls/x509write_csr.c @@ -33,10 +33,8 @@ #if defined(MBEDTLS_X509_CSR_WRITE_C) #include "x509_csr.h" -#include "x509_internal.h" #include "oid.h" #include "asn1write.h" -#include "platform_util.h" #include #include @@ -45,19 +43,14 @@ #include "pem.h" #endif -/* - * For the currently used signature algorithms the buffer to store any signature - * must be at least of size MAX(MBEDTLS_ECDSA_MAX_LEN, MBEDTLS_MPI_MAX_SIZE) - */ -#if MBEDTLS_ECDSA_MAX_LEN > MBEDTLS_MPI_MAX_SIZE -#define SIGNATURE_MAX_SIZE MBEDTLS_ECDSA_MAX_LEN -#else -#define SIGNATURE_MAX_SIZE MBEDTLS_MPI_MAX_SIZE -#endif +/* 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; +} void mbedtls_x509write_csr_init( mbedtls_x509write_csr *ctx ) { - mbedtls_platform_memset( ctx, 0, sizeof( mbedtls_x509write_csr ) ); + memset( ctx, 0, sizeof( mbedtls_x509write_csr ) ); } void mbedtls_x509write_csr_free( mbedtls_x509write_csr *ctx ) @@ -65,7 +58,7 @@ void mbedtls_x509write_csr_free( mbedtls_x509write_csr *ctx ) mbedtls_asn1_free_named_data_list( &ctx->subject ); mbedtls_asn1_free_named_data_list( &ctx->extensions ); - mbedtls_platform_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 ) @@ -170,7 +163,7 @@ int mbedtls_x509write_csr_der( mbedtls_x509write_csr *ctx, unsigned char *buf, s size_t sig_oid_len = 0; unsigned char *c, *c2; unsigned char hash[64]; - unsigned char sig[SIGNATURE_MAX_SIZE]; + unsigned char sig[MBEDTLS_MPI_MAX_SIZE]; unsigned char tmp_buf[2048]; size_t pub_len = 0, sig_and_oid_len = 0, sig_len; size_t len = 0; @@ -227,9 +220,7 @@ int mbedtls_x509write_csr_der( mbedtls_x509write_csr *ctx, unsigned char *buf, s /* * Prepare signature */ - ret = mbedtls_md( mbedtls_md_info_from_type( ctx->md_alg ), c, len, hash ); - if( ret != 0 ) - return( ret ); + mbedtls_md( mbedtls_md_info_from_type( ctx->md_alg ), c, len, hash ); if( ( ret = mbedtls_pk_sign( ctx->key, ctx->md_alg, hash, 0, sig, &sig_len, f_rng, p_rng ) ) != 0 ) @@ -261,7 +252,7 @@ int mbedtls_x509write_csr_der( mbedtls_x509write_csr *ctx, unsigned char *buf, s return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); c2 -= len; - mbedtls_platform_memcpy( c2, c, len ); + memcpy( c2, c, len ); len += sig_and_oid_len; MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c2, buf, len ) ); diff --git a/APP_Framework/Framework/security/mbedtls/xtea.c b/APP_Framework/Framework/security/mbedtls/xtea.c new file mode 100644 index 000000000..d2efbdbc9 --- /dev/null +++ b/APP_Framework/Framework/security/mbedtls/xtea.c @@ -0,0 +1,281 @@ +/* + * An 32-bit implementation of the XTEA algorithm + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_XTEA_C) + +#include "xtea.h" + +#include + +#if defined(MBEDTLS_SELF_TEST) +#if defined(MBEDTLS_PLATFORM_C) +#include "platform.h" +#else +#include +#define mbedtls_printf printf +#endif /* MBEDTLS_PLATFORM_C */ +#endif /* MBEDTLS_SELF_TEST */ + +#if !defined(MBEDTLS_XTEA_ALT) + +/* 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; +} + +/* + * 32-bit integer manipulation macros (big endian) + */ +#ifndef GET_UINT32_BE +#define GET_UINT32_BE(n,b,i) \ +{ \ + (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ + | ( (uint32_t) (b)[(i) + 1] << 16 ) \ + | ( (uint32_t) (b)[(i) + 2] << 8 ) \ + | ( (uint32_t) (b)[(i) + 3] ); \ +} +#endif + +#ifndef PUT_UINT32_BE +#define PUT_UINT32_BE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) ); \ +} +#endif + +void mbedtls_xtea_init( mbedtls_xtea_context *ctx ) +{ + memset( ctx, 0, sizeof( mbedtls_xtea_context ) ); +} + +void mbedtls_xtea_free( mbedtls_xtea_context *ctx ) +{ + if( ctx == NULL ) + return; + + mbedtls_zeroize( ctx, sizeof( mbedtls_xtea_context ) ); +} + +/* + * XTEA key schedule + */ +void mbedtls_xtea_setup( mbedtls_xtea_context *ctx, const unsigned char key[16] ) +{ + int i; + + memset( ctx, 0, sizeof(mbedtls_xtea_context) ); + + for( i = 0; i < 4; i++ ) + { + GET_UINT32_BE( ctx->k[i], key, i << 2 ); + } +} + +/* + * XTEA encrypt function + */ +int mbedtls_xtea_crypt_ecb( mbedtls_xtea_context *ctx, int mode, + const unsigned char input[8], unsigned char output[8]) +{ + uint32_t *k, v0, v1, i; + + k = ctx->k; + + GET_UINT32_BE( v0, input, 0 ); + GET_UINT32_BE( v1, input, 4 ); + + if( mode == MBEDTLS_XTEA_ENCRYPT ) + { + uint32_t sum = 0, delta = 0x9E3779B9; + + for( i = 0; i < 32; i++ ) + { + v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]); + sum += delta; + v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]); + } + } + else /* MBEDTLS_XTEA_DECRYPT */ + { + uint32_t delta = 0x9E3779B9, sum = delta * 32; + + for( i = 0; i < 32; i++ ) + { + v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]); + sum -= delta; + v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]); + } + } + + PUT_UINT32_BE( v0, output, 0 ); + PUT_UINT32_BE( v1, output, 4 ); + + return( 0 ); +} + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +/* + * XTEA-CBC buffer encryption/decryption + */ +int mbedtls_xtea_crypt_cbc( mbedtls_xtea_context *ctx, int mode, size_t length, + unsigned char iv[8], const unsigned char *input, + unsigned char *output) +{ + int i; + unsigned char temp[8]; + + if( length % 8 ) + return( MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH ); + + if( mode == MBEDTLS_XTEA_DECRYPT ) + { + while( length > 0 ) + { + memcpy( temp, input, 8 ); + mbedtls_xtea_crypt_ecb( ctx, mode, input, output ); + + for( i = 0; i < 8; i++ ) + output[i] = (unsigned char)( output[i] ^ iv[i] ); + + memcpy( iv, temp, 8 ); + + input += 8; + output += 8; + length -= 8; + } + } + else + { + while( length > 0 ) + { + for( i = 0; i < 8; i++ ) + output[i] = (unsigned char)( input[i] ^ iv[i] ); + + mbedtls_xtea_crypt_ecb( ctx, mode, output, output ); + memcpy( iv, output, 8 ); + + input += 8; + output += 8; + length -= 8; + } + } + + return( 0 ); +} +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#endif /* !MBEDTLS_XTEA_ALT */ + +#if defined(MBEDTLS_SELF_TEST) + +/* + * XTEA tests vectors (non-official) + */ + +static const unsigned char xtea_test_key[6][16] = +{ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f }, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f }, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 } +}; + +static const unsigned char xtea_test_pt[6][8] = +{ + { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48 }, + { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 }, + { 0x5a, 0x5b, 0x6e, 0x27, 0x89, 0x48, 0xd7, 0x7f }, + { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48 }, + { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 }, + { 0x70, 0xe1, 0x22, 0x5d, 0x6e, 0x4e, 0x76, 0x55 } +}; + +static const unsigned char xtea_test_ct[6][8] = +{ + { 0x49, 0x7d, 0xf3, 0xd0, 0x72, 0x61, 0x2c, 0xb5 }, + { 0xe7, 0x8f, 0x2d, 0x13, 0x74, 0x43, 0x41, 0xd8 }, + { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 }, + { 0xa0, 0x39, 0x05, 0x89, 0xf8, 0xb8, 0xef, 0xa5 }, + { 0xed, 0x23, 0x37, 0x5a, 0x82, 0x1a, 0x8c, 0x2d }, + { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 } +}; + +/* + * Checkup routine + */ +int mbedtls_xtea_self_test( int verbose ) +{ + int i, ret = 0; + unsigned char buf[8]; + mbedtls_xtea_context ctx; + + mbedtls_xtea_init( &ctx ); + for( i = 0; i < 6; i++ ) + { + if( verbose != 0 ) + mbedtls_printf( " XTEA test #%d: ", i + 1 ); + + memcpy( buf, xtea_test_pt[i], 8 ); + + mbedtls_xtea_setup( &ctx, xtea_test_key[i] ); + mbedtls_xtea_crypt_ecb( &ctx, MBEDTLS_XTEA_ENCRYPT, buf, buf ); + + if( memcmp( buf, xtea_test_ct[i], 8 ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + ret = 1; + goto exit; + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + } + + if( verbose != 0 ) + mbedtls_printf( "\n" ); + +exit: + mbedtls_xtea_free( &ctx ); + + return( ret ); +} + +#endif /* MBEDTLS_SELF_TEST */ + +#endif /* MBEDTLS_XTEA_C */ diff --git a/APP_Framework/Framework/security/mbedtls/xtea.h b/APP_Framework/Framework/security/mbedtls/xtea.h index b47f55350..34ccee3c2 100644 --- a/APP_Framework/Framework/security/mbedtls/xtea.h +++ b/APP_Framework/Framework/security/mbedtls/xtea.h @@ -37,31 +37,25 @@ #define MBEDTLS_XTEA_DECRYPT 0 #define MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH -0x0028 /**< The data input has an invalid length. */ - -/* MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED is deprecated and should not be used. */ #define MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED -0x0029 /**< XTEA hardware accelerator failed. */ -#ifdef __cplusplus -extern "C" { -#endif - #if !defined(MBEDTLS_XTEA_ALT) // Regular implementation // +#ifdef __cplusplus +extern "C" { +#endif + /** * \brief XTEA context structure */ -typedef struct mbedtls_xtea_context +typedef struct { uint32_t k[4]; /*!< key */ } mbedtls_xtea_context; -#else /* MBEDTLS_XTEA_ALT */ -#include "xtea_alt.h" -#endif /* MBEDTLS_XTEA_ALT */ - /** * \brief Initialize XTEA context * @@ -121,7 +115,17 @@ int mbedtls_xtea_crypt_cbc( mbedtls_xtea_context *ctx, unsigned char *output); #endif /* MBEDTLS_CIPHER_MODE_CBC */ -#if defined(MBEDTLS_SELF_TEST) +#ifdef __cplusplus +} +#endif + +#else /* MBEDTLS_XTEA_ALT */ +#include "xtea_alt.h" +#endif /* MBEDTLS_XTEA_ALT */ + +#ifdef __cplusplus +extern "C" { +#endif /** * \brief Checkup routine @@ -130,8 +134,6 @@ int mbedtls_xtea_crypt_cbc( mbedtls_xtea_context *ctx, */ int mbedtls_xtea_self_test( int verbose ); -#endif /* MBEDTLS_SELF_TEST */ - #ifdef __cplusplus } #endif