From 65b56ef87f3222fff7dc599dd23e6c2aa5491419 Mon Sep 17 00:00:00 2001 From: Ron Eldor Date: Thu, 26 Sep 2019 16:40:48 +0300 Subject: [PATCH] Change key derivation for srtp Use the export keys functionality, to call the public API `mbedtls_ssl_tls_prf()`, and remove the function `mbedtls_ssl_get_dtls_srtp_key_material()`. Signed-off-by: Johan Pascal --- include/mbedtls/ssl.h | 25 -------- library/ssl_tls.c | 49 --------------- programs/ssl/ssl_client2.c | 126 ++++++++++++++++++++++++++++++------- programs/ssl/ssl_server2.c | 123 +++++++++++++++++++++++++++++------- 4 files changed, 204 insertions(+), 119 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 6bcb5ecb98..a859093779 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -893,12 +893,6 @@ typedef struct mbedtls_dtls_srtp_info_t { /*! The SRTP profile that was negotiated*/ mbedtls_ssl_srtp_profile chosen_dtls_srtp_profile; - /*! master keys and master salt for SRTP generated during handshake */ - unsigned char dtls_srtp_keys[MBEDTLS_DTLS_SRTP_MAX_KEY_MATERIAL_LENGTH]; - /*! length in bytes of master keys and master salt for - * SRTP generated during handshake - */ - size_t dtls_srtp_keys_len; /*! The mki_value used, with max size of 256 bytes */ unsigned char mki_value[MBEDTLS_DTLS_SRTP_MAX_MKI_LENGTH]; /*! The length of mki_value */ @@ -3249,25 +3243,6 @@ int mbedtls_ssl_dtls_srtp_set_mki_value( mbedtls_ssl_context *ssl, mbedtls_ssl_srtp_profile mbedtls_ssl_get_dtls_srtp_protection_profile ( const mbedtls_ssl_context *ssl ); -/** - * \brief Get the generated DTLS-SRTP key material. - * This function should be called after the handshake is - * completed. It shall returns 60 bytes of key material - * generated according to RFC 5764 - * - * \param ssl SSL context tobe used. - * \param key Buffer to hold the generated key material. - * \param key_buffer_len Key buffer size. - * \param olen the actual number of bytes written to key. - * - * \return 0 on success, #MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL if - * the key buffer is too small to hold the generated key. - */ -int mbedtls_ssl_get_dtls_srtp_key_material( const mbedtls_ssl_context *ssl, - unsigned char *key, - size_t key_buffer_len, - size_t *olen ); - /** * \brief Utility function to get information on DTLS-SRTP profile. * diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 1b4779b4fb..5d98caa2a0 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -871,31 +871,6 @@ static int ssl_populate_transform( mbedtls_ssl_transform *transform, (void) ssl; #endif -#if defined(MBEDTLS_SSL_DTLS_SRTP) - /* check if we have a chosen srtp protection profile */ - if ( ssl->dtls_srtp_info.chosen_dtls_srtp_profile != MBEDTLS_SRTP_UNSET_PROFILE ) - { - /* derive key material for srtp session RFC5764 section 4.2 - * master key and master salt are respectively 128 bits and 112 bits - * for all currently available modes: - * SRTP_AES128_CM_HMAC_SHA1_80, SRTP_AES128_CM_HMAC_SHA1_32 - * SRTP_NULL_HMAC_SHA1_80, SRTP_NULL_HMAC_SHA1_32 - * So we must export 2*(128 + 112) = 480 bits - */ - ssl->dtls_srtp_info.dtls_srtp_keys_len = MBEDTLS_DTLS_SRTP_MAX_KEY_MATERIAL_LENGTH; - - ret = tls_prf( master, 48, "EXTRACTOR-dtls_srtp", - randbytes, 64, ssl->dtls_srtp_info.dtls_srtp_keys, - ssl->dtls_srtp_info.dtls_srtp_keys_len ); - - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "dtls srtp prf", ret ); - return( ret ); - } - } -#endif /* MBEDTLS_SSL_DTLS_SRTP */ - /* * Some data just needs copying into the structure */ @@ -4837,25 +4812,6 @@ mbedtls_ssl_srtp_profile { return( ssl->dtls_srtp_info.chosen_dtls_srtp_profile ); } - -int mbedtls_ssl_get_dtls_srtp_key_material( const mbedtls_ssl_context *ssl, - unsigned char *key, - size_t key_buffer_len, - size_t *olen ) -{ - - /* check output buffer size */ - if( key_buffer_len < ssl->dtls_srtp_info.dtls_srtp_keys_len ) - { - return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); - } - - memcpy( key, ssl->dtls_srtp_info.dtls_srtp_keys, - ssl->dtls_srtp_info.dtls_srtp_keys_len ); - *olen = ssl->dtls_srtp_info.dtls_srtp_keys_len; - - return( 0 ); -} #endif /* MBEDTLS_SSL_DTLS_SRTP */ void mbedtls_ssl_conf_max_version( mbedtls_ssl_config *conf, int major, int minor ) @@ -6955,11 +6911,6 @@ void mbedtls_ssl_free( mbedtls_ssl_context *ssl ) mbedtls_free( ssl->cli_id ); #endif -#if defined (MBEDTLS_SSL_DTLS_SRTP) - mbedtls_platform_zeroize( ssl->dtls_srtp_info.dtls_srtp_keys, - ssl->dtls_srtp_info.dtls_srtp_keys_len ); -#endif /* MBEDTLS_SSL_DTLS_SRTP */ - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= free" ) ); /* Actually clear after last debug message */ diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index 8bfd0c3291..448f1572ab 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -257,10 +257,26 @@ int main( void ) " This cannot be used with eap_tls=1\n" #define USAGE_NSS_KEYLOG_FILE \ " nss_keylog_file=%%s\n" -#else +#if defined(MBEDTLS_SSL_DTLS_SRTP) +#define USAGE_SRTP \ + " use_srtp=%%d default: 0 (disabled)\n" \ + " This cannot be used with eap_tls=1 or "\ + " nss_keylog=1\n" \ + " srtp_force_profile=%%d default: all enabled\n" \ + " available profiles:\n" \ + " 1 - SRTP_AES128_CM_HMAC_SHA1_80\n" \ + " 2 - SRTP_AES128_CM_HMAC_SHA1_32\n" \ + " 3 - SRTP_NULL_HMAC_SHA1_80\n" \ + " 4 - SRTP_NULL_HMAC_SHA1_32\n" \ + " mki=%%s default: \"\" (in hex, without 0x)\n" +#else /* MBEDTLS_SSL_DTLS_SRTP */ +#define USAGE_SRTP "" +#endif +#else /* MBEDTLS_SSL_EXPORT_KEYS */ #define USAGE_EAP_TLS "" #define USAGE_NSS_KEYLOG "" #define USAGE_NSS_KEYLOG_FILE "" +#define USAGE_SRTP "" #endif /* MBEDTLS_SSL_EXPORT_KEYS */ #if defined(MBEDTLS_SSL_TRUNCATED_HMAC) @@ -324,20 +340,6 @@ int main( void ) #define USAGE_DTLS "" #endif -#if defined(MBEDTLS_SSL_DTLS_SRTP) -#define USAGE_SRTP \ - " use_srtp=%%d default: 0 (disabled)\n" \ - " srtp_force_profile=%%d default: all enabled\n" \ - " available profiles:\n" \ - " 1 - SRTP_AES128_CM_HMAC_SHA1_80\n" \ - " 2 - SRTP_AES128_CM_HMAC_SHA1_32\n" \ - " 3 - SRTP_NULL_HMAC_SHA1_80\n" \ - " 4 - SRTP_NULL_HMAC_SHA1_32\n" \ - " mki=%%s default: \"\" (in hex, without 0x)\n" -#else -#define USAGE_SRTP "" -#endif - #if defined(MBEDTLS_SSL_FALLBACK_SCSV) #define USAGE_FALLBACK \ " fallback=0/1 default: (library default: off)\n" @@ -676,7 +678,43 @@ exit: sizeof( nss_keylog_line ) ); return( ret ); } -#endif + +#if defined( MBEDTLS_SSL_DTLS_SRTP ) +typedef struct dtls_srtp_keys +{ + unsigned char master_secret[48]; + unsigned char randbytes[64]; + mbedtls_tls_prf_types tls_prf_type; +} dtls_srtp_keys; + +static int dtls_srtp_key_derivation( void *p_expkey, + const unsigned char *ms, + const unsigned char *kb, + size_t maclen, + size_t keylen, + size_t ivlen, + const unsigned char client_random[32], + const unsigned char server_random[32], + mbedtls_tls_prf_types tls_prf_type ) +{ + dtls_srtp_keys *keys = (dtls_srtp_keys *)p_expkey; + + ( ( void ) kb ); + 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_type = tls_prf_type; + + if( opt.debug_level > 2 ) + { + mbedtls_printf("exported maclen is %u\n", (unsigned)maclen); + mbedtls_printf("exported keylen is %u\n", (unsigned)keylen); + mbedtls_printf("exported ivlen is %u\n", (unsigned)ivlen); + } + return( 0 ); +} +#endif /* MBEDTLS_SSL_DTLS_SRTP */ +#endif /* MBEDTLS_SSL_EXPORT_KEYS */ static void my_debug( void *ctx, int level, const char *file, int line, @@ -1157,7 +1195,6 @@ int main( int argc, char *argv[] ) #endif #if defined(MBEDTLS_SSL_DTLS_SRTP) unsigned char mki[MBEDTLS_DTLS_SRTP_MAX_MKI_LENGTH]; - size_t mki_len = 0; #endif const char *pers = "ssl_client2"; @@ -1202,7 +1239,13 @@ int main( int argc, char *argv[] ) unsigned char eap_tls_iv[8]; const char* eap_tls_label = "client EAP encryption"; eap_tls_keys eap_tls_keying; -#endif +#if defined( MBEDTLS_SSL_DTLS_SRTP ) + /*! master keys and master salt for SRTP generated during handshake */ + unsigned char dtls_srtp_key_material[MBEDTLS_DTLS_SRTP_MAX_KEY_MATERIAL_LENGTH]; + const char* dtls_srtp_label = "EXTRACTOR-dtls_srtp"; + dtls_srtp_keys dtls_srtp_keying; +#endif /* MBEDTLS_SSL_DTLS_SRTP */ +#endif /* MBEDTLS_SSL_EXPORT_KEYS */ #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) mbedtls_memory_buffer_alloc_init( alloc_buf, sizeof(alloc_buf) ); @@ -2344,7 +2387,14 @@ int main( int argc, char *argv[] ) nss_keylog_export, NULL ); } -#endif +#if defined( MBEDTLS_SSL_DTLS_SRTP ) + else if( opt.use_srtp != 0 ) + { + mbedtls_ssl_conf_export_keys_ext_cb( &conf, dtls_srtp_key_derivation, + &dtls_srtp_keying ); + } +#endif /* MBEDTLS_SSL_DTLS_SRTP */ +#endif /* MBEDTLS_SSL_EXPORT_KEYS */ #if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) if( opt.recsplit != DFL_RECSPLIT ) @@ -2553,7 +2603,7 @@ int main( int argc, char *argv[] ) mbedtls_ecp_set_max_ops( opt.ec_max_ops ); #endif - #if defined(MBEDTLS_SSL_DTLS_SRTP) +#if defined(MBEDTLS_SSL_DTLS_SRTP) if( opt.use_srtp != DFL_USE_SRTP && strlen( opt.mki ) != 0 ) { if( mbedtls_test_unhexify( mki, sizeof( mki ), @@ -2565,7 +2615,7 @@ int main( int argc, char *argv[] ) mbedtls_ssl_conf_srtp_mki_value_supported( &conf, MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED ); if( ( ret = mbedtls_ssl_dtls_srtp_set_mki_value( &ssl, mki, - strlen( mki ) ) ) != 0 ) + strlen( opt.mki ) / 2 ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_ssl_dtls_srtp_set_mki_value returned %d\n\n", ret ); goto exit; @@ -2694,7 +2744,39 @@ int main( int argc, char *argv[] ) } mbedtls_printf("\n"); } -#endif + +#if defined( MBEDTLS_SSL_DTLS_SRTP ) + else if( opt.use_srtp != 0 ) + { + size_t j = 0; + + if( ( ret = mbedtls_ssl_tls_prf( dtls_srtp_keying.tls_prf_type, + dtls_srtp_keying.master_secret, + sizeof( dtls_srtp_keying.master_secret ), + dtls_srtp_label, + dtls_srtp_keying.randbytes, + sizeof( dtls_srtp_keying.randbytes ), + dtls_srtp_key_material, + sizeof( dtls_srtp_key_material ) ) ) + != 0 ) + { + mbedtls_printf( " failed\n ! mbedtls_ssl_tls_prf returned -0x%x\n\n", + -ret ); + goto exit; + } + + mbedtls_printf( " DTLS-SRTP key material is:" ); + for( j = 0; j < sizeof( dtls_srtp_key_material ); j++ ) + { + if( j % 8 == 0 ) + mbedtls_printf("\n "); + mbedtls_printf("%02x ", dtls_srtp_key_material[j] ); + } + + mbedtls_printf("\n"); + } +#endif /* MBEDTLS_SSL_DTLS_SRTP */ +#endif /* MBEDTLS_SSL_EXPORT_KEYS */ 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 f3c359042f..93fea686cd 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -328,10 +328,24 @@ int main( void ) " This cannot be used with eap_tls=1\n" #define USAGE_NSS_KEYLOG_FILE \ " nss_keylog_file=%%s\n" -#else +#if defined(MBEDTLS_SSL_DTLS_SRTP) +#define USAGE_SRTP \ + " use_srtp=%%d default: 0 (disabled)\n" \ + " srtp_force_profile=%%d default: all enabled\n" \ + " available profiles:\n" \ + " 1 - SRTP_AES128_CM_HMAC_SHA1_80\n" \ + " 2 - SRTP_AES128_CM_HMAC_SHA1_32\n" \ + " 3 - SRTP_NULL_HMAC_SHA1_80\n" \ + " 4 - SRTP_NULL_HMAC_SHA1_32\n" \ + " support_mki=%%d default: 0 (not supported)\n" +#else /* MBEDTLS_SSL_DTLS_SRTP */ +#define USAGE_SRTP "" +#endif +#else /* MBEDTLS_SSL_EXPORT_KEYS */ #define USAGE_EAP_TLS "" #define USAGE_NSS_KEYLOG "" #define USAGE_NSS_KEYLOG_FILE "" +#define USAGE_SRTP "" #endif /* MBEDTLS_SSL_EXPORT_KEYS */ #if defined(MBEDTLS_SSL_CACHE_C) @@ -414,20 +428,6 @@ int main( void ) #define USAGE_DTLS "" #endif -#if defined(MBEDTLS_SSL_DTLS_SRTP) -#define USAGE_SRTP \ - " use_srtp=%%d default: 0 (disabled)\n" \ - " srtp_force_profile=%%d default: all enabled\n" \ - " available profiles:\n" \ - " 1 - SRTP_AES128_CM_HMAC_SHA1_80\n" \ - " 2 - SRTP_AES128_CM_HMAC_SHA1_32\n" \ - " 3 - SRTP_NULL_HMAC_SHA1_80\n" \ - " 4 - SRTP_NULL_HMAC_SHA1_32\n" \ - " support_mki=%%d default: 0 (not supported)\n" -#else -#define USAGE_SRTP "" -#endif - #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) #define USAGE_EMS \ " extended_ms=0/1 default: (library default: on)\n" @@ -781,7 +781,43 @@ exit: return( ret ); } -#endif +#if defined( MBEDTLS_SSL_DTLS_SRTP ) +typedef struct dtls_srtp_keys +{ + unsigned char master_secret[48]; + unsigned char randbytes[64]; + mbedtls_tls_prf_types tls_prf_type; +} dtls_srtp_keys; + +static int dtls_srtp_key_derivation( void *p_expkey, + const unsigned char *ms, + const unsigned char *kb, + size_t maclen, + size_t keylen, + size_t ivlen, + const unsigned char client_random[32], + const unsigned char server_random[32], + mbedtls_tls_prf_types tls_prf_type ) +{ + dtls_srtp_keys *keys = (dtls_srtp_keys *)p_expkey; + + ( ( void ) kb ); + 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_type = tls_prf_type; + + if( opt.debug_level > 2 ) + { + mbedtls_printf("exported maclen is %u\n", (unsigned)maclen); + mbedtls_printf("exported keylen is %u\n", (unsigned)keylen); + mbedtls_printf("exported ivlen is %u\n", (unsigned)ivlen); + } + return( 0 ); +} +#endif /* MBEDTLS_SSL_DTLS_SRTP */ + +#endif /* MBEDTLS_SSL_EXPORT_KEYS */ static void my_debug( void *ctx, int level, const char *file, int line, @@ -1824,10 +1860,6 @@ int main( int argc, char *argv[] ) size_t context_buf_len = 0; #endif -#if defined(MBEDTLS_SSL_DTLS_SRTP) - unsigned char mki[MBEDTLS_DTLS_SRTP_MAX_MKI_LENGTH]; - size_t mki_len = 0; -#endif int i; char *p, *q; const int *list; @@ -1839,7 +1871,13 @@ int main( int argc, char *argv[] ) unsigned char eap_tls_iv[8]; const char* eap_tls_label = "client EAP encryption"; eap_tls_keys eap_tls_keying; -#endif +#if defined( MBEDTLS_SSL_DTLS_SRTP ) + /*! master keys and master salt for SRTP generated during handshake */ + unsigned char dtls_srtp_key_material[MBEDTLS_DTLS_SRTP_MAX_KEY_MATERIAL_LENGTH]; + const char* dtls_srtp_label = "EXTRACTOR-dtls_srtp"; + dtls_srtp_keys dtls_srtp_keying; +#endif /* MBEDTLS_SSL_DTLS_SRTP */ +#endif /* MBEDTLS_SSL_EXPORT_KEYS */ #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) mbedtls_memory_buffer_alloc_init( alloc_buf, sizeof(alloc_buf) ); @@ -3164,7 +3202,14 @@ int main( int argc, char *argv[] ) nss_keylog_export, NULL ); } -#endif +#if defined( MBEDTLS_SSL_DTLS_SRTP ) + else if( opt.use_srtp != 0 ) + { + mbedtls_ssl_conf_export_keys_ext_cb( &conf, dtls_srtp_key_derivation, + &dtls_srtp_keying ); + } +#endif /* MBEDTLS_SSL_DTLS_SRTP */ +#endif /* MBEDTLS_SSL_EXPORT_KEYS */ #if defined(MBEDTLS_SSL_ALPN) if( opt.alpn_string != NULL ) @@ -3810,7 +3855,39 @@ handshake: } mbedtls_printf("\n"); } -#endif + +#if defined( MBEDTLS_SSL_DTLS_SRTP ) + else if( opt.use_srtp != 0 ) + { + size_t j = 0; + + if( ( ret = mbedtls_ssl_tls_prf( dtls_srtp_keying.tls_prf_type, + dtls_srtp_keying.master_secret, + sizeof( dtls_srtp_keying.master_secret ), + dtls_srtp_label, + dtls_srtp_keying.randbytes, + sizeof( dtls_srtp_keying.randbytes ), + dtls_srtp_key_material, + sizeof( dtls_srtp_key_material ) ) ) + != 0 ) + { + mbedtls_printf( " failed\n ! mbedtls_ssl_tls_prf returned -0x%x\n\n", + -ret ); + goto exit; + } + + mbedtls_printf( " DTLS-SRTP key material is:" ); + for( j = 0; j < sizeof( dtls_srtp_key_material ); j++ ) + { + if( j % 8 == 0 ) + mbedtls_printf("\n "); + mbedtls_printf("%02x ", dtls_srtp_key_material[j] ); + } + + mbedtls_printf("\n"); + } +#endif /* MBEDTLS_SSL_DTLS_SRTP */ +#endif /* MBEDTLS_SSL_EXPORT_KEYS */ #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) ret = report_cid_usage( &ssl, "initial handshake" );