Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Dtls Srtp support (RFC5764) #3235

Merged
merged 63 commits into from
Oct 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
b62bb51
Add RFC5764 - SRTP key generation during DTLS handshake
jeannotlapin Dec 3, 2015
bbc057a
Move available dtls srtp profile list to ssl_config
jeannotlapin Feb 4, 2016
2d9470b
Improve DTLS SRTP API with a dedicated function to get generated keys
jeannotlapin Feb 8, 2016
c28f1f6
Fix typos in documentation
jeannotlapin Feb 9, 2017
701984d
Comply with mbedtls naming rules
jeannotlapin Feb 9, 2017
3479078
Remove compilation warning
jeannotlapin Feb 9, 2017
3adb992
Add mki value and some review comments
Dec 21, 2017
591f162
support mki value
Jan 22, 2018
a37326a
Make keyu material length in \ out
Mar 29, 2018
349877e
Fix idetifier check script error
Mar 29, 2018
9e90964
Fix doxygen script errors
Apr 1, 2018
57cc70e
Enforce SRTP mandatory HS messages
Apr 2, 2018
4cbe693
Add ChangeLog
Apr 3, 2018
9d36d31
Fix failure in ssl-opts.sh
Jul 1, 2018
6ea6451
Add dtls-srtp to client and server examples
Jul 2, 2018
12c6ead
Fix mki issues
Jul 3, 2018
1c399bd
Set authmode to optional, if not set
Jul 4, 2018
b465539
Add tests and code to support
Jul 5, 2018
311b95a
Fix compilation errors
Jul 8, 2018
3c6a44b
Add interop tests
Jul 10, 2018
2b3dfe4
Force IPv6 for DTLS interop tests with gnutls-cli
Jul 11, 2018
ef72faf
Style fixes
Jul 12, 2018
a978804
Style fixes
Dec 5, 2018
089c9fe
Improve readability
Dec 6, 2018
f0f7c19
Add comment describing the feature
Dec 6, 2018
75870ec
Change byte copy to memcpy
Dec 6, 2018
313d7b5
Add variable validation
Dec 10, 2018
9cfb5eb
Disable SRTP by default
Dec 10, 2018
5d991c9
Force IPv4 in gnutls_cli srtp tests
Jan 15, 2019
65b56ef
Change key derivation for srtp
Sep 26, 2019
8f284c1
Add the SRTP configuration to query_config
Sep 26, 2019
44c0a0a
Stick to ChangeLog rules
jeannotlapin Apr 23, 2020
b64eab7
fix style
jeannotlapin Apr 23, 2020
1d957e6
Fix build warning
jeannotlapin May 6, 2020
48f62e9
Fix ssl_client2 after rebase
jeannotlapin Aug 22, 2020
8526957
Minor style modifications
jeannotlapin Aug 25, 2020
a89ca86
The client shall not enforce the use of client certificate with use_s…
jeannotlapin Aug 25, 2020
042d456
Improve client Hello use_srtp parsing
jeannotlapin Aug 25, 2020
8f70fba
Check the server hello output buffer size when writing the use_srtp ext
jeannotlapin Sep 2, 2020
9bc97ca
SRTP-DTLS protection profile configuration list not copied into ssl_c…
jeannotlapin Sep 21, 2020
d576fdb
Style + fix bound check in write_use_srt_ext
jeannotlapin Sep 22, 2020
4f09926
use_srtp extension shall not interfere in the handshake settings
jeannotlapin Sep 22, 2020
43f9490
SRTP profiles definition use macros only
jeannotlapin Sep 22, 2020
253d026
set protection profile API gets a MBEDTLS_TLS_SRTP_UNSET terminated list
jeannotlapin Sep 22, 2020
f6417ec
mki length feats in a uint16_t
jeannotlapin Sep 22, 2020
a455cd9
mbedtls_ssl_get_srtp_profile_as_string declared and defined in ssl.h
jeannotlapin Sep 22, 2020
e79c1e8
style
jeannotlapin Sep 22, 2020
aae4d22
Improve code readability
jeannotlapin Sep 22, 2020
77696ee
Add bound check in the client ssl_write_use_srtp_ext
jeannotlapin Sep 22, 2020
842d671
Update include/mbedtls/config.h
jeannotlapin Sep 23, 2020
d387aa0
style + missing cast
jeannotlapin Sep 23, 2020
39cfd3b
interop test: openssl generate the DTLS-SRTP keys
jeannotlapin Sep 23, 2020
9bc50b0
Test check the key material exported match
jeannotlapin Sep 24, 2020
1040315
style
jeannotlapin Oct 9, 2020
76fdf1d
Minor fix and improvements
jeannotlapin Oct 22, 2020
adbd944
More minor fix
jeannotlapin Oct 26, 2020
20c7db3
API modified so server side can get mki value
jeannotlapin Oct 26, 2020
275874b
Fix previous commit
jeannotlapin Oct 27, 2020
0dbcd1d
Make API safer
jeannotlapin Oct 28, 2020
2258a4f
Do not return a structure, use a return parameter
jeannotlapin Oct 28, 2020
5ef72d2
Style and typos
jeannotlapin Oct 28, 2020
c3ccd98
Check transport in the extension parser/writer
jeannotlapin Oct 28, 2020
5fbe9e7
remove useless parentheses
jeannotlapin Oct 29, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions ChangeLog.d/feature-dtls-srtp.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Features
* Add support for DTLS-SRTP as defined in RFC 5764. Contributed by Johan Pascal, improved by Ron Eldor.
4 changes: 4 additions & 0 deletions include/mbedtls/check_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -871,6 +871,10 @@
#endif /* MBEDTLS_DEPRECATED_REMOVED */
#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */

