Add eap-tls key derivation in the examples.

Add support for eap-tls key derivation functionality,
in `ssl_client2` and `ssl_server2` reference applications.
This commit is contained in:
Ron Eldor 2019-05-12 11:03:32 +03:00
parent c4d3ef4721
commit b7fd64ce2b
3 changed files with 193 additions and 2 deletions

View file

@ -1270,7 +1270,7 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
{ {
ssl->conf->f_export_keys_ext( ssl->conf->p_export_keys, ssl->conf->f_export_keys_ext( ssl->conf->p_export_keys,
session->master, keyblk, session->master, keyblk,
mac_key_len, transform->keylen, mac_key_len, keylen,
iv_copy_len, handshake->tls_prf, iv_copy_len, handshake->tls_prf,
handshake->randbytes + 32, handshake->randbytes + 32,
handshake->randbytes ); handshake->randbytes );

View file

@ -126,7 +126,7 @@ int main( void )
#define DFL_EXTENDED_MS -1 #define DFL_EXTENDED_MS -1
#define DFL_ETM -1 #define DFL_ETM -1
#define DFL_CA_CALLBACK 0 #define DFL_CA_CALLBACK 0
#define DFL_EAP_TLS 0
#define GET_REQUEST "GET %s HTTP/1.0\r\nExtra-header: " #define GET_REQUEST "GET %s HTTP/1.0\r\nExtra-header: "
#define GET_REQUEST_END "\r\n\r\n" #define GET_REQUEST_END "\r\n\r\n"
@ -204,6 +204,13 @@ int main( void )
#define USAGE_TICKETS "" #define USAGE_TICKETS ""
#endif /* MBEDTLS_SSL_SESSION_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) #if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
#define USAGE_TRUNC_HMAC \ #define USAGE_TRUNC_HMAC \
" trunc_hmac=%%d default: library default\n" " trunc_hmac=%%d default: library default\n"
@ -348,6 +355,7 @@ int main( void )
" reco_delay=%%d default: 0 seconds\n" \ " reco_delay=%%d default: 0 seconds\n" \
" reconnect_hard=%%d default: 0 (disabled)\n" \ " reconnect_hard=%%d default: 0 (disabled)\n" \
USAGE_TICKETS \ USAGE_TICKETS \
USAGE_EAP_TLS \
USAGE_MAX_FRAG_LEN \ USAGE_MAX_FRAG_LEN \
USAGE_TRUNC_HMAC \ USAGE_TRUNC_HMAC \
USAGE_CONTEXT_CRT_CB \ USAGE_CONTEXT_CRT_CB \
@ -448,10 +456,44 @@ struct options
int extended_ms; /* negotiate extended master secret? */ int extended_ms; /* negotiate extended master secret? */
int etm; /* negotiate encrypt then mac? */ int etm; /* negotiate encrypt then mac? */
int context_crt_cb; /* use context-specific CRT verify callback */ int context_crt_cb; /* use context-specific CRT verify callback */
int eap_tls; /* derive EAP-TLS keying material? */
} opt; } opt;
int query_config( const char *config ); 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, static void my_debug( void *ctx, int level,
const char *file, int line, const char *file, int line,
const char *str ) const char *str )
@ -713,6 +755,12 @@ int main( int argc, char *argv[] )
#endif #endif
char *p, *q; char *p, *q;
const int *list; 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. * Make sure memory references are valid.
@ -818,6 +866,7 @@ int main( int argc, char *argv[] )
opt.extended_ms = DFL_EXTENDED_MS; opt.extended_ms = DFL_EXTENDED_MS;
opt.etm = DFL_ETM; opt.etm = DFL_ETM;
opt.dgram_packing = DFL_DGRAM_PACKING; opt.dgram_packing = DFL_DGRAM_PACKING;
opt.eap_tls = DFL_EAP_TLS;
for( i = 1; i < argc; i++ ) for( i = 1; i < argc; i++ )
{ {
@ -1176,6 +1225,12 @@ int main( int argc, char *argv[] )
{ {
return query_config( q ); 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 else
goto usage; goto usage;
} }
@ -1652,6 +1707,12 @@ int main( int argc, char *argv[] )
mbedtls_ssl_conf_encrypt_then_mac( &conf, opt.etm ); mbedtls_ssl_conf_encrypt_then_mac( &conf, opt.etm );
#endif #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 defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
if( opt.recsplit != DFL_RECSPLIT ) if( opt.recsplit != DFL_RECSPLIT )
mbedtls_ssl_conf_cbc_record_splitting( &conf, opt.recsplit mbedtls_ssl_conf_cbc_record_splitting( &conf, opt.recsplit
@ -1917,6 +1978,40 @@ int main( int argc, char *argv[] )
} }
#endif #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 ) if( opt.reconnect != 0 )
{ {
mbedtls_printf(" . Saving session for reuse..." ); mbedtls_printf(" . Saving session for reuse..." );

View file

@ -168,6 +168,7 @@ int main( void )
#define DFL_EXTENDED_MS -1 #define DFL_EXTENDED_MS -1
#define DFL_ETM -1 #define DFL_ETM -1
#define DFL_CA_CALLBACK 0 #define DFL_CA_CALLBACK 0
#define DFL_EAP_TLS 0
#define LONG_RESPONSE "<p>01-blah-blah-blah-blah-blah-blah-blah-blah-blah\r\n" \ #define LONG_RESPONSE "<p>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" \ "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 "" #define USAGE_TICKETS ""
#endif /* MBEDTLS_SSL_SESSION_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) #if defined(MBEDTLS_SSL_CACHE_C)
#define USAGE_CACHE \ #define USAGE_CACHE \
" cache_max=%%d default: cache default (50)\n" \ " cache_max=%%d default: cache default (50)\n" \
@ -442,6 +450,7 @@ int main( void )
" exchanges=%%d default: 1\n" \ " exchanges=%%d default: 1\n" \
"\n" \ "\n" \
USAGE_TICKETS \ USAGE_TICKETS \
USAGE_EAP_TLS \
USAGE_CACHE \ USAGE_CACHE \
USAGE_MAX_FRAG_LEN \ USAGE_MAX_FRAG_LEN \
USAGE_TRUNC_HMAC \ USAGE_TRUNC_HMAC \
@ -563,10 +572,44 @@ struct options
int dtls_mtu; /* UDP Maximum tranport unit for DTLS */ int dtls_mtu; /* UDP Maximum tranport unit for DTLS */
int dgram_packing; /* allow/forbid datagram packing */ int dgram_packing; /* allow/forbid datagram packing */
int badmac_limit; /* Limit of records with bad MAC */ int badmac_limit; /* Limit of records with bad MAC */
int eap_tls; /* derive EAP-TLS keying material? */
} opt; } opt;
int query_config( const char *config ); 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, static void my_debug( void *ctx, int level,
const char *file, int line, const char *file, int line,
const char *str ) const char *str )
@ -1444,6 +1487,12 @@ int main( int argc, char *argv[] )
#if defined(MBEDTLS_USE_PSA_CRYPTO) #if defined(MBEDTLS_USE_PSA_CRYPTO)
psa_status_t status; psa_status_t status;
#endif #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) #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
mbedtls_memory_buffer_alloc_init( alloc_buf, sizeof(alloc_buf) ); 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.badmac_limit = DFL_BADMAC_LIMIT;
opt.extended_ms = DFL_EXTENDED_MS; opt.extended_ms = DFL_EXTENDED_MS;
opt.etm = DFL_ETM; opt.etm = DFL_ETM;
opt.eap_tls = DFL_EAP_TLS;
for( i = 1; i < argc; i++ ) for( i = 1; i < argc; i++ )
{ {
@ -1975,6 +2025,12 @@ int main( int argc, char *argv[] )
{ {
return query_config( q ); 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 else
goto usage; goto usage;
} }
@ -2537,6 +2593,12 @@ int main( int argc, char *argv[] )
mbedtls_ssl_conf_encrypt_then_mac( &conf, opt.etm ); mbedtls_ssl_conf_encrypt_then_mac( &conf, opt.etm );
#endif #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 defined(MBEDTLS_SSL_ALPN)
if( opt.alpn_string != NULL ) if( opt.alpn_string != NULL )
if( ( ret = mbedtls_ssl_conf_alpn_protocols( &conf, alpn_list ) ) != 0 ) if( ( ret = mbedtls_ssl_conf_alpn_protocols( &conf, alpn_list ) ) != 0 )
@ -3117,6 +3179,40 @@ handshake:
} }
#endif /* MBEDTLS_X509_CRT_PARSE_C */ #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 ) if( opt.exchanges == 0 )
goto close_notify; goto close_notify;