diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 6a6ed0e47..620adf968 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -1270,7 +1270,7 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl ) { ssl->conf->f_export_keys_ext( ssl->conf->p_export_keys, session->master, keyblk, - mac_key_len, transform->keylen, + mac_key_len, keylen, iv_copy_len, handshake->tls_prf, handshake->randbytes + 32, handshake->randbytes ); diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index 2cddfb42a..353a5800f 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -126,7 +126,7 @@ int main( void ) #define DFL_EXTENDED_MS -1 #define DFL_ETM -1 #define DFL_CA_CALLBACK 0 - +#define DFL_EAP_TLS 0 #define GET_REQUEST "GET %s HTTP/1.0\r\nExtra-header: " #define GET_REQUEST_END "\r\n\r\n" @@ -204,6 +204,13 @@ int main( void ) #define USAGE_TICKETS "" #endif /* MBEDTLS_SSL_SESSION_TICKETS */ +#if defined(MBEDTLS_SSL_EXPORT_KEYS) +#define USAGE_EAP_TLS \ + " eap_tls=%%d default: 0 (disabled)\n" +#else +#define USAGE_EAP_TLS "" +#endif /* MBEDTLS_SSL_EXPORT_KEYS */ + #if defined(MBEDTLS_SSL_TRUNCATED_HMAC) #define USAGE_TRUNC_HMAC \ " trunc_hmac=%%d default: library default\n" @@ -348,6 +355,7 @@ int main( void ) " reco_delay=%%d default: 0 seconds\n" \ " reconnect_hard=%%d default: 0 (disabled)\n" \ USAGE_TICKETS \ + USAGE_EAP_TLS \ USAGE_MAX_FRAG_LEN \ USAGE_TRUNC_HMAC \ USAGE_CONTEXT_CRT_CB \ @@ -448,10 +456,44 @@ struct options int extended_ms; /* negotiate extended master secret? */ int etm; /* negotiate encrypt then mac? */ int context_crt_cb; /* use context-specific CRT verify callback */ + int eap_tls; /* derive EAP-TLS keying material? */ } opt; int query_config( const char *config ); +#if defined(MBEDTLS_SSL_EXPORT_KEYS) +typedef struct eap_tls_keys +{ + unsigned char master_secret[48]; + unsigned char randbytes[64]; + mbedtls_ssl_tls_prf *tls_prf; +} eap_tls_keys; + +static int eap_tls_key_derivation ( void *p_expkey, + const unsigned char *ms, + const unsigned char *kb, + size_t maclen, + size_t keylen, + size_t ivlen, + mbedtls_ssl_tls_prf *tls_prf, + unsigned char client_random[32], + unsigned char server_random[32] ) +{ + eap_tls_keys *keys = (eap_tls_keys *)p_expkey; + + ( ( void ) kb ); + ( ( void ) maclen ); + ( ( void ) keylen ); + ( ( void ) ivlen ); + memcpy( keys->master_secret, ms, sizeof( keys->master_secret ) ); + memcpy( keys->randbytes, client_random, 32 ); + memcpy( keys->randbytes + 32, server_random, 32 ); + keys->tls_prf = tls_prf; + + return( 0 ); +} +#endif + static void my_debug( void *ctx, int level, const char *file, int line, const char *str ) @@ -713,6 +755,12 @@ int main( int argc, char *argv[] ) #endif char *p, *q; const int *list; +#if defined(MBEDTLS_SSL_EXPORT_KEYS) + unsigned char eap_tls_keymaterial[16]; + unsigned char eap_tls_iv[8]; + const char* eap_tls_label = "client EAP encryption"; + eap_tls_keys eap_tls_keying; +#endif /* * Make sure memory references are valid. @@ -818,6 +866,7 @@ int main( int argc, char *argv[] ) opt.extended_ms = DFL_EXTENDED_MS; opt.etm = DFL_ETM; opt.dgram_packing = DFL_DGRAM_PACKING; + opt.eap_tls = DFL_EAP_TLS; for( i = 1; i < argc; i++ ) { @@ -1176,6 +1225,12 @@ int main( int argc, char *argv[] ) { return query_config( q ); } + else if( strcmp( p, "eap_tls" ) == 0 ) + { + opt.eap_tls = atoi( q ); + if( opt.eap_tls < 0 || opt.eap_tls > 1 ) + goto usage; + } else goto usage; } @@ -1652,6 +1707,12 @@ int main( int argc, char *argv[] ) mbedtls_ssl_conf_encrypt_then_mac( &conf, opt.etm ); #endif +#if defined(MBEDTLS_SSL_EXPORT_KEYS) + if( opt.eap_tls != 0 ) + mbedtls_ssl_conf_export_keys_ext_cb( &conf, eap_tls_key_derivation, + &eap_tls_keying ); +#endif + #if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) if( opt.recsplit != DFL_RECSPLIT ) mbedtls_ssl_conf_cbc_record_splitting( &conf, opt.recsplit @@ -1917,6 +1978,40 @@ int main( int argc, char *argv[] ) } #endif +#if defined(MBEDTLS_SSL_EXPORT_KEYS) + if( opt.eap_tls != 0 && + eap_tls_keying.tls_prf != NULL ) + { + size_t j = 0; + eap_tls_keying.tls_prf( eap_tls_keying.master_secret, + sizeof( eap_tls_keying.master_secret ), + eap_tls_label, + eap_tls_keying.randbytes, + sizeof( eap_tls_keying.randbytes ), + eap_tls_keymaterial, + sizeof( eap_tls_keymaterial ) ); + mbedtls_printf( " EAP-TLS key material is:" ); + for( j = 0; j < sizeof( eap_tls_keymaterial ); j++ ) + { + if( j % 8 == 0 ) + mbedtls_printf("\n "); + mbedtls_printf("%02x ", eap_tls_keymaterial[j] ); + } + mbedtls_printf("\n"); + + eap_tls_keying.tls_prf( NULL, 0, eap_tls_label, eap_tls_keying.randbytes, + sizeof( eap_tls_keying.randbytes ), eap_tls_iv, + sizeof( eap_tls_iv ) ); + mbedtls_printf( " EAP-TLS IV is:" ); + for( j = 0; j < sizeof( eap_tls_iv ); j++ ) + { + if( j % 8 == 0 ) + mbedtls_printf("\n "); + mbedtls_printf("%02x ", eap_tls_iv[j] ); + } + mbedtls_printf("\n"); + } +#endif if( opt.reconnect != 0 ) { mbedtls_printf(" . Saving session for reuse..." ); diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index 5ee90ac35..54e2e5197 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -168,6 +168,7 @@ int main( void ) #define DFL_EXTENDED_MS -1 #define DFL_ETM -1 #define DFL_CA_CALLBACK 0 +#define DFL_EAP_TLS 0 #define LONG_RESPONSE "

01-blah-blah-blah-blah-blah-blah-blah-blah-blah\r\n" \ "02-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah\r\n" \ @@ -281,6 +282,13 @@ int main( void ) #define USAGE_TICKETS "" #endif /* MBEDTLS_SSL_SESSION_TICKETS */ +#if defined(MBEDTLS_SSL_EXPORT_KEYS) +#define USAGE_EAP_TLS \ + " eap_tls=%%d default: 0 (disabled)\n" +#else +#define USAGE_EAP_TLS "" +#endif /* MBEDTLS_SSL_EXPORT_KEYS */ + #if defined(MBEDTLS_SSL_CACHE_C) #define USAGE_CACHE \ " cache_max=%%d default: cache default (50)\n" \ @@ -442,6 +450,7 @@ int main( void ) " exchanges=%%d default: 1\n" \ "\n" \ USAGE_TICKETS \ + USAGE_EAP_TLS \ USAGE_CACHE \ USAGE_MAX_FRAG_LEN \ USAGE_TRUNC_HMAC \ @@ -563,10 +572,44 @@ struct options int dtls_mtu; /* UDP Maximum tranport unit for DTLS */ int dgram_packing; /* allow/forbid datagram packing */ int badmac_limit; /* Limit of records with bad MAC */ + int eap_tls; /* derive EAP-TLS keying material? */ } opt; int query_config( const char *config ); +#if defined(MBEDTLS_SSL_EXPORT_KEYS) +typedef struct eap_tls_keys +{ + unsigned char master_secret[48]; + unsigned char randbytes[64]; + mbedtls_ssl_tls_prf *tls_prf; +} eap_tls_keys; + +static int eap_tls_key_derivation ( void *p_expkey, + const unsigned char *ms, + const unsigned char *kb, + size_t maclen, + size_t keylen, + size_t ivlen, + mbedtls_ssl_tls_prf *tls_prf, + unsigned char client_random[32], + unsigned char server_random[32] ) +{ + eap_tls_keys *keys = (eap_tls_keys *)p_expkey; + + ( ( void ) kb ); + ( ( void ) maclen ); + ( ( void ) keylen ); + ( ( void ) ivlen ); + memcpy( keys->master_secret, ms, sizeof( keys->master_secret ) ); + memcpy( keys->randbytes, client_random, 32 ); + memcpy( keys->randbytes + 32, server_random, 32 ); + keys->tls_prf = tls_prf; + + return( 0 ); +} +#endif + static void my_debug( void *ctx, int level, const char *file, int line, const char *str ) @@ -1444,6 +1487,12 @@ int main( int argc, char *argv[] ) #if defined(MBEDTLS_USE_PSA_CRYPTO) psa_status_t status; #endif +#if defined(MBEDTLS_SSL_EXPORT_KEYS) + unsigned char eap_tls_keymaterial[16]; + unsigned char eap_tls_iv[8]; + const char* eap_tls_label = "client EAP encryption"; + eap_tls_keys eap_tls_keying; +#endif #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) mbedtls_memory_buffer_alloc_init( alloc_buf, sizeof(alloc_buf) ); @@ -1585,6 +1634,7 @@ int main( int argc, char *argv[] ) opt.badmac_limit = DFL_BADMAC_LIMIT; opt.extended_ms = DFL_EXTENDED_MS; opt.etm = DFL_ETM; + opt.eap_tls = DFL_EAP_TLS; for( i = 1; i < argc; i++ ) { @@ -1975,6 +2025,12 @@ int main( int argc, char *argv[] ) { return query_config( q ); } + else if( strcmp( p, "eap_tls" ) == 0 ) + { + opt.eap_tls = atoi( q ); + if( opt.eap_tls < 0 || opt.eap_tls > 1 ) + goto usage; + } else goto usage; } @@ -2537,6 +2593,12 @@ int main( int argc, char *argv[] ) mbedtls_ssl_conf_encrypt_then_mac( &conf, opt.etm ); #endif +#if defined(MBEDTLS_SSL_EXPORT_KEYS) + if( opt.eap_tls != 0 ) + mbedtls_ssl_conf_export_keys_ext_cb( &conf, eap_tls_key_derivation, + &eap_tls_keying ); +#endif + #if defined(MBEDTLS_SSL_ALPN) if( opt.alpn_string != NULL ) if( ( ret = mbedtls_ssl_conf_alpn_protocols( &conf, alpn_list ) ) != 0 ) @@ -3117,6 +3179,40 @@ handshake: } #endif /* MBEDTLS_X509_CRT_PARSE_C */ +#if defined(MBEDTLS_SSL_EXPORT_KEYS) + if( opt.eap_tls != 0 && + eap_tls_keying.tls_prf != NULL ) + { + size_t j = 0; + eap_tls_keying.tls_prf( eap_tls_keying.master_secret, + sizeof( eap_tls_keying.master_secret ), + eap_tls_label, + eap_tls_keying.randbytes, + sizeof( eap_tls_keying.randbytes ), + eap_tls_keymaterial, + sizeof( eap_tls_keymaterial ) ); + mbedtls_printf( " EAP-TLS key material is:" ); + for( j = 0; j < sizeof( eap_tls_keymaterial ); j++ ) + { + if( j % 8 == 0 ) + mbedtls_printf("\n "); + mbedtls_printf("%02x ", eap_tls_keymaterial[j] ); + } + mbedtls_printf("\n"); + + eap_tls_keying.tls_prf( NULL, 0, eap_tls_label, eap_tls_keying.randbytes, + sizeof( eap_tls_keying.randbytes ), eap_tls_iv, + sizeof( eap_tls_iv ) ); + mbedtls_printf( " EAP-TLS IV is:" ); + for( j = 0; j < sizeof( eap_tls_iv ); j++ ) + { + if( j % 8 == 0 ) + mbedtls_printf("\n "); + mbedtls_printf("%02x ", eap_tls_iv[j] ); + } + mbedtls_printf("\n"); + } +#endif if( opt.exchanges == 0 ) goto close_notify;