#if defined(MBEDTLS_SSL_DTLS_SRTP) && ( !defined(MBEDTLS_SSL_PROTO_DTLS) )
#error "MBEDTLS_SSL_DTLS_SRTP defined, but not all prerequisites"
#endif

/*
* Avoid warning from -pedantic. This is a convenient place for this
* workaround since this is included by every single file before the
Expand Down
31 changes: 31 additions & 0 deletions include/mbedtls/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -1812,6 +1812,37 @@
*/
#define MBEDTLS_SSL_DTLS_HELLO_VERIFY

/**
* \def MBEDTLS_SSL_DTLS_SRTP
*
* Enable support for negotation of DTLS-SRTP (RFC 5764)
* through the use_srtp extension.
*
* \note This feature provides the minimum functionality required
* to negotiate the use of DTLS-SRTP and to allow the derivation of
* the associated SRTP packet protection key material.
* In particular, the SRTP packet protection itself, as well as the
* demultiplexing of RTP and DTLS packets at the datagram layer
* (see Section 5 of RFC 5764), are not handled by this feature.
* Instead, after successful completion of a handshake negotiating
* the use of DTLS-SRTP, the extended key exporter API
* mbedtls_ssl_conf_export_keys_ext_cb() should be used to implement
yanesca marked this conversation as resolved.
Show resolved Hide resolved
* the key exporter described in Section 4.2 of RFC 5764 and RFC 5705
* (this is implemented in the SSL example programs).
* The resulting key should then be passed to an SRTP stack.
*
* Setting this option enables the runtime API
* mbedtls_ssl_conf_dtls_srtp_protection_profiles()
* through which the supported DTLS-SRTP protection
* profiles can be configured. You must call this API at
* runtime if you wish to negotiate the use of DTLS-SRTP.
*
* Requires: MBEDTLS_SSL_PROTO_DTLS
*
* Uncomment this to enable support for use_srtp extension.
*/
//#define MBEDTLS_SSL_DTLS_SRTP

/**
* \def MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE
*
Expand Down
160 changes: 159 additions & 1 deletion include/mbedtls/ssl.h
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,9 @@
#define MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED 1
#define MBEDTLS_SSL_CERT_REQ_CA_LIST_DISABLED 0

#define MBEDTLS_SSL_DTLS_SRTP_MKI_UNSUPPORTED 0
#define MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED 1

/*
* Default range for DTLS retransmission timer value, in milliseconds.
* RFC 6347 4.2.4.1 says from 1 second to 60 seconds.
Expand Down Expand Up @@ -393,6 +396,8 @@

#define MBEDTLS_TLS_EXT_SIG_ALG 13

#define MBEDTLS_TLS_EXT_USE_SRTP 14

#define MBEDTLS_TLS_EXT_ALPN 16

#define MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC 22 /* 0x16 */
Expand Down Expand Up @@ -851,6 +856,41 @@ typedef void mbedtls_ssl_async_cancel_t( mbedtls_ssl_context *ssl );
#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED &&
!MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */

#if defined(MBEDTLS_SSL_DTLS_SRTP)

#define MBEDTLS_TLS_SRTP_MAX_MKI_LENGTH 255
#define MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH 4
/*
yanesca marked this conversation as resolved.
Show resolved Hide resolved
* For code readability use a typedef for DTLS-SRTP profiles
*
* Use_srtp extension protection profiles values as defined in
* http://www.iana.org/assignments/srtp-protection/srtp-protection.xhtml
*
* Reminder: if this list is expanded mbedtls_ssl_check_srtp_profile_value
* must be updated too.
*/
#define MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80 ( (uint16_t) 0x0001)
#define MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32 ( (uint16_t) 0x0002)
#define MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80 ( (uint16_t) 0x0005)
#define MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32 ( (uint16_t) 0x0006)
/* This one is not iana defined, but for code readability. */
#define MBEDTLS_TLS_SRTP_UNSET ( (uint16_t) 0x0000)

typedef uint16_t mbedtls_ssl_srtp_profile;
yanesca marked this conversation as resolved.
Show resolved Hide resolved

typedef struct mbedtls_dtls_srtp_info_t
{
/*! The SRTP profile that was negotiated. */
mbedtls_ssl_srtp_profile chosen_dtls_srtp_profile;
/*! The length of mki_value. */
uint16_t mki_len;
/*! The mki_value used, with max size of 256 bytes. */
unsigned char mki_value[MBEDTLS_TLS_SRTP_MAX_MKI_LENGTH];
}
mbedtls_dtls_srtp_info;

#endif /* MBEDTLS_SSL_DTLS_SRTP */

/*
* This structure is used for storing current session data.
*
Expand Down Expand Up @@ -1057,6 +1097,13 @@ struct mbedtls_ssl_config
const char **alpn_list; /*!< ordered list of protocols */
#endif

#if defined(MBEDTLS_SSL_DTLS_SRTP)
/*! ordered list of supported srtp profile */
const mbedtls_ssl_srtp_profile *dtls_srtp_profile_list;
/*! number of supported profiles */
size_t dtls_srtp_profile_list_len;
#endif /* MBEDTLS_SSL_DTLS_SRTP */

/*
* Numerical settings (int then char)
*/
Expand Down Expand Up @@ -1137,9 +1184,12 @@ struct mbedtls_ssl_config
* record with unexpected CID
* should lead to failure. */
#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
#if defined(MBEDTLS_SSL_DTLS_SRTP)
unsigned int dtls_srtp_mki_support : 1; /* support having mki_value
in the use_srtp extension */
#endif
};


struct mbedtls_ssl_context
{
const mbedtls_ssl_config *conf; /*!< configuration information */
Expand Down Expand Up @@ -1298,6 +1348,13 @@ struct mbedtls_ssl_context
const char *alpn_chosen; /*!< negotiated protocol */
#endif /* MBEDTLS_SSL_ALPN */

#if defined(MBEDTLS_SSL_DTLS_SRTP)
/*
* use_srtp extension
*/
mbedtls_dtls_srtp_info dtls_srtp_info;
#endif /* MBEDTLS_SSL_DTLS_SRTP */

/*
* Information for DTLS hello verify
*/
Expand Down Expand Up @@ -2032,6 +2089,8 @@ void mbedtls_ssl_conf_export_keys_cb( mbedtls_ssl_config *conf,
* (Default: none.)
*
* \note See \c mbedtls_ssl_export_keys_ext_t.
* \warning Exported key material must not be used for any purpose
* before the (D)TLS handshake is completed
*
* \param conf SSL configuration context
* \param f_export_keys_ext Callback for exporting keys
Expand Down Expand Up @@ -3120,6 +3179,105 @@ 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_DTLS_SRTP)
#if defined(MBEDTLS_DEBUG_C)
static inline const char *mbedtls_ssl_get_srtp_profile_as_string( mbedtls_ssl_srtp_profile profile )
{
switch( profile )
{
case MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80:
return( "MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80" );
case MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32:
return( "MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32" );
case MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80:
return( "MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80" );
case MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32:
return( "MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32" );
default: break;
}
return( "" );
}
#endif /* MBEDTLS_DEBUG_C */
/**
* \brief Manage support for mki(master key id) value
* in use_srtp extension.
* MKI is an optional part of SRTP used for key management
* and re-keying. See RFC3711 section 3.1 for details.
* The default value is
* #MBEDTLS_SSL_DTLS_SRTP_MKI_UNSUPPORTED.
*
* \param conf The SSL configuration to manage mki support.
* \param support_mki_value Enable or disable mki usage. Values are
* #MBEDTLS_SSL_DTLS_SRTP_MKI_UNSUPPORTED
* or #MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED.
*/
void mbedtls_ssl_conf_srtp_mki_value_supported( mbedtls_ssl_config *conf,
int support_mki_value );

/**
* \brief Set the supported DTLS-SRTP protection profiles.
*
* \param conf SSL configuration
* \param profiles Pointer to a List of MBEDTLS_TLS_SRTP_UNSET terminated
* supported protection profiles
* in decreasing preference order.
* The pointer to the list is recorded by the library
* for later reference as required, so the lifetime
* of the table must be at least as long as the lifetime
* of the SSL configuration structure.
* The list must not hold more than
* MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH elements
hanno-becker marked this conversation as resolved.
Show resolved Hide resolved
* (excluding the terminating MBEDTLS_TLS_SRTP_UNSET).
*
* \return 0 on success
* \return #MBEDTLS_ERR_SSL_BAD_INPUT_DATA when the list of
* protection profiles is incorrect.
*/
int mbedtls_ssl_conf_dtls_srtp_protection_profiles
( mbedtls_ssl_config *conf,
const mbedtls_ssl_srtp_profile *profiles );

/**
* \brief Set the mki_value for the current DTLS-SRTP session.
*
yanesca marked this conversation as resolved.
Show resolved Hide resolved
* \param ssl SSL context to use.
* \param mki_value The MKI value to set.
* \param mki_len The length of the MKI value.
*
* \note This function is relevant on client side only.
* The server discovers the mki value during handshake.
* A mki value set on server side using this function
* is ignored.
*
* \return 0 on success
* \return #MBEDTLS_ERR_SSL_BAD_INPUT_DATA
* \return #MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE
*/
int mbedtls_ssl_dtls_srtp_set_mki_value( mbedtls_ssl_context *ssl,
unsigned char *mki_value,
uint16_t mki_len );
/**
* \brief Get the negotiated DTLS-SRTP informations:
* Protection profile and MKI value.
*
* \warning This function must be called after the handshake is
* completed. The value returned by this function must
* not be trusted or acted upon before the handshake completes.
*
* \param ssl The SSL context to query.
* \param dtls_srtp_info The negotiated DTLS-SRTP informations:
* - Protection profile in use.
* A direct mapping of the iana defined value for protection
* profile on an uint16_t.
http://www.iana.org/assignments/srtp-protection/srtp-protection.xhtml
* #MBEDTLS_TLS_SRTP_UNSET if the use of SRTP was not negotiated
* or peer's Hello packet was not parsed yet.
* - mki size and value( if size is > 0 ).
*/
void mbedtls_ssl_get_dtls_srtp_negotiation_result( const mbedtls_ssl_context *ssl,
mbedtls_dtls_srtp_info *dtls_srtp_info );
#endif /* MBEDTLS_SSL_DTLS_SRTP */

/**
* \brief Set the maximum supported version sent from the client side
* and/or accepted at the server side
Expand Down
17 changes: 17 additions & 0 deletions include/mbedtls/ssl_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -1095,6 +1095,23 @@ int mbedtls_ssl_check_sig_hash( const mbedtls_ssl_context *ssl,
mbedtls_md_type_t md );
#endif

#if defined(MBEDTLS_SSL_DTLS_SRTP)
static inline mbedtls_ssl_srtp_profile mbedtls_ssl_check_srtp_profile_value
( const uint16_t srtp_profile_value )
{
switch( srtp_profile_value )
{
case MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80:
case MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32:
case MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80:
case MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32:
return srtp_profile_value;
default: break;
}
return( MBEDTLS_TLS_SRTP_UNSET );
}
#endif

#if defined(MBEDTLS_X509_CRT_PARSE_C)
static inline mbedtls_pk_context *mbedtls_ssl_own_key( mbedtls_ssl_context *ssl )
{
Expand Down