From b62bb51affcd576f6bbcd20da7038bf831de77f7 Mon Sep 17 00:00:00 2001
From: Johan Pascal <johan.pascal@belledonne-communications.com>
Date: Thu, 3 Dec 2015 21:56:45 +0100
Subject: [PATCH 01/63] Add RFC5764 - SRTP key generation during DTLS handshake

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 include/mbedtls/config.h |  11 +++
 include/mbedtls/ssl.h    |  59 ++++++++++++++
 library/ssl_cli.c        | 163 +++++++++++++++++++++++++++++++++++++++
 library/ssl_srv.c        | 137 ++++++++++++++++++++++++++++++++
 library/ssl_tls.c        |  79 +++++++++++++++++++
 5 files changed, 449 insertions(+)

diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h
index 48e8855e8664..2ed3ec29e815 100644
--- a/include/mbedtls/config.h
+++ b/include/mbedtls/config.h
@@ -1812,6 +1812,17 @@
  */
 #define MBEDTLS_SSL_DTLS_HELLO_VERIFY
 
+/**
+ * \def MBEDTLS_SSL_DTLS_SRTP
+ *
+ * Enable support for DTLS-SRTP, RFC5764
+ *
+ * Requires: MBEDTLS_SSL_PROTO_DTLS
+ *
+ * Comment this to disable support for DTLS-SRTP.
+ */
+#define MBEDTLS_SSL_DTLS_SRTP
+
 /**
  * \def MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE
  *
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index a0912614fc3a..55eeb182fcfc 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -393,6 +393,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 */
@@ -409,6 +411,14 @@
 
 #define MBEDTLS_TLS_EXT_RENEGOTIATION_INFO      0xFF01
 
+/*
+ * use_srtp extension protection profiles values as defined in http://www.iana.org/assignments/srtp-protection/srtp-protection.xhtml
+ */
+#define MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80_IANA_VALUE     0x0001
+#define MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32_IANA_VALUE     0x0002
+#define MBEDTLS_SRTP_NULL_HMAC_SHA1_80_IANA_VALUE          0x0005
+#define MBEDTLS_SRTP_NULL_HMAC_SHA1_32_IANA_VALUE          0x0006
+
 /*
  * Size defines
  */
@@ -851,6 +861,19 @@ 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)
+/*
+ * List of SRTP profiles for DTLS-SRTP
+ */
+enum mbedtls_DTLS_SRTP_protection_profiles {
+    MBEDTLS_SRTP_UNSET_PROFILE,
+    MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80,
+    MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32,
+    MBEDTLS_SRTP_NULL_HMAC_SHA1_80,
+    MBEDTLS_SRTP_NULL_HMAC_SHA1_32,
+};
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+
 /*
  * This structure is used for storing current session data.
  *
@@ -1298,6 +1321,17 @@ struct mbedtls_ssl_context
     const char *alpn_chosen;    /*!<  negotiated protocol                   */
 #endif /* MBEDTLS_SSL_ALPN */
 
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+    /*
+     * use_srtp extension
+     */
+    enum mbedtls_DTLS_SRTP_protection_profiles *dtls_srtp_profiles_list; /*!< ordered list of supported srtp profile */
+    size_t dtls_srtp_profiles_list_len; /*!< number of supported profiles */
+    enum mbedtls_DTLS_SRTP_protection_profiles chosen_dtls_srtp_profile; /*!< negotiated profil */
+    unsigned char *dtls_srtp_keys; /*<! master keys and master salt for SRTP generated during handshake */
+    size_t dtls_srtp_keys_len; /*<! length in bytes of master keys and master salt for SRTP generated during handshake */
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+
     /*
      * Information for DTLS hello verify
      */
@@ -3120,6 +3154,31 @@ 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)
+/**
+ * \brief                   Set the supported DTLS-SRTP protection profiles.
+ *
+ * \param ssl               SSL context
+ * \param protos            List of supported protection profiles,
+ *                          in decreasing preference order.
+ * \param profiles_number   Number of supported profiles.
+ *
+ * \return         0 on success, or MBEDTLS_ERR_SSL_BAD_INPUT_DATA.
+ */
+int mbedtls_ssl_set_dtls_srtp_protection_profiles( mbedtls_ssl_context *ssl, const enum mbedtls_DTLS_SRTP_protection_profiles *profiles, size_t profiles_number);
+
+/**
+ * \brief          Get the negotiated DTLS-SRTP Protection Profile.
+ *                 This function should be called after the handshake is
+ *                 completed.
+ *
+ * \param ssl      SSL context
+ *
+ * \return         Protection Profile enum member, SRTP_UNSET_PROFILE if no protocol was negotiated.
+ */
+enum mbedtls_DTLS_SRTP_protection_profiles mbedtls_ssl_get_dtls_srtp_protection_profile( const mbedtls_ssl_context *ssl);
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+
 /**
  * \brief          Set the maximum supported version sent from the client side
  *                 and/or accepted at the server side
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index 083b720be114..f392c50dfa30 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -756,6 +756,79 @@ static int ssl_write_alpn_ext( mbedtls_ssl_context *ssl,
 }
 #endif /* MBEDTLS_SSL_ALPN */
 
+#if defined (MBEDTLS_SSL_DTLS_SRTP)
+static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
+                                unsigned char *buf, size_t *olen )
+{
+    unsigned char *p = buf;
+    size_t protection_profiles_index = 0;
+
+    *olen = 0;
+
+    if( (ssl->dtls_srtp_profiles_list == NULL)  || (ssl->dtls_srtp_profiles_list_len == 0) )
+    {
+        return;
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding use_srtp extension" ) );
+
+    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_USE_SRTP >> 8 ) & 0xFF );
+    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_USE_SRTP      ) & 0xFF );
+
+    /* RFC5764 section 4.1.1
+     * uint8 SRTPProtectionProfile[2];
+     *
+     * struct {
+     *   SRTPProtectionProfiles SRTPProtectionProfiles;
+     *   opaque srtp_mki<0..255>;
+     * } UseSRTPData;
+
+     * SRTPProtectionProfile SRTPProtectionProfiles<2..2^16-1>;
+     *
+     * Note: srtp_mki is not supported
+     */
+
+    /* Extension length = 2bytes for profiles lenght, ssl->dtls_srtp_profiles_list_len*2 (each profile is 2 bytes length ) + 1 byte for the non implemented srtp_mki vector length (always 0) */
+    *p++ = (unsigned char)( ( ( 2 + 2*(ssl->dtls_srtp_profiles_list_len) + 1 ) >> 8 ) & 0xFF );
+    *p++ = (unsigned char)( ( ( 2 + 2*(ssl->dtls_srtp_profiles_list_len) + 1 )      ) & 0xFF );
+
+
+    /* protection profile length: 2*(ssl->dtls_srtp_profiles_list_len) */
+    *p++ = (unsigned char)( ( ( 2*(ssl->dtls_srtp_profiles_list_len) ) >> 8 ) & 0xFF );
+    *p++ = (unsigned char)( ( 2*(ssl->dtls_srtp_profiles_list_len) ) & 0xFF );
+
+    for( protection_profiles_index=0; protection_profiles_index < ssl->dtls_srtp_profiles_list_len; protection_profiles_index++ )
+    {
+        switch (ssl->dtls_srtp_profiles_list[protection_profiles_index]) {
+            case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80:
+                *p++ = ( ( ( MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80_IANA_VALUE ) >> 8 ) & 0xFF);
+                *p++ = ( ( MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80_IANA_VALUE ) & 0xFF);
+                break;
+            case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32:
+                *p++ = ( ( ( MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32_IANA_VALUE ) >> 8 ) & 0xFF);
+                *p++ = ( ( MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32_IANA_VALUE ) & 0xFF);
+                break;
+            case MBEDTLS_SRTP_NULL_HMAC_SHA1_80:
+                *p++ = ( ( ( MBEDTLS_SRTP_NULL_HMAC_SHA1_80_IANA_VALUE ) >> 8 ) & 0xFF);
+                *p++ = ( ( MBEDTLS_SRTP_NULL_HMAC_SHA1_80_IANA_VALUE ) & 0xFF);
+                break;
+            case MBEDTLS_SRTP_NULL_HMAC_SHA1_32:
+                *p++ = ( ( ( MBEDTLS_SRTP_NULL_HMAC_SHA1_32_IANA_VALUE ) >> 8 ) & 0xFF);
+                *p++ = ( ( MBEDTLS_SRTP_NULL_HMAC_SHA1_32_IANA_VALUE ) & 0xFF);
+                break;
+            default:
+                /* Note: we shall never arrive here as protection profiles is checked by ssl_set_dtls_srtp_protection_profiles function */
+                MBEDTLS_SSL_DEBUG_MSG( 1, ( "client hello, ignore illegal DTLS-SRTP protection profile %d",  ssl->dtls_srtp_profiles_list[protection_profiles_index]) );
+                break;
+        }
+    }
+
+    *p++ = 0x00;  /* non implemented srtp_mki vector length is always 0 */
+    /* total extension length: extension type (2 bytes) + extension length (2 bytes) + protection profile length (2 bytes) + 2*nb protection profiles + srtp_mki vector length(1 byte)*/
+    *olen = 2 + 2 + 2 + 2*(ssl->dtls_srtp_profiles_list_len) + 1;
+}
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+
 /*
  * Generate random bytes for ClientHello
  */
@@ -1277,6 +1350,11 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
     ext_len += olen;
 #endif
 
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+    ssl_write_use_srtp_ext( ssl, p + 2 + ext_len, &olen );
+    ext_len += olen;
+#endif
+
 #if defined(MBEDTLS_SSL_SESSION_TICKETS)
     if( ( ret = ssl_write_session_ticket_ext( ssl, p + 2 + ext_len,
                                               end, &olen ) ) != 0 )
@@ -1710,6 +1788,81 @@ static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl,
 }
 #endif /* MBEDTLS_SSL_ALPN */
 
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
+                               const unsigned char *buf, size_t len )
+{
+    enum mbedtls_DTLS_SRTP_protection_profiles server_protection = MBEDTLS_SRTP_UNSET_PROFILE;
+    size_t i;
+    uint16_t server_protection_profile_value = 0;
+
+    /* If use_srtp is not configured, just ignore the extension */
+    if( ( ssl->dtls_srtp_profiles_list == NULL ) || ( ssl->dtls_srtp_profiles_list_len == 0 ) )
+        return( 0 );
+
+    /* RFC5764 section 4.1.1
+     * uint8 SRTPProtectionProfile[2];
+     *
+     * struct {
+     *   SRTPProtectionProfiles SRTPProtectionProfiles;
+     *   opaque srtp_mki<0..255>;
+     * } UseSRTPData;
+
+     * SRTPProtectionProfile SRTPProtectionProfiles<2..2^16-1>;
+     *
+     * Note: srtp_mki is not supported
+     */
+
+    /* Length is 5 : one protection profile(2 bytes) + length(2 bytes) and potential srtp_mki which won't be parsed */
+    if( len < 5 )
+        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+
+    /*
+     * get the server protection profile
+     */
+    if (((uint16_t)(buf[0]<<8 | buf[1])) != 0x0002) { /* protection profile length must be 0x0002 as we must have only one protection profile in server Hello */
+        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+    } else {
+        server_protection_profile_value = buf[2]<<8 | buf[3];
+    }
+
+    /*
+     * Check we have the server profile in our list
+     */
+    for( i=0; i < ssl->dtls_srtp_profiles_list_len; i++)
+    {
+        switch ( server_protection_profile_value ) {
+            case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80_IANA_VALUE:
+                server_protection = MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80;
+                break;
+            case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32_IANA_VALUE:
+                server_protection = MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32;
+                break;
+            case MBEDTLS_SRTP_NULL_HMAC_SHA1_80_IANA_VALUE:
+                server_protection = MBEDTLS_SRTP_NULL_HMAC_SHA1_80;
+                break;
+            case MBEDTLS_SRTP_NULL_HMAC_SHA1_32_IANA_VALUE:
+                server_protection = MBEDTLS_SRTP_NULL_HMAC_SHA1_32;
+                break;
+            default:
+                server_protection = MBEDTLS_SRTP_UNSET_PROFILE;
+                break;
+        }
+
+        if (server_protection == ssl->dtls_srtp_profiles_list[i]) {
+            ssl->chosen_dtls_srtp_profile = ssl->dtls_srtp_profiles_list[i];
+            return 0;
+        }
+    }
+
+    /* If we get there, no match was found : server problem, it shall never answer with incompatible profile */
+    ssl->chosen_dtls_srtp_profile = MBEDTLS_SRTP_UNSET_PROFILE;
+    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_DTLS_SRTP */
+
 /*
  * Parse HelloVerifyRequest.  Only called after verifying the HS type.
  */
@@ -2278,6 +2431,16 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
             break;
 #endif /* MBEDTLS_SSL_ALPN */
 
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+        case MBEDTLS_TLS_EXT_USE_SRTP:
+            MBEDTLS_SSL_DEBUG_MSG( 3, ( "found use_srtp extension" ) );
+
+            if( ( ret = ssl_parse_use_srtp_ext( ssl, ext + 4, ext_size ) ) != 0 )
+                return( ret );
+
+            break;
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+
         default:
             MBEDTLS_SSL_DEBUG_MSG( 3,
                 ( "unknown extension found: %d (ignoring)", ext_id ) );
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index 2e63fced35b2..a14ec8664091 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -776,6 +776,78 @@ static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl,
 }
 #endif /* MBEDTLS_SSL_ALPN */
 
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
+                               const unsigned char *buf, size_t len )
+{
+    enum mbedtls_DTLS_SRTP_protection_profiles client_protection = MBEDTLS_SRTP_UNSET_PROFILE;
+    size_t i,j;
+    uint16_t profile_length;
+
+    /* If use_srtp is not configured, just ignore the extension */
+    if( ( ssl->dtls_srtp_profiles_list == NULL ) || ( ssl->dtls_srtp_profiles_list_len == 0 ) )
+        return( 0 );
+
+    /* RFC5764 section 4.1.1
+     * uint8 SRTPProtectionProfile[2];
+     *
+     * struct {
+     *   SRTPProtectionProfiles SRTPProtectionProfiles;
+     *   opaque srtp_mki<0..255>;
+     * } UseSRTPData;
+
+     * SRTPProtectionProfile SRTPProtectionProfiles<2..2^16-1>;
+     *
+     * Note: srtp_mki is not supported
+     */
+
+    /* Min length is 5 : at least one protection profile(2 bytes) and length(2 bytes) + srtp_mki length(1 byte) */
+    if( len < 5 )
+        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+
+    /*
+     * Use our order of preference
+     */
+    profile_length = buf[0]<<8|buf[1]; /* first 2 bytes are protection profile length(in bytes) */
+    for( i=0; i < ssl->dtls_srtp_profiles_list_len; i++)
+    {
+        /* parse the extension list values are defined in http://www.iana.org/assignments/srtp-protection/srtp-protection.xhtml */
+        for (j=0; j<profile_length; j+=2) { /* parse only the protection profile, srtp_mki is not supported and ignored */
+            uint16_t protection_profile_value = buf[j+2]<<8 | buf[j+3]; /* +2 to skip the length field */
+
+            switch ( protection_profile_value ) {
+                case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80_IANA_VALUE:
+                    client_protection = MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80;
+                    break;
+                case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32_IANA_VALUE:
+                    client_protection = MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32;
+                    break;
+                case MBEDTLS_SRTP_NULL_HMAC_SHA1_80_IANA_VALUE:
+                    client_protection = MBEDTLS_SRTP_NULL_HMAC_SHA1_80;
+                    break;
+                case MBEDTLS_SRTP_NULL_HMAC_SHA1_32_IANA_VALUE:
+                    client_protection = MBEDTLS_SRTP_NULL_HMAC_SHA1_32;
+                    break;
+                default:
+                    client_protection = MBEDTLS_SRTP_UNSET_PROFILE;
+                    break;
+            }
+
+            if (client_protection == ssl->dtls_srtp_profiles_list[i]) {
+                ssl->chosen_dtls_srtp_profile = ssl->dtls_srtp_profiles_list[i];
+                return 0;
+            }
+        }
+    }
+
+    /* If we get there, no match was found */
+    ssl->chosen_dtls_srtp_profile = MBEDTLS_SRTP_UNSET_PROFILE;
+    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_DTLS_SRTP */
+
 /*
  * Auxiliary functions for ServerHello parsing and related actions
  */
@@ -1942,6 +2014,15 @@ static int ssl_parse_client_hello( mbedtls_ssl_context *ssl )
                 break;
 #endif /* MBEDTLS_SSL_SESSION_TICKETS */
 
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+            case MBEDTLS_TLS_EXT_USE_SRTP:
+                MBEDTLS_SSL_DEBUG_MSG( 3, ( "found use_srtp extension" ) );
+                ret = ssl_parse_use_srtp_ext( ssl, ext + 4, ext_size );
+                if ( ret != 0 )
+                    return( ret );
+                break;
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+
             default:
                 MBEDTLS_SSL_DEBUG_MSG( 3, ( "unknown extension found: %d (ignoring)",
                                ext_id ) );
@@ -2500,6 +2581,57 @@ static void ssl_write_alpn_ext( mbedtls_ssl_context *ssl,
 }
 #endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C */
 
+#if defined(MBEDTLS_SSL_DTLS_SRTP )
+static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
+                                unsigned char *buf, size_t *olen )
+{
+    if( ssl->chosen_dtls_srtp_profile == MBEDTLS_SRTP_UNSET_PROFILE )
+    {
+        *olen = 0;
+        return;
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding use_srtp extension" ) );
+
+    /* extension */
+    buf[0] = (unsigned char)( ( MBEDTLS_TLS_EXT_USE_SRTP >> 8 ) & 0xFF );
+    buf[1] = (unsigned char)( ( MBEDTLS_TLS_EXT_USE_SRTP      ) & 0xFF );
+    /* total length (5: only one profile(2 bytes) and length(2bytes) and srtp_mki not supported so zero length(1byte) ) */
+    buf[2] = 0x00;
+    buf[3] = 0x05;
+
+    /* protection profile length: 2 */
+    buf[4] = 0x00;
+    buf[5] = 0x02;
+    switch (ssl->chosen_dtls_srtp_profile) {
+        case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80:
+            buf[6] = (unsigned char)( ( MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80_IANA_VALUE >> 8) & 0xFF );
+            buf[7] = (unsigned char)( ( MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80_IANA_VALUE     ) & 0xFF );
+            break;
+        case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32:
+            buf[6] = (unsigned char)( ( MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32_IANA_VALUE >> 8) & 0xFF );
+            buf[7] = (unsigned char)( ( MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32_IANA_VALUE     ) & 0xFF );
+            break;
+        case MBEDTLS_SRTP_NULL_HMAC_SHA1_80:
+            buf[6] = (unsigned char)( ( MBEDTLS_SRTP_NULL_HMAC_SHA1_80_IANA_VALUE >> 8) & 0xFF );
+            buf[7] = (unsigned char)( ( MBEDTLS_SRTP_NULL_HMAC_SHA1_80_IANA_VALUE     ) & 0xFF );
+            break;
+        case MBEDTLS_SRTP_NULL_HMAC_SHA1_32:
+            buf[6] = (unsigned char)( ( MBEDTLS_SRTP_NULL_HMAC_SHA1_32_IANA_VALUE >> 8) & 0xFF );
+            buf[7] = (unsigned char)( ( MBEDTLS_SRTP_NULL_HMAC_SHA1_32_IANA_VALUE     ) & 0xFF );
+            break;
+        default:
+            *olen = 0;
+            return;
+            break;
+    }
+
+    buf[8] = 0x00; /* unsupported srtp_mki variable length vector set to 0 */
+
+    *olen = 9;
+}
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+
 #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
 static int ssl_write_hello_verify_request( mbedtls_ssl_context *ssl )
 {
@@ -2788,6 +2920,11 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl )
     ext_len += olen;
 #endif
 
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+    ssl_write_use_srtp_ext( ssl, p + 2 + ext_len, &olen);
+    ext_len += olen;
+#endif
+
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, total extension length: %d", ext_len ) );
 
     if( ext_len > 0 )
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 34953f2698d5..d739dfc719c7 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -871,6 +871,30 @@ 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->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_keys_len = 60;
+
+        ssl->dtls_srtp_keys = (unsigned char *)mbedtls_calloc(1, ssl->dtls_srtp_keys_len);
+
+        ret = handshake->tls_prf( session->master, 48, "EXTRACTOR-dtls_srtp",
+                        handshake->randbytes, 64, ssl->dtls_srtp_keys, ssl->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
      */
@@ -3859,6 +3883,14 @@ int mbedtls_ssl_setup( mbedtls_ssl_context *ssl,
 
     mbedtls_ssl_reset_in_out_pointers( ssl );
 
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+    ssl->dtls_srtp_profiles_list = NULL;
+    ssl->dtls_srtp_profiles_list_len = 0;
+    ssl->chosen_dtls_srtp_profile = MBEDTLS_SRTP_UNSET_PROFILE;
+    ssl->dtls_srtp_keys = NULL;
+    ssl->dtls_srtp_keys_len = 0;
+#endif
+
     if( ( ret = ssl_handshake_init( ssl ) ) != 0 )
         goto error;
 
@@ -4685,6 +4717,48 @@ const char *mbedtls_ssl_get_alpn_protocol( const mbedtls_ssl_context *ssl )
 }
 #endif /* MBEDTLS_SSL_ALPN */
 
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+int mbedtls_ssl_set_dtls_srtp_protection_profiles( mbedtls_ssl_context *ssl, const enum mbedtls_DTLS_SRTP_protection_profiles *profiles, size_t profiles_number)
+{
+    size_t i;
+    /* check in put validity : must be a list of profiles from enumeration */
+    /* maximum length is 4 as only 4 protection profiles are defined */
+    if (profiles_number>4) {
+            return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+    }
+
+    mbedtls_free(ssl->dtls_srtp_profiles_list);
+    ssl->dtls_srtp_profiles_list = (enum mbedtls_DTLS_SRTP_protection_profiles *)mbedtls_calloc(1, profiles_number*sizeof(enum mbedtls_DTLS_SRTP_protection_profiles));
+
+    for (i=0; i<profiles_number; i++) {
+        switch (profiles[i]) {
+            case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80:
+            case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32:
+            case MBEDTLS_SRTP_NULL_HMAC_SHA1_80:
+            case MBEDTLS_SRTP_NULL_HMAC_SHA1_32:
+                ssl->dtls_srtp_profiles_list[i] = profiles[i];
+                break;
+            default:
+                mbedtls_free(ssl->dtls_srtp_profiles_list);
+                ssl->dtls_srtp_profiles_list = NULL;
+                ssl->dtls_srtp_profiles_list_len = 0;
+                return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+        }
+    }
+
+    /* assign array length */
+    ssl->dtls_srtp_profiles_list_len = profiles_number;
+
+    return( 0 );
+}
+
+enum mbedtls_DTLS_SRTP_protection_profiles mbedtls_ssl_get_dtls_srtp_protection_profile( const mbedtls_ssl_context *ssl)
+{
+    return( ssl->chosen_dtls_srtp_profile);
+}
+
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+
 void mbedtls_ssl_conf_max_version( mbedtls_ssl_config *conf, int major, int minor )
 {
     conf->max_major_ver = major;
@@ -6782,6 +6856,11 @@ void mbedtls_ssl_free( mbedtls_ssl_context *ssl )
     mbedtls_free( ssl->cli_id );
 #endif
 
+#if defined (MBEDTLS_SSL_DTLS_SRTP)
+    mbedtls_free( ssl->dtls_srtp_profiles_list );
+    mbedtls_free( ssl->dtls_srtp_keys );
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= free" ) );
 
     /* Actually clear after last debug message */

From bbc057af735d5961183a7cbeb396673e43201e6e Mon Sep 17 00:00:00 2001
From: Johan Pascal <johan.pascal@belledonne-communications.com>
Date: Thu, 4 Feb 2016 22:07:32 +0100
Subject: [PATCH 02/63] Move available dtls srtp profile list to ssl_config

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 include/mbedtls/ssl.h | 16 +++++++++++-----
 library/ssl_cli.c     | 30 +++++++++++++++---------------
 library/ssl_srv.c     |  8 ++++----
 library/ssl_tls.c     | 24 +++++++++++++-----------
 4 files changed, 43 insertions(+), 35 deletions(-)

diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index 55eeb182fcfc..4ba83380bd83 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -1080,6 +1080,14 @@ struct mbedtls_ssl_config
     const char **alpn_list;         /*!< ordered list of protocols          */
 #endif
 
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+    /*
+     * use_srtp extension
+     */
+    enum mbedtls_DTLS_SRTP_protection_profiles *dtls_srtp_profiles_list; /*!< ordered list of supported srtp profile */
+    size_t dtls_srtp_profiles_list_len; /*!< number of supported profiles */
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+
     /*
      * Numerical settings (int then char)
      */
@@ -1325,9 +1333,7 @@ struct mbedtls_ssl_context
     /*
      * use_srtp extension
      */
-    enum mbedtls_DTLS_SRTP_protection_profiles *dtls_srtp_profiles_list; /*!< ordered list of supported srtp profile */
-    size_t dtls_srtp_profiles_list_len; /*!< number of supported profiles */
-    enum mbedtls_DTLS_SRTP_protection_profiles chosen_dtls_srtp_profile; /*!< negotiated profil */
+    enum mbedtls_DTLS_SRTP_protection_profiles chosen_dtls_srtp_profile; /*!< negotiated SRTP profile */
     unsigned char *dtls_srtp_keys; /*<! master keys and master salt for SRTP generated during handshake */
     size_t dtls_srtp_keys_len; /*<! length in bytes of master keys and master salt for SRTP generated during handshake */
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
@@ -3158,14 +3164,14 @@ const char *mbedtls_ssl_get_alpn_protocol( const mbedtls_ssl_context *ssl );
 /**
  * \brief                   Set the supported DTLS-SRTP protection profiles.
  *
- * \param ssl               SSL context
+ * \param ssl               SSL configuration
  * \param protos            List of supported protection profiles,
  *                          in decreasing preference order.
  * \param profiles_number   Number of supported profiles.
  *
  * \return         0 on success, or MBEDTLS_ERR_SSL_BAD_INPUT_DATA.
  */
-int mbedtls_ssl_set_dtls_srtp_protection_profiles( mbedtls_ssl_context *ssl, const enum mbedtls_DTLS_SRTP_protection_profiles *profiles, size_t profiles_number);
+int mbedtls_ssl_conf_dtls_srtp_protection_profiles( mbedtls_ssl_config *conf, const enum mbedtls_DTLS_SRTP_protection_profiles *profiles, size_t profiles_number);
 
 /**
  * \brief          Get the negotiated DTLS-SRTP Protection Profile.
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index f392c50dfa30..50bc5e39a40b 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -765,7 +765,7 @@ static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
 
     *olen = 0;
 
-    if( (ssl->dtls_srtp_profiles_list == NULL)  || (ssl->dtls_srtp_profiles_list_len == 0) )
+    if( (ssl->conf->dtls_srtp_profiles_list == NULL)  || (ssl->conf->dtls_srtp_profiles_list_len == 0) )
     {
         return;
     }
@@ -788,18 +788,18 @@ static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
      * Note: srtp_mki is not supported
      */
 
-    /* Extension length = 2bytes for profiles lenght, ssl->dtls_srtp_profiles_list_len*2 (each profile is 2 bytes length ) + 1 byte for the non implemented srtp_mki vector length (always 0) */
-    *p++ = (unsigned char)( ( ( 2 + 2*(ssl->dtls_srtp_profiles_list_len) + 1 ) >> 8 ) & 0xFF );
-    *p++ = (unsigned char)( ( ( 2 + 2*(ssl->dtls_srtp_profiles_list_len) + 1 )      ) & 0xFF );
+    /* Extension length = 2bytes for profiles lenght, ssl->conf->dtls_srtp_profiles_list_len*2 (each profile is 2 bytes length ) + 1 byte for the non implemented srtp_mki vector length (always 0) */
+    *p++ = (unsigned char)( ( ( 2 + 2*(ssl->conf->dtls_srtp_profiles_list_len) + 1 ) >> 8 ) & 0xFF );
+    *p++ = (unsigned char)( ( ( 2 + 2*(ssl->conf->dtls_srtp_profiles_list_len) + 1 )      ) & 0xFF );
 
 
-    /* protection profile length: 2*(ssl->dtls_srtp_profiles_list_len) */
-    *p++ = (unsigned char)( ( ( 2*(ssl->dtls_srtp_profiles_list_len) ) >> 8 ) & 0xFF );
-    *p++ = (unsigned char)( ( 2*(ssl->dtls_srtp_profiles_list_len) ) & 0xFF );
+    /* protection profile length: 2*(ssl->conf->dtls_srtp_profiles_list_len) */
+    *p++ = (unsigned char)( ( ( 2*(ssl->conf->dtls_srtp_profiles_list_len) ) >> 8 ) & 0xFF );
+    *p++ = (unsigned char)( ( 2*(ssl->conf->dtls_srtp_profiles_list_len) ) & 0xFF );
 
-    for( protection_profiles_index=0; protection_profiles_index < ssl->dtls_srtp_profiles_list_len; protection_profiles_index++ )
+    for( protection_profiles_index=0; protection_profiles_index < ssl->conf->dtls_srtp_profiles_list_len; protection_profiles_index++ )
     {
-        switch (ssl->dtls_srtp_profiles_list[protection_profiles_index]) {
+        switch (ssl->conf->dtls_srtp_profiles_list[protection_profiles_index]) {
             case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80:
                 *p++ = ( ( ( MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80_IANA_VALUE ) >> 8 ) & 0xFF);
                 *p++ = ( ( MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80_IANA_VALUE ) & 0xFF);
@@ -818,14 +818,14 @@ static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
                 break;
             default:
                 /* Note: we shall never arrive here as protection profiles is checked by ssl_set_dtls_srtp_protection_profiles function */
-                MBEDTLS_SSL_DEBUG_MSG( 1, ( "client hello, ignore illegal DTLS-SRTP protection profile %d",  ssl->dtls_srtp_profiles_list[protection_profiles_index]) );
+                MBEDTLS_SSL_DEBUG_MSG( 1, ( "client hello, ignore illegal DTLS-SRTP protection profile %d",  ssl->conf->dtls_srtp_profiles_list[protection_profiles_index]) );
                 break;
         }
     }
 
     *p++ = 0x00;  /* non implemented srtp_mki vector length is always 0 */
     /* total extension length: extension type (2 bytes) + extension length (2 bytes) + protection profile length (2 bytes) + 2*nb protection profiles + srtp_mki vector length(1 byte)*/
-    *olen = 2 + 2 + 2 + 2*(ssl->dtls_srtp_profiles_list_len) + 1;
+    *olen = 2 + 2 + 2 + 2*(ssl->conf->dtls_srtp_profiles_list_len) + 1;
 }
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
 
@@ -1797,7 +1797,7 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
     uint16_t server_protection_profile_value = 0;
 
     /* If use_srtp is not configured, just ignore the extension */
-    if( ( ssl->dtls_srtp_profiles_list == NULL ) || ( ssl->dtls_srtp_profiles_list_len == 0 ) )
+    if( ( ssl->conf->dtls_srtp_profiles_list == NULL ) || ( ssl->conf->dtls_srtp_profiles_list_len == 0 ) )
         return( 0 );
 
     /* RFC5764 section 4.1.1
@@ -1829,7 +1829,7 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
     /*
      * Check we have the server profile in our list
      */
-    for( i=0; i < ssl->dtls_srtp_profiles_list_len; i++)
+    for( i=0; i < ssl->conf->dtls_srtp_profiles_list_len; i++)
     {
         switch ( server_protection_profile_value ) {
             case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80_IANA_VALUE:
@@ -1849,8 +1849,8 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
                 break;
         }
 
-        if (server_protection == ssl->dtls_srtp_profiles_list[i]) {
-            ssl->chosen_dtls_srtp_profile = ssl->dtls_srtp_profiles_list[i];
+        if (server_protection == ssl->conf->dtls_srtp_profiles_list[i]) {
+            ssl->chosen_dtls_srtp_profile = ssl->conf->dtls_srtp_profiles_list[i];
             return 0;
         }
     }
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index a14ec8664091..ee2ae89bca3c 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -785,7 +785,7 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
     uint16_t profile_length;
 
     /* If use_srtp is not configured, just ignore the extension */
-    if( ( ssl->dtls_srtp_profiles_list == NULL ) || ( ssl->dtls_srtp_profiles_list_len == 0 ) )
+    if( ( ssl->conf->dtls_srtp_profiles_list == NULL ) || ( ssl->conf->dtls_srtp_profiles_list_len == 0 ) )
         return( 0 );
 
     /* RFC5764 section 4.1.1
@@ -809,7 +809,7 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
      * Use our order of preference
      */
     profile_length = buf[0]<<8|buf[1]; /* first 2 bytes are protection profile length(in bytes) */
-    for( i=0; i < ssl->dtls_srtp_profiles_list_len; i++)
+    for( i=0; i < ssl->conf->dtls_srtp_profiles_list_len; i++)
     {
         /* parse the extension list values are defined in http://www.iana.org/assignments/srtp-protection/srtp-protection.xhtml */
         for (j=0; j<profile_length; j+=2) { /* parse only the protection profile, srtp_mki is not supported and ignored */
@@ -833,8 +833,8 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
                     break;
             }
 
-            if (client_protection == ssl->dtls_srtp_profiles_list[i]) {
-                ssl->chosen_dtls_srtp_profile = ssl->dtls_srtp_profiles_list[i];
+            if (client_protection == ssl->conf->dtls_srtp_profiles_list[i]) {
+                ssl->chosen_dtls_srtp_profile = ssl->conf->dtls_srtp_profiles_list[i];
                 return 0;
             }
         }
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index d739dfc719c7..09a1409a6d20 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -3884,8 +3884,6 @@ int mbedtls_ssl_setup( mbedtls_ssl_context *ssl,
     mbedtls_ssl_reset_in_out_pointers( ssl );
 
 #if defined(MBEDTLS_SSL_DTLS_SRTP)
-    ssl->dtls_srtp_profiles_list = NULL;
-    ssl->dtls_srtp_profiles_list_len = 0;
     ssl->chosen_dtls_srtp_profile = MBEDTLS_SRTP_UNSET_PROFILE;
     ssl->dtls_srtp_keys = NULL;
     ssl->dtls_srtp_keys_len = 0;
@@ -4718,7 +4716,7 @@ const char *mbedtls_ssl_get_alpn_protocol( const mbedtls_ssl_context *ssl )
 #endif /* MBEDTLS_SSL_ALPN */
 
 #if defined(MBEDTLS_SSL_DTLS_SRTP)
-int mbedtls_ssl_set_dtls_srtp_protection_profiles( mbedtls_ssl_context *ssl, const enum mbedtls_DTLS_SRTP_protection_profiles *profiles, size_t profiles_number)
+int mbedtls_ssl_conf_dtls_srtp_protection_profiles( mbedtls_ssl_config *conf, const enum mbedtls_DTLS_SRTP_protection_profiles *profiles, size_t profiles_number)
 {
     size_t i;
     /* check in put validity : must be a list of profiles from enumeration */
@@ -4727,8 +4725,8 @@ int mbedtls_ssl_set_dtls_srtp_protection_profiles( mbedtls_ssl_context *ssl, con
             return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
     }
 
-    mbedtls_free(ssl->dtls_srtp_profiles_list);
-    ssl->dtls_srtp_profiles_list = (enum mbedtls_DTLS_SRTP_protection_profiles *)mbedtls_calloc(1, profiles_number*sizeof(enum mbedtls_DTLS_SRTP_protection_profiles));
+    mbedtls_free(conf->dtls_srtp_profiles_list);
+    conf->dtls_srtp_profiles_list = (enum mbedtls_DTLS_SRTP_protection_profiles *)mbedtls_calloc(1, profiles_number*sizeof(enum mbedtls_DTLS_SRTP_protection_profiles));
 
     for (i=0; i<profiles_number; i++) {
         switch (profiles[i]) {
@@ -4736,18 +4734,18 @@ int mbedtls_ssl_set_dtls_srtp_protection_profiles( mbedtls_ssl_context *ssl, con
             case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32:
             case MBEDTLS_SRTP_NULL_HMAC_SHA1_80:
             case MBEDTLS_SRTP_NULL_HMAC_SHA1_32:
-                ssl->dtls_srtp_profiles_list[i] = profiles[i];
+                conf->dtls_srtp_profiles_list[i] = profiles[i];
                 break;
             default:
-                mbedtls_free(ssl->dtls_srtp_profiles_list);
-                ssl->dtls_srtp_profiles_list = NULL;
-                ssl->dtls_srtp_profiles_list_len = 0;
+                mbedtls_free(conf->dtls_srtp_profiles_list);
+                conf->dtls_srtp_profiles_list = NULL;
+                conf->dtls_srtp_profiles_list_len = 0;
                 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
         }
     }
 
     /* assign array length */
-    ssl->dtls_srtp_profiles_list_len = profiles_number;
+    conf->dtls_srtp_profiles_list_len = profiles_number;
 
     return( 0 );
 }
@@ -6857,7 +6855,7 @@ void mbedtls_ssl_free( mbedtls_ssl_context *ssl )
 #endif
 
 #if defined (MBEDTLS_SSL_DTLS_SRTP)
-    mbedtls_free( ssl->dtls_srtp_profiles_list );
+    mbedtls_zeroize( ssl->dtls_srtp_keys, ssl->dtls_srtp_keys_len );
     mbedtls_free( ssl->dtls_srtp_keys );
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
 
@@ -7114,6 +7112,10 @@ void mbedtls_ssl_config_free( mbedtls_ssl_config *conf )
     ssl_key_cert_free( conf->key_cert );
 #endif
 
+#if defined (MBEDTLS_SSL_DTLS_SRTP)
+    mbedtls_free( conf->dtls_srtp_profiles_list );
+#endif
+
     mbedtls_platform_zeroize( conf, sizeof( mbedtls_ssl_config ) );
 }
 

From 2d9470be76fc4907635d1d973ae2f7cb6c2842b2 Mon Sep 17 00:00:00 2001
From: Johan Pascal <johan.pascal@belledonne-communications.com>
Date: Mon, 8 Feb 2016 22:35:41 +0100
Subject: [PATCH 03/63] Improve DTLS SRTP API with a dedicated function to get
 generated keys

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 include/mbedtls/ssl.h | 16 +++++++++++++++-
 library/ssl_tls.c     | 13 +++++++++++++
 2 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index 4ba83380bd83..cee2ba80f191 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -3180,9 +3180,23 @@ int mbedtls_ssl_conf_dtls_srtp_protection_profiles( mbedtls_ssl_config *conf, co
  *
  * \param ssl      SSL context
  *
- * \return         Protection Profile enum member, SRTP_UNSET_PROFILE if no protocol was negotiated.
+ * \return         Protection Profile enum member, MBEDTLS_SRTP_UNSET_PROFILE if no protocol was negotiated.
  */
 enum mbedtls_DTLS_SRTP_protection_profiles 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 80 bytes of key material generated according to RFC5764
+ *
+ * \param ssl              SSL context
+ * \param key              Buffer to hold the generated key material
+ * \param key_buffer_len   Length in bytes of the key buffer
+ * \param key_len          Actual length of data written in the key buffer
+ *
+ * \return         0 on succes, 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, const size_t key_buffer_len, size_t *key_len );
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
 
 /**
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 09a1409a6d20..2b9f78a94d7e 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -4755,6 +4755,19 @@ enum mbedtls_DTLS_SRTP_protection_profiles mbedtls_ssl_get_dtls_srtp_protection_
     return( ssl->chosen_dtls_srtp_profile);
 }
 
+int mbedtls_ssl_get_dtls_srtp_key_material( const mbedtls_ssl_context *ssl, unsigned char *key, const size_t key_buffer_len, size_t *key_len ) {
+    *key_len = 0;
+
+    /* check output buffer size */
+    if ( key_buffer_len < ssl->dtls_srtp_keys_len) {
+        return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
+    }
+
+    memcpy( key, ssl->dtls_srtp_keys, ssl->dtls_srtp_keys_len);
+    *key_len = ssl->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 )

From c28f1f600e238854827ef86da821d73e1fbec9b3 Mon Sep 17 00:00:00 2001
From: Johan Pascal <johan.pascal@belledonne-communications.com>
Date: Thu, 9 Feb 2017 08:55:16 +0700
Subject: [PATCH 04/63] Fix typos in documentation

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 include/mbedtls/ssl.h | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index cee2ba80f191..e93617c96a40 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -1334,8 +1334,8 @@ struct mbedtls_ssl_context
      * use_srtp extension
      */
     enum mbedtls_DTLS_SRTP_protection_profiles chosen_dtls_srtp_profile; /*!< negotiated SRTP profile */
-    unsigned char *dtls_srtp_keys; /*<! master keys and master salt for SRTP generated during handshake */
-    size_t dtls_srtp_keys_len; /*<! length in bytes of master keys and master salt for SRTP generated during handshake */
+    unsigned char *dtls_srtp_keys; /*!< master keys and master salt for SRTP generated during handshake */
+    size_t dtls_srtp_keys_len; /*!< length in bytes of master keys and master salt for SRTP generated during handshake */
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
 
     /*
@@ -3164,8 +3164,8 @@ const char *mbedtls_ssl_get_alpn_protocol( const mbedtls_ssl_context *ssl );
 /**
  * \brief                   Set the supported DTLS-SRTP protection profiles.
  *
- * \param ssl               SSL configuration
- * \param protos            List of supported protection profiles,
+ * \param conf              SSL configuration
+ * \param profiles          List of supported protection profiles,
  *                          in decreasing preference order.
  * \param profiles_number   Number of supported profiles.
  *

From 701984d3001573233f06fcc6c23577519fa03fed Mon Sep 17 00:00:00 2001
From: Johan Pascal <johan.pascal@belledonne-communications.com>
Date: Thu, 9 Feb 2017 09:56:05 +0700
Subject: [PATCH 05/63] Comply with mbedtls naming rules

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 include/mbedtls/ssl.h      | 14 ++++++++------
 library/ssl_cli.c          |  2 +-
 library/ssl_srv.c          |  2 +-
 library/ssl_tls.c          |  6 +++---
 library/version_features.c |  3 +++
 5 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index e93617c96a40..e3459cd566e1 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -865,13 +865,15 @@ typedef void mbedtls_ssl_async_cancel_t( mbedtls_ssl_context *ssl );
 /*
  * List of SRTP profiles for DTLS-SRTP
  */
-enum mbedtls_DTLS_SRTP_protection_profiles {
+typedef enum
+{
     MBEDTLS_SRTP_UNSET_PROFILE,
     MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80,
     MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32,
     MBEDTLS_SRTP_NULL_HMAC_SHA1_80,
     MBEDTLS_SRTP_NULL_HMAC_SHA1_32,
-};
+}
+mbedtls_dtls_srtp_protection_profiles;
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
 
 /*
@@ -1084,7 +1086,7 @@ struct mbedtls_ssl_config
     /*
      * use_srtp extension
      */
-    enum mbedtls_DTLS_SRTP_protection_profiles *dtls_srtp_profiles_list; /*!< ordered list of supported srtp profile */
+    mbedtls_dtls_srtp_protection_profiles *dtls_srtp_profiles_list; /*!< ordered list of supported srtp profile */
     size_t dtls_srtp_profiles_list_len; /*!< number of supported profiles */
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
 
@@ -1333,7 +1335,7 @@ struct mbedtls_ssl_context
     /*
      * use_srtp extension
      */
-    enum mbedtls_DTLS_SRTP_protection_profiles chosen_dtls_srtp_profile; /*!< negotiated SRTP profile */
+    mbedtls_dtls_srtp_protection_profiles chosen_dtls_srtp_profile; /*!< negotiated SRTP profile */
     unsigned char *dtls_srtp_keys; /*!< master keys and master salt for SRTP generated during handshake */
     size_t dtls_srtp_keys_len; /*!< length in bytes of master keys and master salt for SRTP generated during handshake */
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
@@ -3171,7 +3173,7 @@ const char *mbedtls_ssl_get_alpn_protocol( const mbedtls_ssl_context *ssl );
  *
  * \return         0 on success, or MBEDTLS_ERR_SSL_BAD_INPUT_DATA.
  */
-int mbedtls_ssl_conf_dtls_srtp_protection_profiles( mbedtls_ssl_config *conf, const enum mbedtls_DTLS_SRTP_protection_profiles *profiles, size_t profiles_number);
+int mbedtls_ssl_conf_dtls_srtp_protection_profiles( mbedtls_ssl_config *conf, const mbedtls_dtls_srtp_protection_profiles *profiles, size_t profiles_number);
 
 /**
  * \brief          Get the negotiated DTLS-SRTP Protection Profile.
@@ -3182,7 +3184,7 @@ int mbedtls_ssl_conf_dtls_srtp_protection_profiles( mbedtls_ssl_config *conf, co
  *
  * \return         Protection Profile enum member, MBEDTLS_SRTP_UNSET_PROFILE if no protocol was negotiated.
  */
-enum mbedtls_DTLS_SRTP_protection_profiles mbedtls_ssl_get_dtls_srtp_protection_profile( const mbedtls_ssl_context *ssl);
+mbedtls_dtls_srtp_protection_profiles mbedtls_ssl_get_dtls_srtp_protection_profile( const mbedtls_ssl_context *ssl);
 
 /**
  * \brief                  Get the generated DTLS-SRTP key material.
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index 50bc5e39a40b..a15bb30335bb 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -1792,7 +1792,7 @@ static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl,
 static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
                                const unsigned char *buf, size_t len )
 {
-    enum mbedtls_DTLS_SRTP_protection_profiles server_protection = MBEDTLS_SRTP_UNSET_PROFILE;
+    mbedtls_dtls_srtp_protection_profiles server_protection = MBEDTLS_SRTP_UNSET_PROFILE;
     size_t i;
     uint16_t server_protection_profile_value = 0;
 
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index ee2ae89bca3c..1336848e73a4 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -780,7 +780,7 @@ static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl,
 static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
                                const unsigned char *buf, size_t len )
 {
-    enum mbedtls_DTLS_SRTP_protection_profiles client_protection = MBEDTLS_SRTP_UNSET_PROFILE;
+    mbedtls_dtls_srtp_protection_profiles client_protection = MBEDTLS_SRTP_UNSET_PROFILE;
     size_t i,j;
     uint16_t profile_length;
 
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 2b9f78a94d7e..18ad5044626f 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -4716,7 +4716,7 @@ const char *mbedtls_ssl_get_alpn_protocol( const mbedtls_ssl_context *ssl )
 #endif /* MBEDTLS_SSL_ALPN */
 
 #if defined(MBEDTLS_SSL_DTLS_SRTP)
-int mbedtls_ssl_conf_dtls_srtp_protection_profiles( mbedtls_ssl_config *conf, const enum mbedtls_DTLS_SRTP_protection_profiles *profiles, size_t profiles_number)
+int mbedtls_ssl_conf_dtls_srtp_protection_profiles( mbedtls_ssl_config *conf, const mbedtls_dtls_srtp_protection_profiles *profiles, size_t profiles_number)
 {
     size_t i;
     /* check in put validity : must be a list of profiles from enumeration */
@@ -4726,7 +4726,7 @@ int mbedtls_ssl_conf_dtls_srtp_protection_profiles( mbedtls_ssl_config *conf, co
     }
 
     mbedtls_free(conf->dtls_srtp_profiles_list);
-    conf->dtls_srtp_profiles_list = (enum mbedtls_DTLS_SRTP_protection_profiles *)mbedtls_calloc(1, profiles_number*sizeof(enum mbedtls_DTLS_SRTP_protection_profiles));
+    conf->dtls_srtp_profiles_list = (mbedtls_dtls_srtp_protection_profiles *)mbedtls_calloc(1, profiles_number*sizeof(mbedtls_dtls_srtp_protection_profiles));
 
     for (i=0; i<profiles_number; i++) {
         switch (profiles[i]) {
@@ -4750,7 +4750,7 @@ int mbedtls_ssl_conf_dtls_srtp_protection_profiles( mbedtls_ssl_config *conf, co
     return( 0 );
 }
 
-enum mbedtls_DTLS_SRTP_protection_profiles mbedtls_ssl_get_dtls_srtp_protection_profile( const mbedtls_ssl_context *ssl)
+mbedtls_dtls_srtp_protection_profiles mbedtls_ssl_get_dtls_srtp_protection_profile( const mbedtls_ssl_context *ssl)
 {
     return( ssl->chosen_dtls_srtp_profile);
 }
diff --git a/library/version_features.c b/library/version_features.c
index 62b05537c9ee..42ccaf95407c 100644
--- a/library/version_features.c
+++ b/library/version_features.c
@@ -534,6 +534,9 @@ static const char * const features[] = {
 #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
     "MBEDTLS_SSL_DTLS_HELLO_VERIFY",
 #endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+    "MBEDTLS_SSL_DTLS_SRTP",
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
 #if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE)
     "MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE",
 #endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE */

From 34790789b67e0724b296130c85fde03ff1654afd Mon Sep 17 00:00:00 2001
From: Johan Pascal <johan.pascal@belledonne-communications.com>
Date: Thu, 9 Feb 2017 10:14:09 +0700
Subject: [PATCH 06/63] Remove compilation warning

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 library/ssl_srv.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index 1336848e73a4..caefaa5d62d7 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -2623,7 +2623,6 @@ static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
         default:
             *olen = 0;
             return;
-            break;
     }
 
     buf[8] = 0x00; /* unsupported srtp_mki variable length vector set to 0 */

From 3adb9928f32a1b94f012591f869ec60cd4188e73 Mon Sep 17 00:00:00 2001
From: Ron Eldor <Ron.Eldor@arm.com>
Date: Thu, 21 Dec 2017 10:15:08 +0200
Subject: [PATCH 07/63] Add mki value and some review comments

1. Add check for prerequisites in check_config.h
2. Add mki value to use_srtp extension
3. address some review comments

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 include/mbedtls/check_config.h |  4 +++
 include/mbedtls/ssl.h          | 36 ++++++++++++++++---------
 library/ssl_cli.c              | 49 +++++++++++++++++++++-------------
 library/ssl_srv.c              | 24 ++++++++---------
 library/ssl_tls.c              | 46 +++++++++++++++----------------
 5 files changed, 91 insertions(+), 68 deletions(-)

diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h
index 120c1d32f3ae..fd979db84e6a 100644
--- a/include/mbedtls/check_config.h
+++ b/include/mbedtls/check_config.h
@@ -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
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index e3459cd566e1..3c84bb7d0509 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -862,6 +862,9 @@ typedef void mbedtls_ssl_async_cancel_t( mbedtls_ssl_context *ssl );
           !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
 
 #if defined(MBEDTLS_SSL_DTLS_SRTP)
+
+#define MBEDTLS_DTLS_SRTP_MAX_KEY_MATERIAL_LENGTH    60
+#define MBEDTLS_DTLS_SRTP_MAX_MKI_LENGTH             255
 /*
  * List of SRTP profiles for DTLS-SRTP
  */
@@ -873,7 +876,17 @@ typedef enum
     MBEDTLS_SRTP_NULL_HMAC_SHA1_80,
     MBEDTLS_SRTP_NULL_HMAC_SHA1_32,
 }
-mbedtls_dtls_srtp_protection_profiles;
+mbedtls_ssl_srtp_profile;
+
+typedef struct mbedtls_dtls_srtp_info_t
+{
+    mbedtls_ssl_srtp_profile chosen_dtls_srtp_profile; /*!< negotiated SRTP profile */
+    unsigned char dtls_srtp_keys[MBEDTLS_DTLS_SRTP_MAX_KEY_MATERIAL_LENGTH]; /*!< master keys and master salt for SRTP generated during handshake */
+    size_t dtls_srtp_keys_len; /*!< length in bytes of master keys and master salt for SRTP generated during handshake */
+    unsigned char mki_value[MBEDTLS_DTLS_SRTP_MAX_MKI_LENGTH]; /* opaque srtp_mki<0..255> */
+    size_t                 mki_len;
+}mbedtls_dtls_srtp_info;
+
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
 
 /*
@@ -1083,11 +1096,8 @@ struct mbedtls_ssl_config
 #endif
 
 #if defined(MBEDTLS_SSL_DTLS_SRTP)
-    /*
-     * use_srtp extension
-     */
-    mbedtls_dtls_srtp_protection_profiles *dtls_srtp_profiles_list; /*!< ordered list of supported srtp profile */
-    size_t dtls_srtp_profiles_list_len; /*!< number of supported profiles */
+    mbedtls_ssl_srtp_profile *dtls_srtp_profile_list; /*!< ordered list of supported srtp profile */
+    size_t dtls_srtp_profile_list_len; /*!< number of supported profiles */
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
 
     /*
@@ -1170,9 +1180,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          */
@@ -1335,9 +1348,7 @@ struct mbedtls_ssl_context
     /*
      * use_srtp extension
      */
-    mbedtls_dtls_srtp_protection_profiles chosen_dtls_srtp_profile; /*!< negotiated SRTP profile */
-    unsigned char *dtls_srtp_keys; /*!< master keys and master salt for SRTP generated during handshake */
-    size_t dtls_srtp_keys_len; /*!< length in bytes of master keys and master salt for SRTP generated during handshake */
+    mbedtls_dtls_srtp_info dtls_srtp_info;
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
 
     /*
@@ -3173,8 +3184,7 @@ const char *mbedtls_ssl_get_alpn_protocol( const mbedtls_ssl_context *ssl );
  *
  * \return         0 on success, or MBEDTLS_ERR_SSL_BAD_INPUT_DATA.
  */
-int mbedtls_ssl_conf_dtls_srtp_protection_profiles( mbedtls_ssl_config *conf, const mbedtls_dtls_srtp_protection_profiles *profiles, size_t profiles_number);
-
+int mbedtls_ssl_conf_dtls_srtp_protection_profiles( mbedtls_ssl_config *conf, const mbedtls_ssl_srtp_profile *profiles, size_t profiles_number);
 /**
  * \brief          Get the negotiated DTLS-SRTP Protection Profile.
  *                 This function should be called after the handshake is
@@ -3184,7 +3194,7 @@ int mbedtls_ssl_conf_dtls_srtp_protection_profiles( mbedtls_ssl_config *conf, co
  *
  * \return         Protection Profile enum member, MBEDTLS_SRTP_UNSET_PROFILE if no protocol was negotiated.
  */
-mbedtls_dtls_srtp_protection_profiles mbedtls_ssl_get_dtls_srtp_protection_profile( const 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.
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index a15bb30335bb..17cd4828b30b 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -765,7 +765,7 @@ static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
 
     *olen = 0;
 
-    if( (ssl->conf->dtls_srtp_profiles_list == NULL)  || (ssl->conf->dtls_srtp_profiles_list_len == 0) )
+    if( (ssl->conf->dtls_srtp_profile_list == NULL)  || (ssl->conf->dtls_srtp_profile_list_len == 0) )
     {
         return;
     }
@@ -788,44 +788,52 @@ static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
      * Note: srtp_mki is not supported
      */
 
-    /* Extension length = 2bytes for profiles lenght, ssl->conf->dtls_srtp_profiles_list_len*2 (each profile is 2 bytes length ) + 1 byte for the non implemented srtp_mki vector length (always 0) */
-    *p++ = (unsigned char)( ( ( 2 + 2*(ssl->conf->dtls_srtp_profiles_list_len) + 1 ) >> 8 ) & 0xFF );
-    *p++ = (unsigned char)( ( ( 2 + 2*(ssl->conf->dtls_srtp_profiles_list_len) + 1 )      ) & 0xFF );
+    /* Extension length = 2bytes for profiles lenght, ssl->conf->dtls_srtp_profile_list_len*2 (each profile is 2 bytes length ) + 1 byte for the non implemented srtp_mki vector length (always 0) */
+    *p++ = (unsigned char)( ( ( 2 + 2*(ssl->conf->dtls_srtp_profile_list_len) + 1 ) >> 8 ) & 0xFF );
+    *p++ = (unsigned char)( ( ( 2 + 2*(ssl->conf->dtls_srtp_profile_list_len) + 1 )      ) & 0xFF );
 
 
-    /* protection profile length: 2*(ssl->conf->dtls_srtp_profiles_list_len) */
-    *p++ = (unsigned char)( ( ( 2*(ssl->conf->dtls_srtp_profiles_list_len) ) >> 8 ) & 0xFF );
-    *p++ = (unsigned char)( ( 2*(ssl->conf->dtls_srtp_profiles_list_len) ) & 0xFF );
+    /* protection profile length: 2*(ssl->conf->dtls_srtp_profile_list_len) */
+    *p++ = (unsigned char)( ( ( 2*(ssl->conf->dtls_srtp_profile_list_len) ) >> 8 ) & 0xFF );
+    *p++ = (unsigned char)( ( 2*(ssl->conf->dtls_srtp_profile_list_len) ) & 0xFF );
 
-    for( protection_profiles_index=0; protection_profiles_index < ssl->conf->dtls_srtp_profiles_list_len; protection_profiles_index++ )
+    for( protection_profiles_index=0; protection_profiles_index < ssl->conf->dtls_srtp_profile_list_len; protection_profiles_index++ )
     {
-        switch (ssl->conf->dtls_srtp_profiles_list[protection_profiles_index]) {
+        switch (ssl->conf->dtls_srtp_profile_list[protection_profiles_index]) {
             case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80:
+                MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_write_use_srtp_ext, add profile: %04x",
+                        MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80_IANA_VALUE ) );
                 *p++ = ( ( ( MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80_IANA_VALUE ) >> 8 ) & 0xFF);
                 *p++ = ( ( MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80_IANA_VALUE ) & 0xFF);
                 break;
             case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32:
+                MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_write_use_srtp_ext, add profile: %04x",
+                        MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32_IANA_VALUE ) );
                 *p++ = ( ( ( MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32_IANA_VALUE ) >> 8 ) & 0xFF);
                 *p++ = ( ( MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32_IANA_VALUE ) & 0xFF);
                 break;
             case MBEDTLS_SRTP_NULL_HMAC_SHA1_80:
+                MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_write_use_srtp_ext, add profile: %04x",
+                        MBEDTLS_SRTP_NULL_HMAC_SHA1_80_IANA_VALUE ) );
                 *p++ = ( ( ( MBEDTLS_SRTP_NULL_HMAC_SHA1_80_IANA_VALUE ) >> 8 ) & 0xFF);
                 *p++ = ( ( MBEDTLS_SRTP_NULL_HMAC_SHA1_80_IANA_VALUE ) & 0xFF);
                 break;
             case MBEDTLS_SRTP_NULL_HMAC_SHA1_32:
+                MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_write_use_srtp_ext, add profile: %04x",
+                        MBEDTLS_SRTP_NULL_HMAC_SHA1_32_IANA_VALUE ) );
                 *p++ = ( ( ( MBEDTLS_SRTP_NULL_HMAC_SHA1_32_IANA_VALUE ) >> 8 ) & 0xFF);
                 *p++ = ( ( MBEDTLS_SRTP_NULL_HMAC_SHA1_32_IANA_VALUE ) & 0xFF);
                 break;
             default:
                 /* Note: we shall never arrive here as protection profiles is checked by ssl_set_dtls_srtp_protection_profiles function */
-                MBEDTLS_SSL_DEBUG_MSG( 1, ( "client hello, ignore illegal DTLS-SRTP protection profile %d",  ssl->conf->dtls_srtp_profiles_list[protection_profiles_index]) );
+                MBEDTLS_SSL_DEBUG_MSG( 1, ( "client hello, ignore illegal DTLS-SRTP protection profile %d",  ssl->conf->dtls_srtp_profile_list[protection_profiles_index]) );
                 break;
         }
     }
 
     *p++ = 0x00;  /* non implemented srtp_mki vector length is always 0 */
     /* total extension length: extension type (2 bytes) + extension length (2 bytes) + protection profile length (2 bytes) + 2*nb protection profiles + srtp_mki vector length(1 byte)*/
-    *olen = 2 + 2 + 2 + 2*(ssl->conf->dtls_srtp_profiles_list_len) + 1;
+    *olen = 2 + 2 + 2 + 2*(ssl->conf->dtls_srtp_profile_list_len) + 1;
 }
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
 
@@ -1351,8 +1359,11 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
 #endif
 
 #if defined(MBEDTLS_SSL_DTLS_SRTP)
-    ssl_write_use_srtp_ext( ssl, p + 2 + ext_len, &olen );
-    ext_len += olen;
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    {
+        ssl_write_use_srtp_ext( ssl, p + 2 + ext_len, &olen );
+        ext_len += olen;
+    }
 #endif
 
 #if defined(MBEDTLS_SSL_SESSION_TICKETS)
@@ -1792,12 +1803,12 @@ static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl,
 static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
                                const unsigned char *buf, size_t len )
 {
-    mbedtls_dtls_srtp_protection_profiles server_protection = MBEDTLS_SRTP_UNSET_PROFILE;
+    mbedtls_ssl_srtp_profile server_protection = MBEDTLS_SRTP_UNSET_PROFILE;
     size_t i;
     uint16_t server_protection_profile_value = 0;
 
     /* If use_srtp is not configured, just ignore the extension */
-    if( ( ssl->conf->dtls_srtp_profiles_list == NULL ) || ( ssl->conf->dtls_srtp_profiles_list_len == 0 ) )
+    if( ( ssl->conf->dtls_srtp_profile_list == NULL ) || ( ssl->conf->dtls_srtp_profile_list_len == 0 ) )
         return( 0 );
 
     /* RFC5764 section 4.1.1
@@ -1829,7 +1840,7 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
     /*
      * Check we have the server profile in our list
      */
-    for( i=0; i < ssl->conf->dtls_srtp_profiles_list_len; i++)
+    for( i=0; i < ssl->conf->dtls_srtp_profile_list_len; i++)
     {
         switch ( server_protection_profile_value ) {
             case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80_IANA_VALUE:
@@ -1849,14 +1860,14 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
                 break;
         }
 
-        if (server_protection == ssl->conf->dtls_srtp_profiles_list[i]) {
-            ssl->chosen_dtls_srtp_profile = ssl->conf->dtls_srtp_profiles_list[i];
+        if (server_protection == ssl->conf->dtls_srtp_profile_list[i]) {
+            ssl->dtls_srtp_info.chosen_dtls_srtp_profile = ssl->conf->dtls_srtp_profile_list[i];
             return 0;
         }
     }
 
     /* If we get there, no match was found : server problem, it shall never answer with incompatible profile */
-    ssl->chosen_dtls_srtp_profile = MBEDTLS_SRTP_UNSET_PROFILE;
+    ssl->dtls_srtp_info.chosen_dtls_srtp_profile = MBEDTLS_SRTP_UNSET_PROFILE;
     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 );
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index caefaa5d62d7..68afcbaef702 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -780,12 +780,12 @@ static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl,
 static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
                                const unsigned char *buf, size_t len )
 {
-    mbedtls_dtls_srtp_protection_profiles client_protection = MBEDTLS_SRTP_UNSET_PROFILE;
+    mbedtls_ssl_srtp_profile client_protection = MBEDTLS_SRTP_UNSET_PROFILE;
     size_t i,j;
     uint16_t profile_length;
 
     /* If use_srtp is not configured, just ignore the extension */
-    if( ( ssl->conf->dtls_srtp_profiles_list == NULL ) || ( ssl->conf->dtls_srtp_profiles_list_len == 0 ) )
+    if( ( ssl->conf->dtls_srtp_profile_list == NULL ) || ( ssl->conf->dtls_srtp_profile_list_len == 0 ) )
         return( 0 );
 
     /* RFC5764 section 4.1.1
@@ -809,7 +809,7 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
      * Use our order of preference
      */
     profile_length = buf[0]<<8|buf[1]; /* first 2 bytes are protection profile length(in bytes) */
-    for( i=0; i < ssl->conf->dtls_srtp_profiles_list_len; i++)
+    for( i=0; i < ssl->conf->dtls_srtp_profile_list_len; i++)
     {
         /* parse the extension list values are defined in http://www.iana.org/assignments/srtp-protection/srtp-protection.xhtml */
         for (j=0; j<profile_length; j+=2) { /* parse only the protection profile, srtp_mki is not supported and ignored */
@@ -833,18 +833,18 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
                     break;
             }
 
-            if (client_protection == ssl->conf->dtls_srtp_profiles_list[i]) {
-                ssl->chosen_dtls_srtp_profile = ssl->conf->dtls_srtp_profiles_list[i];
+            if (client_protection == ssl->conf->dtls_srtp_profile_list[i]) {
+                ssl->dtls_srtp_info.chosen_dtls_srtp_profile = ssl->conf->dtls_srtp_profile_list[i];
                 return 0;
             }
         }
     }
 
     /* If we get there, no match was found */
-    ssl->chosen_dtls_srtp_profile = MBEDTLS_SRTP_UNSET_PROFILE;
-    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->dtls_srtp_info.chosen_dtls_srtp_profile = MBEDTLS_SRTP_UNSET_PROFILE;
+  //  mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+  //                          MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+    return( 0 );
 }
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
 
@@ -2581,11 +2581,11 @@ static void ssl_write_alpn_ext( mbedtls_ssl_context *ssl,
 }
 #endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C */
 
-#if defined(MBEDTLS_SSL_DTLS_SRTP )
+#if defined(MBEDTLS_SSL_DTLS_SRTP ) && defined(MBEDTLS_SSL_PROTO_DTLS)
 static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
                                 unsigned char *buf, size_t *olen )
 {
-    if( ssl->chosen_dtls_srtp_profile == MBEDTLS_SRTP_UNSET_PROFILE )
+    if( ssl->dtls_srtp_info.chosen_dtls_srtp_profile == MBEDTLS_SRTP_UNSET_PROFILE )
     {
         *olen = 0;
         return;
@@ -2603,7 +2603,7 @@ static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
     /* protection profile length: 2 */
     buf[4] = 0x00;
     buf[5] = 0x02;
-    switch (ssl->chosen_dtls_srtp_profile) {
+    switch (ssl->dtls_srtp_info.chosen_dtls_srtp_profile) {
         case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80:
             buf[6] = (unsigned char)( ( MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80_IANA_VALUE >> 8) & 0xFF );
             buf[7] = (unsigned char)( ( MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80_IANA_VALUE     ) & 0xFF );
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 18ad5044626f..48ddd9a6734d 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -873,19 +873,19 @@ static int ssl_populate_transform( mbedtls_ssl_transform *transform,
 
 #if defined(MBEDTLS_SSL_DTLS_SRTP)
     /* check if we have a chosen srtp protection profile */
-    if (ssl->chosen_dtls_srtp_profile != MBEDTLS_SRTP_UNSET_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_keys_len = 60;
+	ssl->dtls_srtp_info.dtls_srtp_keys_len = MBEDTLS_DTLS_SRTP_MAX_KEY_MATERIAL_LENGTH;
 
-        ssl->dtls_srtp_keys = (unsigned char *)mbedtls_calloc(1, ssl->dtls_srtp_keys_len);
+	//ssl->dtls_srtp_info.dtls_srtp_keys = (unsigned char *)mbedtls_calloc(1, ssl->dtls_srtp_info.dtls_srtp_keys_len);
 
-        ret = handshake->tls_prf( session->master, 48, "EXTRACTOR-dtls_srtp",
-                        handshake->randbytes, 64, ssl->dtls_srtp_keys, ssl->dtls_srtp_keys_len );
+	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 )
         {
@@ -3884,9 +3884,7 @@ int mbedtls_ssl_setup( mbedtls_ssl_context *ssl,
     mbedtls_ssl_reset_in_out_pointers( ssl );
 
 #if defined(MBEDTLS_SSL_DTLS_SRTP)
-    ssl->chosen_dtls_srtp_profile = MBEDTLS_SRTP_UNSET_PROFILE;
-    ssl->dtls_srtp_keys = NULL;
-    ssl->dtls_srtp_keys_len = 0;
+    memset( &ssl->dtls_srtp_info, 0, sizeof(ssl->dtls_srtp_info) );
 #endif
 
     if( ( ret = ssl_handshake_init( ssl ) ) != 0 )
@@ -4716,7 +4714,7 @@ const char *mbedtls_ssl_get_alpn_protocol( const mbedtls_ssl_context *ssl )
 #endif /* MBEDTLS_SSL_ALPN */
 
 #if defined(MBEDTLS_SSL_DTLS_SRTP)
-int mbedtls_ssl_conf_dtls_srtp_protection_profiles( mbedtls_ssl_config *conf, const mbedtls_dtls_srtp_protection_profiles *profiles, size_t profiles_number)
+int mbedtls_ssl_conf_dtls_srtp_protection_profiles( mbedtls_ssl_config *conf, const mbedtls_ssl_srtp_profile *profiles, size_t profiles_number)
 {
     size_t i;
     /* check in put validity : must be a list of profiles from enumeration */
@@ -4725,8 +4723,8 @@ int mbedtls_ssl_conf_dtls_srtp_protection_profiles( mbedtls_ssl_config *conf, co
             return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
     }
 
-    mbedtls_free(conf->dtls_srtp_profiles_list);
-    conf->dtls_srtp_profiles_list = (mbedtls_dtls_srtp_protection_profiles *)mbedtls_calloc(1, profiles_number*sizeof(mbedtls_dtls_srtp_protection_profiles));
+    mbedtls_free(conf->dtls_srtp_profile_list);
+    conf->dtls_srtp_profile_list = (mbedtls_ssl_srtp_profile *)mbedtls_calloc(1, profiles_number*sizeof(mbedtls_ssl_srtp_profile));
 
     for (i=0; i<profiles_number; i++) {
         switch (profiles[i]) {
@@ -4734,37 +4732,37 @@ int mbedtls_ssl_conf_dtls_srtp_protection_profiles( mbedtls_ssl_config *conf, co
             case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32:
             case MBEDTLS_SRTP_NULL_HMAC_SHA1_80:
             case MBEDTLS_SRTP_NULL_HMAC_SHA1_32:
-                conf->dtls_srtp_profiles_list[i] = profiles[i];
+                conf->dtls_srtp_profile_list[i] = profiles[i];
                 break;
             default:
-                mbedtls_free(conf->dtls_srtp_profiles_list);
-                conf->dtls_srtp_profiles_list = NULL;
-                conf->dtls_srtp_profiles_list_len = 0;
+                mbedtls_free(conf->dtls_srtp_profile_list);
+                conf->dtls_srtp_profile_list = NULL;
+                conf->dtls_srtp_profile_list_len = 0;
                 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
         }
     }
 
     /* assign array length */
-    conf->dtls_srtp_profiles_list_len = profiles_number;
+    conf->dtls_srtp_profile_list_len = profiles_number;
 
     return( 0 );
 }
 
-mbedtls_dtls_srtp_protection_profiles mbedtls_ssl_get_dtls_srtp_protection_profile( const mbedtls_ssl_context *ssl)
+mbedtls_ssl_srtp_profile mbedtls_ssl_get_dtls_srtp_protection_profile( const mbedtls_ssl_context *ssl)
 {
-    return( ssl->chosen_dtls_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, const size_t key_buffer_len, size_t *key_len ) {
     *key_len = 0;
 
     /* check output buffer size */
-    if ( key_buffer_len < ssl->dtls_srtp_keys_len) {
+    if ( key_buffer_len < ssl->dtls_srtp_info.dtls_srtp_keys_len) {
         return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
     }
 
-    memcpy( key, ssl->dtls_srtp_keys, ssl->dtls_srtp_keys_len);
-    *key_len = ssl->dtls_srtp_keys_len;
+    memcpy( key, ssl->dtls_srtp_info.dtls_srtp_keys, ssl->dtls_srtp_info.dtls_srtp_keys_len);
+    *key_len = ssl->dtls_srtp_info.dtls_srtp_keys_len;
 
     return 0;
 }
@@ -6868,8 +6866,8 @@ void mbedtls_ssl_free( mbedtls_ssl_context *ssl )
 #endif
 
 #if defined (MBEDTLS_SSL_DTLS_SRTP)
-    mbedtls_zeroize( ssl->dtls_srtp_keys, ssl->dtls_srtp_keys_len );
-    mbedtls_free( ssl->dtls_srtp_keys );
+    mbedtls_platform_zeroize( ssl->dtls_srtp_info.dtls_srtp_keys, ssl->dtls_srtp_info.dtls_srtp_keys_len );
+    //mbedtls_free( ssl->dtls_srtp_keys );
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
 
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= free" ) );
@@ -7126,7 +7124,7 @@ void mbedtls_ssl_config_free( mbedtls_ssl_config *conf )
 #endif
 
 #if defined (MBEDTLS_SSL_DTLS_SRTP)
-    mbedtls_free( conf->dtls_srtp_profiles_list );
+    mbedtls_free( conf->dtls_srtp_profile_list );
 #endif
 
     mbedtls_platform_zeroize( conf, sizeof( mbedtls_ssl_config ) );

From 591f162bed106f5a225de4f6e193f19f3565273d Mon Sep 17 00:00:00 2001
From: Ron Eldor <Ron.Eldor@arm.com>
Date: Mon, 22 Jan 2018 12:30:04 +0200
Subject: [PATCH 08/63] support mki value

Add support mki value in the DTLS-SRTP

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 include/mbedtls/ssl.h |  28 ++++++++++-
 library/ssl_cli.c     |  72 +++++++++++++++++++--------
 library/ssl_srv.c     | 111 +++++++++++++++++++++++++++---------------
 library/ssl_tls.c     |  18 +++++++
 4 files changed, 168 insertions(+), 61 deletions(-)

diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index 3c84bb7d0509..72ba687d395d 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -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.
@@ -1182,7 +1185,7 @@ struct mbedtls_ssl_config
 #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     */
+                                               in the use_srtp extension     */
 #endif
 };
 
@@ -3174,6 +3177,16 @@ const char *mbedtls_ssl_get_alpn_protocol( const mbedtls_ssl_context *ssl );
 #endif /* MBEDTLS_SSL_ALPN */
 
 #if defined(MBEDTLS_SSL_DTLS_SRTP)
+/**
+ * \brief          Add support for mki value in use_srtp extension
+ *                 (Default: MBEDTLS_SSL_DTLS_SRTP_MKI_UNSUPPORTED)
+ *
+ * \param conf     SSL configuration
+ * \param truncate Enable or disable (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.
  *
@@ -3185,6 +3198,17 @@ const char *mbedtls_ssl_get_alpn_protocol( const mbedtls_ssl_context *ssl );
  * \return         0 on success, or MBEDTLS_ERR_SSL_BAD_INPUT_DATA.
  */
 int mbedtls_ssl_conf_dtls_srtp_protection_profiles( mbedtls_ssl_config *conf, const mbedtls_ssl_srtp_profile *profiles, size_t profiles_number);
+
+/**
+ * \brief                   Set the mki_value for the current dtls session.
+ *
+ * \param ssl              SSL context
+ * \param mki_value        MKI value to set
+ * \param mki_len          MKI length
+ *
+ * \return         0 on success, MBEDTLS_ERR_SSL_BAD_INPUT_DATA or MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE
+ */
+int mbedtls_ssl_dtls_srtp_set_mki_value( mbedtls_ssl_context *ssl, unsigned char* mki_value, size_t mki_len );
 /**
  * \brief          Get the negotiated DTLS-SRTP Protection Profile.
  *                 This function should be called after the handshake is
@@ -3194,7 +3218,7 @@ int mbedtls_ssl_conf_dtls_srtp_protection_profiles( mbedtls_ssl_config *conf, co
  *
  * \return         Protection Profile enum member, MBEDTLS_SRTP_UNSET_PROFILE if no protocol was negotiated.
  */
-mbedtls_ssl_srtp_profile mbedtls_ssl_get_dtls_srtp_protection_profile( const 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.
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index 17cd4828b30b..8b9f2f0f7d82 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -762,6 +762,7 @@ static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
 {
     unsigned char *p = buf;
     size_t protection_profiles_index = 0;
+    size_t mki_len = 0, i;
 
     *olen = 0;
 
@@ -785,12 +786,15 @@ static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
 
      * SRTPProtectionProfile SRTPProtectionProfiles<2..2^16-1>;
      *
-     * Note: srtp_mki is not supported
      */
-
-    /* Extension length = 2bytes for profiles lenght, ssl->conf->dtls_srtp_profile_list_len*2 (each profile is 2 bytes length ) + 1 byte for the non implemented srtp_mki vector length (always 0) */
-    *p++ = (unsigned char)( ( ( 2 + 2*(ssl->conf->dtls_srtp_profile_list_len) + 1 ) >> 8 ) & 0xFF );
-    *p++ = (unsigned char)( ( ( 2 + 2*(ssl->conf->dtls_srtp_profile_list_len) + 1 )      ) & 0xFF );
+    if( ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED &&
+                ssl->dtls_srtp_info.mki_len != 0 )
+    {
+        mki_len = ssl->dtls_srtp_info.mki_len;
+    }
+    /* Extension length = 2bytes for profiles length, ssl->conf->dtls_srtp_profile_list_len*2 (each profile is 2 bytes length ) + 1 byte for srtp_mki vector length and the mki_len value */
+    *p++ = (unsigned char)( ( ( 2 + 2*(ssl->conf->dtls_srtp_profile_list_len) + 1 + mki_len ) >> 8 ) & 0xFF );
+    *p++ = (unsigned char)( ( ( 2 + 2*(ssl->conf->dtls_srtp_profile_list_len) + 1 + mki_len )      ) & 0xFF );
 
 
     /* protection profile length: 2*(ssl->conf->dtls_srtp_profile_list_len) */
@@ -831,9 +835,18 @@ static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
         }
     }
 
-    *p++ = 0x00;  /* non implemented srtp_mki vector length is always 0 */
+    *p++ = mki_len & 0xFF;
+
+    if( mki_len != 0 )
+    {
+        for( i=0; i < mki_len; i++ )
+        {
+            *p++ = ssl->dtls_srtp_info.mki_value[i];
+        }
+    }
+
     /* total extension length: extension type (2 bytes) + extension length (2 bytes) + protection profile length (2 bytes) + 2*nb protection profiles + srtp_mki vector length(1 byte)*/
-    *olen = 2 + 2 + 2 + 2*(ssl->conf->dtls_srtp_profile_list_len) + 1;
+    *olen = 2 + 2 + 2 + 2*( ssl->conf->dtls_srtp_profile_list_len ) + 1 + mki_len;
 }
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
 
@@ -1804,7 +1817,7 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
                                const unsigned char *buf, size_t len )
 {
     mbedtls_ssl_srtp_profile server_protection = MBEDTLS_SRTP_UNSET_PROFILE;
-    size_t i;
+    size_t i, mki_len = 0;
     uint16_t server_protection_profile_value = 0;
 
     /* If use_srtp is not configured, just ignore the extension */
@@ -1821,22 +1834,28 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
 
      * SRTPProtectionProfile SRTPProtectionProfiles<2..2^16-1>;
      *
-     * Note: srtp_mki is not supported
      */
+    if( ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED &&
+                ssl->dtls_srtp_info.mki_len != 0 )
+    {
+        mki_len = ssl->dtls_srtp_info.mki_len;
+    }
 
-    /* Length is 5 : one protection profile(2 bytes) + length(2 bytes) and potential srtp_mki which won't be parsed */
-    if( len < 5 )
+    /* Length is 5 and optional mki_value : one protection profile(2 bytes) + length(2 bytes) and srtp_mki */
+    if( ( len != 5 ) && ( len != ( 5 + mki_len ) ) )
         return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
 
     /*
      * get the server protection profile
      */
-    if (((uint16_t)(buf[0]<<8 | buf[1])) != 0x0002) { /* protection profile length must be 0x0002 as we must have only one protection profile in server Hello */
+    if (((uint16_t)( ( buf[0]<<8 ) | buf[1] ) ) != 0x0002) { /* protection profile length must be 0x0002 as we must have only one protection profile in server Hello */
         return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
     } else {
-        server_protection_profile_value = buf[2]<<8 | buf[3];
+        server_protection_profile_value = ( buf[2]<<8 ) | buf[3];
     }
 
+    ssl->dtls_srtp_info.chosen_dtls_srtp_profile = MBEDTLS_SRTP_UNSET_PROFILE;
+
     /*
      * Check we have the server profile in our list
      */
@@ -1862,15 +1881,30 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
 
         if (server_protection == ssl->conf->dtls_srtp_profile_list[i]) {
             ssl->dtls_srtp_info.chosen_dtls_srtp_profile = ssl->conf->dtls_srtp_profile_list[i];
-            return 0;
+            break;
         }
     }
 
-    /* If we get there, no match was found : server problem, it shall never answer with incompatible profile */
-    ssl->dtls_srtp_info.chosen_dtls_srtp_profile = MBEDTLS_SRTP_UNSET_PROFILE;
-    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 );
+    /* If no match was found : server problem, it shall never answer with incompatible profile */
+    if( ssl->dtls_srtp_info.chosen_dtls_srtp_profile == MBEDTLS_SRTP_UNSET_PROFILE )
+    {
+        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 );
+    }
+    /* RFC5764:
+     *  If the client detects a nonzero-length MKI in the server's response
+     *  that is different than the one the client offered, then the client
+     *  MUST abort the handshake and SHOULD send an invalid_parameter alert.
+     */
+    if( len > 5  &&
+        ( memcmp( ssl->dtls_srtp_info.mki_value, &buf[5], mki_len ) ) )
+    {
+        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 );
+    }
+    return 0;
 }
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
 
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index 68afcbaef702..f5229efb42d9 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -782,7 +782,7 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
 {
     mbedtls_ssl_srtp_profile client_protection = MBEDTLS_SRTP_UNSET_PROFILE;
     size_t i,j;
-    uint16_t profile_length;
+    size_t profile_length;
 
     /* If use_srtp is not configured, just ignore the extension */
     if( ( ssl->conf->dtls_srtp_profile_list == NULL ) || ( ssl->conf->dtls_srtp_profile_list_len == 0 ) )
@@ -798,53 +798,71 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
 
      * SRTPProtectionProfile SRTPProtectionProfiles<2..2^16-1>;
      *
-     * Note: srtp_mki is not supported
      */
 
     /* Min length is 5 : at least one protection profile(2 bytes) and length(2 bytes) + srtp_mki length(1 byte) */
     if( len < 5 )
         return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
 
-    /*
-     * Use our order of preference
-     */
-    profile_length = buf[0]<<8|buf[1]; /* first 2 bytes are protection profile length(in bytes) */
-    for( i=0; i < ssl->conf->dtls_srtp_profile_list_len; i++)
-    {
-        /* parse the extension list values are defined in http://www.iana.org/assignments/srtp-protection/srtp-protection.xhtml */
-        for (j=0; j<profile_length; j+=2) { /* parse only the protection profile, srtp_mki is not supported and ignored */
-            uint16_t protection_profile_value = buf[j+2]<<8 | buf[j+3]; /* +2 to skip the length field */
+   ssl->dtls_srtp_info.chosen_dtls_srtp_profile = MBEDTLS_SRTP_UNSET_PROFILE;
+
+    profile_length = ( buf[0]<<8 ) | buf[1]; /* first 2 bytes are protection profile length(in bytes) */
 
-            switch ( protection_profile_value ) {
-                case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80_IANA_VALUE:
-                    client_protection = MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80;
-                    break;
-                case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32_IANA_VALUE:
-                    client_protection = MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32;
-                    break;
-                case MBEDTLS_SRTP_NULL_HMAC_SHA1_80_IANA_VALUE:
-                    client_protection = MBEDTLS_SRTP_NULL_HMAC_SHA1_80;
-                    break;
-                case MBEDTLS_SRTP_NULL_HMAC_SHA1_32_IANA_VALUE:
-                    client_protection = MBEDTLS_SRTP_NULL_HMAC_SHA1_32;
-                    break;
-                default:
-                    client_protection = MBEDTLS_SRTP_UNSET_PROFILE;
-                    break;
-            }
 
-            if (client_protection == ssl->conf->dtls_srtp_profile_list[i]) {
+    /* parse the extension list values are defined in http://www.iana.org/assignments/srtp-protection/srtp-protection.xhtml */
+    for( j=0; j < profile_length; j+=2 )
+    {
+        uint16_t protection_profile_value = buf[j+2]<<8 | buf[j+3]; /* +2 to skip the length field */
+
+        switch ( protection_profile_value )
+        {
+            case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80_IANA_VALUE:
+                client_protection = MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80;
+                break;
+            case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32_IANA_VALUE:
+                client_protection = MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32;
+                break;
+            case MBEDTLS_SRTP_NULL_HMAC_SHA1_80_IANA_VALUE:
+                client_protection = MBEDTLS_SRTP_NULL_HMAC_SHA1_80;
+                break;
+            case MBEDTLS_SRTP_NULL_HMAC_SHA1_32_IANA_VALUE:
+                client_protection = MBEDTLS_SRTP_NULL_HMAC_SHA1_32;
+                break;
+            default:
+                client_protection = MBEDTLS_SRTP_UNSET_PROFILE;
+                break;
+        }
+        /* check if suggested profile is in our list */
+        for( i=0; i < ssl->conf->dtls_srtp_profile_list_len; i++)
+        {
+            if( client_protection == ssl->conf->dtls_srtp_profile_list[i] )
+            {
                 ssl->dtls_srtp_info.chosen_dtls_srtp_profile = ssl->conf->dtls_srtp_profile_list[i];
-                return 0;
+                break;
             }
         }
+        if( ssl->dtls_srtp_info.chosen_dtls_srtp_profile != MBEDTLS_SRTP_UNSET_PROFILE )
+            break;
     }
+    if( ( ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED ) &&
+          ( len > ( profile_length + 2 ) ) )
+    {
+        ssl->dtls_srtp_info.mki_len = buf[ profile_length + 2 ];
+        if( ssl->dtls_srtp_info.mki_len > MBEDTLS_DTLS_SRTP_MAX_MKI_LENGTH )
+        {
+            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                            MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+            ssl->dtls_srtp_info.mki_len = 0;
+            return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+        }
 
-    /* If we get there, no match was found */
-    ssl->dtls_srtp_info.chosen_dtls_srtp_profile = MBEDTLS_SRTP_UNSET_PROFILE;
-  //  mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-  //                          MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
-    return( 0 );
+        for( i=0; i < ssl->dtls_srtp_info.mki_len; i++ )
+        {
+            ssl->dtls_srtp_info.mki_value[i] = buf[ profile_length + 2 + i ];
+        }
+    }
+
+     return( 0 );
 }
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
 
@@ -2585,6 +2603,8 @@ static void ssl_write_alpn_ext( mbedtls_ssl_context *ssl,
 static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
                                 unsigned char *buf, size_t *olen )
 {
+    size_t mki_len = 0, ext_len = 0, i;
+
     if( ssl->dtls_srtp_info.chosen_dtls_srtp_profile == MBEDTLS_SRTP_UNSET_PROFILE )
     {
         *olen = 0;
@@ -2593,12 +2613,19 @@ static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
 
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding use_srtp extension" ) );
 
+    if( ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED &&
+                ssl->dtls_srtp_info.mki_len != 0 )
+    {
+        mki_len = ssl->dtls_srtp_info.mki_len;
+    }
+
     /* extension */
     buf[0] = (unsigned char)( ( MBEDTLS_TLS_EXT_USE_SRTP >> 8 ) & 0xFF );
     buf[1] = (unsigned char)( ( MBEDTLS_TLS_EXT_USE_SRTP      ) & 0xFF );
-    /* total length (5: only one profile(2 bytes) and length(2bytes) and srtp_mki not supported so zero length(1byte) ) */
-    buf[2] = 0x00;
-    buf[3] = 0x05;
+    /* total length 5 and mki value: only one profile(2 bytes) and length(2 bytes) and srtp_mki  ) */
+    ext_len = 5 + mki_len;
+    buf[2] = (unsigned char)( ( ext_len >> 8 ) & 0xFF );
+    buf[3] = (unsigned char)( ext_len & 0xFF );
 
     /* protection profile length: 2 */
     buf[4] = 0x00;
@@ -2625,9 +2652,13 @@ static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
             return;
     }
 
-    buf[8] = 0x00; /* unsupported srtp_mki variable length vector set to 0 */
+    buf[8] = mki_len & 0xFF;
+    for( i=0; i < mki_len; i++ )
+    {
+        buf[ 9 + i ] = ssl->dtls_srtp_info.mki_value[i];
+    }
 
-    *olen = 9;
+    *olen = 9 + mki_len;
 }
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
 
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 48ddd9a6734d..ecdd4f636ae4 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -4714,6 +4714,24 @@ const char *mbedtls_ssl_get_alpn_protocol( const mbedtls_ssl_context *ssl )
 #endif /* MBEDTLS_SSL_ALPN */
 
 #if defined(MBEDTLS_SSL_DTLS_SRTP)
+void mbedtls_ssl_conf_srtp_mki_value_supported( mbedtls_ssl_config *conf, int support_mki_value )
+{
+    conf->dtls_srtp_mki_support = support_mki_value;
+}
+
+int mbedtls_ssl_dtls_srtp_set_mki_value( mbedtls_ssl_context *ssl, unsigned char* mki_value, size_t mki_len )
+{
+    if ( mki_len > MBEDTLS_DTLS_SRTP_MAX_MKI_LENGTH )
+        return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+
+    if( ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_UNSUPPORTED )
+        return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
+
+    memcpy( ssl->dtls_srtp_info.mki_value, mki_value, mki_len );
+    ssl->dtls_srtp_info.mki_len = mki_len;
+    return 0;
+}
+
 int mbedtls_ssl_conf_dtls_srtp_protection_profiles( mbedtls_ssl_config *conf, const mbedtls_ssl_srtp_profile *profiles, size_t profiles_number)
 {
     size_t i;

From a37326abb1d39346ea134351405e1e3935c87733 Mon Sep 17 00:00:00 2001
From: Ron Eldor <Ron.Eldor@arm.com>
Date: Thu, 29 Mar 2018 18:26:30 +0300
Subject: [PATCH 09/63] Make keyu material length in \ out

Make the key material length in mbedtls_ssl_get_dtls_srtp_key_material
to be in\out, like it is done all over the library

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 include/mbedtls/ssl.h | 2 +-
 library/ssl_tls.c     | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index 72ba687d395d..de92897f523e 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -3232,7 +3232,7 @@ mbedtls_ssl_srtp_profile mbedtls_ssl_get_dtls_srtp_protection_profile( const mbe
  *
  * \return         0 on succes, 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, const size_t key_buffer_len, size_t *key_len );
+int mbedtls_ssl_get_dtls_srtp_key_material( const mbedtls_ssl_context *ssl, unsigned char *key, size_t *key_len );
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
 
 /**
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index ecdd4f636ae4..9f55db4394bc 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -4771,11 +4771,11 @@ mbedtls_ssl_srtp_profile mbedtls_ssl_get_dtls_srtp_protection_profile( const mbe
     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, const size_t key_buffer_len, size_t *key_len ) {
+int mbedtls_ssl_get_dtls_srtp_key_material( const mbedtls_ssl_context *ssl, unsigned char *key, size_t *key_len ) {
     *key_len = 0;
 
     /* check output buffer size */
-    if ( key_buffer_len < ssl->dtls_srtp_info.dtls_srtp_keys_len) {
+    if ( *key_len < ssl->dtls_srtp_info.dtls_srtp_keys_len) {
         return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
     }
 

From 349877e9480ccdda729c399a515df0075bb251d3 Mon Sep 17 00:00:00 2001
From: Ron Eldor <Ron.Eldor@arm.com>
Date: Thu, 29 Mar 2018 18:35:09 +0300
Subject: [PATCH 10/63] Fix idetifier check script error

Fix script error for identifier check

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 include/mbedtls/ssl.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index de92897f523e..d37b390a26d6 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -888,7 +888,8 @@ typedef struct mbedtls_dtls_srtp_info_t
     size_t dtls_srtp_keys_len; /*!< length in bytes of master keys and master salt for SRTP generated during handshake */
     unsigned char mki_value[MBEDTLS_DTLS_SRTP_MAX_MKI_LENGTH]; /* opaque srtp_mki<0..255> */
     size_t                 mki_len;
-}mbedtls_dtls_srtp_info;
+}
+mbedtls_dtls_srtp_info;
 
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
 

From 9e9096476e96226549468b9dc632609f74190675 Mon Sep 17 00:00:00 2001
From: Ron Eldor <Ron.Eldor@arm.com>
Date: Sun, 1 Apr 2018 17:35:07 +0300
Subject: [PATCH 11/63] Fix doxygen script errors

Fix errors raised by doxygen.sh test script

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 include/mbedtls/ssl.h | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index d37b390a26d6..83f2f425f5a1 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -3179,11 +3179,11 @@ const char *mbedtls_ssl_get_alpn_protocol( const mbedtls_ssl_context *ssl );
 
 #if defined(MBEDTLS_SSL_DTLS_SRTP)
 /**
- * \brief          Add support for mki value in use_srtp extension
- *                 (Default: MBEDTLS_SSL_DTLS_SRTP_MKI_UNSUPPORTED)
+ * \brief                   Add support for mki value in use_srtp extension
+ *                          (Default: MBEDTLS_SSL_DTLS_SRTP_MKI_UNSUPPORTED)
  *
- * \param conf     SSL configuration
- * \param truncate Enable or disable (MBEDTLS_SSL_DTLS_SRTP_MKI_UNSUPPORTED or
+ * \param conf              SSL configuration
+ * \param support_mki_value Enable or disable (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 );
@@ -3228,8 +3228,7 @@ mbedtls_ssl_srtp_profile mbedtls_ssl_get_dtls_srtp_protection_profile( const mbe
  *
  * \param ssl              SSL context
  * \param key              Buffer to hold the generated key material
- * \param key_buffer_len   Length in bytes of the key buffer
- * \param key_len          Actual length of data written in the key buffer
+ * \param key_len          [in/out] key buffer size. outputs the actual number of bytes written
  *
  * \return         0 on succes, MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL if the key buffer is too small to hold the generated key
  */

From 57cc70ec8193ee7a118d852c425b2551c0b22588 Mon Sep 17 00:00:00 2001
From: Ron Eldor <Ron.Eldor@arm.com>
Date: Mon, 2 Apr 2018 18:25:16 +0300
Subject: [PATCH 12/63] Enforce SRTP mandatory HS messages

Enforce CertificateRequest, client and server Certificates, and
CertificateVerify messages, which are mandatory in DTLS-SRTP,
as defined in RFC 5764 section 4.1

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 library/ssl_cli.c | 32 +++++++++++++++++++++++++++-----
 library/ssl_srv.c | 23 +++++++++++++++++++++--
 library/ssl_tls.c | 33 +++++++++++++++++++++++++++------
 3 files changed, 75 insertions(+), 13 deletions(-)

diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index 8b9f2f0f7d82..c7798eb0e217 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -3454,8 +3454,20 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
 
     if( ssl->client_auth == 0 )
     {
-        /* Current message is probably the ServerHelloDone */
-        ssl->keep_current_message = 1;
+#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 ) {
+            ret = MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
+        }
+        else
+        {
+#endif
+            /* MBEDTLS_SSL_DTLS_SRTP */
+            /* Current message is probably the ServerHelloDone */
+            ssl->keep_current_message = 1;
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+        }
+#endif
         goto exit;
     }
 
@@ -4102,9 +4114,19 @@ static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
 
     if( ssl->client_auth == 0 || mbedtls_ssl_own_cert( ssl ) == NULL )
     {
-        MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
-        ssl->state++;
-        return( 0 );
+#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 ) {
+            return ( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
+        }
+        else
+        {
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+            ssl->state++;
+            return( 0 );
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+        }
+#endif
     }
 
     if( mbedtls_ssl_own_key( ssl ) == NULL )
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index f5229efb42d9..1f497aea520d 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -3018,14 +3018,33 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
     if( ssl->handshake->sni_authmode != MBEDTLS_SSL_VERIFY_UNSET )
         authmode = ssl->handshake->sni_authmode;
     else
+#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 ) {
+        authmode = MBEDTLS_SSL_VERIFY_REQUIRED;
+    }
+        else
 #endif
         authmode = ssl->conf->authmode;
 
     if( !mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) ||
         authmode == MBEDTLS_SSL_VERIFY_NONE )
     {
-        MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate request" ) );
-        return( 0 );
+#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 ) {
+            MBEDTLS_SSL_DEBUG_MSG( 2, ( "should not happen" ) );
+            return ( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
+        }
+        else
+        {
+#endif
+            MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate request" ) );
+            return( 0 );
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+        }
+#endif
     }
 
     /*
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 9f55db4394bc..987b33024e82 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -873,7 +873,7 @@ static int ssl_populate_transform( mbedtls_ssl_transform *transform,
 
 #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) {
+    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
@@ -2112,9 +2112,20 @@ int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl )
 
     if( !mbedtls_ssl_ciphersuite_uses_srv_cert( ciphersuite_info ) )
     {
-        MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) );
-        ssl->state++;
-        return( 0 );
+#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 ) {
+            return ( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
+        }
+        else
+        {
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+            MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) );
+            ssl->state++;
+            return( 0 );
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+        }
+#endif
     }
 
 #if defined(MBEDTLS_SSL_CLI_C)
@@ -2739,9 +2750,20 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
 #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
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+                       : ssl->dtls_srtp_info.chosen_dtls_srtp_profile !=
+                               MBEDTLS_SRTP_UNSET_PROFILE
+                       ? MBEDTLS_SSL_VERIFY_REQUIRED
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
                        : ssl->conf->authmode;
 #else
-    const int authmode = ssl->conf->authmode;
+    const int authmode =
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+            ssl->dtls_srtp_info.chosen_dtls_srtp_profile !=
+                                           MBEDTLS_SRTP_UNSET_PROFILE ?
+                         MBEDTLS_SSL_VERIFY_REQUIRED :
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+            ssl->conf->authmode;
 #endif
     void *rs_ctx = NULL;
     mbedtls_x509_crt *chain = NULL;
@@ -4772,7 +4794,6 @@ mbedtls_ssl_srtp_profile mbedtls_ssl_get_dtls_srtp_protection_profile( const mbe
 }
 
 int mbedtls_ssl_get_dtls_srtp_key_material( const mbedtls_ssl_context *ssl, unsigned char *key, size_t *key_len ) {
-    *key_len = 0;
 
     /* check output buffer size */
     if ( *key_len < ssl->dtls_srtp_info.dtls_srtp_keys_len) {

From 4cbe69332ab1d79f94b32c2b68afbba664537126 Mon Sep 17 00:00:00 2001
From: Ron Eldor <Ron.Eldor@arm.com>
Date: Tue, 3 Apr 2018 18:29:25 +0300
Subject: [PATCH 13/63] Add ChangeLog

Add ChangLog item, describing the feature

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 ChangeLog | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index 594c3cf4a4cc..69e094ce4497 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -730,6 +730,10 @@ Changes
    * Ciphersuites based on 3DES now have the lowest priority by default when
      they are enabled.
 
+Features
+   * Add support for DTLS-SRTP as defined in RFC 5764. Based on contribution done
+     by Johan Pascal in #361.
+
 = mbed TLS 2.16.0 branch released 2018-12-21
 
 Features

From 9d36d311e3adddabdabdc6bfa839c45d3e958158 Mon Sep 17 00:00:00 2001
From: Ron Eldor <Ron.Eldor@arm.com>
Date: Sun, 1 Jul 2018 15:27:22 +0300
Subject: [PATCH 14/63] Fix failure in ssl-opts.sh

Return a debg message that was removed in previous commit,
Whic is searched in the ssl-opts.sh test.

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 library/ssl_cli.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index c7798eb0e217..4073f89bd721 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -4122,6 +4122,7 @@ static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
         else
         {
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
+            MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
             ssl->state++;
             return( 0 );
 #if defined(MBEDTLS_SSL_DTLS_SRTP)

From 6ea64518ad7d7a1d52b3d4a8f3d07a2b4b7047dd Mon Sep 17 00:00:00 2001
From: Ron Eldor <Ron.Eldor@arm.com>
Date: Mon, 2 Jul 2018 10:08:07 +0300
Subject: [PATCH 15/63] Add dtls-srtp to client and server examples

Add dtls-srtp to `ssl_client2` and `ssl_server2` examples,
for reference and for allowing in tests.

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 programs/ssl/ssl_client2.c | 91 ++++++++++++++++++++++++++++++++++++-
 programs/ssl/ssl_server2.c | 92 +++++++++++++++++++++++++++++++++++++-
 2 files changed, 180 insertions(+), 3 deletions(-)

diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index b9047df1d190..d9d5cad36c90 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -150,6 +150,9 @@ int main( void )
 #define DFL_NSS_KEYLOG_FILE     NULL
 #define DFL_SKIP_CLOSE_NOTIFY   0
 #define DFL_QUERY_CONFIG_MODE   0
+#define DFL_USE_SRTP            0
+#define DFL_SRTP_FORCE_PROFILE  MBEDTLS_SRTP_UNSET_PROFILE
+#define DFL_SRTP_MKI            ""
 
 #define GET_REQUEST "GET %s HTTP/1.0\r\nExtra-header: "
 #define GET_REQUEST_END "\r\n\r\n"
@@ -321,6 +324,20 @@ 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"
@@ -407,6 +424,7 @@ int main( void )
     "\n"                                                    \
     USAGE_DTLS                                              \
     USAGE_CID                                               \
+    USAGE_SRTP                                              \
     "\n"
 #define USAGE2 \
     "    auth_mode=%%s        default: (library default: none)\n" \
@@ -541,6 +559,9 @@ struct options
     int reproducible;           /* make communication reproducible          */
     int skip_close_notify;      /* skip sending the close_notify alert      */
     int query_config_mode;      /* whether to read config                   */
+    int use_srtp;               /* Support SRTP                             */
+    int force_srtp_profile;     /* SRTP protection profile to use or all    */
+    const char* mki;            /* The dtls mki value to use                */
 } opt;
 
 int query_config( const char *config );
@@ -1134,6 +1155,10 @@ int main( int argc, char *argv[] )
     mbedtls_ecp_group_id curve_list[CURVE_LIST_SIZE];
     const mbedtls_ecp_curve_info *curve_cur;
 #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";
 
@@ -1304,6 +1329,9 @@ int main( int argc, char *argv[] )
     opt.nss_keylog_file     = DFL_NSS_KEYLOG_FILE;
     opt.skip_close_notify   = DFL_SKIP_CLOSE_NOTIFY;
     opt.query_config_mode   = DFL_QUERY_CONFIG_MODE;
+    opt.use_srtp            = DFL_USE_SRTP;
+    opt.force_srtp_profile  = DFL_SRTP_FORCE_PROFILE;
+    opt.mki                 = DFL_SRTP_MKI;
 
     for( i = 1; i < argc; i++ )
     {
@@ -1729,6 +1757,18 @@ int main( int argc, char *argv[] )
             opt.skip_close_notify = atoi( q );
             if( opt.skip_close_notify < 0 || opt.skip_close_notify > 1 )
                 goto usage;
+	}
+        else if( strcmp( p, "use_srtp" ) == 0 )
+        {
+            opt.use_srtp = atoi ( q );
+        }
+        else if( strcmp( p, "srtp_force_profile" ) == 0 )
+        {
+            opt.force_srtp_profile = atoi( q );
+        }
+        else if( strcmp( p, "mki" ) == 0 )
+        {
+            opt.mki = q;
         }
         else
             goto usage;
@@ -1837,7 +1877,6 @@ int main( int argc, char *argv[] )
             opt.arc4 = MBEDTLS_SSL_ARC4_ENABLED;
         }
 
-
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
         if( opt.psk_opaque != 0 )
         {
@@ -2240,6 +2279,37 @@ int main( int argc, char *argv[] )
     }
 #endif
 
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+    if( opt.use_srtp != DFL_USE_SRTP )
+    {
+        if( opt.force_srtp_profile != DFL_SRTP_FORCE_PROFILE )
+        {
+            const mbedtls_ssl_srtp_profile forced_profile[] = { opt.force_srtp_profile };
+            ret = mbedtls_ssl_conf_dtls_srtp_protection_profiles( &conf, forced_profile, sizeof( forced_profile ) / sizeof( mbedtls_ssl_srtp_profile ) );
+        }
+        else
+        {
+            const mbedtls_ssl_srtp_profile default_profiles[] = { MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80,
+                                                                  MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32,
+                                                                  MBEDTLS_SRTP_NULL_HMAC_SHA1_80,
+                                                                  MBEDTLS_SRTP_NULL_HMAC_SHA1_32 };
+            ret = mbedtls_ssl_conf_dtls_srtp_protection_profiles( &conf, default_profiles, sizeof( default_profiles ) / sizeof( mbedtls_ssl_srtp_profile ) );
+        }
+
+        if( ret != 0 )
+        {
+            mbedtls_printf( " failed\n  ! mbedtls_ssl_conf_dtls_srtp_protection_profiles returned %d\n\n", ret );
+            goto exit;
+        }
+
+    }
+    else if( opt.force_srtp_profile != DFL_SRTP_FORCE_PROFILE )
+    {
+        mbedtls_printf( " failed\n  ! must enable use_srtp to force srtp profile\n\n" );
+        goto exit;
+    }
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+
 #if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
     if( opt.trunc_hmac != DFL_TRUNC_HMAC )
         mbedtls_ssl_conf_truncated_hmac( &conf, opt.trunc_hmac );
@@ -2476,6 +2546,25 @@ int main( int argc, char *argv[] )
         mbedtls_ecp_set_max_ops( opt.ec_max_ops );
 #endif
 
+    #if defined(MBEDTLS_SSL_DTLS_SRTP)
+    if( opt.use_srtp != DFL_USE_SRTP &&  strlen( opt.mki ) != 0 )
+    {
+        if( mbedtls_test_unhexify( mki, sizeof( mki ),
+                                   opt.mki,&mki_len ) != 0 )
+        {
+            mbedtls_printf( "mki value not valid hex\n" );
+             goto exit;
+        }
+
+        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 )
+        {
+            mbedtls_printf( " failed\n  ! mbedtls_ssl_dtls_srtp_set_mki_value returned %d\n\n", ret );
+            goto exit;
+        }
+    }
+#endif
+
     mbedtls_printf( " ok\n" );
 
     /*
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index a98aec1191eb..be45e54634d3 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -183,6 +183,9 @@ int main( void )
 #define DFL_NSS_KEYLOG          0
 #define DFL_NSS_KEYLOG_FILE     NULL
 #define DFL_QUERY_CONFIG_MODE   0
+#define DFL_USE_SRTP            0
+#define DFL_SRTP_FORCE_PROFILE  MBEDTLS_SRTP_UNSET_PROFILE
+#define DFL_SRTP_MKI            ""
 
 #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"  \
@@ -411,6 +414,20 @@ 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_EXTENDED_MASTER_SECRET)
 #define USAGE_EMS \
     "    extended_ms=0/1     default: (library default: on)\n"
@@ -490,6 +507,7 @@ int main( void )
     "    read_timeout=%%d     default: 0 ms (no timeout)\n"    \
     "\n"                                                    \
     USAGE_DTLS                                              \
+    USAGE_SRTP                                              \
     USAGE_COOKIES                                           \
     USAGE_ANTI_REPLAY                                       \
     USAGE_BADMAC_LIMIT                                      \
@@ -645,6 +663,9 @@ struct options
                                  * after renegotiation                      */
     int reproducible;           /* make communication reproducible          */
     int query_config_mode;      /* whether to read config                   */
+    int use_srtp;               /* Support SRTP                             */
+    int force_srtp_profile;     /* SRTP protection profile to use or all    */
+    const char* mki;            /* The dtls mki value to use                */
 } opt;
 
 int query_config( const char *config );
@@ -1792,7 +1813,6 @@ int main( int argc, char *argv[] )
 #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
     unsigned char alloc_buf[MEMORY_HEAP_SIZE];
 #endif
-
 #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
     unsigned char cid[MBEDTLS_SSL_CID_IN_LEN_MAX];
     unsigned char cid_renego[MBEDTLS_SSL_CID_IN_LEN_MAX];
@@ -1804,6 +1824,10 @@ 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;
@@ -1976,6 +2000,9 @@ int main( int argc, char *argv[] )
     opt.nss_keylog          = DFL_NSS_KEYLOG;
     opt.nss_keylog_file     = DFL_NSS_KEYLOG_FILE;
     opt.query_config_mode   = DFL_QUERY_CONFIG_MODE;
+    opt.use_srtp            = DFL_USE_SRTP;
+    opt.force_srtp_profile  = DFL_SRTP_FORCE_PROFILE;
+    opt.mki                 = DFL_SRTP_MKI;
 
     for( i = 1; i < argc; i++ )
     {
@@ -2424,6 +2451,18 @@ int main( int argc, char *argv[] )
         {
             opt.nss_keylog_file = q;
         }
+        else if( strcmp( p, "use_srtp" ) == 0 )
+        {
+            opt.use_srtp = atoi ( q );
+        }
+        else if( strcmp( p, "srtp_force_profile" ) == 0 )
+        {
+            opt.force_srtp_profile = atoi( q );
+        }
+        else if( strcmp( p, "mki" ) == 0 )
+        {
+            opt.mki = q;
+        }
         else
             goto usage;
     }
@@ -3028,7 +3067,7 @@ int main( int argc, char *argv[] )
     {
         mbedtls_printf( " failed\n  ! mbedtls_ssl_conf_max_frag_len returned %d\n\n", ret );
         goto exit;
-    };
+    }
 #endif
 
 #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
@@ -3058,6 +3097,37 @@ int main( int argc, char *argv[] )
     }
 #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
 
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+    if( opt.use_srtp != DFL_USE_SRTP )
+    {
+        if( opt.force_srtp_profile != DFL_SRTP_FORCE_PROFILE )
+        {
+            const mbedtls_ssl_srtp_profile forced_profile[] = { opt.force_srtp_profile };
+            ret = mbedtls_ssl_conf_dtls_srtp_protection_profiles( &conf, forced_profile, sizeof( forced_profile ) / sizeof( mbedtls_ssl_srtp_profile ) );
+        }
+        else
+        {
+            const mbedtls_ssl_srtp_profile default_profiles[] = { MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80,
+                                                                  MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32,
+                                                                  MBEDTLS_SRTP_NULL_HMAC_SHA1_80,
+                                                                  MBEDTLS_SRTP_NULL_HMAC_SHA1_32 };
+            ret = mbedtls_ssl_conf_dtls_srtp_protection_profiles( &conf, default_profiles, sizeof( default_profiles ) / sizeof( mbedtls_ssl_srtp_profile ) );
+        }
+
+        if( ret != 0 )
+        {
+            mbedtls_printf( " failed\n  ! mbedtls_ssl_conf_dtls_srtp_protection_profiles returned %d\n\n", ret );
+            goto exit;
+        }
+
+    }
+    else if( opt.force_srtp_profile != DFL_SRTP_FORCE_PROFILE )
+    {
+        mbedtls_printf( " failed\n  ! must enable use_srtp to force srtp profile\n\n" );
+        goto exit;
+    }
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+
 #if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
     if( opt.trunc_hmac != DFL_TRUNC_HMAC )
         mbedtls_ssl_conf_truncated_hmac( &conf, opt.trunc_hmac );
@@ -3464,6 +3534,24 @@ int main( int argc, char *argv[] )
                                             mbedtls_timing_get_delay );
 #endif
 
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+    if( opt.use_srtp != DFL_USE_SRTP &&  strlen( opt.mki ) != 0 )
+    {
+        if( unhexify( mki, opt.mki, &mki_len ) != 0 )
+        {
+            mbedtls_printf( "mki value not valid hex\n" );
+             goto exit;
+        }
+
+        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, mki_len) ) != 0 )
+        {
+            mbedtls_printf( " failed\n  ! mbedtls_ssl_dtls_srtp_set_mki_value returned %d\n\n", ret );
+            goto exit;
+        }
+    }
+#endif
+
     mbedtls_printf( " ok\n" );
 
 reset:

From 12c6eaddd505919160852d98291d3d4f390b7479 Mon Sep 17 00:00:00 2001
From: Ron Eldor <Ron.Eldor@arm.com>
Date: Tue, 3 Jul 2018 15:08:32 +0300
Subject: [PATCH 16/63] Fix mki issues

1. Set correct mki from the `use_srtp` extension.
2. Use mki value received from the client as the mki used by server.
3. Use `mbedtls_ssl_dtls_srtp_set_mki_value()` as a client API only.

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 library/ssl_cli.c          |  2 +-
 library/ssl_srv.c          |  7 ++++---
 programs/ssl/ssl_server2.c | 35 +++++++++++------------------------
 3 files changed, 16 insertions(+), 28 deletions(-)

diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index 4073f89bd721..7d9c9c317e84 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -1851,7 +1851,7 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
     if (((uint16_t)( ( buf[0]<<8 ) | buf[1] ) ) != 0x0002) { /* protection profile length must be 0x0002 as we must have only one protection profile in server Hello */
         return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
     } else {
-        server_protection_profile_value = ( buf[2]<<8 ) | buf[3];
+        server_protection_profile_value = ( buf[2] << 8 ) | buf[3];
     }
 
     ssl->dtls_srtp_info.chosen_dtls_srtp_profile = MBEDTLS_SRTP_UNSET_PROFILE;
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index 1f497aea520d..82baeca10c44 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -800,13 +800,13 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
      *
      */
 
-    /* Min length is 5 : at least one protection profile(2 bytes) and length(2 bytes) + srtp_mki length(1 byte) */
+    /* Min length is 5: at least one protection profile(2 bytes) and length(2 bytes) + srtp_mki length(1 byte) */
     if( len < 5 )
         return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
 
    ssl->dtls_srtp_info.chosen_dtls_srtp_profile = MBEDTLS_SRTP_UNSET_PROFILE;
 
-    profile_length = ( buf[0]<<8 ) | buf[1]; /* first 2 bytes are protection profile length(in bytes) */
+    profile_length = ( buf[0] << 8 ) | buf[1]; /* first 2 bytes are protection profile length(in bytes) */
 
 
     /* parse the extension list values are defined in http://www.iana.org/assignments/srtp-protection/srtp-protection.xhtml */
@@ -856,9 +856,10 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
             return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
         }
 
+        ssl->dtls_srtp_info.mki_len = buf[ profile_length + 2 ];
         for( i=0; i < ssl->dtls_srtp_info.mki_len; i++ )
         {
-            ssl->dtls_srtp_info.mki_value[i] = buf[ profile_length + 2 + i ];
+            ssl->dtls_srtp_info.mki_value[i] = buf[ profile_length + 2 + 1 + i ];
         }
     }
 
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index be45e54634d3..2db5887d2c7a 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -185,7 +185,7 @@ int main( void )
 #define DFL_QUERY_CONFIG_MODE   0
 #define DFL_USE_SRTP            0
 #define DFL_SRTP_FORCE_PROFILE  MBEDTLS_SRTP_UNSET_PROFILE
-#define DFL_SRTP_MKI            ""
+#define DFL_SRTP_SUPPORT_MKI    0
 
 #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"  \
@@ -423,7 +423,7 @@ int main( void )
     "                        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"
+    "    support_mki=%%d     default: 0 (not supported)\n"
 #else
 #define USAGE_SRTP ""
 #endif
@@ -665,7 +665,7 @@ struct options
     int query_config_mode;      /* whether to read config                   */
     int use_srtp;               /* Support SRTP                             */
     int force_srtp_profile;     /* SRTP protection profile to use or all    */
-    const char* mki;            /* The dtls mki value to use                */
+    int support_mki;            /* The dtls mki mki support                 */
 } opt;
 
 int query_config( const char *config );
@@ -2002,7 +2002,7 @@ int main( int argc, char *argv[] )
     opt.query_config_mode   = DFL_QUERY_CONFIG_MODE;
     opt.use_srtp            = DFL_USE_SRTP;
     opt.force_srtp_profile  = DFL_SRTP_FORCE_PROFILE;
-    opt.mki                 = DFL_SRTP_MKI;
+    opt.support_mki         = DFL_SRTP_SUPPORT_MKI;
 
     for( i = 1; i < argc; i++ )
     {
@@ -2459,9 +2459,9 @@ int main( int argc, char *argv[] )
         {
             opt.force_srtp_profile = atoi( q );
         }
-        else if( strcmp( p, "mki" ) == 0 )
+        else if( strcmp( p, "support_mki" ) == 0 )
         {
-            opt.mki = q;
+            opt.support_mki = atoi( q );
         }
         else
             goto usage;
@@ -3120,6 +3120,11 @@ int main( int argc, char *argv[] )
             goto exit;
         }
 
+        mbedtls_ssl_conf_srtp_mki_value_supported( &conf,
+                                                   opt.support_mki ?
+                                                   MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED :
+                                                   MBEDTLS_SSL_DTLS_SRTP_MKI_UNSUPPORTED );
+
     }
     else if( opt.force_srtp_profile != DFL_SRTP_FORCE_PROFILE )
     {
@@ -3534,24 +3539,6 @@ int main( int argc, char *argv[] )
                                             mbedtls_timing_get_delay );
 #endif
 
-#if defined(MBEDTLS_SSL_DTLS_SRTP)
-    if( opt.use_srtp != DFL_USE_SRTP &&  strlen( opt.mki ) != 0 )
-    {
-        if( unhexify( mki, opt.mki, &mki_len ) != 0 )
-        {
-            mbedtls_printf( "mki value not valid hex\n" );
-             goto exit;
-        }
-
-        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, mki_len) ) != 0 )
-        {
-            mbedtls_printf( " failed\n  ! mbedtls_ssl_dtls_srtp_set_mki_value returned %d\n\n", ret );
-            goto exit;
-        }
-    }
-#endif
-
     mbedtls_printf( " ok\n" );
 
 reset:

From 1c399bdffe2054b8b0ad9729f9e218f8eb469492 Mon Sep 17 00:00:00 2001
From: Ron Eldor <Ron.Eldor@arm.com>
Date: Wed, 4 Jul 2018 18:45:27 +0300
Subject: [PATCH 17/63] Set authmode to optional, if not set

Set authmode to `MBEDTLS_SSL_VERIFY_REQUIRED` when using dtls-srtp,
in case authmode was not set. This is to support self signed certificates
received by the server, which is the case with webRTC. Certificate fingerprints
are verified outside the dtls stack, as defined in RFC 5763.

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 library/ssl_srv.c | 6 +++---
 library/ssl_tls.c | 6 ++++--
 2 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index 82baeca10c44..00549649cf08 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -3021,9 +3021,9 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
     else
 #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 ) {
-        authmode = MBEDTLS_SSL_VERIFY_REQUIRED;
+    /* check if we have a chosen srtp protection profile, force verify mode to be at least OPTIONAL */
+    if ( ( ssl->dtls_srtp_info.chosen_dtls_srtp_profile != MBEDTLS_SRTP_UNSET_PROFILE ) && ( ssl->conf->authmode == MBEDTLS_SSL_VERIFY_NONE ) ) {
+        authmode = MBEDTLS_SSL_VERIFY_OPTIONAL;
     }
         else
 #endif
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 987b33024e82..02efcb4123ca 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -2753,6 +2753,7 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
 #if defined(MBEDTLS_SSL_DTLS_SRTP)
                        : ssl->dtls_srtp_info.chosen_dtls_srtp_profile !=
                                MBEDTLS_SRTP_UNSET_PROFILE
+                       && ssl->conf->authmode == MBEDTLS_SSL_VERIFY_NONE
                        ? MBEDTLS_SSL_VERIFY_REQUIRED
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
                        : ssl->conf->authmode;
@@ -2760,8 +2761,9 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
     const int authmode =
 #if defined(MBEDTLS_SSL_DTLS_SRTP)
             ssl->dtls_srtp_info.chosen_dtls_srtp_profile !=
-                                           MBEDTLS_SRTP_UNSET_PROFILE ?
-                         MBEDTLS_SSL_VERIFY_REQUIRED :
+                                           MBEDTLS_SRTP_UNSET_PROFILE &&
+            ssl->conf->authmode == MBEDTLS_SSL_VERIFY_NONE ?
+            MBEDTLS_SSL_VERIFY_REQUIRED :
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
             ssl->conf->authmode;
 #endif

From b465539476fc9191c24fa9e839fb84cafb3036ef Mon Sep 17 00:00:00 2001
From: Ron Eldor <Ron.Eldor@arm.com>
Date: Thu, 5 Jul 2018 18:25:39 +0300
Subject: [PATCH 18/63] Add tests and code to support

1. Add DTLS-SRTP tests in `ssl-opts.sh`
2. Add logs for the tests to filter.
3. Add function to get the profile informations.

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 library/ssl_cli.c |  14 ++++++
 library/ssl_srv.c |   9 ++++
 library/ssl_tls.c |  24 +++++++++
 tests/ssl-opt.sh  | 125 ++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 172 insertions(+)

diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index 7d9c9c317e84..d6b429df2fe8 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -843,6 +843,7 @@ static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
         {
             *p++ = ssl->dtls_srtp_info.mki_value[i];
         }
+        MBEDTLS_SSL_DEBUG_BUF( 3, "sending mki",  ssl->dtls_srtp_info.mki_value, ssl->dtls_srtp_info.mki_len );
     }
 
     /* total extension length: extension type (2 bytes) + extension length (2 bytes) + protection profile length (2 bytes) + 2*nb protection profiles + srtp_mki vector length(1 byte)*/
@@ -1819,6 +1820,7 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
     mbedtls_ssl_srtp_profile server_protection = MBEDTLS_SRTP_UNSET_PROFILE;
     size_t i, mki_len = 0;
     uint16_t server_protection_profile_value = 0;
+    const mbedtls_ssl_srtp_profile_info * profile_info;
 
     /* If use_srtp is not configured, just ignore the extension */
     if( ( ssl->conf->dtls_srtp_profile_list == NULL ) || ( ssl->conf->dtls_srtp_profile_list_len == 0 ) )
@@ -1878,9 +1880,15 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
                 server_protection = MBEDTLS_SRTP_UNSET_PROFILE;
                 break;
         }
+        profile_info = mbedtls_ssl_dtls_srtp_profile_info_from_id( server_protection );
+        if( profile_info != NULL )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 3, ( "found srtp profile: %s", profile_info->name ) );
+        }
 
         if (server_protection == ssl->conf->dtls_srtp_profile_list[i]) {
             ssl->dtls_srtp_info.chosen_dtls_srtp_profile = ssl->conf->dtls_srtp_profile_list[i];
+            MBEDTLS_SSL_DEBUG_MSG( 3, ( "selected srtp profile: %s", profile_info->name ) );
             break;
         }
     }
@@ -1904,6 +1912,12 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
                                         MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
         return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
     }
+#if defined (MBEDTLS_DEBUG_C)
+    if( len > 5)
+    {
+        MBEDTLS_SSL_DEBUG_BUF( 3, "received mki",  ssl->dtls_srtp_info.mki_value, ssl->dtls_srtp_info.mki_len );
+    }
+#endif
     return 0;
 }
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index 00549649cf08..4c59e5b40dcc 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -783,6 +783,7 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
     mbedtls_ssl_srtp_profile client_protection = MBEDTLS_SRTP_UNSET_PROFILE;
     size_t i,j;
     size_t profile_length;
+    const mbedtls_ssl_srtp_profile_info * profile_info;
 
     /* If use_srtp is not configured, just ignore the extension */
     if( ( ssl->conf->dtls_srtp_profile_list == NULL ) || ( ssl->conf->dtls_srtp_profile_list_len == 0 ) )
@@ -832,12 +833,18 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
                 client_protection = MBEDTLS_SRTP_UNSET_PROFILE;
                 break;
         }
+        profile_info = mbedtls_ssl_dtls_srtp_profile_info_from_id( client_protection );
+        if( profile_info != NULL )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 3, ( "found srtp profile: %s", profile_info->name ) );
+        }
         /* check if suggested profile is in our list */
         for( i=0; i < ssl->conf->dtls_srtp_profile_list_len; i++)
         {
             if( client_protection == ssl->conf->dtls_srtp_profile_list[i] )
             {
                 ssl->dtls_srtp_info.chosen_dtls_srtp_profile = ssl->conf->dtls_srtp_profile_list[i];
+                MBEDTLS_SSL_DEBUG_MSG( 3, ( "selected srtp profile: %s", profile_info->name ) );
                 break;
             }
         }
@@ -861,6 +868,8 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
         {
             ssl->dtls_srtp_info.mki_value[i] = buf[ profile_length + 2 + 1 + i ];
         }
+
+        MBEDTLS_SSL_DEBUG_BUF( 3, "using mki",  ssl->dtls_srtp_info.mki_value, ssl->dtls_srtp_info.mki_len );
     }
 
      return( 0 );
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 02efcb4123ca..18c86a5ce184 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -4738,6 +4738,30 @@ const char *mbedtls_ssl_get_alpn_protocol( const mbedtls_ssl_context *ssl )
 #endif /* MBEDTLS_SSL_ALPN */
 
 #if defined(MBEDTLS_SSL_DTLS_SRTP)
+static const mbedtls_ssl_srtp_profile_info srtp_profile_definitions[] =
+{
+    { MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80, "MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80" },
+    { MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32, "MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32" },
+    { MBEDTLS_SRTP_NULL_HMAC_SHA1_80, "MBEDTLS_SRTP_NULL_HMAC_SHA1_80" },
+    { MBEDTLS_SRTP_NULL_HMAC_SHA1_32, "MBEDTLS_SRTP_NULL_HMAC_SHA1_32" },
+    { MBEDTLS_SRTP_UNSET_PROFILE, "" }
+};
+
+const mbedtls_ssl_srtp_profile_info *mbedtls_ssl_dtls_srtp_profile_info_from_id( mbedtls_ssl_srtp_profile profile )
+{
+    const mbedtls_ssl_srtp_profile_info *cur = srtp_profile_definitions;
+
+    while( cur->profile != MBEDTLS_SRTP_UNSET_PROFILE )
+    {
+        if( cur->profile == profile )
+            return( cur );
+
+        cur++;
+    }
+
+    return( NULL );
+}
+
 void mbedtls_ssl_conf_srtp_mki_value_supported( mbedtls_ssl_config *conf, int support_mki_value )
 {
     conf->dtls_srtp_mki_support = support_mki_value;
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index 653d88da72a3..ada4dbeb17b4 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -8713,6 +8713,131 @@ run_test    "DTLS fragmenting: 3d, openssl client, DTLS 1.0" \
             0 \
             -s "fragmenting handshake message"
 
+# Tests for DTLS-SRTP (RFC 5764)
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP all profiles supported" \
+          "$P_SRV dtls=1 use_srtp=1 debug_level=3" \
+          "$P_CLI dtls=1 use_srtp=1 debug_level=3" \
+          0 \
+          -s "found use_srtp extension" \
+          -s "found srtp profile" \
+          -s "selected srtp profile" \
+          -s "server hello, adding use_srtp extension" \
+          -c "client hello, adding use_srtp extension" \
+          -c "found use_srtp extension" \
+          -c "found srtp profile" \
+          -c "selected srtp profile" \
+          -C "error"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP server supports all profiles. Client supports one profile." \
+          "$P_SRV dtls=1 use_srtp=1 debug_level=3" \
+          "$P_CLI dtls=1 use_srtp=1 srtp_force_profile=3 debug_level=3" \
+          0 \
+          -s "found use_srtp extension" \
+          -s "found srtp profile: MBEDTLS_SRTP_NULL_HMAC_SHA1_80" \
+          -s "selected srtp profile: MBEDTLS_SRTP_NULL_HMAC_SHA1_80" \
+          -s "server hello, adding use_srtp extension" \
+          -c "client hello, adding use_srtp extension" \
+          -c "found use_srtp extension" \
+          -c "found srtp profile: MBEDTLS_SRTP_NULL_HMAC_SHA1_80" \
+          -c "selected srtp profile" \
+          -C "error"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP server supports one profile. Client supports profiles." \
+          "$P_SRV dtls=1 use_srtp=1 srtp_force_profile=4 debug_level=3" \
+          "$P_CLI dtls=1 use_srtp=1 debug_level=3" \
+          0 \
+          -s "found use_srtp extension" \
+          -s "found srtp profile" \
+          -s "selected srtp profile: MBEDTLS_SRTP_NULL_HMAC_SHA1_32" \
+          -s "server hello, adding use_srtp extension" \
+          -c "client hello, adding use_srtp extension" \
+          -c "found use_srtp extension" \
+          -c "found srtp profile: MBEDTLS_SRTP_NULL_HMAC_SHA1_32" \
+          -c "selected srtp profile" \
+          -C "error"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP server and Client support only one matching profile." \
+          "$P_SRV dtls=1 use_srtp=1 srtp_force_profile=2 debug_level=3" \
+          "$P_CLI dtls=1 use_srtp=1 srtp_force_profile=2 debug_level=3" \
+          0 \
+          -s "found use_srtp extension" \
+          -s "found srtp profile: MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32" \
+          -s "selected srtp profile: MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32" \
+          -s "server hello, adding use_srtp extension" \
+          -c "client hello, adding use_srtp extension" \
+          -c "found use_srtp extension" \
+          -c "found srtp profile: MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32" \
+          -c "selected srtp profile" \
+          -C "error"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP server and Client support only one different profile." \
+          "$P_SRV dtls=1 use_srtp=1 srtp_force_profile=2 debug_level=3" \
+          "$P_CLI dtls=1 use_srtp=1 srtp_force_profile=4 debug_level=3" \
+          0 \
+          -s "found use_srtp extension" \
+          -s "found srtp profile: MBEDTLS_SRTP_NULL_HMAC_SHA1_32" \
+          -S "selected srtp profile" \
+          -S "server hello, adding use_srtp extension" \
+          -c "client hello, adding use_srtp extension" \
+          -C "found use_srtp extension" \
+          -C "found srtp profile" \
+          -C "selected srtp profile" \
+          -C "error"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP server doesn't support use_srtp extension." \
+          "$P_SRV dtls=1 debug_level=3" \
+          "$P_CLI dtls=1 use_srtp=1 debug_level=3" \
+          0 \
+          -s "found use_srtp extension" \
+          -S "server hello, adding use_srtp extension" \
+          -c "client hello, adding use_srtp extension" \
+          -C "found use_srtp extension" \
+          -C "found srtp profile" \
+          -C "selected srtp profile" \
+          -C "error"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP all profiles supported. mki used" \
+          "$P_SRV dtls=1 use_srtp=1 support_mki=1 debug_level=3" \
+          "$P_CLI dtls=1 use_srtp=1 mki=542310ab34290481 debug_level=3" \
+          0 \
+          -s "found use_srtp extension" \
+          -s "found srtp profile" \
+          -s "selected srtp profile" \
+          -s "server hello, adding use_srtp extension" \
+          -s "dumping 'using mki' (8 bytes)" \
+          -c "client hello, adding use_srtp extension" \
+          -c "found use_srtp extension" \
+          -c "found srtp profile" \
+          -c "selected srtp profile" \
+          -c "dumping 'sending mki' (8 bytes)" \
+          -c "dumping 'received mki' (8 bytes)" \
+          -C "error"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP all profiles supported. server doesn't support mki." \
+          "$P_SRV dtls=1 use_srtp=1 debug_level=3" \
+          "$P_CLI dtls=1 use_srtp=1 mki=542310ab34290481 debug_level=3" \
+          0 \
+          -s "found use_srtp extension" \
+          -s "found srtp profile" \
+          -s "selected srtp profile" \
+          -s "server hello, adding use_srtp extension" \
+          -S "dumping 'using mki' (8 bytes)" \
+          -c "client hello, adding use_srtp extension" \
+          -c "found use_srtp extension" \
+          -c "found srtp profile" \
+          -c "selected srtp profile" \
+          -c "dumping 'sending mki' (8 bytes)" \
+          -C "dumping 'received mki' (8 bytes)" \
+          -C "error"
+
 # Tests for specific things with "unreliable" UDP connection
 
 not_with_valgrind # spurious resend due to timeout

From 311b95aafee86fa2f4c5fec81a9618069c757cc4 Mon Sep 17 00:00:00 2001
From: Ron Eldor <Ron.Eldor@arm.com>
Date: Sun, 8 Jul 2018 08:50:31 +0300
Subject: [PATCH 19/63] Fix compilation errors

Fix compilation errors when `MBEDTLS_DTLS_SRTP` not set
1. Add file missed in previous commmit.
2. In sample applications, set `DFL_FORCE_SRTP_PROFILE` to 0.

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 include/mbedtls/ssl.h      | 16 ++++++++++++++++
 programs/ssl/ssl_client2.c |  2 +-
 programs/ssl/ssl_server2.c |  2 +-
 3 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index 83f2f425f5a1..698334739c40 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -881,6 +881,13 @@ typedef enum
 }
 mbedtls_ssl_srtp_profile;
 
+typedef struct
+{
+    const mbedtls_ssl_srtp_profile   profile;
+    const char                      *name;
+}
+mbedtls_ssl_srtp_profile_info;
+
 typedef struct mbedtls_dtls_srtp_info_t
 {
     mbedtls_ssl_srtp_profile chosen_dtls_srtp_profile; /*!< negotiated SRTP profile */
@@ -3233,6 +3240,15 @@ mbedtls_ssl_srtp_profile mbedtls_ssl_get_dtls_srtp_protection_profile( const mbe
  * \return         0 on succes, 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_len );
+
+/**
+ * \brief                  Utility function to get information on dtls srtp profile.
+ *
+ * \param profile          The dtls-srtp profile id to get info on.
+ *
+ * \return         mbedtls_ssl_srtp_profile_info* on success, NULL if not found
+ */
+const mbedtls_ssl_srtp_profile_info *mbedtls_ssl_dtls_srtp_profile_info_from_id( mbedtls_ssl_srtp_profile profile );
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
 
 /**
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index d9d5cad36c90..4ae740c63c5a 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -151,7 +151,7 @@ int main( void )
 #define DFL_SKIP_CLOSE_NOTIFY   0
 #define DFL_QUERY_CONFIG_MODE   0
 #define DFL_USE_SRTP            0
-#define DFL_SRTP_FORCE_PROFILE  MBEDTLS_SRTP_UNSET_PROFILE
+#define DFL_SRTP_FORCE_PROFILE  0
 #define DFL_SRTP_MKI            ""
 
 #define GET_REQUEST "GET %s HTTP/1.0\r\nExtra-header: "
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index 2db5887d2c7a..137838c77091 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -184,7 +184,7 @@ int main( void )
 #define DFL_NSS_KEYLOG_FILE     NULL
 #define DFL_QUERY_CONFIG_MODE   0
 #define DFL_USE_SRTP            0
-#define DFL_SRTP_FORCE_PROFILE  MBEDTLS_SRTP_UNSET_PROFILE
+#define DFL_SRTP_FORCE_PROFILE  0
 #define DFL_SRTP_SUPPORT_MKI    0
 
 #define LONG_RESPONSE "<p>01-blah-blah-blah-blah-blah-blah-blah-blah-blah\r\n" \

From 3c6a44bed8719c3b3336ee4779c4d2a048a9ea00 Mon Sep 17 00:00:00 2001
From: Ron Eldor <Ron.Eldor@arm.com>
Date: Tue, 10 Jul 2018 10:32:10 +0300
Subject: [PATCH 20/63] Add interop tests

Add some interoperability tests with openssl and gnutls, in ssl-opts.sh.

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 tests/ssl-opt.sh | 332 ++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 331 insertions(+), 1 deletion(-)

diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index ada4dbeb17b4..cd2e7c74f464 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -8745,7 +8745,7 @@ run_test  "DTLS-SRTP server supports all profiles. Client supports one profile."
           -C "error"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
-run_test  "DTLS-SRTP server supports one profile. Client supports profiles." \
+run_test  "DTLS-SRTP server supports one profile. Client supports all profiles." \
           "$P_SRV dtls=1 use_srtp=1 srtp_force_profile=4 debug_level=3" \
           "$P_CLI dtls=1 use_srtp=1 debug_level=3" \
           0 \
@@ -8838,6 +8838,336 @@ run_test  "DTLS-SRTP all profiles supported. server doesn't support mki." \
           -C "dumping 'received mki' (8 bytes)" \
           -C "error"
 
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP all profiles supported. openssl client." \
+          "$P_SRV dtls=1 use_srtp=1 debug_level=3" \
+          "$O_CLI -dtls1 -use_srtp SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32" \
+          0 \
+          -s "found use_srtp extension" \
+          -s "found srtp profile" \
+          -s "selected srtp profile" \
+          -s "server hello, adding use_srtp extension" \
+          -c "SRTP Extension negotiated, profile=SRTP_AES128_CM_SHA1_80"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP server supports all profiles. Client supports all profiles, in different order. openssl client." \
+          "$P_SRV dtls=1 use_srtp=1 debug_level=3" \
+          "$O_CLI -dtls1 -use_srtp SRTP_AES128_CM_SHA1_32:SRTP_AES128_CM_SHA1_80" \
+          0 \
+          -s "found use_srtp extension" \
+          -s "found srtp profile" \
+          -s "selected srtp profile" \
+          -s "server hello, adding use_srtp extension" \
+          -c "SRTP Extension negotiated, profile=SRTP_AES128_CM_SHA1_32"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP server supports all profiles. Client supports one profile. openssl client." \
+          "$P_SRV dtls=1 use_srtp=1 debug_level=3" \
+          "$O_CLI -dtls1 -use_srtp SRTP_AES128_CM_SHA1_32" \
+          0 \
+          -s "found use_srtp extension" \
+          -s "found srtp profile" \
+          -s "selected srtp profile" \
+          -s "server hello, adding use_srtp extension" \
+          -c "SRTP Extension negotiated, profile=SRTP_AES128_CM_SHA1_32"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP server supports one profile. Client supports all profiles. openssl client." \
+          "$P_SRV dtls=1 use_srtp=1 srtp_force_profile=2 debug_level=3" \
+          "$O_CLI -dtls1 -use_srtp SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32" \
+          0 \
+          -s "found use_srtp extension" \
+          -s "found srtp profile" \
+          -s "selected srtp profile" \
+          -s "server hello, adding use_srtp extension" \
+          -c "SRTP Extension negotiated, profile=SRTP_AES128_CM_SHA1_32"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP server and Client support only one matching profile. openssl client." \
+          "$P_SRV dtls=1 use_srtp=1 srtp_force_profile=2 debug_level=3" \
+          "$O_CLI -dtls1 -use_srtp SRTP_AES128_CM_SHA1_32" \
+          0 \
+          -s "found use_srtp extension" \
+          -s "found srtp profile" \
+          -s "selected srtp profile" \
+          -s "server hello, adding use_srtp extension" \
+          -c "SRTP Extension negotiated, profile=SRTP_AES128_CM_SHA1_32"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP server and Client support only one different profile. openssl client." \
+          "$P_SRV dtls=1 use_srtp=1 srtp_force_profile=1 debug_level=3" \
+          "$O_CLI -dtls1 -use_srtp SRTP_AES128_CM_SHA1_32" \
+          0 \
+          -s "found use_srtp extension" \
+          -s "found srtp profile" \
+          -S "selected srtp profile" \
+          -S "server hello, adding use_srtp extension" \
+          -C "SRTP Extension negotiated, profile"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP server doesn't support use_srtp extension. openssl client" \
+          "$P_SRV dtls=1 debug_level=3" \
+          "$O_CLI -dtls1 -use_srtp SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32" \
+          0 \
+          -s "found use_srtp extension" \
+          -S "server hello, adding use_srtp extension" \
+          -C "SRTP Extension negotiated, profile"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP all profiles supported. openssl server" \
+          "$O_SRV -dtls1 -verify 0 -use_srtp SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32" \
+          "$P_CLI dtls=1 use_srtp=1 debug_level=3" \
+          0 \
+          -c "client hello, adding use_srtp extension" \
+          -c "found use_srtp extension" \
+          -c "found srtp profile" \
+          -c "selected srtp profile: MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80" \
+          -C "error"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP server supports all profiles. Client supports all profiles, in different order. openssl server." \
+          "$O_SRV -dtls1 -verify 0 -use_srtp SRTP_AES128_CM_SHA1_32:SRTP_AES128_CM_SHA1_80" \
+          "$P_CLI dtls=1 use_srtp=1 debug_level=3" \
+          0 \
+          -c "client hello, adding use_srtp extension" \
+          -c "found use_srtp extension" \
+          -c "found srtp profile" \
+          -c "selected srtp profile" \
+          -C "error"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP server supports all profiles. Client supports one profile. openssl server." \
+          "$O_SRV -dtls1 -verify 0 -use_srtp SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32" \
+          "$P_CLI dtls=1 use_srtp=1 srtp_force_profile=2 debug_level=3" \
+          0 \
+          -c "client hello, adding use_srtp extension" \
+          -c "found use_srtp extension" \
+          -c "found srtp profile: MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32" \
+          -c "selected srtp profile" \
+          -C "error"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP server supports one profile. Client supports all profiles. openssl server." \
+          "$O_SRV -dtls1 -verify 0 -use_srtp SRTP_AES128_CM_SHA1_32" \
+          "$P_CLI dtls=1 use_srtp=1 debug_level=3" \
+          0 \
+          -c "client hello, adding use_srtp extension" \
+          -c "found use_srtp extension" \
+          -c "found srtp profile: MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32" \
+          -c "selected srtp profile" \
+          -C "error"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP server and Client support only one matching profile. openssl server." \
+          "$O_SRV -dtls1 -verify 0 -use_srtp SRTP_AES128_CM_SHA1_32" \
+          "$P_CLI dtls=1 use_srtp=1 srtp_force_profile=2 debug_level=3" \
+          0 \
+          -c "client hello, adding use_srtp extension" \
+          -c "found use_srtp extension" \
+          -c "found srtp profile: MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32" \
+          -c "selected srtp profile" \
+          -C "error"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP server and Client support only one different profile. openssl server." \
+          "$O_SRV -dtls1 -verify 0 -use_srtp SRTP_AES128_CM_SHA1_32" \
+          "$P_CLI dtls=1 use_srtp=1 srtp_force_profile=4 debug_level=3" \
+          0 \
+          -c "client hello, adding use_srtp extension" \
+          -C "found use_srtp extension" \
+          -C "found srtp profile" \
+          -C "selected srtp profile" \
+          -C "error"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP server doesn't support use_srtp extension. openssl server" \
+          "$O_SRV -dtls1" \
+          "$P_CLI dtls=1 use_srtp=1 debug_level=3" \
+          0 \
+          -c "client hello, adding use_srtp extension" \
+          -C "found use_srtp extension" \
+          -C "found srtp profile" \
+          -C "selected srtp profile" \
+          -C "error"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP all profiles supported. server doesn't support mki. openssl server." \
+          "$O_SRV -dtls1 -verify 0 -use_srtp SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32" \
+          "$P_CLI dtls=1 use_srtp=1 mki=542310ab34290481 debug_level=3" \
+          0 \
+          -c "client hello, adding use_srtp extension" \
+          -c "found use_srtp extension" \
+          -c "found srtp profile" \
+          -c "selected srtp profile" \
+          -c "dumping 'sending mki' (8 bytes)" \
+          -C "dumping 'received mki' (8 bytes)" \
+          -C "error"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP all profiles supported. gnutls client." \
+          "$P_SRV dtls=1 use_srtp=1 debug_level=3" \
+          "$G_CLI -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_80:SRTP_AES128_CM_HMAC_SHA1_32:SRTP_NULL_HMAC_SHA1_80:SRTP_NULL_SHA1_32" \
+          0 \
+          -s "found use_srtp extension" \
+          -s "found srtp profile" \
+          -s "selected srtp profile" \
+          -s "server hello, adding use_srtp extension" \
+          -c "SRTP profile: SRTP_AES128_CM_HMAC_SHA1_80"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP server supports all profiles. Client supports all profiles, in different order. gnutls client." \
+          "$P_SRV dtls=1 use_srtp=1 debug_level=3" \
+          "$G_CLI -u --srtp-profiles=SRTP_NULL_HMAC_SHA1_80:SRTP_AES128_CM_HMAC_SHA1_80:SRTP_NULL_SHA1_32:SRTP_AES128_CM_HMAC_SHA1_32" \
+          0 \
+          -s "found use_srtp extension" \
+          -s "found srtp profile" \
+          -s "selected srtp profile" \
+          -s "server hello, adding use_srtp extension" \
+          -c "SRTP profile: SRTP_NULL_HMAC_SHA1_80"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP server supports all profiles. Client supports one profile. gnutls client." \
+          "$P_SRV dtls=1 use_srtp=1 debug_level=3" \
+          "$G_CLI -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_32" \
+          0 \
+          -s "found use_srtp extension" \
+          -s "found srtp profile: MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32" \
+          -s "selected srtp profile: MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32" \
+          -s "server hello, adding use_srtp extension" \
+          -c "SRTP profile: SRTP_AES128_CM_HMAC_SHA1_32"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP server supports one profile. Client supports all profiles. gnutls client." \
+          "$P_SRV dtls=1 use_srtp=1 srtp_force_profile=4 debug_level=3" \
+          "$G_CLI -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_80:SRTP_AES128_CM_HMAC_SHA1_32:SRTP_NULL_HMAC_SHA1_80:SRTP_NULL_SHA1_32" \
+          0 \
+          -s "found use_srtp extension" \
+          -s "found srtp profile" \
+          -s "selected srtp profile: MBEDTLS_SRTP_NULL_HMAC_SHA1_32" \
+          -s "server hello, adding use_srtp extension" \
+          -c "SRTP profile: SRTP_NULL_SHA1_32"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP server and Client support only one matching profile. gnutls client." \
+          "$P_SRV dtls=1 use_srtp=1 srtp_force_profile=2 debug_level=3" \
+          "$G_CLI -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_32" \
+          0 \
+          -s "found use_srtp extension" \
+          -s "found srtp profile" \
+          -s "selected srtp profile" \
+          -s "server hello, adding use_srtp extension" \
+          -c "SRTP profile: SRTP_AES128_CM_HMAC_SHA1_32"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP server and Client support only one different profile. gnutls client." \
+          "$P_SRV dtls=1 use_srtp=1 srtp_force_profile=1 debug_level=3" \
+          "$G_CLI -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_32" \
+          0 \
+          -s "found use_srtp extension" \
+          -s "found srtp profile" \
+          -S "selected srtp profile" \
+          -S "server hello, adding use_srtp extension" \
+          -C "SRTP profile:"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP server doesn't support use_srtp extension. gnutls client" \
+          "$P_SRV dtls=1 debug_level=3" \
+          "$G_CLI -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_80:SRTP_AES128_CM_HMAC_SHA1_32:SRTP_NULL_HMAC_SHA1_80:SRTP_NULL_SHA1_32" \
+          0 \
+          -s "found use_srtp extension" \
+          -S "server hello, adding use_srtp extension" \
+          -C "SRTP profile:"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP all profiles supported. gnutls server" \
+          "$G_SRV -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_80:SRTP_AES128_CM_HMAC_SHA1_32:SRTP_NULL_HMAC_SHA1_80:SRTP_NULL_SHA1_32" \
+          "$P_CLI dtls=1 use_srtp=1 debug_level=3" \
+          0 \
+          -c "client hello, adding use_srtp extension" \
+          -c "found use_srtp extension" \
+          -c "found srtp profile" \
+          -c "selected srtp profile: MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80" \
+          -C "error"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP server supports all profiles. Client supports all profiles, in different order. gnutls server." \
+          "$G_SRV -u --srtp-profiles=SRTP_NULL_SHA1_32:SRTP_AES128_CM_HMAC_SHA1_32:SRTP_AES128_CM_HMAC_SHA1_80:SRTP_NULL_HMAC_SHA1_80:SRTP_NULL_SHA1_32" \
+          "$P_CLI dtls=1 use_srtp=1 debug_level=3" \
+          0 \
+          -c "client hello, adding use_srtp extension" \
+          -c "found use_srtp extension" \
+          -c "found srtp profile" \
+          -c "selected srtp profile: MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80" \
+          -C "error"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP server supports all profiles. Client supports one profile. gnutls server." \
+          "$G_SRV -u --srtp-profiles=SRTP_NULL_SHA1_32:SRTP_AES128_CM_HMAC_SHA1_32:SRTP_AES128_CM_HMAC_SHA1_80:SRTP_NULL_HMAC_SHA1_80:SRTP_NULL_SHA1_32" \
+          "$P_CLI dtls=1 use_srtp=1 srtp_force_profile=2 debug_level=3" \
+          0 \
+          -c "client hello, adding use_srtp extension" \
+          -c "found use_srtp extension" \
+          -c "found srtp profile: MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32" \
+          -c "selected srtp profile" \
+          -C "error"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP server supports one profile. Client supports all profiles. gnutls server." \
+          "$G_SRV -u --srtp-profiles=SRTP_NULL_HMAC_SHA1_80" \
+          "$P_CLI dtls=1 use_srtp=30 debug_level=3" \
+          0 \
+          -c "client hello, adding use_srtp extension" \
+          -c "found use_srtp extension" \
+          -c "found srtp profile: MBEDTLS_SRTP_NULL_HMAC_SHA1_80" \
+          -c "selected srtp profile" \
+          -C "error"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP server and Client support only one matching profile. gnutls server." \
+          "$G_SRV -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_32" \
+          "$P_CLI dtls=1 use_srtp=1 srtp_force_profile=2 debug_level=3" \
+          0 \
+          -c "client hello, adding use_srtp extension" \
+          -c "found use_srtp extension" \
+          -c "found srtp profile: MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32" \
+          -c "selected srtp profile" \
+          -C "error"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP server and Client support only one different profile. gnutls server." \
+          "$G_SRV -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_32" \
+          "$P_CLI dtls=1 use_srtp=1 srtp_force_profile=4 debug_level=3" \
+          0 \
+          -c "client hello, adding use_srtp extension" \
+          -C "found use_srtp extension" \
+          -C "found srtp profile" \
+          -C "selected srtp profile" \
+          -C "error"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP server doesn't support use_srtp extension. gnutls server" \
+          "$G_SRV -u" \
+          "$P_CLI dtls=1 use_srtp=1 debug_level=3" \
+          0 \
+          -c "client hello, adding use_srtp extension" \
+          -C "found use_srtp extension" \
+          -C "found srtp profile" \
+          -C "selected srtp profile" \
+          -C "error"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP all profiles supported. mki used. gnutls server." \
+          "$G_SRV -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_80:SRTP_AES128_CM_HMAC_SHA1_32:SRTP_NULL_HMAC_SHA1_80:SRTP_NULL_SHA1_32" \
+          "$P_CLI dtls=1 use_srtp=1 mki=542310ab34290481 debug_level=3" \
+          0 \
+          -c "client hello, adding use_srtp extension" \
+          -c "found use_srtp extension" \
+          -c "found srtp profile" \
+          -c "selected srtp profile" \
+          -c "dumping 'sending mki' (8 bytes)" \
+          -c "dumping 'received mki' (8 bytes)" \
+          -C "error"
+
 # Tests for specific things with "unreliable" UDP connection
 
 not_with_valgrind # spurious resend due to timeout

From 2b3dfe41af9fc8a6d61aa662f6585073367fc0e1 Mon Sep 17 00:00:00 2001
From: Ron Eldor <Ron.Eldor@arm.com>
Date: Wed, 11 Jul 2018 11:53:37 +0300
Subject: [PATCH 21/63] Force IPv6 for DTLS interop tests with gnutls-cli

Since `gnutls-cli` resolves `localhost` as an IPv6 address, and the server
is bound to IPv4 address, gnutl-cli fails to negotiate DTLS sessions.
Force the server to bind to IPv6 address, as a workaround.

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 tests/ssl-opt.sh | 42 +++++++++++++++++++++++++++++++++++-------
 1 file changed, 35 insertions(+), 7 deletions(-)

diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index cd2e7c74f464..ad38f5d267b5 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -9003,9 +9003,13 @@ run_test  "DTLS-SRTP all profiles supported. server doesn't support mki. openssl
           -C "dumping 'received mki' (8 bytes)" \
           -C "error"
 
+# gnutls-cli resolves localhost as an IPv6 address, when enabled,
+# and fails to send messagges over UDP, causing DTLS negotiation to fail.
+# Force server to bind to IPv6 address
+requires_ipv6
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
 run_test  "DTLS-SRTP all profiles supported. gnutls client." \
-          "$P_SRV dtls=1 use_srtp=1 debug_level=3" \
+          "$P_SRV dtls=1 use_srtp=1 debug_level=3 server_addr=::1" \
           "$G_CLI -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_80:SRTP_AES128_CM_HMAC_SHA1_32:SRTP_NULL_HMAC_SHA1_80:SRTP_NULL_SHA1_32" \
           0 \
           -s "found use_srtp extension" \
@@ -9014,9 +9018,13 @@ run_test  "DTLS-SRTP all profiles supported. gnutls client." \
           -s "server hello, adding use_srtp extension" \
           -c "SRTP profile: SRTP_AES128_CM_HMAC_SHA1_80"
 
+# gnutls-cli resolves localhost as an IPv6 address, when enabled,
+# and fails to send messagges over UDP, causing DTLS negotiation to fail.
+# Force server to bind to IPv6 address
+requires_ipv6
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
 run_test  "DTLS-SRTP server supports all profiles. Client supports all profiles, in different order. gnutls client." \
-          "$P_SRV dtls=1 use_srtp=1 debug_level=3" \
+          "$P_SRV dtls=1 use_srtp=1 debug_level=3 server_addr=::1" \
           "$G_CLI -u --srtp-profiles=SRTP_NULL_HMAC_SHA1_80:SRTP_AES128_CM_HMAC_SHA1_80:SRTP_NULL_SHA1_32:SRTP_AES128_CM_HMAC_SHA1_32" \
           0 \
           -s "found use_srtp extension" \
@@ -9025,9 +9033,13 @@ run_test  "DTLS-SRTP server supports all profiles. Client supports all profiles,
           -s "server hello, adding use_srtp extension" \
           -c "SRTP profile: SRTP_NULL_HMAC_SHA1_80"
 
+# gnutls-cli resolves localhost as an IPv6 address, when enabled,
+# and fails to send messagges over UDP, causing DTLS negotiation to fail.
+# Force server to bind to IPv6 address
+requires_ipv6
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
 run_test  "DTLS-SRTP server supports all profiles. Client supports one profile. gnutls client." \
-          "$P_SRV dtls=1 use_srtp=1 debug_level=3" \
+          "$P_SRV dtls=1 use_srtp=1 debug_level=3 server_addr=::1" \
           "$G_CLI -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_32" \
           0 \
           -s "found use_srtp extension" \
@@ -9036,9 +9048,13 @@ run_test  "DTLS-SRTP server supports all profiles. Client supports one profile.
           -s "server hello, adding use_srtp extension" \
           -c "SRTP profile: SRTP_AES128_CM_HMAC_SHA1_32"
 
+# gnutls-cli resolves localhost as an IPv6 address, when enabled,
+# and fails to send messagges over UDP, causing DTLS negotiation to fail.
+# Force server to bind to IPv6 address
+requires_ipv6
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
 run_test  "DTLS-SRTP server supports one profile. Client supports all profiles. gnutls client." \
-          "$P_SRV dtls=1 use_srtp=1 srtp_force_profile=4 debug_level=3" \
+          "$P_SRV dtls=1 use_srtp=1 srtp_force_profile=4 debug_level=3 server_addr=::1" \
           "$G_CLI -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_80:SRTP_AES128_CM_HMAC_SHA1_32:SRTP_NULL_HMAC_SHA1_80:SRTP_NULL_SHA1_32" \
           0 \
           -s "found use_srtp extension" \
@@ -9047,9 +9063,13 @@ run_test  "DTLS-SRTP server supports one profile. Client supports all profiles.
           -s "server hello, adding use_srtp extension" \
           -c "SRTP profile: SRTP_NULL_SHA1_32"
 
+# gnutls-cli resolves localhost as an IPv6 address, when enabled,
+# and fails to send messagges over UDP, causing DTLS negotiation to fail.
+# Force server to bind to IPv6 address
+requires_ipv6
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
 run_test  "DTLS-SRTP server and Client support only one matching profile. gnutls client." \
-          "$P_SRV dtls=1 use_srtp=1 srtp_force_profile=2 debug_level=3" \
+          "$P_SRV dtls=1 use_srtp=1 srtp_force_profile=2 debug_level=3 server_addr=::1" \
           "$G_CLI -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_32" \
           0 \
           -s "found use_srtp extension" \
@@ -9058,9 +9078,13 @@ run_test  "DTLS-SRTP server and Client support only one matching profile. gnutls
           -s "server hello, adding use_srtp extension" \
           -c "SRTP profile: SRTP_AES128_CM_HMAC_SHA1_32"
 
+# gnutls-cli resolves localhost as an IPv6 address, when enabled,
+# and fails to send messagges over UDP, causing DTLS negotiation to fail.
+# Force server to bind to IPv6 address
+requires_ipv6
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
 run_test  "DTLS-SRTP server and Client support only one different profile. gnutls client." \
-          "$P_SRV dtls=1 use_srtp=1 srtp_force_profile=1 debug_level=3" \
+          "$P_SRV dtls=1 use_srtp=1 srtp_force_profile=1 debug_level=3 server_addr=::1" \
           "$G_CLI -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_32" \
           0 \
           -s "found use_srtp extension" \
@@ -9069,9 +9093,13 @@ run_test  "DTLS-SRTP server and Client support only one different profile. gnutl
           -S "server hello, adding use_srtp extension" \
           -C "SRTP profile:"
 
+# gnutls-cli resolves localhost as an IPv6 address, when enabled,
+# and fails to send messagges over UDP, causing DTLS negotiation to fail.
+# Force server to bind to IPv6 address
+requires_ipv6
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
 run_test  "DTLS-SRTP server doesn't support use_srtp extension. gnutls client" \
-          "$P_SRV dtls=1 debug_level=3" \
+          "$P_SRV dtls=1 debug_level=3 server_addr=::1" \
           "$G_CLI -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_80:SRTP_AES128_CM_HMAC_SHA1_32:SRTP_NULL_HMAC_SHA1_80:SRTP_NULL_SHA1_32" \
           0 \
           -s "found use_srtp extension" \

From ef72faf2bbcdac7df981a598bb25d3961b33f839 Mon Sep 17 00:00:00 2001
From: Ron Eldor <Ron.Eldor@arm.com>
Date: Thu, 12 Jul 2018 11:54:20 +0300
Subject: [PATCH 22/63] Style fixes

1. Adjust to 80 colums where possible.
2. Add \ remove spaces where needed.
3. Fix alignments.

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 include/mbedtls/ssl.h      |  36 +++++++----
 library/ssl_cli.c          | 121 ++++++++++++++++++++++++-------------
 library/ssl_srv.c          |  87 ++++++++++++++++----------
 library/ssl_tls.c          |  66 +++++++++++---------
 programs/ssl/ssl_client2.c |  13 ++--
 programs/ssl/ssl_server2.c |   8 ++-
 6 files changed, 212 insertions(+), 119 deletions(-)

diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index 698334739c40..f60fc9940b8e 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -3190,10 +3190,11 @@ const char *mbedtls_ssl_get_alpn_protocol( const mbedtls_ssl_context *ssl );
  *                          (Default: MBEDTLS_SSL_DTLS_SRTP_MKI_UNSUPPORTED)
  *
  * \param conf              SSL configuration
- * \param support_mki_value Enable or disable (MBEDTLS_SSL_DTLS_SRTP_MKI_UNSUPPORTED or
- *                                    MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED)
+ * \param support_mki_value Enable or disable (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 );
+void mbedtls_ssl_conf_srtp_mki_value_supported( mbedtls_ssl_config *conf,
+                                                int support_mki_value );
 
 /**
  * \brief                   Set the supported DTLS-SRTP protection profiles.
@@ -3205,7 +3206,9 @@ void mbedtls_ssl_conf_srtp_mki_value_supported( mbedtls_ssl_config *conf, int su
  *
  * \return         0 on success, or MBEDTLS_ERR_SSL_BAD_INPUT_DATA.
  */
-int mbedtls_ssl_conf_dtls_srtp_protection_profiles( mbedtls_ssl_config *conf, const mbedtls_ssl_srtp_profile *profiles, size_t profiles_number);
+int mbedtls_ssl_conf_dtls_srtp_protection_profiles( mbedtls_ssl_config *conf,
+                                                    const mbedtls_ssl_srtp_profile *profiles,
+                                                    size_t profiles_number );
 
 /**
  * \brief                   Set the mki_value for the current dtls session.
@@ -3214,9 +3217,12 @@ int mbedtls_ssl_conf_dtls_srtp_protection_profiles( mbedtls_ssl_config *conf, co
  * \param mki_value        MKI value to set
  * \param mki_len          MKI length
  *
- * \return         0 on success, MBEDTLS_ERR_SSL_BAD_INPUT_DATA or MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE
+ * \return         0 on success, MBEDTLS_ERR_SSL_BAD_INPUT_DATA
+ *                 or MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE on failure
  */
-int mbedtls_ssl_dtls_srtp_set_mki_value( mbedtls_ssl_context *ssl, unsigned char* mki_value, size_t mki_len );
+int mbedtls_ssl_dtls_srtp_set_mki_value( mbedtls_ssl_context *ssl,
+                                         unsigned char *mki_value,
+                                         size_t mki_len );
 /**
  * \brief          Get the negotiated DTLS-SRTP Protection Profile.
  *                 This function should be called after the handshake is
@@ -3224,22 +3230,28 @@ int mbedtls_ssl_dtls_srtp_set_mki_value( mbedtls_ssl_context *ssl, unsigned char
  *
  * \param ssl      SSL context
  *
- * \return         Protection Profile enum member, MBEDTLS_SRTP_UNSET_PROFILE if no protocol was negotiated.
+ * \return         Protection Profile enum member,
+ *                 MBEDTLS_SRTP_UNSET_PROFILE if no protocol was negotiated.
  */
 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 80 bytes of key material generated according to RFC5764
+ *                         completed. It shall returns 80 bytes of key material
+ *                         generated according to RFC5764
  *
  * \param ssl              SSL context
  * \param key              Buffer to hold the generated key material
- * \param key_len          [in/out] key buffer size. outputs the actual number of bytes written
+ * \param key_len          [in/out] key buffer size. outputs the actual number
+ *                         of bytes written
  *
- * \return         0 on succes, MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL if the key buffer is too small to hold the generated key
+ * \return         0 on succes, 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_len );
+int mbedtls_ssl_get_dtls_srtp_key_material( const mbedtls_ssl_context *ssl,
+                                            unsigned char *key,
+                                            size_t *key_len );
 
 /**
  * \brief                  Utility function to get information on dtls srtp profile.
@@ -3267,7 +3279,7 @@ const mbedtls_ssl_srtp_profile_info *mbedtls_ssl_dtls_srtp_profile_info_from_id(
  *                 MBEDTLS_SSL_MINOR_VERSION_1 and MBEDTLS_SSL_MINOR_VERSION_2,
  *                 MBEDTLS_SSL_MINOR_VERSION_3 supported)
  */
-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 );
 
 /**
  * \brief          Set the minimum accepted SSL/TLS protocol version
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index d6b429df2fe8..8335f0033c58 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -766,7 +766,8 @@ static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
 
     *olen = 0;
 
-    if( (ssl->conf->dtls_srtp_profile_list == NULL)  || (ssl->conf->dtls_srtp_profile_list_len == 0) )
+    if( (ssl->conf->dtls_srtp_profile_list == NULL) ||
+        (ssl->conf->dtls_srtp_profile_list_len == 0) )
     {
         return;
     }
@@ -785,52 +786,69 @@ static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
      * } UseSRTPData;
 
      * SRTPProtectionProfile SRTPProtectionProfiles<2..2^16-1>;
-     *
      */
     if( ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED &&
-                ssl->dtls_srtp_info.mki_len != 0 )
+        ssl->dtls_srtp_info.mki_len != 0 )
     {
         mki_len = ssl->dtls_srtp_info.mki_len;
     }
-    /* Extension length = 2bytes for profiles length, ssl->conf->dtls_srtp_profile_list_len*2 (each profile is 2 bytes length ) + 1 byte for srtp_mki vector length and the mki_len value */
-    *p++ = (unsigned char)( ( ( 2 + 2*(ssl->conf->dtls_srtp_profile_list_len) + 1 + mki_len ) >> 8 ) & 0xFF );
-    *p++ = (unsigned char)( ( ( 2 + 2*(ssl->conf->dtls_srtp_profile_list_len) + 1 + mki_len )      ) & 0xFF );
-
+    /* Extension length = 2 bytes for profiles length,
+     *                    ssl->conf->dtls_srtp_profile_list_len * 2 (each profile is 2 bytes length ),
+     *                    1 byte for srtp_mki vector length and the mki_len value
+     */
+    *p++ = (unsigned char)( ( ( 2 + 2 * ( ssl->conf->dtls_srtp_profile_list_len )
+                                + 1 + mki_len ) >> 8 ) & 0xFF );
+    *p++ = (unsigned char)( ( ( 2 + 2 * (ssl->conf->dtls_srtp_profile_list_len )
+                                + 1 + mki_len )      ) & 0xFF );
 
     /* protection profile length: 2*(ssl->conf->dtls_srtp_profile_list_len) */
-    *p++ = (unsigned char)( ( ( 2*(ssl->conf->dtls_srtp_profile_list_len) ) >> 8 ) & 0xFF );
-    *p++ = (unsigned char)( ( 2*(ssl->conf->dtls_srtp_profile_list_len) ) & 0xFF );
+    *p++ = (unsigned char)( ( ( 2 * (ssl->conf->dtls_srtp_profile_list_len) )
+                              >> 8 ) & 0xFF );
+    *p++ = (unsigned char)( ( 2 * (ssl->conf->dtls_srtp_profile_list_len) )
+                            & 0xFF );
 
-    for( protection_profiles_index=0; protection_profiles_index < ssl->conf->dtls_srtp_profile_list_len; protection_profiles_index++ )
+    for( protection_profiles_index=0;
+         protection_profiles_index < ssl->conf->dtls_srtp_profile_list_len;
+         protection_profiles_index++ )
     {
         switch (ssl->conf->dtls_srtp_profile_list[protection_profiles_index]) {
             case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80:
                 MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_write_use_srtp_ext, add profile: %04x",
                         MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80_IANA_VALUE ) );
-                *p++ = ( ( ( MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80_IANA_VALUE ) >> 8 ) & 0xFF);
-                *p++ = ( ( MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80_IANA_VALUE ) & 0xFF);
+                *p++ = ( ( ( MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80_IANA_VALUE )
+                            >> 8 ) & 0xFF );
+                *p++ = ( ( MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80_IANA_VALUE )
+                          & 0xFF );
                 break;
             case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32:
                 MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_write_use_srtp_ext, add profile: %04x",
                         MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32_IANA_VALUE ) );
-                *p++ = ( ( ( MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32_IANA_VALUE ) >> 8 ) & 0xFF);
-                *p++ = ( ( MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32_IANA_VALUE ) & 0xFF);
+                *p++ = ( ( ( MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32_IANA_VALUE )
+                            >> 8 ) & 0xFF );
+                *p++ = ( ( MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32_IANA_VALUE )
+                         & 0xFF );
                 break;
             case MBEDTLS_SRTP_NULL_HMAC_SHA1_80:
                 MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_write_use_srtp_ext, add profile: %04x",
                         MBEDTLS_SRTP_NULL_HMAC_SHA1_80_IANA_VALUE ) );
-                *p++ = ( ( ( MBEDTLS_SRTP_NULL_HMAC_SHA1_80_IANA_VALUE ) >> 8 ) & 0xFF);
-                *p++ = ( ( MBEDTLS_SRTP_NULL_HMAC_SHA1_80_IANA_VALUE ) & 0xFF);
+                *p++ = ( ( ( MBEDTLS_SRTP_NULL_HMAC_SHA1_80_IANA_VALUE ) >> 8 )
+                         & 0xFF ) ;
+                *p++ = ( ( MBEDTLS_SRTP_NULL_HMAC_SHA1_80_IANA_VALUE ) & 0xFF );
                 break;
             case MBEDTLS_SRTP_NULL_HMAC_SHA1_32:
                 MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_write_use_srtp_ext, add profile: %04x",
                         MBEDTLS_SRTP_NULL_HMAC_SHA1_32_IANA_VALUE ) );
-                *p++ = ( ( ( MBEDTLS_SRTP_NULL_HMAC_SHA1_32_IANA_VALUE ) >> 8 ) & 0xFF);
-                *p++ = ( ( MBEDTLS_SRTP_NULL_HMAC_SHA1_32_IANA_VALUE ) & 0xFF);
+                *p++ = ( ( ( MBEDTLS_SRTP_NULL_HMAC_SHA1_32_IANA_VALUE ) >> 8 )
+                         & 0xFF );
+                *p++ = ( ( MBEDTLS_SRTP_NULL_HMAC_SHA1_32_IANA_VALUE ) & 0xFF );
                 break;
             default:
-                /* Note: we shall never arrive here as protection profiles is checked by ssl_set_dtls_srtp_protection_profiles function */
-                MBEDTLS_SSL_DEBUG_MSG( 1, ( "client hello, ignore illegal DTLS-SRTP protection profile %d",  ssl->conf->dtls_srtp_profile_list[protection_profiles_index]) );
+                /*
+                 * Note: we shall never arrive here as protection profiles
+                 * is checked by ssl_set_dtls_srtp_protection_profiles function
+                 */
+                MBEDTLS_SSL_DEBUG_MSG( 1, ( "client hello, ignore illegal DTLS-SRTP protection profile %d",
+                                            ssl->conf->dtls_srtp_profile_list[protection_profiles_index]) );
                 break;
         }
     }
@@ -843,11 +861,18 @@ static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
         {
             *p++ = ssl->dtls_srtp_info.mki_value[i];
         }
-        MBEDTLS_SSL_DEBUG_BUF( 3, "sending mki",  ssl->dtls_srtp_info.mki_value, ssl->dtls_srtp_info.mki_len );
+        MBEDTLS_SSL_DEBUG_BUF( 3, "sending mki",  ssl->dtls_srtp_info.mki_value,
+                               ssl->dtls_srtp_info.mki_len );
     }
 
-    /* total extension length: extension type (2 bytes) + extension length (2 bytes) + protection profile length (2 bytes) + 2*nb protection profiles + srtp_mki vector length(1 byte)*/
-    *olen = 2 + 2 + 2 + 2*( ssl->conf->dtls_srtp_profile_list_len ) + 1 + mki_len;
+    /*
+     * total extension length: extension type (2 bytes)
+     *                         + extension length (2 bytes)
+     *                         + protection profile length (2 bytes)
+     *                         + 2 * number of protection profiles
+     *                         + srtp_mki vector length(1 byte)
+     */
+    *olen = 2 + 2 + 2 + 2 * ( ssl->conf->dtls_srtp_profile_list_len ) + 1 + mki_len;
 }
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
 
@@ -1815,7 +1840,8 @@ static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl,
 
 #if defined(MBEDTLS_SSL_DTLS_SRTP)
 static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
-                               const unsigned char *buf, size_t len )
+                                   const unsigned char *buf,
+                                   size_t len )
 {
     mbedtls_ssl_srtp_profile server_protection = MBEDTLS_SRTP_UNSET_PROFILE;
     size_t i, mki_len = 0;
@@ -1823,7 +1849,8 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
     const mbedtls_ssl_srtp_profile_info * profile_info;
 
     /* If use_srtp is not configured, just ignore the extension */
-    if( ( ssl->conf->dtls_srtp_profile_list == NULL ) || ( ssl->conf->dtls_srtp_profile_list_len == 0 ) )
+    if( ssl->conf->dtls_srtp_profile_list == NULL ||
+        ssl->conf->dtls_srtp_profile_list_len == 0  )
         return( 0 );
 
     /* RFC5764 section 4.1.1
@@ -1838,21 +1865,32 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
      *
      */
     if( ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED &&
-                ssl->dtls_srtp_info.mki_len != 0 )
+        ssl->dtls_srtp_info.mki_len != 0 )
     {
         mki_len = ssl->dtls_srtp_info.mki_len;
     }
 
-    /* Length is 5 and optional mki_value : one protection profile(2 bytes) + length(2 bytes) and srtp_mki */
+    /*
+     * Length is 5 and optional mki_value : one protection profile(2 bytes)
+     *                                      + length(2 bytes) and srtp_mki
+     */
     if( ( len != 5 ) && ( len != ( 5 + mki_len ) ) )
         return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
 
     /*
      * get the server protection profile
      */
-    if (((uint16_t)( ( buf[0]<<8 ) | buf[1] ) ) != 0x0002) { /* protection profile length must be 0x0002 as we must have only one protection profile in server Hello */
+
+    /*
+     * protection profile length must be 0x0002 as we must have only
+     * one protection profile in server Hello
+     */
+    if( ( (uint16_t)( ( buf[0] << 8 ) | buf[1] ) ) != 0x0002 )
+    {
         return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
-    } else {
+    }
+    else
+    {
         server_protection_profile_value = ( buf[2] << 8 ) | buf[3];
     }
 
@@ -1863,7 +1901,7 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
      */
     for( i=0; i < ssl->conf->dtls_srtp_profile_list_len; i++)
     {
-        switch ( server_protection_profile_value ) {
+        switch( server_protection_profile_value ) {
             case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80_IANA_VALUE:
                 server_protection = MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80;
                 break;
@@ -1886,7 +1924,7 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
             MBEDTLS_SSL_DEBUG_MSG( 3, ( "found srtp profile: %s", profile_info->name ) );
         }
 
-        if (server_protection == ssl->conf->dtls_srtp_profile_list[i]) {
+        if( server_protection == ssl->conf->dtls_srtp_profile_list[i] ) {
             ssl->dtls_srtp_info.chosen_dtls_srtp_profile = ssl->conf->dtls_srtp_profile_list[i];
             MBEDTLS_SSL_DEBUG_MSG( 3, ( "selected srtp profile: %s", profile_info->name ) );
             break;
@@ -1897,10 +1935,11 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
     if( ssl->dtls_srtp_info.chosen_dtls_srtp_profile == MBEDTLS_SRTP_UNSET_PROFILE )
     {
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                         MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+                                        MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
         return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
     }
-    /* RFC5764:
+    /*
+     * RFC5764:
      *  If the client detects a nonzero-length MKI in the server's response
      *  that is different than the one the client offered, then the client
      *  MUST abort the handshake and SHOULD send an invalid_parameter alert.
@@ -1913,9 +1952,10 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
         return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
     }
 #if defined (MBEDTLS_DEBUG_C)
-    if( len > 5)
+    if( len > 5 )
     {
-        MBEDTLS_SSL_DEBUG_BUF( 3, "received mki",  ssl->dtls_srtp_info.mki_value, ssl->dtls_srtp_info.mki_len );
+        MBEDTLS_SSL_DEBUG_BUF( 3, "received mki",  ssl->dtls_srtp_info.mki_value,
+                                                   ssl->dtls_srtp_info.mki_len );
     }
 #endif
     return 0;
@@ -3469,14 +3509,13 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
     if( ssl->client_auth == 0 )
     {
 #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 ) {
+        /* check if we have a chosen srtp protection profile */
+        if( ssl->dtls_srtp_info.chosen_dtls_srtp_profile != MBEDTLS_SRTP_UNSET_PROFILE ) {
             ret = MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
         }
         else
         {
-#endif
-            /* MBEDTLS_SSL_DTLS_SRTP */
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
             /* Current message is probably the ServerHelloDone */
             ssl->keep_current_message = 1;
 #if defined(MBEDTLS_SSL_DTLS_SRTP)
@@ -4129,8 +4168,8 @@ static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
     if( ssl->client_auth == 0 || mbedtls_ssl_own_cert( ssl ) == NULL )
     {
 #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 ) {
+        /* check if we have a chosen srtp protection profile */
+        if( ssl->dtls_srtp_info.chosen_dtls_srtp_profile != MBEDTLS_SRTP_UNSET_PROFILE ) {
             return ( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
         }
         else
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index 4c59e5b40dcc..38908c840c82 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -778,15 +778,17 @@ static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl,
 
 #if defined(MBEDTLS_SSL_DTLS_SRTP)
 static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
-                               const unsigned char *buf, size_t len )
+                                   const unsigned char *buf,
+                                   size_t len )
 {
     mbedtls_ssl_srtp_profile client_protection = MBEDTLS_SRTP_UNSET_PROFILE;
     size_t i,j;
     size_t profile_length;
-    const mbedtls_ssl_srtp_profile_info * profile_info;
+    const mbedtls_ssl_srtp_profile_info *profile_info;
 
     /* If use_srtp is not configured, just ignore the extension */
-    if( ( ssl->conf->dtls_srtp_profile_list == NULL ) || ( ssl->conf->dtls_srtp_profile_list_len == 0 ) )
+    if( ssl->conf->dtls_srtp_profile_list == NULL ||
+        ssl->conf->dtls_srtp_profile_list_len == 0 )
         return( 0 );
 
     /* RFC5764 section 4.1.1
@@ -798,22 +800,28 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
      * } UseSRTPData;
 
      * SRTPProtectionProfile SRTPProtectionProfiles<2..2^16-1>;
-     *
      */
 
-    /* Min length is 5: at least one protection profile(2 bytes) and length(2 bytes) + srtp_mki length(1 byte) */
+    /*
+     * Min length is 5: at least one protection profile(2 bytes)
+     *                  and length(2 bytes) + srtp_mki length(1 byte)
+     */
     if( len < 5 )
         return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
 
    ssl->dtls_srtp_info.chosen_dtls_srtp_profile = MBEDTLS_SRTP_UNSET_PROFILE;
 
-    profile_length = ( buf[0] << 8 ) | buf[1]; /* first 2 bytes are protection profile length(in bytes) */
+    /* first 2 bytes are protection profile length(in bytes) */
+    profile_length = ( buf[0] << 8 ) | buf[1];
 
-
-    /* parse the extension list values are defined in http://www.iana.org/assignments/srtp-protection/srtp-protection.xhtml */
-    for( j=0; j < profile_length; j+=2 )
+    /*
+     * parse the extension list values are defined in
+     * http://www.iana.org/assignments/srtp-protection/srtp-protection.xhtml
+     */
+    for( j=0; j < profile_length; j += 2 )
     {
-        uint16_t protection_profile_value = buf[j+2]<<8 | buf[j+3]; /* +2 to skip the length field */
+        /* + 2 to skip the length field */
+        uint16_t protection_profile_value = buf[j + 2] << 8 | buf[j+3];
 
         switch ( protection_profile_value )
         {
@@ -854,7 +862,7 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
     if( ( ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED ) &&
           ( len > ( profile_length + 2 ) ) )
     {
-        ssl->dtls_srtp_info.mki_len = buf[ profile_length + 2 ];
+        ssl->dtls_srtp_info.mki_len = buf[profile_length + 2];
         if( ssl->dtls_srtp_info.mki_len > MBEDTLS_DTLS_SRTP_MAX_MKI_LENGTH )
         {
             mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
@@ -863,13 +871,14 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
             return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
         }
 
-        ssl->dtls_srtp_info.mki_len = buf[ profile_length + 2 ];
+        ssl->dtls_srtp_info.mki_len = buf[profile_length + 2];
         for( i=0; i < ssl->dtls_srtp_info.mki_len; i++ )
         {
-            ssl->dtls_srtp_info.mki_value[i] = buf[ profile_length + 2 + 1 + i ];
+            ssl->dtls_srtp_info.mki_value[i] = buf[profile_length + 2 + 1 + i];
         }
 
-        MBEDTLS_SSL_DEBUG_BUF( 3, "using mki",  ssl->dtls_srtp_info.mki_value, ssl->dtls_srtp_info.mki_len );
+        MBEDTLS_SSL_DEBUG_BUF( 3, "using mki",  ssl->dtls_srtp_info.mki_value,
+                                                ssl->dtls_srtp_info.mki_len );
     }
 
      return( 0 );
@@ -2611,7 +2620,8 @@ static void ssl_write_alpn_ext( mbedtls_ssl_context *ssl,
 
 #if defined(MBEDTLS_SSL_DTLS_SRTP ) && defined(MBEDTLS_SSL_PROTO_DTLS)
 static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
-                                unsigned char *buf, size_t *olen )
+                                    unsigned char *buf,
+                                    size_t *olen )
 {
     size_t mki_len = 0, ext_len = 0, i;
 
@@ -2624,7 +2634,7 @@ static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding use_srtp extension" ) );
 
     if( ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED &&
-                ssl->dtls_srtp_info.mki_len != 0 )
+        ssl->dtls_srtp_info.mki_len != 0 )
     {
         mki_len = ssl->dtls_srtp_info.mki_len;
     }
@@ -2632,7 +2642,10 @@ static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
     /* extension */
     buf[0] = (unsigned char)( ( MBEDTLS_TLS_EXT_USE_SRTP >> 8 ) & 0xFF );
     buf[1] = (unsigned char)( ( MBEDTLS_TLS_EXT_USE_SRTP      ) & 0xFF );
-    /* total length 5 and mki value: only one profile(2 bytes) and length(2 bytes) and srtp_mki  ) */
+    /*
+     * total length 5 and mki value: only one profile(2 bytes)
+     *              and length(2 bytes) and srtp_mki  )
+     */
     ext_len = 5 + mki_len;
     buf[2] = (unsigned char)( ( ext_len >> 8 ) & 0xFF );
     buf[3] = (unsigned char)( ext_len & 0xFF );
@@ -2642,20 +2655,28 @@ static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
     buf[5] = 0x02;
     switch (ssl->dtls_srtp_info.chosen_dtls_srtp_profile) {
         case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80:
-            buf[6] = (unsigned char)( ( MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80_IANA_VALUE >> 8) & 0xFF );
-            buf[7] = (unsigned char)( ( MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80_IANA_VALUE     ) & 0xFF );
+            buf[6] = (unsigned char)( ( MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80_IANA_VALUE >> 8 )
+                                      & 0xFF );
+            buf[7] = (unsigned char)( ( MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80_IANA_VALUE     )
+                                      & 0xFF );
             break;
         case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32:
-            buf[6] = (unsigned char)( ( MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32_IANA_VALUE >> 8) & 0xFF );
-            buf[7] = (unsigned char)( ( MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32_IANA_VALUE     ) & 0xFF );
+            buf[6] = (unsigned char)( ( MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32_IANA_VALUE >> 8 )
+                                      & 0xFF );
+            buf[7] = (unsigned char)( ( MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32_IANA_VALUE      )
+                                      & 0xFF );
             break;
         case MBEDTLS_SRTP_NULL_HMAC_SHA1_80:
-            buf[6] = (unsigned char)( ( MBEDTLS_SRTP_NULL_HMAC_SHA1_80_IANA_VALUE >> 8) & 0xFF );
-            buf[7] = (unsigned char)( ( MBEDTLS_SRTP_NULL_HMAC_SHA1_80_IANA_VALUE     ) & 0xFF );
+            buf[6] = (unsigned char)( ( MBEDTLS_SRTP_NULL_HMAC_SHA1_80_IANA_VALUE >> 8 )
+                                      & 0xFF );
+            buf[7] = (unsigned char)( ( MBEDTLS_SRTP_NULL_HMAC_SHA1_80_IANA_VALUE      )
+                                      & 0xFF );
             break;
         case MBEDTLS_SRTP_NULL_HMAC_SHA1_32:
-            buf[6] = (unsigned char)( ( MBEDTLS_SRTP_NULL_HMAC_SHA1_32_IANA_VALUE >> 8) & 0xFF );
-            buf[7] = (unsigned char)( ( MBEDTLS_SRTP_NULL_HMAC_SHA1_32_IANA_VALUE     ) & 0xFF );
+            buf[6] = (unsigned char)( ( MBEDTLS_SRTP_NULL_HMAC_SHA1_32_IANA_VALUE >> 8 )
+                                      & 0xFF );
+            buf[7] = (unsigned char)( ( MBEDTLS_SRTP_NULL_HMAC_SHA1_32_IANA_VALUE      )
+                                      & 0xFF );
             break;
         default:
             *olen = 0;
@@ -2665,7 +2686,7 @@ static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
     buf[8] = mki_len & 0xFF;
     for( i=0; i < mki_len; i++ )
     {
-        buf[ 9 + i ] = ssl->dtls_srtp_info.mki_value[i];
+        buf[9 + i] = ssl->dtls_srtp_info.mki_value[i];
     }
 
     *olen = 9 + mki_len;
@@ -2961,7 +2982,7 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl )
 #endif
 
 #if defined(MBEDTLS_SSL_DTLS_SRTP)
-    ssl_write_use_srtp_ext( ssl, p + 2 + ext_len, &olen);
+    ssl_write_use_srtp_ext( ssl, p + 2 + ext_len, &olen );
     ext_len += olen;
 #endif
 
@@ -3030,11 +3051,15 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
     else
 #endif
 #if defined(MBEDTLS_SSL_DTLS_SRTP)
-    /* check if we have a chosen srtp protection profile, force verify mode to be at least OPTIONAL */
-    if ( ( ssl->dtls_srtp_info.chosen_dtls_srtp_profile != MBEDTLS_SRTP_UNSET_PROFILE ) && ( ssl->conf->authmode == MBEDTLS_SSL_VERIFY_NONE ) ) {
+    /*
+     * check if we have a chosen srtp protection profile,
+     * force verify mode to be at least OPTIONAL
+     */
+    if ( ssl->dtls_srtp_info.chosen_dtls_srtp_profile != MBEDTLS_SRTP_UNSET_PROFILE &&
+         ssl->conf->authmode == MBEDTLS_SSL_VERIFY_NONE ) {
         authmode = MBEDTLS_SSL_VERIFY_OPTIONAL;
     }
-        else
+    else
 #endif
         authmode = ssl->conf->authmode;
 
@@ -3045,7 +3070,7 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
     /* check if we have a chosen srtp protection profile */
         if ( ssl->dtls_srtp_info.chosen_dtls_srtp_profile != MBEDTLS_SRTP_UNSET_PROFILE ) {
             MBEDTLS_SSL_DEBUG_MSG( 2, ( "should not happen" ) );
-            return ( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
+            return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
         }
         else
         {
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 18c86a5ce184..3a0fbfc8a9fc 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -873,19 +873,19 @@ static int ssl_populate_transform( mbedtls_ssl_transform *transform,
 
 #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 :
+    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;
 
-	//ssl->dtls_srtp_info.dtls_srtp_keys = (unsigned char *)mbedtls_calloc(1, ssl->dtls_srtp_info.dtls_srtp_keys_len);
-
-	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 );
+        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 )
         {
@@ -2113,9 +2113,9 @@ int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl )
     if( !mbedtls_ssl_ciphersuite_uses_srv_cert( ciphersuite_info ) )
     {
 #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 ) {
-            return ( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
+        /* check if we have a chosen srtp protection profile */
+        if( ssl->dtls_srtp_info.chosen_dtls_srtp_profile != MBEDTLS_SRTP_UNSET_PROFILE ) {
+            return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
         }
         else
         {
@@ -2754,7 +2754,7 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
                        : ssl->dtls_srtp_info.chosen_dtls_srtp_profile !=
                                MBEDTLS_SRTP_UNSET_PROFILE
                        && ssl->conf->authmode == MBEDTLS_SSL_VERIFY_NONE
-                       ? MBEDTLS_SSL_VERIFY_REQUIRED
+                       ? MBEDTLS_SSL_VERIFY_OPTIONAL
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
                        : ssl->conf->authmode;
 #else
@@ -2763,7 +2763,7 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
             ssl->dtls_srtp_info.chosen_dtls_srtp_profile !=
                                            MBEDTLS_SRTP_UNSET_PROFILE &&
             ssl->conf->authmode == MBEDTLS_SSL_VERIFY_NONE ?
-            MBEDTLS_SSL_VERIFY_REQUIRED :
+            MBEDTLS_SSL_VERIFY_OPTIONAL :
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
             ssl->conf->authmode;
 #endif
@@ -4762,12 +4762,15 @@ const mbedtls_ssl_srtp_profile_info *mbedtls_ssl_dtls_srtp_profile_info_from_id(
     return( NULL );
 }
 
-void mbedtls_ssl_conf_srtp_mki_value_supported( mbedtls_ssl_config *conf, int support_mki_value )
+void mbedtls_ssl_conf_srtp_mki_value_supported( mbedtls_ssl_config *conf,
+                                                int support_mki_value )
 {
     conf->dtls_srtp_mki_support = support_mki_value;
 }
 
-int mbedtls_ssl_dtls_srtp_set_mki_value( mbedtls_ssl_context *ssl, unsigned char* mki_value, size_t mki_len )
+int mbedtls_ssl_dtls_srtp_set_mki_value( mbedtls_ssl_context *ssl,
+                                         unsigned char *mki_value,
+                                         size_t mki_len )
 {
     if ( mki_len > MBEDTLS_DTLS_SRTP_MAX_MKI_LENGTH )
         return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
@@ -4780,20 +4783,22 @@ int mbedtls_ssl_dtls_srtp_set_mki_value( mbedtls_ssl_context *ssl, unsigned char
     return 0;
 }
 
-int mbedtls_ssl_conf_dtls_srtp_protection_profiles( mbedtls_ssl_config *conf, const mbedtls_ssl_srtp_profile *profiles, size_t profiles_number)
+int mbedtls_ssl_conf_dtls_srtp_protection_profiles( mbedtls_ssl_config *conf,
+                                                    const mbedtls_ssl_srtp_profile *profiles,
+                                                    size_t profiles_number )
 {
     size_t i;
     /* check in put validity : must be a list of profiles from enumeration */
     /* maximum length is 4 as only 4 protection profiles are defined */
-    if (profiles_number>4) {
-            return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+    if( profiles_number > 4 ) {
+        return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
     }
 
-    mbedtls_free(conf->dtls_srtp_profile_list);
-    conf->dtls_srtp_profile_list = (mbedtls_ssl_srtp_profile *)mbedtls_calloc(1, profiles_number*sizeof(mbedtls_ssl_srtp_profile));
+    mbedtls_free( conf->dtls_srtp_profile_list );
+    conf->dtls_srtp_profile_list = (mbedtls_ssl_srtp_profile*)mbedtls_calloc(1, profiles_number * sizeof( mbedtls_ssl_srtp_profile ) );
 
-    for (i=0; i<profiles_number; i++) {
-        switch (profiles[i]) {
+    for( i=0; i < profiles_number; i++ ) {
+        switch( profiles[i] ) {
             case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80:
             case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32:
             case MBEDTLS_SRTP_NULL_HMAC_SHA1_80:
@@ -4801,7 +4806,7 @@ int mbedtls_ssl_conf_dtls_srtp_protection_profiles( mbedtls_ssl_config *conf, co
                 conf->dtls_srtp_profile_list[i] = profiles[i];
                 break;
             default:
-                mbedtls_free(conf->dtls_srtp_profile_list);
+                mbedtls_free( conf->dtls_srtp_profile_list );
                 conf->dtls_srtp_profile_list = NULL;
                 conf->dtls_srtp_profile_list_len = 0;
                 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
@@ -4814,19 +4819,22 @@ int mbedtls_ssl_conf_dtls_srtp_protection_profiles( mbedtls_ssl_config *conf, co
     return( 0 );
 }
 
-mbedtls_ssl_srtp_profile mbedtls_ssl_get_dtls_srtp_protection_profile( const mbedtls_ssl_context *ssl)
+mbedtls_ssl_srtp_profile mbedtls_ssl_get_dtls_srtp_protection_profile( const mbedtls_ssl_context *ssl )
 {
-    return( ssl->dtls_srtp_info.chosen_dtls_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_len ) {
+int mbedtls_ssl_get_dtls_srtp_key_material( const mbedtls_ssl_context *ssl,
+                                            unsigned char *key,
+                                            size_t *key_len ) {
 
     /* check output buffer size */
-    if ( *key_len < ssl->dtls_srtp_info.dtls_srtp_keys_len) {
+    if( *key_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);
+    memcpy( key, ssl->dtls_srtp_info.dtls_srtp_keys,
+            ssl->dtls_srtp_info.dtls_srtp_keys_len );
     *key_len = ssl->dtls_srtp_info.dtls_srtp_keys_len;
 
     return 0;
@@ -6931,8 +6939,8 @@ void mbedtls_ssl_free( mbedtls_ssl_context *ssl )
 #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 );
-    //mbedtls_free( ssl->dtls_srtp_keys );
+    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" ) );
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index 4ae740c63c5a..062fa11f69d5 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -561,7 +561,7 @@ struct options
     int query_config_mode;      /* whether to read config                   */
     int use_srtp;               /* Support SRTP                             */
     int force_srtp_profile;     /* SRTP protection profile to use or all    */
-    const char* mki;            /* The dtls mki value to use                */
+    const char *mki;            /* The dtls mki value to use                */
 } opt;
 
 int query_config( const char *config );
@@ -2285,7 +2285,9 @@ int main( int argc, char *argv[] )
         if( opt.force_srtp_profile != DFL_SRTP_FORCE_PROFILE )
         {
             const mbedtls_ssl_srtp_profile forced_profile[] = { opt.force_srtp_profile };
-            ret = mbedtls_ssl_conf_dtls_srtp_protection_profiles( &conf, forced_profile, sizeof( forced_profile ) / sizeof( mbedtls_ssl_srtp_profile ) );
+            ret = mbedtls_ssl_conf_dtls_srtp_protection_profiles( &conf,
+                                                                  forced_profile,
+                                                                  sizeof( forced_profile ) / sizeof( mbedtls_ssl_srtp_profile ) );
         }
         else
         {
@@ -2293,7 +2295,9 @@ int main( int argc, char *argv[] )
                                                                   MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32,
                                                                   MBEDTLS_SRTP_NULL_HMAC_SHA1_80,
                                                                   MBEDTLS_SRTP_NULL_HMAC_SHA1_32 };
-            ret = mbedtls_ssl_conf_dtls_srtp_protection_profiles( &conf, default_profiles, sizeof( default_profiles ) / sizeof( mbedtls_ssl_srtp_profile ) );
+            ret = mbedtls_ssl_conf_dtls_srtp_protection_profiles( &conf,
+                                                                  default_profiles,
+                                                                  sizeof( default_profiles ) / sizeof( mbedtls_ssl_srtp_profile ) );
         }
 
         if( ret != 0 )
@@ -2557,7 +2561,8 @@ 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 )
+        if( ( ret = mbedtls_ssl_dtls_srtp_set_mki_value( &ssl, mki,
+                                                         strlen( mki ) ) ) != 0 )
         {
             mbedtls_printf( " failed\n  ! mbedtls_ssl_dtls_srtp_set_mki_value returned %d\n\n", ret );
             goto exit;
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index 137838c77091..f3c359042f5c 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -3103,7 +3103,9 @@ int main( int argc, char *argv[] )
         if( opt.force_srtp_profile != DFL_SRTP_FORCE_PROFILE )
         {
             const mbedtls_ssl_srtp_profile forced_profile[] = { opt.force_srtp_profile };
-            ret = mbedtls_ssl_conf_dtls_srtp_protection_profiles( &conf, forced_profile, sizeof( forced_profile ) / sizeof( mbedtls_ssl_srtp_profile ) );
+            ret = mbedtls_ssl_conf_dtls_srtp_protection_profiles( &conf,
+                                                                  forced_profile,
+                                                                  sizeof( forced_profile ) / sizeof( mbedtls_ssl_srtp_profile ) );
         }
         else
         {
@@ -3111,7 +3113,9 @@ int main( int argc, char *argv[] )
                                                                   MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32,
                                                                   MBEDTLS_SRTP_NULL_HMAC_SHA1_80,
                                                                   MBEDTLS_SRTP_NULL_HMAC_SHA1_32 };
-            ret = mbedtls_ssl_conf_dtls_srtp_protection_profiles( &conf, default_profiles, sizeof( default_profiles ) / sizeof( mbedtls_ssl_srtp_profile ) );
+            ret = mbedtls_ssl_conf_dtls_srtp_protection_profiles( &conf,
+                                                                  default_profiles,
+                                                                  sizeof( default_profiles ) / sizeof( mbedtls_ssl_srtp_profile ) );
         }
 
         if( ret != 0 )

From a978804a1bded30adcbcc16aca4a229b0a59f601 Mon Sep 17 00:00:00 2001
From: Ron Eldor <Ron.Eldor@arm.com>
Date: Wed, 5 Dec 2018 11:04:31 +0200
Subject: [PATCH 23/63] Style fixes

1. Fix indentations.
2. Remove redundant whitespaces.
3. Keep short lines.
4. Grammar fixes.
5. Rephrase function description.

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 ChangeLog                  |  4 +-
 include/mbedtls/ssl.h      | 84 +++++++++++++++++++++++---------------
 library/ssl_cli.c          | 29 ++++++-------
 library/ssl_srv.c          | 12 +++---
 library/ssl_tls.c          | 44 +++++++++++++-------
 programs/ssl/ssl_client2.c | 23 ++++++-----
 6 files changed, 116 insertions(+), 80 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 69e094ce4497..83b566bdb748 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -731,8 +731,8 @@ Changes
      they are enabled.
 
 Features
-   * Add support for DTLS-SRTP as defined in RFC 5764. Based on contribution done
-     by Johan Pascal in #361.
+   * Add support for DTLS-SRTP as defined in RFC 5764. Based on #361 contributed
+     by Johan Pascal.
 
 = mbed TLS 2.16.0 branch released 2018-12-21
 
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index f60fc9940b8e..1f8d1769c211 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -415,7 +415,8 @@
 #define MBEDTLS_TLS_EXT_RENEGOTIATION_INFO      0xFF01
 
 /*
- * use_srtp extension protection profiles values as defined in http://www.iana.org/assignments/srtp-protection/srtp-protection.xhtml
+ * Use_srtp extension protection profiles values as defined in
+ * http://www.iana.org/assignments/srtp-protection/srtp-protection.xhtml
  */
 #define MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80_IANA_VALUE     0x0001
 #define MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32_IANA_VALUE     0x0002
@@ -890,10 +891,17 @@ mbedtls_ssl_srtp_profile_info;
 
 typedef struct mbedtls_dtls_srtp_info_t
 {
-    mbedtls_ssl_srtp_profile chosen_dtls_srtp_profile; /*!< negotiated SRTP profile */
-    unsigned char dtls_srtp_keys[MBEDTLS_DTLS_SRTP_MAX_KEY_MATERIAL_LENGTH]; /*!< master keys and master salt for SRTP generated during handshake */
-    size_t dtls_srtp_keys_len; /*!< length in bytes of master keys and master salt for SRTP generated during handshake */
-    unsigned char mki_value[MBEDTLS_DTLS_SRTP_MAX_MKI_LENGTH]; /* opaque srtp_mki<0..255> */
+    /*! 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 */
     size_t                 mki_len;
 }
 mbedtls_dtls_srtp_info;
@@ -1107,8 +1115,10 @@ struct mbedtls_ssl_config
 #endif
 
 #if defined(MBEDTLS_SSL_DTLS_SRTP)
-    mbedtls_ssl_srtp_profile *dtls_srtp_profile_list; /*!< ordered list of supported srtp profile */
-    size_t dtls_srtp_profile_list_len; /*!< number of supported profiles */
+    /*! ordered list of supported srtp profile */
+    mbedtls_ssl_srtp_profile *dtls_srtp_profile_list;
+    /*! number of supported profiles */
+    size_t dtls_srtp_profile_list_len;
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
 
     /*
@@ -3186,12 +3196,14 @@ const char *mbedtls_ssl_get_alpn_protocol( const mbedtls_ssl_context *ssl );
 
 #if defined(MBEDTLS_SSL_DTLS_SRTP)
 /**
- * \brief                   Add support for mki value in use_srtp extension
- *                          (Default: MBEDTLS_SSL_DTLS_SRTP_MKI_UNSUPPORTED)
+ * \brief                   Add support for mki value in use_srtp extension.
+ *                          The default value is
+ *                          #MBEDTLS_SSL_DTLS_SRTP_MKI_UNSUPPORTED.
  *
  * \param conf              SSL configuration
- * \param support_mki_value Enable or disable (MBEDTLS_SSL_DTLS_SRTP_MKI_UNSUPPORTED
- *                          or MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED)
+ * \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 );
@@ -3204,21 +3216,22 @@ void mbedtls_ssl_conf_srtp_mki_value_supported( mbedtls_ssl_config *conf,
  *                          in decreasing preference order.
  * \param profiles_number   Number of supported profiles.
  *
- * \return         0 on success, or MBEDTLS_ERR_SSL_BAD_INPUT_DATA.
+ * \return                  0 on success, or #MBEDTLS_ERR_SSL_BAD_INPUT_DATA.
  */
-int mbedtls_ssl_conf_dtls_srtp_protection_profiles( mbedtls_ssl_config *conf,
-                                                    const mbedtls_ssl_srtp_profile *profiles,
-                                                    size_t profiles_number );
+int mbedtls_ssl_conf_dtls_srtp_protection_profiles
+                               ( mbedtls_ssl_config *conf,
+                                 const mbedtls_ssl_srtp_profile *profiles,
+                                 size_t profiles_number );
 
 /**
- * \brief                   Set the mki_value for the current dtls session.
+ * \brief                  Set the mki_value for the current DTLS-SRTP session.
  *
- * \param ssl              SSL context
- * \param mki_value        MKI value to set
- * \param mki_len          MKI length
+ * \param ssl              SSL context to use.
+ * \param mki_value        The MKI value to set.
+ * \param mki_len          The length of the MKI value.
  *
- * \return         0 on success, MBEDTLS_ERR_SSL_BAD_INPUT_DATA
- *                 or MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE on failure
+ * \return         0 on success, #MBEDTLS_ERR_SSL_BAD_INPUT_DATA
+ *                 or #MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE on failure
  */
 int mbedtls_ssl_dtls_srtp_set_mki_value( mbedtls_ssl_context *ssl,
                                          unsigned char *mki_value,
@@ -3231,36 +3244,39 @@ int mbedtls_ssl_dtls_srtp_set_mki_value( mbedtls_ssl_context *ssl,
  * \param ssl      SSL context
  *
  * \return         Protection Profile enum member,
- *                 MBEDTLS_SRTP_UNSET_PROFILE if no protocol was negotiated.
+ *                 #MBEDTLS_SRTP_UNSET_PROFILE if no protocol was negotiated.
  */
-mbedtls_ssl_srtp_profile mbedtls_ssl_get_dtls_srtp_protection_profile( const 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 80 bytes of key material
- *                         generated according to RFC5764
+ *                         completed. It shall returns 60 bytes of key material
+ *                         generated according to RFC 5764
  *
- * \param ssl              SSL context
- * \param key              Buffer to hold the generated key material
+ * \param ssl              SSL context tobe used.
+ * \param key              Buffer to hold the generated key material.
  * \param key_len          [in/out] key buffer size. outputs the actual number
- *                         of bytes written
+ *                         of bytes written.
  *
- * \return         0 on succes, MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL if the key buffer
- *                 is too small to hold the generated 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_len );
 
 /**
- * \brief                  Utility function to get information on dtls srtp profile.
+ * \brief                  Utility function to get information on DTLS-SRTP profile.
  *
  * \param profile          The dtls-srtp profile id to get info on.
  *
- * \return         mbedtls_ssl_srtp_profile_info* on success, NULL if not found
+ * \return                 Address of the SRTP profile information structure on
+ *                         success,NULL if not found.
  */
-const mbedtls_ssl_srtp_profile_info *mbedtls_ssl_dtls_srtp_profile_info_from_id( mbedtls_ssl_srtp_profile profile );
+const mbedtls_ssl_srtp_profile_info *mbedtls_ssl_dtls_srtp_profile_info_from_id
+                                           ( mbedtls_ssl_srtp_profile profile );
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
 
 /**
@@ -3279,7 +3295,7 @@ const mbedtls_ssl_srtp_profile_info *mbedtls_ssl_dtls_srtp_profile_info_from_id(
  *                 MBEDTLS_SSL_MINOR_VERSION_1 and MBEDTLS_SSL_MINOR_VERSION_2,
  *                 MBEDTLS_SSL_MINOR_VERSION_3 supported)
  */
-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 );
 
 /**
  * \brief          Set the minimum accepted SSL/TLS protocol version
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index 8335f0033c58..13547ce8a02b 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -756,9 +756,9 @@ static int ssl_write_alpn_ext( mbedtls_ssl_context *ssl,
 }
 #endif /* MBEDTLS_SSL_ALPN */
 
-#if defined (MBEDTLS_SSL_DTLS_SRTP)
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
 static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
-                                unsigned char *buf, size_t *olen )
+                                    unsigned char *buf, size_t *olen )
 {
     unsigned char *p = buf;
     size_t protection_profiles_index = 0;
@@ -766,8 +766,8 @@ static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
 
     *olen = 0;
 
-    if( (ssl->conf->dtls_srtp_profile_list == NULL) ||
-        (ssl->conf->dtls_srtp_profile_list_len == 0) )
+    if( ( ssl->conf->dtls_srtp_profile_list == NULL ) ||
+        ( ssl->conf->dtls_srtp_profile_list_len == 0  ) )
     {
         return;
     }
@@ -777,14 +777,13 @@ static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
     *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_USE_SRTP >> 8 ) & 0xFF );
     *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_USE_SRTP      ) & 0xFF );
 
-    /* RFC5764 section 4.1.1
+    /* RFC 5764 section 4.1.1
      * uint8 SRTPProtectionProfile[2];
      *
      * struct {
      *   SRTPProtectionProfiles SRTPProtectionProfiles;
      *   opaque srtp_mki<0..255>;
      * } UseSRTPData;
-
      * SRTPProtectionProfile SRTPProtectionProfiles<2..2^16-1>;
      */
     if( ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED &&
@@ -811,7 +810,7 @@ static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
          protection_profiles_index < ssl->conf->dtls_srtp_profile_list_len;
          protection_profiles_index++ )
     {
-        switch (ssl->conf->dtls_srtp_profile_list[protection_profiles_index]) {
+        switch( ssl->conf->dtls_srtp_profile_list[protection_profiles_index] ) {
             case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80:
                 MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_write_use_srtp_ext, add profile: %04x",
                         MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80_IANA_VALUE ) );
@@ -848,7 +847,7 @@ static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
                  * is checked by ssl_set_dtls_srtp_protection_profiles function
                  */
                 MBEDTLS_SSL_DEBUG_MSG( 1, ( "client hello, ignore illegal DTLS-SRTP protection profile %d",
-                                            ssl->conf->dtls_srtp_profile_list[protection_profiles_index]) );
+                                            ssl->conf->dtls_srtp_profile_list[protection_profiles_index] ) );
                 break;
         }
     }
@@ -1853,7 +1852,7 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
         ssl->conf->dtls_srtp_profile_list_len == 0  )
         return( 0 );
 
-    /* RFC5764 section 4.1.1
+    /* RFC 5764 section 4.1.1
      * uint8 SRTPProtectionProfile[2];
      *
      * struct {
@@ -1954,11 +1953,11 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
 #if defined (MBEDTLS_DEBUG_C)
     if( len > 5 )
     {
-        MBEDTLS_SSL_DEBUG_BUF( 3, "received mki",  ssl->dtls_srtp_info.mki_value,
-                                                   ssl->dtls_srtp_info.mki_len );
+        MBEDTLS_SSL_DEBUG_BUF( 3, "received mki", ssl->dtls_srtp_info.mki_value,
+                                                  ssl->dtls_srtp_info.mki_len );
     }
 #endif
-    return 0;
+    return( 0 );
 }
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
 
@@ -3510,7 +3509,8 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
     {
 #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 ) {
+        if( ssl->dtls_srtp_info.chosen_dtls_srtp_profile != MBEDTLS_SRTP_UNSET_PROFILE )
+        {
             ret = MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
         }
         else
@@ -4169,7 +4169,8 @@ static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
     {
 #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 ) {
+        if( ssl->dtls_srtp_info.chosen_dtls_srtp_profile != MBEDTLS_SRTP_UNSET_PROFILE )
+        {
             return ( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
         }
         else
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index 38908c840c82..fae8f6063466 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -847,7 +847,7 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
             MBEDTLS_SSL_DEBUG_MSG( 3, ( "found srtp profile: %s", profile_info->name ) );
         }
         /* check if suggested profile is in our list */
-        for( i=0; i < ssl->conf->dtls_srtp_profile_list_len; i++)
+        for( i = 0; i < ssl->conf->dtls_srtp_profile_list_len; i++)
         {
             if( client_protection == ssl->conf->dtls_srtp_profile_list[i] )
             {
@@ -860,7 +860,7 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
             break;
     }
     if( ( ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED ) &&
-          ( len > ( profile_length + 2 ) ) )
+        ( len > ( profile_length + 2 ) ) )
     {
         ssl->dtls_srtp_info.mki_len = buf[profile_length + 2];
         if( ssl->dtls_srtp_info.mki_len > MBEDTLS_DTLS_SRTP_MAX_MKI_LENGTH )
@@ -3056,7 +3056,8 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
      * force verify mode to be at least OPTIONAL
      */
     if ( ssl->dtls_srtp_info.chosen_dtls_srtp_profile != MBEDTLS_SRTP_UNSET_PROFILE &&
-         ssl->conf->authmode == MBEDTLS_SSL_VERIFY_NONE ) {
+         ssl->conf->authmode == MBEDTLS_SSL_VERIFY_NONE )
+    {
         authmode = MBEDTLS_SSL_VERIFY_OPTIONAL;
     }
     else
@@ -3067,8 +3068,9 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
         authmode == MBEDTLS_SSL_VERIFY_NONE )
     {
 #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 ) {
+        /* check if we have a chosen srtp protection profile */
+        if ( ssl->dtls_srtp_info.chosen_dtls_srtp_profile != MBEDTLS_SRTP_UNSET_PROFILE )
+        {
             MBEDTLS_SSL_DEBUG_MSG( 2, ( "should not happen" ) );
             return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
         }
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 3a0fbfc8a9fc..0ec29135de84 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -873,10 +873,11 @@ static int ssl_populate_transform( mbedtls_ssl_transform *transform,
 
 #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 ) {
+    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 :
+         * 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
@@ -2114,7 +2115,8 @@ int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl )
     {
 #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 ) {
+        if( ssl->dtls_srtp_info.chosen_dtls_srtp_profile != MBEDTLS_SRTP_UNSET_PROFILE )
+	{
             return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
         }
         else
@@ -4773,14 +4775,18 @@ int mbedtls_ssl_dtls_srtp_set_mki_value( mbedtls_ssl_context *ssl,
                                          size_t mki_len )
 {
     if ( mki_len > MBEDTLS_DTLS_SRTP_MAX_MKI_LENGTH )
+    {
         return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+    }
 
     if( ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_UNSUPPORTED )
+    {
         return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
+    }
 
     memcpy( ssl->dtls_srtp_info.mki_value, mki_value, mki_len );
     ssl->dtls_srtp_info.mki_len = mki_len;
-    return 0;
+    return( 0 );
 }
 
 int mbedtls_ssl_conf_dtls_srtp_protection_profiles( mbedtls_ssl_config *conf,
@@ -4788,14 +4794,19 @@ int mbedtls_ssl_conf_dtls_srtp_protection_profiles( mbedtls_ssl_config *conf,
                                                     size_t profiles_number )
 {
     size_t i;
-    /* check in put validity : must be a list of profiles from enumeration */
-    /* maximum length is 4 as only 4 protection profiles are defined */
-    if( profiles_number > 4 ) {
-        return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+    /*
+     * Check input validity : must be a list of profiles from enumeration.
+     * Maximum length is 4 as only 4 protection profiles are defined.
+     */
+    if( profiles_number > 4 )
+    {
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
     }
 
     mbedtls_free( conf->dtls_srtp_profile_list );
-    conf->dtls_srtp_profile_list = (mbedtls_ssl_srtp_profile*)mbedtls_calloc(1, profiles_number * sizeof( mbedtls_ssl_srtp_profile ) );
+    conf->dtls_srtp_profile_list =
+            (mbedtls_ssl_srtp_profile*)mbedtls_calloc(1,
+             profiles_number * sizeof( mbedtls_ssl_srtp_profile ) );
 
     for( i=0; i < profiles_number; i++ ) {
         switch( profiles[i] ) {
@@ -4809,7 +4820,7 @@ int mbedtls_ssl_conf_dtls_srtp_protection_profiles( mbedtls_ssl_config *conf,
                 mbedtls_free( conf->dtls_srtp_profile_list );
                 conf->dtls_srtp_profile_list = NULL;
                 conf->dtls_srtp_profile_list_len = 0;
-                return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+                return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
         }
     }
 
@@ -4819,25 +4830,28 @@ int mbedtls_ssl_conf_dtls_srtp_protection_profiles( mbedtls_ssl_config *conf,
     return( 0 );
 }
 
-mbedtls_ssl_srtp_profile mbedtls_ssl_get_dtls_srtp_protection_profile( const mbedtls_ssl_context *ssl )
+mbedtls_ssl_srtp_profile
+     mbedtls_ssl_get_dtls_srtp_protection_profile( const mbedtls_ssl_context *ssl )
 {
     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_len ) {
+                                            size_t *key_len )
+{
 
     /* check output buffer size */
-    if( *key_len < ssl->dtls_srtp_info.dtls_srtp_keys_len ) {
-        return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
+    if( *key_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 );
     *key_len = ssl->dtls_srtp_info.dtls_srtp_keys_len;
 
-    return 0;
+    return( 0 );
 }
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
 
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index 062fa11f69d5..8bfd0c3291d3 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -2285,19 +2285,22 @@ int main( int argc, char *argv[] )
         if( opt.force_srtp_profile != DFL_SRTP_FORCE_PROFILE )
         {
             const mbedtls_ssl_srtp_profile forced_profile[] = { opt.force_srtp_profile };
-            ret = mbedtls_ssl_conf_dtls_srtp_protection_profiles( &conf,
-                                                                  forced_profile,
-                                                                  sizeof( forced_profile ) / sizeof( mbedtls_ssl_srtp_profile ) );
+            ret = mbedtls_ssl_conf_dtls_srtp_protection_profiles
+                    ( &conf,
+                     forced_profile,
+                     sizeof( forced_profile ) / sizeof( mbedtls_ssl_srtp_profile ) );
         }
         else
         {
-            const mbedtls_ssl_srtp_profile default_profiles[] = { MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80,
-                                                                  MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32,
-                                                                  MBEDTLS_SRTP_NULL_HMAC_SHA1_80,
-                                                                  MBEDTLS_SRTP_NULL_HMAC_SHA1_32 };
-            ret = mbedtls_ssl_conf_dtls_srtp_protection_profiles( &conf,
-                                                                  default_profiles,
-                                                                  sizeof( default_profiles ) / sizeof( mbedtls_ssl_srtp_profile ) );
+            const mbedtls_ssl_srtp_profile default_profiles[] =
+                { MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80,
+                  MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32,
+                  MBEDTLS_SRTP_NULL_HMAC_SHA1_80,
+                  MBEDTLS_SRTP_NULL_HMAC_SHA1_32 };
+            ret = mbedtls_ssl_conf_dtls_srtp_protection_profiles
+                    ( &conf,
+                      default_profiles,
+                      sizeof( default_profiles ) / sizeof( mbedtls_ssl_srtp_profile ) );
         }
 
         if( ret != 0 )

From 089c9fe9fa0eb7419b0c40b9b52b4349f8cb26c5 Mon Sep 17 00:00:00 2001
From: Ron Eldor <Ron.Eldor@arm.com>
Date: Thu, 6 Dec 2018 17:12:49 +0200
Subject: [PATCH 24/63] Improve readability

Improve readability of the code:
1. move common code to `ssl_internal.h` as `static inline`.
2. Add comments.
3. Use local variables for extension size.
4. Change function signature, by adding buffer size and output length.
5. Take server srtp profile out of the loop.

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 include/mbedtls/ssl.h          |   7 +-
 include/mbedtls/ssl_internal.h |  48 +++++++++++++
 library/ssl_cli.c              | 125 +++++++++++++++------------------
 library/ssl_srv.c              |  58 ++++-----------
 library/ssl_tls.c              |   7 +-
 5 files changed, 123 insertions(+), 122 deletions(-)

diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index 1f8d1769c211..6bcb5ecb9872 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -3257,15 +3257,16 @@ mbedtls_ssl_srtp_profile mbedtls_ssl_get_dtls_srtp_protection_profile
  *
  * \param ssl              SSL context tobe used.
  * \param key              Buffer to hold the generated key material.
- * \param key_len          [in/out] key buffer size. outputs the actual number
- *                         of bytes written.
+ * \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_len );
+                                            size_t key_buffer_len,
+                                            size_t *olen );
 
 /**
  * \brief                  Utility function to get information on DTLS-SRTP profile.
diff --git a/include/mbedtls/ssl_internal.h b/include/mbedtls/ssl_internal.h
index 7b78c7310edf..c3923ee9d12c 100644
--- a/include/mbedtls/ssl_internal.h
+++ b/include/mbedtls/ssl_internal.h
@@ -1095,6 +1095,54 @@ 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 uint16_t mbedtls_ssl_get_srtp_profile_iana_value
+                                            ( mbedtls_ssl_srtp_profile profile )
+{
+    uint16_t profile_value = 0xffff;
+    switch( profile )
+    {
+        case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80:
+            profile_value = MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80_IANA_VALUE;
+            break;
+        case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32:
+            profile_value = MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32_IANA_VALUE;
+            break;
+        case MBEDTLS_SRTP_NULL_HMAC_SHA1_80:
+            profile_value = MBEDTLS_SRTP_NULL_HMAC_SHA1_80_IANA_VALUE;
+            break;
+        case MBEDTLS_SRTP_NULL_HMAC_SHA1_32:
+            profile_value = MBEDTLS_SRTP_NULL_HMAC_SHA1_32_IANA_VALUE;
+            break;
+        default: break;
+    }
+    return( profile_value );
+}
+
+static inline mbedtls_ssl_srtp_profile mbedtls_ssl_get_srtp_profile_value
+                                                    ( uint16_t srtp_iana_value )
+{
+    mbedtls_ssl_srtp_profile profile_value = MBEDTLS_SRTP_UNSET_PROFILE;
+    switch( srtp_iana_value )
+    {
+        case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80_IANA_VALUE:
+            profile_value = MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80;
+            break;
+        case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32_IANA_VALUE:
+            profile_value = MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32;
+            break;
+        case MBEDTLS_SRTP_NULL_HMAC_SHA1_80_IANA_VALUE:
+            profile_value = MBEDTLS_SRTP_NULL_HMAC_SHA1_80;
+            break;
+        case MBEDTLS_SRTP_NULL_HMAC_SHA1_32_IANA_VALUE:
+            profile_value = MBEDTLS_SRTP_NULL_HMAC_SHA1_32;
+            break;
+        default: break;
+    }
+    return( profile_value );
+}
+#endif
+
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
 static inline mbedtls_pk_context *mbedtls_ssl_own_key( mbedtls_ssl_context *ssl )
 {
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index 13547ce8a02b..261fb2f83af0 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -763,6 +763,8 @@ static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
     unsigned char *p = buf;
     size_t protection_profiles_index = 0;
     size_t mki_len = 0, i;
+    size_t ext_len = 0;
+    uint16_t profile_value = 0;
 
     *olen = 0;
 
@@ -795,10 +797,10 @@ static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
      *                    ssl->conf->dtls_srtp_profile_list_len * 2 (each profile is 2 bytes length ),
      *                    1 byte for srtp_mki vector length and the mki_len value
      */
-    *p++ = (unsigned char)( ( ( 2 + 2 * ( ssl->conf->dtls_srtp_profile_list_len )
-                                + 1 + mki_len ) >> 8 ) & 0xFF );
-    *p++ = (unsigned char)( ( ( 2 + 2 * (ssl->conf->dtls_srtp_profile_list_len )
-                                + 1 + mki_len )      ) & 0xFF );
+    ext_len = 2 + 2 * ( ssl->conf->dtls_srtp_profile_list_len ) + 1 + mki_len;
+
+    *p++ = (unsigned char)( ( ( ext_len & 0xFF00 ) >> 8 ) & 0xFF );
+    *p++ = (unsigned char)( ext_len & 0xFF );
 
     /* protection profile length: 2*(ssl->conf->dtls_srtp_profile_list_len) */
     *p++ = (unsigned char)( ( ( 2 * (ssl->conf->dtls_srtp_profile_list_len) )
@@ -810,45 +812,23 @@ static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
          protection_profiles_index < ssl->conf->dtls_srtp_profile_list_len;
          protection_profiles_index++ )
     {
-        switch( ssl->conf->dtls_srtp_profile_list[protection_profiles_index] ) {
-            case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80:
-                MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_write_use_srtp_ext, add profile: %04x",
-                        MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80_IANA_VALUE ) );
-                *p++ = ( ( ( MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80_IANA_VALUE )
-                            >> 8 ) & 0xFF );
-                *p++ = ( ( MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80_IANA_VALUE )
-                          & 0xFF );
-                break;
-            case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32:
-                MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_write_use_srtp_ext, add profile: %04x",
-                        MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32_IANA_VALUE ) );
-                *p++ = ( ( ( MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32_IANA_VALUE )
-                            >> 8 ) & 0xFF );
-                *p++ = ( ( MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32_IANA_VALUE )
-                         & 0xFF );
-                break;
-            case MBEDTLS_SRTP_NULL_HMAC_SHA1_80:
-                MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_write_use_srtp_ext, add profile: %04x",
-                        MBEDTLS_SRTP_NULL_HMAC_SHA1_80_IANA_VALUE ) );
-                *p++ = ( ( ( MBEDTLS_SRTP_NULL_HMAC_SHA1_80_IANA_VALUE ) >> 8 )
-                         & 0xFF ) ;
-                *p++ = ( ( MBEDTLS_SRTP_NULL_HMAC_SHA1_80_IANA_VALUE ) & 0xFF );
-                break;
-            case MBEDTLS_SRTP_NULL_HMAC_SHA1_32:
-                MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_write_use_srtp_ext, add profile: %04x",
-                        MBEDTLS_SRTP_NULL_HMAC_SHA1_32_IANA_VALUE ) );
-                *p++ = ( ( ( MBEDTLS_SRTP_NULL_HMAC_SHA1_32_IANA_VALUE ) >> 8 )
-                         & 0xFF );
-                *p++ = ( ( MBEDTLS_SRTP_NULL_HMAC_SHA1_32_IANA_VALUE ) & 0xFF );
-                break;
-            default:
-                /*
-                 * Note: we shall never arrive here as protection profiles
-                 * is checked by ssl_set_dtls_srtp_protection_profiles function
-                 */
-                MBEDTLS_SSL_DEBUG_MSG( 1, ( "client hello, ignore illegal DTLS-SRTP protection profile %d",
-                                            ssl->conf->dtls_srtp_profile_list[protection_profiles_index] ) );
-                break;
+        profile_value = mbedtls_ssl_get_srtp_profile_iana_value
+                ( ssl->conf->dtls_srtp_profile_list[protection_profiles_index] );
+        if( profile_value != 0xFFFF )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_write_use_srtp_ext, add profile: %04x",
+                                        profile_value ) );
+            *p++ = ( ( profile_value >> 8 ) & 0xFF );
+            *p++ = ( profile_value & 0xFF );
+        }
+        else
+        {
+            /*
+             * Note: we shall never arrive here as protection profiles
+             * is checked by ssl_set_dtls_srtp_protection_profiles function
+             */
+            MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, ignore illegal DTLS-SRTP protection profile %d",
+                                        ssl->conf->dtls_srtp_profile_list[protection_profiles_index] ) );
         }
     }
 
@@ -1884,13 +1864,17 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
      * protection profile length must be 0x0002 as we must have only
      * one protection profile in server Hello
      */
-    if( ( (uint16_t)( ( buf[0] << 8 ) | buf[1] ) ) != 0x0002 )
+    if( (  buf[0] != 0 ) || ( buf[1] != 2 ) )
     {
         return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
     }
-    else
+
+    server_protection_profile_value = ( buf[2] << 8 ) | buf[3];
+    server_protection = mbedtls_ssl_get_srtp_profile_value( server_protection_profile_value );
+    profile_info = mbedtls_ssl_dtls_srtp_profile_info_from_id( server_protection );
+    if( profile_info != NULL )
     {
-        server_protection_profile_value = ( buf[2] << 8 ) | buf[3];
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "found srtp profile: %s", profile_info->name ) );
     }
 
     ssl->dtls_srtp_info.chosen_dtls_srtp_profile = MBEDTLS_SRTP_UNSET_PROFILE;
@@ -1900,29 +1884,6 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
      */
     for( i=0; i < ssl->conf->dtls_srtp_profile_list_len; i++)
     {
-        switch( server_protection_profile_value ) {
-            case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80_IANA_VALUE:
-                server_protection = MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80;
-                break;
-            case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32_IANA_VALUE:
-                server_protection = MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32;
-                break;
-            case MBEDTLS_SRTP_NULL_HMAC_SHA1_80_IANA_VALUE:
-                server_protection = MBEDTLS_SRTP_NULL_HMAC_SHA1_80;
-                break;
-            case MBEDTLS_SRTP_NULL_HMAC_SHA1_32_IANA_VALUE:
-                server_protection = MBEDTLS_SRTP_NULL_HMAC_SHA1_32;
-                break;
-            default:
-                server_protection = MBEDTLS_SRTP_UNSET_PROFILE;
-                break;
-        }
-        profile_info = mbedtls_ssl_dtls_srtp_profile_info_from_id( server_protection );
-        if( profile_info != NULL )
-        {
-            MBEDTLS_SSL_DEBUG_MSG( 3, ( "found srtp profile: %s", profile_info->name ) );
-        }
-
         if( server_protection == ssl->conf->dtls_srtp_profile_list[i] ) {
             ssl->dtls_srtp_info.chosen_dtls_srtp_profile = ssl->conf->dtls_srtp_profile_list[i];
             MBEDTLS_SSL_DEBUG_MSG( 3, ( "selected srtp profile: %s", profile_info->name ) );
@@ -4168,7 +4129,31 @@ static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
     if( ssl->client_auth == 0 || mbedtls_ssl_own_cert( ssl ) == NULL )
     {
 #if defined(MBEDTLS_SSL_DTLS_SRTP)
-        /* check if we have a chosen srtp protection profile */
+        /*
+         * Check if we have a chosen srtp protection profile.
+         * According to RFC 5764 section 4.1 client certificate in dtls srtp
+         * is mandatory:
+         *        Client                               Server
+         *
+         *   ClientHello + use_srtp   -------->
+         *                                 ServerHello + use_srtp
+         *                                           Certificate*
+         *                                     ServerKeyExchange*
+         *                                     ertificateRequest*
+         *                            <--------   ServerHelloDone
+         *   Certificate*
+         *   ClientKeyExchange
+         *   CertificateVerify*
+         *   [ChangeCipherSpec]
+         *   Finished                 -------->
+         *                                     [ChangeCipherSpec]
+         *                            <--------          Finished
+         *   SRTP packets             <------->      SRTP packets
+         *
+         * Note that '*' indicates messages that are not always sent in DTLS.
+         * The CertificateRequest, client and server Certificates, and
+         * CertificateVerify will be sent in DTLS-SRTP.
+         */
         if( ssl->dtls_srtp_info.chosen_dtls_srtp_profile != MBEDTLS_SRTP_UNSET_PROFILE )
         {
             return ( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index fae8f6063466..fa1c94c7cd71 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -822,25 +822,8 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
     {
         /* + 2 to skip the length field */
         uint16_t protection_profile_value = buf[j + 2] << 8 | buf[j+3];
+        client_protection = mbedtls_ssl_get_srtp_profile_value( protection_profile_value );
 
-        switch ( protection_profile_value )
-        {
-            case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80_IANA_VALUE:
-                client_protection = MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80;
-                break;
-            case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32_IANA_VALUE:
-                client_protection = MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32;
-                break;
-            case MBEDTLS_SRTP_NULL_HMAC_SHA1_80_IANA_VALUE:
-                client_protection = MBEDTLS_SRTP_NULL_HMAC_SHA1_80;
-                break;
-            case MBEDTLS_SRTP_NULL_HMAC_SHA1_32_IANA_VALUE:
-                client_protection = MBEDTLS_SRTP_NULL_HMAC_SHA1_32;
-                break;
-            default:
-                client_protection = MBEDTLS_SRTP_UNSET_PROFILE;
-                break;
-        }
         profile_info = mbedtls_ssl_dtls_srtp_profile_info_from_id( client_protection );
         if( profile_info != NULL )
         {
@@ -2624,6 +2607,7 @@ static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
                                     size_t *olen )
 {
     size_t mki_len = 0, ext_len = 0, i;
+    uint16_t profile_value = 0;
 
     if( ssl->dtls_srtp_info.chosen_dtls_srtp_profile == MBEDTLS_SRTP_UNSET_PROFILE )
     {
@@ -2653,34 +2637,16 @@ static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
     /* protection profile length: 2 */
     buf[4] = 0x00;
     buf[5] = 0x02;
-    switch (ssl->dtls_srtp_info.chosen_dtls_srtp_profile) {
-        case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80:
-            buf[6] = (unsigned char)( ( MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80_IANA_VALUE >> 8 )
-                                      & 0xFF );
-            buf[7] = (unsigned char)( ( MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80_IANA_VALUE     )
-                                      & 0xFF );
-            break;
-        case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32:
-            buf[6] = (unsigned char)( ( MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32_IANA_VALUE >> 8 )
-                                      & 0xFF );
-            buf[7] = (unsigned char)( ( MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32_IANA_VALUE      )
-                                      & 0xFF );
-            break;
-        case MBEDTLS_SRTP_NULL_HMAC_SHA1_80:
-            buf[6] = (unsigned char)( ( MBEDTLS_SRTP_NULL_HMAC_SHA1_80_IANA_VALUE >> 8 )
-                                      & 0xFF );
-            buf[7] = (unsigned char)( ( MBEDTLS_SRTP_NULL_HMAC_SHA1_80_IANA_VALUE      )
-                                      & 0xFF );
-            break;
-        case MBEDTLS_SRTP_NULL_HMAC_SHA1_32:
-            buf[6] = (unsigned char)( ( MBEDTLS_SRTP_NULL_HMAC_SHA1_32_IANA_VALUE >> 8 )
-                                      & 0xFF );
-            buf[7] = (unsigned char)( ( MBEDTLS_SRTP_NULL_HMAC_SHA1_32_IANA_VALUE      )
-                                      & 0xFF );
-            break;
-        default:
-            *olen = 0;
-            return;
+    profile_value = mbedtls_ssl_get_srtp_profile_iana_value( ssl->dtls_srtp_info.chosen_dtls_srtp_profile );
+    if( profile_value != 0xFFFF )
+    {
+        buf[6] = (unsigned char)( ( profile_value >> 8 ) & 0xFF );
+        buf[7] = (unsigned char)( profile_value & 0xFF );
+    }
+    else
+    {
+        *olen = 0;
+        return;
     }
 
     buf[8] = mki_len & 0xFF;
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 0ec29135de84..b15df14d6b38 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -4838,18 +4838,19 @@ mbedtls_ssl_srtp_profile
 
 int mbedtls_ssl_get_dtls_srtp_key_material( const mbedtls_ssl_context *ssl,
                                             unsigned char *key,
-                                            size_t *key_len )
+                                            size_t key_buffer_len,
+                                            size_t *olen )
 {
 
     /* check output buffer size */
-    if( *key_len < ssl->dtls_srtp_info.dtls_srtp_keys_len )
+    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 );
-    *key_len = ssl->dtls_srtp_info.dtls_srtp_keys_len;
+    *olen = ssl->dtls_srtp_info.dtls_srtp_keys_len;
 
     return( 0 );
 }

From f0f7c19457eb9bc05661b41cf246a66bcb13c5dd Mon Sep 17 00:00:00 2001
From: Ron Eldor <Ron.Eldor@arm.com>
Date: Thu, 6 Dec 2018 17:21:52 +0200
Subject: [PATCH 25/63] Add comment describing the feature

Add a comment that describes that the feature only supportes the
`use_srtp` extension, and not hte full DTLS-SRTP RFC.

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 include/mbedtls/config.h | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h
index 2ed3ec29e815..cd7c073b36fc 100644
--- a/include/mbedtls/config.h
+++ b/include/mbedtls/config.h
@@ -1815,7 +1815,10 @@
 /**
  * \def MBEDTLS_SSL_DTLS_SRTP
  *
- * Enable support for DTLS-SRTP, RFC5764
+ * Enable support for DTLS-SRTP, RFC5764, use_srtp extension.
+ * \note Only the dtls-srtp key material negotiation is supported.
+ * Once negotiated, the key should be extracted, and data should be transmitted
+ * via an SRTP stack.
  *
  * Requires: MBEDTLS_SSL_PROTO_DTLS
  *

From 75870ec6a7ad82a60a0faceeb4f2aca321e28cec Mon Sep 17 00:00:00 2001
From: Ron Eldor <Ron.Eldor@arm.com>
Date: Thu, 6 Dec 2018 17:31:55 +0200
Subject: [PATCH 26/63] Change byte copy to memcpy

Change setting the mki value byte after byte with `memcpy()`.

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 library/ssl_cli.c | 7 ++-----
 library/ssl_srv.c | 7 ++-----
 2 files changed, 4 insertions(+), 10 deletions(-)

diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index 261fb2f83af0..a6940f994e30 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -762,7 +762,7 @@ static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
 {
     unsigned char *p = buf;
     size_t protection_profiles_index = 0;
-    size_t mki_len = 0, i;
+    size_t mki_len = 0;
     size_t ext_len = 0;
     uint16_t profile_value = 0;
 
@@ -836,10 +836,7 @@ static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
 
     if( mki_len != 0 )
     {
-        for( i=0; i < mki_len; i++ )
-        {
-            *p++ = ssl->dtls_srtp_info.mki_value[i];
-        }
+        memcpy( p, ssl->dtls_srtp_info.mki_value, mki_len );
         MBEDTLS_SSL_DEBUG_BUF( 3, "sending mki",  ssl->dtls_srtp_info.mki_value,
                                ssl->dtls_srtp_info.mki_len );
     }
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index fa1c94c7cd71..38cdd91a2d3f 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -2606,7 +2606,7 @@ static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
                                     unsigned char *buf,
                                     size_t *olen )
 {
-    size_t mki_len = 0, ext_len = 0, i;
+    size_t mki_len = 0, ext_len = 0;
     uint16_t profile_value = 0;
 
     if( ssl->dtls_srtp_info.chosen_dtls_srtp_profile == MBEDTLS_SRTP_UNSET_PROFILE )
@@ -2650,10 +2650,7 @@ static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
     }
 
     buf[8] = mki_len & 0xFF;
-    for( i=0; i < mki_len; i++ )
-    {
-        buf[9 + i] = ssl->dtls_srtp_info.mki_value[i];
-    }
+    memcpy( &buf[9], ssl->dtls_srtp_info.mki_value, mki_len );
 
     *olen = 9 + mki_len;
 }

From 313d7b5d744866078bb9db579833b261930251c5 Mon Sep 17 00:00:00 2001
From: Ron Eldor <Ron.Eldor@arm.com>
Date: Mon, 10 Dec 2018 14:56:21 +0200
Subject: [PATCH 27/63] Add variable validation

1. Check allocation success.
2. Check parameter correctness in the use_srtp extension
in server and client.

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 library/ssl_cli.c | 16 ++++++++++------
 library/ssl_srv.c | 18 +++++++++++++++---
 library/ssl_tls.c |  2 ++
 3 files changed, 27 insertions(+), 9 deletions(-)

diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index a6940f994e30..fd177acaf6be 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -837,6 +837,10 @@ static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
     if( mki_len != 0 )
     {
         memcpy( p, ssl->dtls_srtp_info.mki_value, mki_len );
+        /*
+         * Increment p to point to the current position.
+         */
+        p += mki_len;
         MBEDTLS_SSL_DEBUG_BUF( 3, "sending mki",  ssl->dtls_srtp_info.mki_value,
                                ssl->dtls_srtp_info.mki_len );
     }
@@ -847,8 +851,9 @@ static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
      *                         + protection profile length (2 bytes)
      *                         + 2 * number of protection profiles
      *                         + srtp_mki vector length(1 byte)
+     *                         + mki value
      */
-    *olen = 2 + 2 + 2 + 2 * ( ssl->conf->dtls_srtp_profile_list_len ) + 1 + mki_len;
+    *olen = p - buf;
 }
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
 
@@ -1848,7 +1853,8 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
 
     /*
      * Length is 5 and optional mki_value : one protection profile(2 bytes)
-     *                                      + length(2 bytes) and srtp_mki
+     *                                      + length(2 bytes) + mki_len(1 byte)
+     *                                      and optional srtp_mki
      */
     if( ( len != 5 ) && ( len != ( 5 + mki_len ) ) )
         return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
@@ -1862,9 +1868,7 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
      * one protection profile in server Hello
      */
     if( (  buf[0] != 0 ) || ( buf[1] != 2 ) )
-    {
         return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
-    }
 
     server_protection_profile_value = ( buf[2] << 8 ) | buf[3];
     server_protection = mbedtls_ssl_get_srtp_profile_value( server_protection_profile_value );
@@ -1901,8 +1905,8 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
      *  that is different than the one the client offered, then the client
      *  MUST abort the handshake and SHOULD send an invalid_parameter alert.
      */
-    if( len > 5  &&
-        ( memcmp( ssl->dtls_srtp_info.mki_value, &buf[5], mki_len ) ) )
+    if( len > 5  && ( buf[4] != mki_len ||
+        ( memcmp( ssl->dtls_srtp_info.mki_value, &buf[5], mki_len ) ) ) )
     {
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index 38cdd91a2d3f..56e0cbf55ddf 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -785,6 +785,8 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
     size_t i,j;
     size_t profile_length;
     const mbedtls_ssl_srtp_profile_info *profile_info;
+    /*! 2 bytes for profile length and 1 byte for mki len */
+    const size_t size_of_lengths = 3;
 
     /* If use_srtp is not configured, just ignore the extension */
     if( ssl->conf->dtls_srtp_profile_list == NULL ||
@@ -806,14 +808,24 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
      * Min length is 5: at least one protection profile(2 bytes)
      *                  and length(2 bytes) + srtp_mki length(1 byte)
      */
-    if( len < 5 )
+    if( len < size_of_lengths + 2 )
+    {
+        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->dtls_srtp_info.chosen_dtls_srtp_profile = MBEDTLS_SRTP_UNSET_PROFILE;
 
     /* first 2 bytes are protection profile length(in bytes) */
     profile_length = ( buf[0] << 8 ) | buf[1];
 
+    if( profile_length > len - size_of_lengths )
+    {
+        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 );
+    }
     /*
      * parse the extension list values are defined in
      * http://www.iana.org/assignments/srtp-protection/srtp-protection.xhtml
@@ -846,7 +858,8 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
         ( len > ( profile_length + 2 ) ) )
     {
         ssl->dtls_srtp_info.mki_len = buf[profile_length + 2];
-        if( ssl->dtls_srtp_info.mki_len > MBEDTLS_DTLS_SRTP_MAX_MKI_LENGTH )
+        if( ssl->dtls_srtp_info.mki_len > MBEDTLS_DTLS_SRTP_MAX_MKI_LENGTH ||
+            ssl->dtls_srtp_info.mki_len + profile_length + size_of_lengths != len )
         {
             mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                             MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
@@ -854,7 +867,6 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
             return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
         }
 
-        ssl->dtls_srtp_info.mki_len = buf[profile_length + 2];
         for( i=0; i < ssl->dtls_srtp_info.mki_len; i++ )
         {
             ssl->dtls_srtp_info.mki_value[i] = buf[profile_length + 2 + 1 + i];
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index b15df14d6b38..1b4779b4fb1c 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -4807,6 +4807,8 @@ int mbedtls_ssl_conf_dtls_srtp_protection_profiles( mbedtls_ssl_config *conf,
     conf->dtls_srtp_profile_list =
             (mbedtls_ssl_srtp_profile*)mbedtls_calloc(1,
              profiles_number * sizeof( mbedtls_ssl_srtp_profile ) );
+    if( conf->dtls_srtp_profile_list == NULL )
+        return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
 
     for( i=0; i < profiles_number; i++ ) {
         switch( profiles[i] ) {

From 9cfb5ebff19c586fc063e9ed9a08105b7807ac0b Mon Sep 17 00:00:00 2001
From: Ron Eldor <Ron.Eldor@arm.com>
Date: Mon, 10 Dec 2018 15:30:14 +0200
Subject: [PATCH 28/63] Disable SRTP by default

Disable `MBEDTLS_SSL_DTLS_SRTP` by default in the configuration file.

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 include/mbedtls/config.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h
index cd7c073b36fc..7a1a2b1e518b 100644
--- a/include/mbedtls/config.h
+++ b/include/mbedtls/config.h
@@ -1822,9 +1822,9 @@
  *
  * Requires: MBEDTLS_SSL_PROTO_DTLS
  *
- * Comment this to disable support for DTLS-SRTP.
+ * Uncomment this to enable support for use_srtp extension.
  */
-#define MBEDTLS_SSL_DTLS_SRTP
+//#define MBEDTLS_SSL_DTLS_SRTP
 
 /**
  * \def MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE

From 5d991c954903dcbf4162b07f6866d60a91f490c1 Mon Sep 17 00:00:00 2001
From: Ron Eldor <Ron.Eldor@arm.com>
Date: Tue, 15 Jan 2019 18:54:03 +0200
Subject: [PATCH 29/63] Force IPv4 in gnutls_cli srtp tests

Force using IPv4 in the GNU_CLI SRTP tests, as introduced for
other tests in #1918.

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 tests/ssl-opt.sh | 71 ++++++++++++++++++++----------------------------
 1 file changed, 29 insertions(+), 42 deletions(-)

diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index ad38f5d267b5..bb31a3cdec27 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -9003,14 +9003,11 @@ run_test  "DTLS-SRTP all profiles supported. server doesn't support mki. openssl
           -C "dumping 'received mki' (8 bytes)" \
           -C "error"
 
-# gnutls-cli resolves localhost as an IPv6 address, when enabled,
-# and fails to send messagges over UDP, causing DTLS negotiation to fail.
-# Force server to bind to IPv6 address
-requires_ipv6
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+requires_gnutls
 run_test  "DTLS-SRTP all profiles supported. gnutls client." \
-          "$P_SRV dtls=1 use_srtp=1 debug_level=3 server_addr=::1" \
-          "$G_CLI -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_80:SRTP_AES128_CM_HMAC_SHA1_32:SRTP_NULL_HMAC_SHA1_80:SRTP_NULL_SHA1_32" \
+          "$P_SRV dtls=1 use_srtp=1 debug_level=3" \
+          "$G_CLI -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_80:SRTP_AES128_CM_HMAC_SHA1_32:SRTP_NULL_HMAC_SHA1_80:SRTP_NULL_SHA1_32 --insecure 127.0.0.1" \
           0 \
           -s "found use_srtp extension" \
           -s "found srtp profile" \
@@ -9018,14 +9015,11 @@ run_test  "DTLS-SRTP all profiles supported. gnutls client." \
           -s "server hello, adding use_srtp extension" \
           -c "SRTP profile: SRTP_AES128_CM_HMAC_SHA1_80"
 
-# gnutls-cli resolves localhost as an IPv6 address, when enabled,
-# and fails to send messagges over UDP, causing DTLS negotiation to fail.
-# Force server to bind to IPv6 address
-requires_ipv6
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+requires_gnutls
 run_test  "DTLS-SRTP server supports all profiles. Client supports all profiles, in different order. gnutls client." \
-          "$P_SRV dtls=1 use_srtp=1 debug_level=3 server_addr=::1" \
-          "$G_CLI -u --srtp-profiles=SRTP_NULL_HMAC_SHA1_80:SRTP_AES128_CM_HMAC_SHA1_80:SRTP_NULL_SHA1_32:SRTP_AES128_CM_HMAC_SHA1_32" \
+          "$P_SRV dtls=1 use_srtp=1 debug_level=3" \
+          "$G_CLI -u --srtp-profiles=SRTP_NULL_HMAC_SHA1_80:SRTP_AES128_CM_HMAC_SHA1_80:SRTP_NULL_SHA1_32:SRTP_AES128_CM_HMAC_SHA1_32 --insecure 127.0.0.1" \
           0 \
           -s "found use_srtp extension" \
           -s "found srtp profile" \
@@ -9033,14 +9027,11 @@ run_test  "DTLS-SRTP server supports all profiles. Client supports all profiles,
           -s "server hello, adding use_srtp extension" \
           -c "SRTP profile: SRTP_NULL_HMAC_SHA1_80"
 
-# gnutls-cli resolves localhost as an IPv6 address, when enabled,
-# and fails to send messagges over UDP, causing DTLS negotiation to fail.
-# Force server to bind to IPv6 address
-requires_ipv6
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+requires_gnutls
 run_test  "DTLS-SRTP server supports all profiles. Client supports one profile. gnutls client." \
-          "$P_SRV dtls=1 use_srtp=1 debug_level=3 server_addr=::1" \
-          "$G_CLI -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_32" \
+          "$P_SRV dtls=1 use_srtp=1 debug_level=3" \
+          "$G_CLI -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_32 --insecure 127.0.0.1" \
           0 \
           -s "found use_srtp extension" \
           -s "found srtp profile: MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32" \
@@ -9048,14 +9039,11 @@ run_test  "DTLS-SRTP server supports all profiles. Client supports one profile.
           -s "server hello, adding use_srtp extension" \
           -c "SRTP profile: SRTP_AES128_CM_HMAC_SHA1_32"
 
-# gnutls-cli resolves localhost as an IPv6 address, when enabled,
-# and fails to send messagges over UDP, causing DTLS negotiation to fail.
-# Force server to bind to IPv6 address
-requires_ipv6
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+requires_gnutls
 run_test  "DTLS-SRTP server supports one profile. Client supports all profiles. gnutls client." \
-          "$P_SRV dtls=1 use_srtp=1 srtp_force_profile=4 debug_level=3 server_addr=::1" \
-          "$G_CLI -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_80:SRTP_AES128_CM_HMAC_SHA1_32:SRTP_NULL_HMAC_SHA1_80:SRTP_NULL_SHA1_32" \
+          "$P_SRV dtls=1 use_srtp=1 srtp_force_profile=4 debug_level=3" \
+          "$G_CLI -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_80:SRTP_AES128_CM_HMAC_SHA1_32:SRTP_NULL_HMAC_SHA1_80:SRTP_NULL_SHA1_32 --insecure 127.0.0.1" \
           0 \
           -s "found use_srtp extension" \
           -s "found srtp profile" \
@@ -9063,14 +9051,11 @@ run_test  "DTLS-SRTP server supports one profile. Client supports all profiles.
           -s "server hello, adding use_srtp extension" \
           -c "SRTP profile: SRTP_NULL_SHA1_32"
 
-# gnutls-cli resolves localhost as an IPv6 address, when enabled,
-# and fails to send messagges over UDP, causing DTLS negotiation to fail.
-# Force server to bind to IPv6 address
-requires_ipv6
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+requires_gnutls
 run_test  "DTLS-SRTP server and Client support only one matching profile. gnutls client." \
-          "$P_SRV dtls=1 use_srtp=1 srtp_force_profile=2 debug_level=3 server_addr=::1" \
-          "$G_CLI -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_32" \
+          "$P_SRV dtls=1 use_srtp=1 srtp_force_profile=2 debug_level=3" \
+          "$G_CLI -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_32 --insecure 127.0.0.1" \
           0 \
           -s "found use_srtp extension" \
           -s "found srtp profile" \
@@ -9078,14 +9063,11 @@ run_test  "DTLS-SRTP server and Client support only one matching profile. gnutls
           -s "server hello, adding use_srtp extension" \
           -c "SRTP profile: SRTP_AES128_CM_HMAC_SHA1_32"
 
-# gnutls-cli resolves localhost as an IPv6 address, when enabled,
-# and fails to send messagges over UDP, causing DTLS negotiation to fail.
-# Force server to bind to IPv6 address
-requires_ipv6
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+requires_gnutls
 run_test  "DTLS-SRTP server and Client support only one different profile. gnutls client." \
-          "$P_SRV dtls=1 use_srtp=1 srtp_force_profile=1 debug_level=3 server_addr=::1" \
-          "$G_CLI -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_32" \
+          "$P_SRV dtls=1 use_srtp=1 srtp_force_profile=1 debug_level=3" \
+          "$G_CLI -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_32 --insecure 127.0.0.1" \
           0 \
           -s "found use_srtp extension" \
           -s "found srtp profile" \
@@ -9093,20 +9075,18 @@ run_test  "DTLS-SRTP server and Client support only one different profile. gnutl
           -S "server hello, adding use_srtp extension" \
           -C "SRTP profile:"
 
-# gnutls-cli resolves localhost as an IPv6 address, when enabled,
-# and fails to send messagges over UDP, causing DTLS negotiation to fail.
-# Force server to bind to IPv6 address
-requires_ipv6
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+requires_gnutls
 run_test  "DTLS-SRTP server doesn't support use_srtp extension. gnutls client" \
-          "$P_SRV dtls=1 debug_level=3 server_addr=::1" \
-          "$G_CLI -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_80:SRTP_AES128_CM_HMAC_SHA1_32:SRTP_NULL_HMAC_SHA1_80:SRTP_NULL_SHA1_32" \
+          "$P_SRV dtls=1 debug_level=3" \
+          "$G_CLI -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_80:SRTP_AES128_CM_HMAC_SHA1_32:SRTP_NULL_HMAC_SHA1_80:SRTP_NULL_SHA1_32 --insecure 127.0.0.1" \
           0 \
           -s "found use_srtp extension" \
           -S "server hello, adding use_srtp extension" \
           -C "SRTP profile:"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+requires_gnutls
 run_test  "DTLS-SRTP all profiles supported. gnutls server" \
           "$G_SRV -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_80:SRTP_AES128_CM_HMAC_SHA1_32:SRTP_NULL_HMAC_SHA1_80:SRTP_NULL_SHA1_32" \
           "$P_CLI dtls=1 use_srtp=1 debug_level=3" \
@@ -9118,6 +9098,7 @@ run_test  "DTLS-SRTP all profiles supported. gnutls server" \
           -C "error"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+requires_gnutls
 run_test  "DTLS-SRTP server supports all profiles. Client supports all profiles, in different order. gnutls server." \
           "$G_SRV -u --srtp-profiles=SRTP_NULL_SHA1_32:SRTP_AES128_CM_HMAC_SHA1_32:SRTP_AES128_CM_HMAC_SHA1_80:SRTP_NULL_HMAC_SHA1_80:SRTP_NULL_SHA1_32" \
           "$P_CLI dtls=1 use_srtp=1 debug_level=3" \
@@ -9129,6 +9110,7 @@ run_test  "DTLS-SRTP server supports all profiles. Client supports all profiles,
           -C "error"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+requires_gnutls
 run_test  "DTLS-SRTP server supports all profiles. Client supports one profile. gnutls server." \
           "$G_SRV -u --srtp-profiles=SRTP_NULL_SHA1_32:SRTP_AES128_CM_HMAC_SHA1_32:SRTP_AES128_CM_HMAC_SHA1_80:SRTP_NULL_HMAC_SHA1_80:SRTP_NULL_SHA1_32" \
           "$P_CLI dtls=1 use_srtp=1 srtp_force_profile=2 debug_level=3" \
@@ -9140,6 +9122,7 @@ run_test  "DTLS-SRTP server supports all profiles. Client supports one profile.
           -C "error"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+requires_gnutls
 run_test  "DTLS-SRTP server supports one profile. Client supports all profiles. gnutls server." \
           "$G_SRV -u --srtp-profiles=SRTP_NULL_HMAC_SHA1_80" \
           "$P_CLI dtls=1 use_srtp=30 debug_level=3" \
@@ -9151,6 +9134,7 @@ run_test  "DTLS-SRTP server supports one profile. Client supports all profiles.
           -C "error"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+requires_gnutls
 run_test  "DTLS-SRTP server and Client support only one matching profile. gnutls server." \
           "$G_SRV -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_32" \
           "$P_CLI dtls=1 use_srtp=1 srtp_force_profile=2 debug_level=3" \
@@ -9162,6 +9146,7 @@ run_test  "DTLS-SRTP server and Client support only one matching profile. gnutls
           -C "error"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+requires_gnutls
 run_test  "DTLS-SRTP server and Client support only one different profile. gnutls server." \
           "$G_SRV -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_32" \
           "$P_CLI dtls=1 use_srtp=1 srtp_force_profile=4 debug_level=3" \
@@ -9173,6 +9158,7 @@ run_test  "DTLS-SRTP server and Client support only one different profile. gnutl
           -C "error"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+requires_gnutls
 run_test  "DTLS-SRTP server doesn't support use_srtp extension. gnutls server" \
           "$G_SRV -u" \
           "$P_CLI dtls=1 use_srtp=1 debug_level=3" \
@@ -9184,6 +9170,7 @@ run_test  "DTLS-SRTP server doesn't support use_srtp extension. gnutls server" \
           -C "error"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+requires_gnutls
 run_test  "DTLS-SRTP all profiles supported. mki used. gnutls server." \
           "$G_SRV -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_80:SRTP_AES128_CM_HMAC_SHA1_32:SRTP_NULL_HMAC_SHA1_80:SRTP_NULL_SHA1_32" \
           "$P_CLI dtls=1 use_srtp=1 mki=542310ab34290481 debug_level=3" \

From 65b56ef87f3222fff7dc599dd23e6c2aa5491419 Mon Sep 17 00:00:00 2001
From: Ron Eldor <Ron.Eldor@arm.com>
Date: Thu, 26 Sep 2019 16:40:48 +0300
Subject: [PATCH 30/63] 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 <johan.pascal@belledonne-communications.com>
---
 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 6bcb5ecb9872..a85909377988 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 1b4779b4fb1c..5d98caa2a0be 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 8bfd0c3291d3..448f1572ab79 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 @@ static int nss_keylog_export( void *p_expkey,
                               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 f3c359042f5c..93fea686cdc2 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 @@ static int nss_keylog_export( void *p_expkey,
     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 @@ 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 defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
     ret = report_cid_usage( &ssl, "initial handshake" );

From 8f284c1b05fb79785f4e20f1f47901853f8e0cca Mon Sep 17 00:00:00 2001
From: Ron Eldor <Ron.Eldor@arm.com>
Date: Thu, 26 Sep 2019 16:43:03 +0300
Subject: [PATCH 31/63] Add the SRTP configuration to query_config

Add the DTLS_SRTP configuration to `query_config`.

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 programs/test/query_config.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/programs/test/query_config.c b/programs/test/query_config.c
index c35502fa43d6..1345b11fec01 100644
--- a/programs/test/query_config.c
+++ b/programs/test/query_config.c
@@ -1480,6 +1480,14 @@ int query_config( const char *config )
     }
 #endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */
 
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+    if( strcmp( "MBEDTLS_SSL_DTLS_SRTP", config ) == 0 )
+    {
+        MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_DTLS_SRTP );
+        return( 0 );
+    }
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+
 #if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE)
     if( strcmp( "MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE", config ) == 0 )
     {

From 44c0a0a60a00bddd4ef45263f8f777bb31189cc3 Mon Sep 17 00:00:00 2001
From: Johan Pascal <johan.pascal@belledonne-communications.com>
Date: Fri, 24 Apr 2020 02:11:42 +0700
Subject: [PATCH 32/63] Stick to ChangeLog rules

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 ChangeLog                         | 4 ----
 ChangeLog.d/feature-dtls-srtp.txt | 2 ++
 2 files changed, 2 insertions(+), 4 deletions(-)
 create mode 100644 ChangeLog.d/feature-dtls-srtp.txt

diff --git a/ChangeLog b/ChangeLog
index 83b566bdb748..594c3cf4a4cc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -730,10 +730,6 @@ Changes
    * Ciphersuites based on 3DES now have the lowest priority by default when
      they are enabled.
 
-Features
-   * Add support for DTLS-SRTP as defined in RFC 5764. Based on #361 contributed
-     by Johan Pascal.
-
 = mbed TLS 2.16.0 branch released 2018-12-21
 
 Features
diff --git a/ChangeLog.d/feature-dtls-srtp.txt b/ChangeLog.d/feature-dtls-srtp.txt
new file mode 100644
index 000000000000..8b9186bb9904
--- /dev/null
+++ b/ChangeLog.d/feature-dtls-srtp.txt
@@ -0,0 +1,2 @@
+Features
+* Add support for DTLS-SRTP as defined in RFC 5764. Contributed by Johan Pascal, improved by Ron Eldor.

From b64eab76562c57fda78935dd90fd9175f93fc7f0 Mon Sep 17 00:00:00 2001
From: Johan Pascal <johan.pascal@belledonne-communications.com>
Date: Fri, 24 Apr 2020 02:53:49 +0700
Subject: [PATCH 33/63] fix style

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 library/ssl_tls.c          | 2 +-
 programs/ssl/ssl_client2.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 5d98caa2a0be..63244a1eba12 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -2091,7 +2091,7 @@ int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl )
 #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 )
-	{
+        {
             return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
         }
         else
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index 448f1572ab79..6a377bd1c564 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -1800,7 +1800,7 @@ int main( int argc, char *argv[] )
             opt.skip_close_notify = atoi( q );
             if( opt.skip_close_notify < 0 || opt.skip_close_notify > 1 )
                 goto usage;
-	}
+        }
         else if( strcmp( p, "use_srtp" ) == 0 )
         {
             opt.use_srtp = atoi ( q );

From 1d957e61eb577a78fdc2053d4ac695f21d1c7db6 Mon Sep 17 00:00:00 2001
From: Johan Pascal <johan.pascal@belledonne-communications.com>
Date: Thu, 7 May 2020 04:20:15 +0700
Subject: [PATCH 34/63] Fix build warning

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 programs/ssl/ssl_client2.c | 2 +-
 programs/ssl/ssl_server2.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index 6a377bd1c564..c34390f88fe8 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -2761,7 +2761,7 @@ int main( int argc, char *argv[] )
                                          != 0 )
         {
             mbedtls_printf( " failed\n  ! mbedtls_ssl_tls_prf returned -0x%x\n\n",
-                            -ret );
+                            (unsigned int) -ret );
             goto exit;
         }
 
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index 93fea686cdc2..dd365b7f0697 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -3872,7 +3872,7 @@ int main( int argc, char *argv[] )
                                          != 0 )
         {
             mbedtls_printf( " failed\n  ! mbedtls_ssl_tls_prf returned -0x%x\n\n",
-                            -ret );
+                            (unsigned int) -ret );
             goto exit;
         }
 

From 48f62e98a83b2099e1f4da55591952f20a1a181d Mon Sep 17 00:00:00 2001
From: Johan Pascal <johan.pascal@belledonne-communications.com>
Date: Sat, 22 Aug 2020 22:04:20 +0200
Subject: [PATCH 35/63] Fix ssl_client2 after rebase

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 programs/ssl/ssl_client2.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index c34390f88fe8..82627ff723b6 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -1195,6 +1195,7 @@ 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";

From 8526957cd5e463e9617f703bb6bb1d93912cd92c Mon Sep 17 00:00:00 2001
From: Johan Pascal <johan.pascal@belledonne-communications.com>
Date: Tue, 25 Aug 2020 10:01:54 +0200
Subject: [PATCH 36/63] Minor style modifications

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 include/mbedtls/ssl.h          | 38 ++++++++++++++++++++--------------
 include/mbedtls/ssl_internal.h | 16 +++++++-------
 library/ssl_srv.c              |  8 ++++++-
 library/ssl_tls.c              |  2 +-
 programs/ssl/ssl_client2.c     |  4 ++--
 programs/ssl/ssl_server2.c     |  2 +-
 6 files changed, 41 insertions(+), 29 deletions(-)

diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index a85909377988..a1056b77303d 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -418,10 +418,10 @@
  * Use_srtp extension protection profiles values as defined in
  * http://www.iana.org/assignments/srtp-protection/srtp-protection.xhtml
  */
-#define MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80_IANA_VALUE     0x0001
-#define MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32_IANA_VALUE     0x0002
-#define MBEDTLS_SRTP_NULL_HMAC_SHA1_80_IANA_VALUE          0x0005
-#define MBEDTLS_SRTP_NULL_HMAC_SHA1_32_IANA_VALUE          0x0006
+#define MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80     0x0001
+#define MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32     0x0002
+#define MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80          0x0005
+#define MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32          0x0006
 
 /*
  * Size defines
@@ -867,8 +867,8 @@ typedef void mbedtls_ssl_async_cancel_t( mbedtls_ssl_context *ssl );
 
 #if defined(MBEDTLS_SSL_DTLS_SRTP)
 
-#define MBEDTLS_DTLS_SRTP_MAX_KEY_MATERIAL_LENGTH    60
-#define MBEDTLS_DTLS_SRTP_MAX_MKI_LENGTH             255
+#define MBEDTLS_TLS_SRTP_MAX_KEY_MATERIAL_LENGTH    60
+#define MBEDTLS_TLS_SRTP_MAX_MKI_LENGTH             255
 /*
  * List of SRTP profiles for DTLS-SRTP
  */
@@ -894,7 +894,7 @@ typedef struct mbedtls_dtls_srtp_info_t
     /*! The SRTP profile that was negotiated*/
     mbedtls_ssl_srtp_profile chosen_dtls_srtp_profile;
     /*! The mki_value used, with max size of 256 bytes */
-    unsigned char mki_value[MBEDTLS_DTLS_SRTP_MAX_MKI_LENGTH];
+    unsigned char mki_value[MBEDTLS_TLS_SRTP_MAX_MKI_LENGTH];
     /*! The length of mki_value */
     size_t                 mki_len;
 }
@@ -3190,7 +3190,9 @@ const char *mbedtls_ssl_get_alpn_protocol( const mbedtls_ssl_context *ssl );
 
 #if defined(MBEDTLS_SSL_DTLS_SRTP)
 /**
- * \brief                   Add support for mki value in use_srtp extension.
+ * \brief                   Add 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.
  *
@@ -3210,7 +3212,8 @@ void mbedtls_ssl_conf_srtp_mki_value_supported( mbedtls_ssl_config *conf,
  *                          in decreasing preference order.
  * \param profiles_number   Number of supported profiles.
  *
- * \return                  0 on success, or #MBEDTLS_ERR_SSL_BAD_INPUT_DATA.
+ * \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,
@@ -3224,8 +3227,9 @@ int mbedtls_ssl_conf_dtls_srtp_protection_profiles
  * \param mki_value        The MKI value to set.
  * \param mki_len          The length of the MKI value.
  *
- * \return         0 on success, #MBEDTLS_ERR_SSL_BAD_INPUT_DATA
- *                 or #MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE on failure
+ * \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,
@@ -3235,10 +3239,11 @@ int mbedtls_ssl_dtls_srtp_set_mki_value( mbedtls_ssl_context *ssl,
  *                 This function should be called after the handshake is
  *                 completed.
  *
- * \param ssl      SSL context
+ * \param ssl      The SSL context to query
  *
- * \return         Protection Profile enum member,
- *                 #MBEDTLS_SRTP_UNSET_PROFILE if no protocol was negotiated.
+ * \return         The DTLS SRTP protection profile in use
+ * \return         #MBEDTLS_SRTP_UNSET_PROFILE if no protocol was negotiated or the handshake is still on
+ *                 early stage
  */
 mbedtls_ssl_srtp_profile mbedtls_ssl_get_dtls_srtp_protection_profile
                                              ( const mbedtls_ssl_context *ssl );
@@ -3246,10 +3251,11 @@ mbedtls_ssl_srtp_profile mbedtls_ssl_get_dtls_srtp_protection_profile
 /**
  * \brief                  Utility function to get information on DTLS-SRTP profile.
  *
- * \param profile          The dtls-srtp profile id to get info on.
+ * \param profile          The DTLS-SRTP profile id to get info on.
  *
  * \return                 Address of the SRTP profile information structure on
- *                         success,NULL if not found.
+ *                         success
+ * \return                 \c NULL if not found.
  */
 const mbedtls_ssl_srtp_profile_info *mbedtls_ssl_dtls_srtp_profile_info_from_id
                                            ( mbedtls_ssl_srtp_profile profile );
diff --git a/include/mbedtls/ssl_internal.h b/include/mbedtls/ssl_internal.h
index c3923ee9d12c..a4c0467df4ee 100644
--- a/include/mbedtls/ssl_internal.h
+++ b/include/mbedtls/ssl_internal.h
@@ -1103,16 +1103,16 @@ static inline uint16_t mbedtls_ssl_get_srtp_profile_iana_value
     switch( profile )
     {
         case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80:
-            profile_value = MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80_IANA_VALUE;
+            profile_value = MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80;
             break;
         case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32:
-            profile_value = MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32_IANA_VALUE;
+            profile_value = MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32;
             break;
         case MBEDTLS_SRTP_NULL_HMAC_SHA1_80:
-            profile_value = MBEDTLS_SRTP_NULL_HMAC_SHA1_80_IANA_VALUE;
+            profile_value = MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80;
             break;
         case MBEDTLS_SRTP_NULL_HMAC_SHA1_32:
-            profile_value = MBEDTLS_SRTP_NULL_HMAC_SHA1_32_IANA_VALUE;
+            profile_value = MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32;
             break;
         default: break;
     }
@@ -1125,16 +1125,16 @@ static inline mbedtls_ssl_srtp_profile mbedtls_ssl_get_srtp_profile_value
     mbedtls_ssl_srtp_profile profile_value = MBEDTLS_SRTP_UNSET_PROFILE;
     switch( srtp_iana_value )
     {
-        case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80_IANA_VALUE:
+        case MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80:
             profile_value = MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80;
             break;
-        case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32_IANA_VALUE:
+        case MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32:
             profile_value = MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32;
             break;
-        case MBEDTLS_SRTP_NULL_HMAC_SHA1_80_IANA_VALUE:
+        case MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80:
             profile_value = MBEDTLS_SRTP_NULL_HMAC_SHA1_80;
             break;
-        case MBEDTLS_SRTP_NULL_HMAC_SHA1_32_IANA_VALUE:
+        case MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32:
             profile_value = MBEDTLS_SRTP_NULL_HMAC_SHA1_32;
             break;
         default: break;
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index 56e0cbf55ddf..0c7e6fdee390 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -791,7 +791,9 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
     /* If use_srtp is not configured, just ignore the extension */
     if( ssl->conf->dtls_srtp_profile_list == NULL ||
         ssl->conf->dtls_srtp_profile_list_len == 0 )
+    {
         return( 0 );
+    }
 
     /* RFC5764 section 4.1.1
      * uint8 SRTPProtectionProfile[2];
@@ -841,6 +843,10 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
         {
             MBEDTLS_SSL_DEBUG_MSG( 3, ( "found srtp profile: %s", profile_info->name ) );
         }
+        else
+        {
+            continue;
+        }
         /* check if suggested profile is in our list */
         for( i = 0; i < ssl->conf->dtls_srtp_profile_list_len; i++)
         {
@@ -858,7 +864,7 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
         ( len > ( profile_length + 2 ) ) )
     {
         ssl->dtls_srtp_info.mki_len = buf[profile_length + 2];
-        if( ssl->dtls_srtp_info.mki_len > MBEDTLS_DTLS_SRTP_MAX_MKI_LENGTH ||
+        if( ssl->dtls_srtp_info.mki_len > MBEDTLS_TLS_SRTP_MAX_MKI_LENGTH ||
             ssl->dtls_srtp_info.mki_len + profile_length + size_of_lengths != len )
         {
             mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 63244a1eba12..4872b6974bcb 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -4749,7 +4749,7 @@ int mbedtls_ssl_dtls_srtp_set_mki_value( mbedtls_ssl_context *ssl,
                                          unsigned char *mki_value,
                                          size_t mki_len )
 {
-    if ( mki_len > MBEDTLS_DTLS_SRTP_MAX_MKI_LENGTH )
+    if ( mki_len > MBEDTLS_TLS_SRTP_MAX_MKI_LENGTH )
     {
         return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
     }
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index 82627ff723b6..644cafad6fd0 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -1194,7 +1194,7 @@ int main( int argc, char *argv[] )
     const mbedtls_ecp_curve_info *curve_cur;
 #endif
 #if defined(MBEDTLS_SSL_DTLS_SRTP)
-    unsigned char mki[MBEDTLS_DTLS_SRTP_MAX_MKI_LENGTH];
+    unsigned char mki[MBEDTLS_TLS_SRTP_MAX_MKI_LENGTH];
     size_t mki_len=0;
 #endif
 
@@ -1242,7 +1242,7 @@ int main( int argc, char *argv[] )
     eap_tls_keys eap_tls_keying;
 #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];
+     unsigned char dtls_srtp_key_material[MBEDTLS_TLS_SRTP_MAX_KEY_MATERIAL_LENGTH];
      const char* dtls_srtp_label = "EXTRACTOR-dtls_srtp";
      dtls_srtp_keys dtls_srtp_keying;
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index dd365b7f0697..069bd44068c7 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -1873,7 +1873,7 @@ int main( int argc, char *argv[] )
     eap_tls_keys eap_tls_keying;
 #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];
+     unsigned char dtls_srtp_key_material[MBEDTLS_TLS_SRTP_MAX_KEY_MATERIAL_LENGTH];
      const char* dtls_srtp_label = "EXTRACTOR-dtls_srtp";
      dtls_srtp_keys dtls_srtp_keying;
 #endif /* MBEDTLS_SSL_DTLS_SRTP */

From a89ca8679f79bd1d15cae77550c954c92d6c847f Mon Sep 17 00:00:00 2001
From: Johan Pascal <johan.pascal@belledonne-communications.com>
Date: Tue, 25 Aug 2020 10:03:19 +0200
Subject: [PATCH 37/63] The client shall not enforce the use of client
 certificate with use_srtp extension This is server's task to request it if
 needed

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 library/ssl_cli.c | 58 ++++-------------------------------------------
 1 file changed, 5 insertions(+), 53 deletions(-)

diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index fd177acaf6be..5bd303a38c83 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -3469,20 +3469,8 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
 
     if( ssl->client_auth == 0 )
     {
-#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 )
-        {
-            ret = MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
-        }
-        else
-        {
-#endif /* MBEDTLS_SSL_DTLS_SRTP */
-            /* Current message is probably the ServerHelloDone */
-            ssl->keep_current_message = 1;
-#if defined(MBEDTLS_SSL_DTLS_SRTP)
-        }
-#endif
+        /* Current message is probably the ServerHelloDone */
+        ssl->keep_current_message = 1;
         goto exit;
     }
 
@@ -4129,45 +4117,9 @@ static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
 
     if( ssl->client_auth == 0 || mbedtls_ssl_own_cert( ssl ) == NULL )
     {
-#if defined(MBEDTLS_SSL_DTLS_SRTP)
-        /*
-         * Check if we have a chosen srtp protection profile.
-         * According to RFC 5764 section 4.1 client certificate in dtls srtp
-         * is mandatory:
-         *        Client                               Server
-         *
-         *   ClientHello + use_srtp   -------->
-         *                                 ServerHello + use_srtp
-         *                                           Certificate*
-         *                                     ServerKeyExchange*
-         *                                     ertificateRequest*
-         *                            <--------   ServerHelloDone
-         *   Certificate*
-         *   ClientKeyExchange
-         *   CertificateVerify*
-         *   [ChangeCipherSpec]
-         *   Finished                 -------->
-         *                                     [ChangeCipherSpec]
-         *                            <--------          Finished
-         *   SRTP packets             <------->      SRTP packets
-         *
-         * Note that '*' indicates messages that are not always sent in DTLS.
-         * The CertificateRequest, client and server Certificates, and
-         * CertificateVerify will be sent in DTLS-SRTP.
-         */
-        if( ssl->dtls_srtp_info.chosen_dtls_srtp_profile != MBEDTLS_SRTP_UNSET_PROFILE )
-        {
-            return ( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
-        }
-        else
-        {
-#endif /* MBEDTLS_SSL_DTLS_SRTP */
-            MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
-            ssl->state++;
-            return( 0 );
-#if defined(MBEDTLS_SSL_DTLS_SRTP)
-        }
-#endif
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
+        ssl->state++;
+        return( 0 );
     }
 
     if( mbedtls_ssl_own_key( ssl ) == NULL )

From 042d4568321c49ce263a298d7057591da3f577db Mon Sep 17 00:00:00 2001
From: Johan Pascal <johan.pascal@belledonne-communications.com>
Date: Tue, 25 Aug 2020 12:14:02 +0200
Subject: [PATCH 38/63] Improve client Hello use_srtp parsing

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 library/ssl_srv.c | 46 +++++++++++++++++++++++++++-------------------
 1 file changed, 27 insertions(+), 19 deletions(-)

diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index 0c7e6fdee390..270700fac9dd 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -783,7 +783,7 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
 {
     mbedtls_ssl_srtp_profile client_protection = MBEDTLS_SRTP_UNSET_PROFILE;
     size_t i,j;
-    size_t profile_length;
+    size_t profile_length,mki_length;
     const mbedtls_ssl_srtp_profile_info *profile_info;
     /*! 2 bytes for profile length and 1 byte for mki len */
     const size_t size_of_lengths = 3;
@@ -809,8 +809,9 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
     /*
      * Min length is 5: at least one protection profile(2 bytes)
      *                  and length(2 bytes) + srtp_mki length(1 byte)
+     * Check here that we have at least 2 bytes of protection profiles length
      */
-    if( len < size_of_lengths + 2 )
+    if( len < 2 )
     {
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
@@ -821,8 +822,11 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
 
     /* first 2 bytes are protection profile length(in bytes) */
     profile_length = ( buf[0] << 8 ) | buf[1];
+    buf += 2;
 
-    if( profile_length > len - size_of_lengths )
+    /* check the buffer size: at least profiles + profile and mki length */
+    if( profile_length + size_of_lengths > len ||
+        profile_length % 2 != 0 ) /* profiles are 2 bytes long, so the length must be even */
     {
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
@@ -834,8 +838,7 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
      */
     for( j=0; j < profile_length; j += 2 )
     {
-        /* + 2 to skip the length field */
-        uint16_t protection_profile_value = buf[j + 2] << 8 | buf[j+3];
+        uint16_t protection_profile_value = buf[j] << 8 | buf[j+1];
         client_protection = mbedtls_ssl_get_srtp_profile_value( protection_profile_value );
 
         profile_info = mbedtls_ssl_dtls_srtp_profile_info_from_id( client_protection );
@@ -860,29 +863,34 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
         if( ssl->dtls_srtp_info.chosen_dtls_srtp_profile != MBEDTLS_SRTP_UNSET_PROFILE )
             break;
     }
-    if( ( ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED ) &&
-        ( len > ( profile_length + 2 ) ) )
+    buf += profile_length; /* buf points to the mki length */
+    mki_length = *buf;
+    buf++;
+
+    if( mki_length > MBEDTLS_TLS_SRTP_MAX_MKI_LENGTH ||
+        mki_length + profile_length + size_of_lengths != len )
     {
-        ssl->dtls_srtp_info.mki_len = buf[profile_length + 2];
-        if( ssl->dtls_srtp_info.mki_len > MBEDTLS_TLS_SRTP_MAX_MKI_LENGTH ||
-            ssl->dtls_srtp_info.mki_len + profile_length + size_of_lengths != len )
-        {
-            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                            MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
-            ssl->dtls_srtp_info.mki_len = 0;
-            return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
-        }
+        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 );
+    }
 
-        for( i=0; i < ssl->dtls_srtp_info.mki_len; i++ )
+    /* Parse the mki only if present and mki is supported locally */
+    if( ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED &&
+          mki_length > 0 )
+    {
+        ssl->dtls_srtp_info.mki_len = mki_length;
+
+        for( i=0; i < mki_length; i++ )
         {
-            ssl->dtls_srtp_info.mki_value[i] = buf[profile_length + 2 + 1 + i];
+            ssl->dtls_srtp_info.mki_value[i] = buf[i];
         }
 
         MBEDTLS_SSL_DEBUG_BUF( 3, "using mki",  ssl->dtls_srtp_info.mki_value,
                                                 ssl->dtls_srtp_info.mki_len );
     }
 
-     return( 0 );
+    return( 0 );
 }
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
 

From 8f70fba988d9c25d8d461e68b2c0c9285e0bc401 Mon Sep 17 00:00:00 2001
From: Johan Pascal <johan.pascal@belledonne-communications.com>
Date: Wed, 2 Sep 2020 10:32:06 +0200
Subject: [PATCH 39/63] Check the server hello output buffer size when writing
 the use_srtp ext

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 library/ssl_srv.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index 270700fac9dd..d07050534f0a 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -2634,10 +2634,12 @@ static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
 {
     size_t mki_len = 0, ext_len = 0;
     uint16_t profile_value = 0;
+    const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
+
+    *olen = 0;
 
     if( ssl->dtls_srtp_info.chosen_dtls_srtp_profile == MBEDTLS_SRTP_UNSET_PROFILE )
     {
-        *olen = 0;
         return;
     }
 
@@ -2649,6 +2651,12 @@ static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
         mki_len = ssl->dtls_srtp_info.mki_len;
     }
 
+    if( end < buf + mki_len + 9 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
+        return;
+    }
+
     /* extension */
     buf[0] = (unsigned char)( ( MBEDTLS_TLS_EXT_USE_SRTP >> 8 ) & 0xFF );
     buf[1] = (unsigned char)( ( MBEDTLS_TLS_EXT_USE_SRTP      ) & 0xFF );
@@ -2671,7 +2679,7 @@ static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
     }
     else
     {
-        *olen = 0;
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "use_srtp extension invalid profile" ) );
         return;
     }
 

From 9bc97ca19d388ae0e155ba6302787acd2bcd4c36 Mon Sep 17 00:00:00 2001
From: Johan Pascal <johan.pascal@belledonne-communications.com>
Date: Mon, 21 Sep 2020 23:44:45 +0200
Subject: [PATCH 40/63] SRTP-DTLS protection profile configuration list not
 copied into ssl_config + improve test + minor style fix

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 include/mbedtls/ssl.h      | 40 +++++++++--------
 library/ssl_cli.c          |  3 +-
 library/ssl_srv.c          |  8 ++++
 library/ssl_tls.c          | 14 +-----
 programs/ssl/ssl_client2.c | 88 ++++++++++++++++++++++----------------
 programs/ssl/ssl_server2.c | 73 +++++++++++++++++--------------
 tests/ssl-opt.sh           | 50 +++++++++++++++++++++-
 7 files changed, 173 insertions(+), 103 deletions(-)

diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index a1056b77303d..44530cb243a1 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -891,12 +891,12 @@ mbedtls_ssl_srtp_profile_info;
 
 typedef struct mbedtls_dtls_srtp_info_t
 {
-    /*! The SRTP profile that was negotiated*/
+    /*! The SRTP profile that was negotiated. */
     mbedtls_ssl_srtp_profile chosen_dtls_srtp_profile;
-    /*! The mki_value used, with max size of 256 bytes */
+    /*! The mki_value used, with max size of 256 bytes. */
     unsigned char mki_value[MBEDTLS_TLS_SRTP_MAX_MKI_LENGTH];
-    /*! The length of mki_value */
-    size_t                 mki_len;
+    /*! The length of mki_value. */
+    size_t mki_len;
 }
 mbedtls_dtls_srtp_info;
 
@@ -1110,7 +1110,7 @@ struct mbedtls_ssl_config
 
 #if defined(MBEDTLS_SSL_DTLS_SRTP)
     /*! ordered list of supported srtp profile */
-    mbedtls_ssl_srtp_profile *dtls_srtp_profile_list;
+    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 */
@@ -3190,13 +3190,14 @@ const char *mbedtls_ssl_get_alpn_protocol( const mbedtls_ssl_context *ssl );
 
 #if defined(MBEDTLS_SSL_DTLS_SRTP)
 /**
- * \brief                   Add 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
+ * \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              SSL configuration
+ * \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.
@@ -3210,10 +3211,15 @@ void mbedtls_ssl_conf_srtp_mki_value_supported( mbedtls_ssl_config *conf,
  * \param conf              SSL configuration
  * \param profiles          List of 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.
  * \param profiles_number   Number of supported profiles.
  *
  * \return                  0 on success
- * \return                  #MBEDTLS_ERR_SSL_BAD_INPUT_DATA when the list of protection profiles is incorrect
+ * \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,
@@ -3239,11 +3245,11 @@ int mbedtls_ssl_dtls_srtp_set_mki_value( mbedtls_ssl_context *ssl,
  *                 This function should be called after the handshake is
  *                 completed.
  *
- * \param ssl      The SSL context to query
+ * \param ssl      The SSL context to query.
  *
- * \return         The DTLS SRTP protection profile in use
- * \return         #MBEDTLS_SRTP_UNSET_PROFILE if no protocol was negotiated or the handshake is still on
- *                 early stage
+ * \return         The DTLS SRTP protection profile in use.
+ * \return         #MBEDTLS_SRTP_UNSET_PROFILE if the use of SRTP was not negotiated
+ *                 or peer's Hello packet was not parsed yet.
  */
 mbedtls_ssl_srtp_profile mbedtls_ssl_get_dtls_srtp_protection_profile
                                              ( const mbedtls_ssl_context *ssl );
@@ -3253,9 +3259,9 @@ mbedtls_ssl_srtp_profile mbedtls_ssl_get_dtls_srtp_protection_profile
  *
  * \param profile          The DTLS-SRTP profile id to get info on.
  *
- * \return                 Address of the SRTP profile information structure on
- *                         success
- * \return                 \c NULL if not found.
+ * \return                 The address of the SRTP profile information structure on
+ *                         success.
+ * \return                 \c NULL if the protection profile \p profile was not found.
  */
 const mbedtls_ssl_srtp_profile_info *mbedtls_ssl_dtls_srtp_profile_info_from_id
                                            ( mbedtls_ssl_srtp_profile profile );
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index 5bd303a38c83..b8acc75624d2 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -788,8 +788,7 @@ static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
      * } UseSRTPData;
      * SRTPProtectionProfile SRTPProtectionProfiles<2..2^16-1>;
      */
-    if( ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED &&
-        ssl->dtls_srtp_info.mki_len != 0 )
+    if( ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED )
     {
         mki_len = ssl->dtls_srtp_info.mki_len;
     }
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index d07050534f0a..6dc219bdd591 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -2651,6 +2651,14 @@ static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
         mki_len = ssl->dtls_srtp_info.mki_len;
     }
 
+    /* The extension total size is 9 bytes :
+     * - 2 bytes for the extension tag
+     * - 2 bytes for the total size
+     * - 2 bytes for the protection profile length
+     * - 2 bytes for the protection profile
+     * - 1 byte for the mki length
+     * +  the actual mki length
+     * Check we have enough room in the output buffer */
     if( end < buf + mki_len + 9 )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 4872b6974bcb..93b60cc9bebc 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -4778,12 +4778,6 @@ int mbedtls_ssl_conf_dtls_srtp_protection_profiles( mbedtls_ssl_config *conf,
         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
     }
 
-    mbedtls_free( conf->dtls_srtp_profile_list );
-    conf->dtls_srtp_profile_list =
-            (mbedtls_ssl_srtp_profile*)mbedtls_calloc(1,
-             profiles_number * sizeof( mbedtls_ssl_srtp_profile ) );
-    if( conf->dtls_srtp_profile_list == NULL )
-        return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
 
     for( i=0; i < profiles_number; i++ ) {
         switch( profiles[i] ) {
@@ -4791,17 +4785,15 @@ int mbedtls_ssl_conf_dtls_srtp_protection_profiles( mbedtls_ssl_config *conf,
             case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32:
             case MBEDTLS_SRTP_NULL_HMAC_SHA1_80:
             case MBEDTLS_SRTP_NULL_HMAC_SHA1_32:
-                conf->dtls_srtp_profile_list[i] = profiles[i];
                 break;
             default:
-                mbedtls_free( conf->dtls_srtp_profile_list );
                 conf->dtls_srtp_profile_list = NULL;
                 conf->dtls_srtp_profile_list_len = 0;
                 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
         }
     }
 
-    /* assign array length */
+    conf->dtls_srtp_profile_list = profiles;
     conf->dtls_srtp_profile_list_len = profiles_number;
 
     return( 0 );
@@ -7164,10 +7156,6 @@ void mbedtls_ssl_config_free( mbedtls_ssl_config *conf )
     ssl_key_cert_free( conf->key_cert );
 #endif
 
-#if defined (MBEDTLS_SSL_DTLS_SRTP)
-    mbedtls_free( conf->dtls_srtp_profile_list );
-#endif
-
     mbedtls_platform_zeroize( conf, sizeof( mbedtls_ssl_config ) );
 }
 
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index 644cafad6fd0..6adaf9216da9 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -262,7 +262,7 @@ int main( void )
     "    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"   \
+    "    srtp_force_profile=%%d  default: 0 (all enabled)\n"   \
     "                        available profiles:\n"       \
     "                        1 - SRTP_AES128_CM_HMAC_SHA1_80\n"  \
     "                        2 - SRTP_AES128_CM_HMAC_SHA1_32\n"  \
@@ -707,9 +707,9 @@ static int dtls_srtp_key_derivation( void *p_expkey,
 
     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);
+        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 );
 }
@@ -1242,9 +1242,15 @@ int main( int argc, char *argv[] )
     eap_tls_keys eap_tls_keying;
 #if defined( MBEDTLS_SSL_DTLS_SRTP )
     /*! master keys and master salt for SRTP generated during handshake */
-     unsigned char dtls_srtp_key_material[MBEDTLS_TLS_SRTP_MAX_KEY_MATERIAL_LENGTH];
-     const char* dtls_srtp_label = "EXTRACTOR-dtls_srtp";
-     dtls_srtp_keys dtls_srtp_keying;
+    unsigned char dtls_srtp_key_material[MBEDTLS_TLS_SRTP_MAX_KEY_MATERIAL_LENGTH];
+    const char* dtls_srtp_label = "EXTRACTOR-dtls_srtp";
+    dtls_srtp_keys dtls_srtp_keying;
+    const mbedtls_ssl_srtp_profile default_profiles[] = {
+        MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80,
+        MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32,
+        MBEDTLS_SRTP_NULL_HMAC_SHA1_80,
+        MBEDTLS_SRTP_NULL_HMAC_SHA1_32
+    };
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
 #endif /* MBEDTLS_SSL_EXPORT_KEYS */
 
@@ -2324,9 +2330,9 @@ int main( int argc, char *argv[] )
 #endif
 
 #if defined(MBEDTLS_SSL_DTLS_SRTP)
-    if( opt.use_srtp != DFL_USE_SRTP )
+    if( opt.use_srtp == 1 )
     {
-        if( opt.force_srtp_profile != DFL_SRTP_FORCE_PROFILE )
+        if( opt.force_srtp_profile != 0 )
         {
             const mbedtls_ssl_srtp_profile forced_profile[] = { opt.force_srtp_profile };
             ret = mbedtls_ssl_conf_dtls_srtp_protection_profiles
@@ -2336,11 +2342,6 @@ int main( int argc, char *argv[] )
         }
         else
         {
-            const mbedtls_ssl_srtp_profile default_profiles[] =
-                { MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80,
-                  MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32,
-                  MBEDTLS_SRTP_NULL_HMAC_SHA1_80,
-                  MBEDTLS_SRTP_NULL_HMAC_SHA1_32 };
             ret = mbedtls_ssl_conf_dtls_srtp_protection_profiles
                     ( &conf,
                       default_profiles,
@@ -2349,12 +2350,14 @@ int main( int argc, char *argv[] )
 
         if( ret != 0 )
         {
-            mbedtls_printf( " failed\n  ! mbedtls_ssl_conf_dtls_srtp_protection_profiles returned %d\n\n", ret );
+            mbedtls_printf( " failed\n  ! "
+                            "mbedtls_ssl_conf_dtls_srtp_protection_profiles returned %d\n\n",
+                            ret );
             goto exit;
         }
 
     }
-    else if( opt.force_srtp_profile != DFL_SRTP_FORCE_PROFILE )
+    else if( opt.force_srtp_profile != 0 )
     {
         mbedtls_printf( " failed\n  ! must enable use_srtp to force srtp profile\n\n" );
         goto exit;
@@ -2605,13 +2608,13 @@ int main( int argc, char *argv[] )
 #endif
 
 #if defined(MBEDTLS_SSL_DTLS_SRTP)
-    if( opt.use_srtp != DFL_USE_SRTP &&  strlen( opt.mki ) != 0 )
+    if( opt.use_srtp != DFL_USE_SRTP && strlen( opt.mki ) != 0 )
     {
         if( mbedtls_test_unhexify( mki, sizeof( mki ),
                                    opt.mki,&mki_len ) != 0 )
         {
             mbedtls_printf( "mki value not valid hex\n" );
-             goto exit;
+            goto exit;
         }
 
         mbedtls_ssl_conf_srtp_mki_value_supported( &conf, MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED );
@@ -2751,30 +2754,39 @@ int main( int argc, char *argv[] )
     {
         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 )
+        if( (mbedtls_ssl_get_dtls_srtp_protection_profile( &ssl )
+             == MBEDTLS_SRTP_UNSET_PROFILE ) )
         {
-            mbedtls_printf( " failed\n  ! mbedtls_ssl_tls_prf returned -0x%x\n\n",
-                            (unsigned int) -ret );
-            goto exit;
+            mbedtls_printf( "    DTLS-SRTP unable to negotiate "
+                            "protection profile\n" );
         }
-
-        mbedtls_printf( "    DTLS-SRTP key material is:" );
-        for( j = 0; j < sizeof( dtls_srtp_key_material ); j++ )
+        else
         {
-            if( j % 8 == 0 )
-                mbedtls_printf("\n    ");
-            mbedtls_printf("%02x ", dtls_srtp_key_material[j] );
-        }
+            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",
+                                (unsigned int) -ret );
+                goto exit;
+            }
 
-        mbedtls_printf("\n");
+            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 */
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index 069bd44068c7..350d8ca51765 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -331,7 +331,7 @@ int main( void )
 #if defined(MBEDTLS_SSL_DTLS_SRTP)
 #define USAGE_SRTP \
     "    use_srtp=%%d         default: 0 (disabled)\n" \
-    "    srtp_force_profile=%%d  default: all enabled\n"   \
+    "    srtp_force_profile=%%d  default: 0 (all enabled)\n"   \
     "                        available profiles:\n"       \
     "                        1 - SRTP_AES128_CM_HMAC_SHA1_80\n"  \
     "                        2 - SRTP_AES128_CM_HMAC_SHA1_32\n"  \
@@ -809,9 +809,9 @@ static int dtls_srtp_key_derivation( void *p_expkey,
 
     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);
+        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 );
 }
@@ -1876,6 +1876,12 @@ int main( int argc, char *argv[] )
      unsigned char dtls_srtp_key_material[MBEDTLS_TLS_SRTP_MAX_KEY_MATERIAL_LENGTH];
      const char* dtls_srtp_label = "EXTRACTOR-dtls_srtp";
      dtls_srtp_keys dtls_srtp_keying;
+     const mbedtls_ssl_srtp_profile default_profiles[] = {
+         MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80,
+         MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32,
+         MBEDTLS_SRTP_NULL_HMAC_SHA1_80,
+         MBEDTLS_SRTP_NULL_HMAC_SHA1_32
+     };
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
 #endif /* MBEDTLS_SSL_EXPORT_KEYS */
 
@@ -3136,9 +3142,9 @@ int main( int argc, char *argv[] )
 #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
 
 #if defined(MBEDTLS_SSL_DTLS_SRTP)
-    if( opt.use_srtp != DFL_USE_SRTP )
+    if( opt.use_srtp == 1 )
     {
-        if( opt.force_srtp_profile != DFL_SRTP_FORCE_PROFILE )
+        if( opt.force_srtp_profile != 0 )
         {
             const mbedtls_ssl_srtp_profile forced_profile[] = { opt.force_srtp_profile };
             ret = mbedtls_ssl_conf_dtls_srtp_protection_profiles( &conf,
@@ -3147,10 +3153,6 @@ int main( int argc, char *argv[] )
         }
         else
         {
-            const mbedtls_ssl_srtp_profile default_profiles[] = { MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80,
-                                                                  MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32,
-                                                                  MBEDTLS_SRTP_NULL_HMAC_SHA1_80,
-                                                                  MBEDTLS_SRTP_NULL_HMAC_SHA1_32 };
             ret = mbedtls_ssl_conf_dtls_srtp_protection_profiles( &conf,
                                                                   default_profiles,
                                                                   sizeof( default_profiles ) / sizeof( mbedtls_ssl_srtp_profile ) );
@@ -3168,7 +3170,7 @@ int main( int argc, char *argv[] )
                                                    MBEDTLS_SSL_DTLS_SRTP_MKI_UNSUPPORTED );
 
     }
-    else if( opt.force_srtp_profile != DFL_SRTP_FORCE_PROFILE )
+    else if( opt.force_srtp_profile != 0 )
     {
         mbedtls_printf( " failed\n  ! must enable use_srtp to force srtp profile\n\n" );
         goto exit;
@@ -3861,30 +3863,39 @@ int main( int argc, char *argv[] )
     {
         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 )
+        if( (mbedtls_ssl_get_dtls_srtp_protection_profile( &ssl )
+             == MBEDTLS_SRTP_UNSET_PROFILE ) )
         {
-            mbedtls_printf( " failed\n  ! mbedtls_ssl_tls_prf returned -0x%x\n\n",
-                            (unsigned int) -ret );
-            goto exit;
+            mbedtls_printf( "    DTLS-SRTP unable to negotiate "
+                            "protection profile\n" );
         }
-
-        mbedtls_printf( "    DTLS-SRTP key material is:" );
-        for( j = 0; j < sizeof( dtls_srtp_key_material ); j++ )
+        else
         {
-            if( j % 8 == 0 )
-                mbedtls_printf("\n    ");
-            mbedtls_printf("%02x ", dtls_srtp_key_material[j] );
-        }
+            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",
+                                (unsigned int) -ret );
+                goto exit;
+            }
 
-        mbedtls_printf("\n");
+            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 */
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index bb31a3cdec27..b820a735b3a1 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -1074,7 +1074,7 @@ P_SRV="$P_SRV server_addr=127.0.0.1 server_port=$SRV_PORT"
 P_CLI="$P_CLI server_addr=127.0.0.1 server_port=+SRV_PORT"
 P_PXY="$P_PXY server_addr=127.0.0.1 server_port=$SRV_PORT listen_addr=127.0.0.1 listen_port=$PXY_PORT ${SEED:+"seed=$SEED"}"
 O_SRV="$O_SRV -accept $SRV_PORT -dhparam data_files/dhparams.pem"
-O_CLI="$O_CLI -connect localhost:+SRV_PORT"
+O_CLI="$O_CLI -connect 127.0.0.1:+SRV_PORT"
 G_SRV="$G_SRV -p $SRV_PORT"
 G_CLI="$G_CLI -p +SRV_PORT"
 
@@ -8723,10 +8723,12 @@ run_test  "DTLS-SRTP all profiles supported" \
           -s "found srtp profile" \
           -s "selected srtp profile" \
           -s "server hello, adding use_srtp extension" \
+          -s "DTLS-SRTP key material is"\
           -c "client hello, adding use_srtp extension" \
           -c "found use_srtp extension" \
           -c "found srtp profile" \
           -c "selected srtp profile" \
+          -c "DTLS-SRTP key material is"\
           -C "error"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
@@ -8738,10 +8740,12 @@ run_test  "DTLS-SRTP server supports all profiles. Client supports one profile."
           -s "found srtp profile: MBEDTLS_SRTP_NULL_HMAC_SHA1_80" \
           -s "selected srtp profile: MBEDTLS_SRTP_NULL_HMAC_SHA1_80" \
           -s "server hello, adding use_srtp extension" \
+          -s "DTLS-SRTP key material is"\
           -c "client hello, adding use_srtp extension" \
           -c "found use_srtp extension" \
           -c "found srtp profile: MBEDTLS_SRTP_NULL_HMAC_SHA1_80" \
           -c "selected srtp profile" \
+          -c "DTLS-SRTP key material is"\
           -C "error"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
@@ -8753,10 +8757,12 @@ run_test  "DTLS-SRTP server supports one profile. Client supports all profiles."
           -s "found srtp profile" \
           -s "selected srtp profile: MBEDTLS_SRTP_NULL_HMAC_SHA1_32" \
           -s "server hello, adding use_srtp extension" \
+          -s "DTLS-SRTP key material is"\
           -c "client hello, adding use_srtp extension" \
           -c "found use_srtp extension" \
           -c "found srtp profile: MBEDTLS_SRTP_NULL_HMAC_SHA1_32" \
           -c "selected srtp profile" \
+          -c "DTLS-SRTP key material is"\
           -C "error"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
@@ -8768,10 +8774,12 @@ run_test  "DTLS-SRTP server and Client support only one matching profile." \
           -s "found srtp profile: MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32" \
           -s "selected srtp profile: MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32" \
           -s "server hello, adding use_srtp extension" \
+          -s "DTLS-SRTP key material is"\
           -c "client hello, adding use_srtp extension" \
           -c "found use_srtp extension" \
           -c "found srtp profile: MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32" \
           -c "selected srtp profile" \
+          -c "DTLS-SRTP key material is"\
           -C "error"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
@@ -8783,10 +8791,12 @@ run_test  "DTLS-SRTP server and Client support only one different profile." \
           -s "found srtp profile: MBEDTLS_SRTP_NULL_HMAC_SHA1_32" \
           -S "selected srtp profile" \
           -S "server hello, adding use_srtp extension" \
+          -S "DTLS-SRTP key material is"\
           -c "client hello, adding use_srtp extension" \
           -C "found use_srtp extension" \
           -C "found srtp profile" \
           -C "selected srtp profile" \
+          -C "DTLS-SRTP key material is"\
           -C "error"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
@@ -8796,10 +8806,12 @@ run_test  "DTLS-SRTP server doesn't support use_srtp extension." \
           0 \
           -s "found use_srtp extension" \
           -S "server hello, adding use_srtp extension" \
+          -S "DTLS-SRTP key material is"\
           -c "client hello, adding use_srtp extension" \
           -C "found use_srtp extension" \
           -C "found srtp profile" \
           -C "selected srtp profile" \
+          -C "DTLS-SRTP key material is"\
           -C "error"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
@@ -8812,12 +8824,14 @@ run_test  "DTLS-SRTP all profiles supported. mki used" \
           -s "selected srtp profile" \
           -s "server hello, adding use_srtp extension" \
           -s "dumping 'using mki' (8 bytes)" \
+          -s "DTLS-SRTP key material is"\
           -c "client hello, adding use_srtp extension" \
           -c "found use_srtp extension" \
           -c "found srtp profile" \
           -c "selected srtp profile" \
           -c "dumping 'sending mki' (8 bytes)" \
           -c "dumping 'received mki' (8 bytes)" \
+          -c "DTLS-SRTP key material is"\
           -C "error"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
@@ -8829,11 +8843,13 @@ run_test  "DTLS-SRTP all profiles supported. server doesn't support mki." \
           -s "found srtp profile" \
           -s "selected srtp profile" \
           -s "server hello, adding use_srtp extension" \
+          -s "DTLS-SRTP key material is"\
           -S "dumping 'using mki' (8 bytes)" \
           -c "client hello, adding use_srtp extension" \
           -c "found use_srtp extension" \
           -c "found srtp profile" \
           -c "selected srtp profile" \
+          -c "DTLS-SRTP key material is"\
           -c "dumping 'sending mki' (8 bytes)" \
           -C "dumping 'received mki' (8 bytes)" \
           -C "error"
@@ -8847,6 +8863,7 @@ run_test  "DTLS-SRTP all profiles supported. openssl client." \
           -s "found srtp profile" \
           -s "selected srtp profile" \
           -s "server hello, adding use_srtp extension" \
+          -s "DTLS-SRTP key material is"\
           -c "SRTP Extension negotiated, profile=SRTP_AES128_CM_SHA1_80"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
@@ -8858,6 +8875,7 @@ run_test  "DTLS-SRTP server supports all profiles. Client supports all profiles,
           -s "found srtp profile" \
           -s "selected srtp profile" \
           -s "server hello, adding use_srtp extension" \
+          -s "DTLS-SRTP key material is"\
           -c "SRTP Extension negotiated, profile=SRTP_AES128_CM_SHA1_32"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
@@ -8869,6 +8887,7 @@ run_test  "DTLS-SRTP server supports all profiles. Client supports one profile.
           -s "found srtp profile" \
           -s "selected srtp profile" \
           -s "server hello, adding use_srtp extension" \
+          -s "DTLS-SRTP key material is"\
           -c "SRTP Extension negotiated, profile=SRTP_AES128_CM_SHA1_32"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
@@ -8880,6 +8899,7 @@ run_test  "DTLS-SRTP server supports one profile. Client supports all profiles.
           -s "found srtp profile" \
           -s "selected srtp profile" \
           -s "server hello, adding use_srtp extension" \
+          -s "DTLS-SRTP key material is"\
           -c "SRTP Extension negotiated, profile=SRTP_AES128_CM_SHA1_32"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
@@ -8891,6 +8911,7 @@ run_test  "DTLS-SRTP server and Client support only one matching profile. openss
           -s "found srtp profile" \
           -s "selected srtp profile" \
           -s "server hello, adding use_srtp extension" \
+          -s "DTLS-SRTP key material is"\
           -c "SRTP Extension negotiated, profile=SRTP_AES128_CM_SHA1_32"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
@@ -8902,6 +8923,7 @@ run_test  "DTLS-SRTP server and Client support only one different profile. opens
           -s "found srtp profile" \
           -S "selected srtp profile" \
           -S "server hello, adding use_srtp extension" \
+          -S "DTLS-SRTP key material is"\
           -C "SRTP Extension negotiated, profile"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
@@ -8911,6 +8933,7 @@ run_test  "DTLS-SRTP server doesn't support use_srtp extension. openssl client"
           0 \
           -s "found use_srtp extension" \
           -S "server hello, adding use_srtp extension" \
+          -S "DTLS-SRTP key material is"\
           -C "SRTP Extension negotiated, profile"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
@@ -8922,6 +8945,7 @@ run_test  "DTLS-SRTP all profiles supported. openssl server" \
           -c "found use_srtp extension" \
           -c "found srtp profile" \
           -c "selected srtp profile: MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80" \
+          -c "DTLS-SRTP key material is"\
           -C "error"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
@@ -8933,6 +8957,7 @@ run_test  "DTLS-SRTP server supports all profiles. Client supports all profiles,
           -c "found use_srtp extension" \
           -c "found srtp profile" \
           -c "selected srtp profile" \
+          -c "DTLS-SRTP key material is"\
           -C "error"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
@@ -8944,6 +8969,7 @@ run_test  "DTLS-SRTP server supports all profiles. Client supports one profile.
           -c "found use_srtp extension" \
           -c "found srtp profile: MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32" \
           -c "selected srtp profile" \
+          -c "DTLS-SRTP key material is"\
           -C "error"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
@@ -8955,6 +8981,7 @@ run_test  "DTLS-SRTP server supports one profile. Client supports all profiles.
           -c "found use_srtp extension" \
           -c "found srtp profile: MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32" \
           -c "selected srtp profile" \
+          -c "DTLS-SRTP key material is"\
           -C "error"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
@@ -8966,6 +8993,7 @@ run_test  "DTLS-SRTP server and Client support only one matching profile. openss
           -c "found use_srtp extension" \
           -c "found srtp profile: MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32" \
           -c "selected srtp profile" \
+          -c "DTLS-SRTP key material is"\
           -C "error"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
@@ -8977,6 +9005,7 @@ run_test  "DTLS-SRTP server and Client support only one different profile. opens
           -C "found use_srtp extension" \
           -C "found srtp profile" \
           -C "selected srtp profile" \
+          -C "DTLS-SRTP key material is"\
           -C "error"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
@@ -8988,6 +9017,7 @@ run_test  "DTLS-SRTP server doesn't support use_srtp extension. openssl server"
           -C "found use_srtp extension" \
           -C "found srtp profile" \
           -C "selected srtp profile" \
+          -C "DTLS-SRTP key material is"\
           -C "error"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
@@ -8999,6 +9029,7 @@ run_test  "DTLS-SRTP all profiles supported. server doesn't support mki. openssl
           -c "found use_srtp extension" \
           -c "found srtp profile" \
           -c "selected srtp profile" \
+          -c "DTLS-SRTP key material is"\
           -c "dumping 'sending mki' (8 bytes)" \
           -C "dumping 'received mki' (8 bytes)" \
           -C "error"
@@ -9013,6 +9044,7 @@ run_test  "DTLS-SRTP all profiles supported. gnutls client." \
           -s "found srtp profile" \
           -s "selected srtp profile" \
           -s "server hello, adding use_srtp extension" \
+          -s "DTLS-SRTP key material is"\
           -c "SRTP profile: SRTP_AES128_CM_HMAC_SHA1_80"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
@@ -9025,6 +9057,7 @@ run_test  "DTLS-SRTP server supports all profiles. Client supports all profiles,
           -s "found srtp profile" \
           -s "selected srtp profile" \
           -s "server hello, adding use_srtp extension" \
+          -s "DTLS-SRTP key material is"\
           -c "SRTP profile: SRTP_NULL_HMAC_SHA1_80"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
@@ -9037,6 +9070,7 @@ run_test  "DTLS-SRTP server supports all profiles. Client supports one profile.
           -s "found srtp profile: MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32" \
           -s "selected srtp profile: MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32" \
           -s "server hello, adding use_srtp extension" \
+          -s "DTLS-SRTP key material is"\
           -c "SRTP profile: SRTP_AES128_CM_HMAC_SHA1_32"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
@@ -9049,6 +9083,7 @@ run_test  "DTLS-SRTP server supports one profile. Client supports all profiles.
           -s "found srtp profile" \
           -s "selected srtp profile: MBEDTLS_SRTP_NULL_HMAC_SHA1_32" \
           -s "server hello, adding use_srtp extension" \
+          -s "DTLS-SRTP key material is"\
           -c "SRTP profile: SRTP_NULL_SHA1_32"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
@@ -9061,6 +9096,7 @@ run_test  "DTLS-SRTP server and Client support only one matching profile. gnutls
           -s "found srtp profile" \
           -s "selected srtp profile" \
           -s "server hello, adding use_srtp extension" \
+          -s "DTLS-SRTP key material is"\
           -c "SRTP profile: SRTP_AES128_CM_HMAC_SHA1_32"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
@@ -9073,6 +9109,7 @@ run_test  "DTLS-SRTP server and Client support only one different profile. gnutl
           -s "found srtp profile" \
           -S "selected srtp profile" \
           -S "server hello, adding use_srtp extension" \
+          -S "DTLS-SRTP key material is"\
           -C "SRTP profile:"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
@@ -9083,6 +9120,7 @@ run_test  "DTLS-SRTP server doesn't support use_srtp extension. gnutls client" \
           0 \
           -s "found use_srtp extension" \
           -S "server hello, adding use_srtp extension" \
+          -S "DTLS-SRTP key material is"\
           -C "SRTP profile:"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
@@ -9095,6 +9133,7 @@ run_test  "DTLS-SRTP all profiles supported. gnutls server" \
           -c "found use_srtp extension" \
           -c "found srtp profile" \
           -c "selected srtp profile: MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80" \
+          -c "DTLS-SRTP key material is"\
           -C "error"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
@@ -9107,6 +9146,7 @@ run_test  "DTLS-SRTP server supports all profiles. Client supports all profiles,
           -c "found use_srtp extension" \
           -c "found srtp profile" \
           -c "selected srtp profile: MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80" \
+          -c "DTLS-SRTP key material is"\
           -C "error"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
@@ -9119,18 +9159,20 @@ run_test  "DTLS-SRTP server supports all profiles. Client supports one profile.
           -c "found use_srtp extension" \
           -c "found srtp profile: MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32" \
           -c "selected srtp profile" \
+          -c "DTLS-SRTP key material is"\
           -C "error"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
 requires_gnutls
 run_test  "DTLS-SRTP server supports one profile. Client supports all profiles. gnutls server." \
           "$G_SRV -u --srtp-profiles=SRTP_NULL_HMAC_SHA1_80" \
-          "$P_CLI dtls=1 use_srtp=30 debug_level=3" \
+          "$P_CLI dtls=1 use_srtp=1 debug_level=3" \
           0 \
           -c "client hello, adding use_srtp extension" \
           -c "found use_srtp extension" \
           -c "found srtp profile: MBEDTLS_SRTP_NULL_HMAC_SHA1_80" \
           -c "selected srtp profile" \
+          -c "DTLS-SRTP key material is"\
           -C "error"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
@@ -9143,6 +9185,7 @@ run_test  "DTLS-SRTP server and Client support only one matching profile. gnutls
           -c "found use_srtp extension" \
           -c "found srtp profile: MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32" \
           -c "selected srtp profile" \
+          -c "DTLS-SRTP key material is"\
           -C "error"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
@@ -9155,6 +9198,7 @@ run_test  "DTLS-SRTP server and Client support only one different profile. gnutl
           -C "found use_srtp extension" \
           -C "found srtp profile" \
           -C "selected srtp profile" \
+          -C "DTLS-SRTP key material is"\
           -C "error"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
@@ -9167,6 +9211,7 @@ run_test  "DTLS-SRTP server doesn't support use_srtp extension. gnutls server" \
           -C "found use_srtp extension" \
           -C "found srtp profile" \
           -C "selected srtp profile" \
+          -C "DTLS-SRTP key material is"\
           -C "error"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
@@ -9179,6 +9224,7 @@ run_test  "DTLS-SRTP all profiles supported. mki used. gnutls server." \
           -c "found use_srtp extension" \
           -c "found srtp profile" \
           -c "selected srtp profile" \
+          -c "DTLS-SRTP key material is"\
           -c "dumping 'sending mki' (8 bytes)" \
           -c "dumping 'received mki' (8 bytes)" \
           -C "error"

From d576fdb1d63a3e2b315362710d08b5439747a9a6 Mon Sep 17 00:00:00 2001
From: Johan Pascal <johan.pascal@belledonne-communications.com>
Date: Tue, 22 Sep 2020 10:39:53 +0200
Subject: [PATCH 41/63] Style + fix bound check in write_use_srt_ext

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 library/ssl_srv.c          |  9 +++++----
 library/ssl_tls.c          | 10 ++++++----
 programs/ssl/ssl_client2.c | 16 ++++++++--------
 programs/ssl/ssl_server2.c | 14 +++++++-------
 4 files changed, 26 insertions(+), 23 deletions(-)

diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index 6dc219bdd591..e151ffe89677 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -2063,6 +2063,7 @@ static int ssl_parse_client_hello( mbedtls_ssl_context *ssl )
 #if defined(MBEDTLS_SSL_DTLS_SRTP)
             case MBEDTLS_TLS_EXT_USE_SRTP:
                 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found use_srtp extension" ) );
+
                 ret = ssl_parse_use_srtp_ext( ssl, ext + 4, ext_size );
                 if ( ret != 0 )
                     return( ret );
@@ -2645,8 +2646,7 @@ static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
 
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding use_srtp extension" ) );
 
-    if( ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED &&
-        ssl->dtls_srtp_info.mki_len != 0 )
+    if( ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED )
     {
         mki_len = ssl->dtls_srtp_info.mki_len;
     }
@@ -2659,7 +2659,7 @@ static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
      * - 1 byte for the mki length
      * +  the actual mki length
      * Check we have enough room in the output buffer */
-    if( end < buf + mki_len + 9 )
+    if( (size_t)( end - buf ) < mki_len + 9 )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
         return;
@@ -2679,7 +2679,8 @@ static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
     /* protection profile length: 2 */
     buf[4] = 0x00;
     buf[5] = 0x02;
-    profile_value = mbedtls_ssl_get_srtp_profile_iana_value( ssl->dtls_srtp_info.chosen_dtls_srtp_profile );
+    profile_value = mbedtls_ssl_get_srtp_profile_iana_value(
+                                ssl->dtls_srtp_info.chosen_dtls_srtp_profile );
     if( profile_value != 0xFFFF )
     {
         buf[6] = (unsigned char)( ( profile_value >> 8 ) & 0xFF );
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 93b60cc9bebc..696eb85ea9e6 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -4751,12 +4751,12 @@ int mbedtls_ssl_dtls_srtp_set_mki_value( mbedtls_ssl_context *ssl,
 {
     if ( mki_len > MBEDTLS_TLS_SRTP_MAX_MKI_LENGTH )
     {
-        return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
     }
 
     if( ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_UNSUPPORTED )
     {
-        return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
+        return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
     }
 
     memcpy( ssl->dtls_srtp_info.mki_value, mki_value, mki_len );
@@ -4779,8 +4779,10 @@ int mbedtls_ssl_conf_dtls_srtp_protection_profiles( mbedtls_ssl_config *conf,
     }
 
 
-    for( i=0; i < profiles_number; i++ ) {
-        switch( profiles[i] ) {
+    for( i=0; i < profiles_number; i++ )
+    {
+        switch( profiles[i] )
+        {
             case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80:
             case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32:
             case MBEDTLS_SRTP_NULL_HMAC_SHA1_80:
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index 6adaf9216da9..d727ebcad747 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -2608,7 +2608,7 @@ int main( int argc, char *argv[] )
 #endif
 
 #if defined(MBEDTLS_SSL_DTLS_SRTP)
-    if( opt.use_srtp != DFL_USE_SRTP && strlen( opt.mki ) != 0 )
+    if( opt.use_srtp != 0 && strlen( opt.mki ) != 0 )
     {
         if( mbedtls_test_unhexify( mki, sizeof( mki ),
                                    opt.mki,&mki_len ) != 0 )
@@ -2754,11 +2754,11 @@ int main( int argc, char *argv[] )
     {
         size_t j = 0;
 
-        if( (mbedtls_ssl_get_dtls_srtp_protection_profile( &ssl )
-             == MBEDTLS_SRTP_UNSET_PROFILE ) )
+        if( ( mbedtls_ssl_get_dtls_srtp_protection_profile( &ssl )
+                                == MBEDTLS_SRTP_UNSET_PROFILE ) )
         {
-            mbedtls_printf( "    DTLS-SRTP unable to negotiate "
-                            "protection profile\n" );
+            mbedtls_printf( "    Unable to negotiate "
+                            "the use of DTLS-SRTP\n" );
         }
         else
         {
@@ -2781,11 +2781,11 @@ int main( int argc, char *argv[] )
             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    " );
+                mbedtls_printf( "%02x ", dtls_srtp_key_material[j] );
             }
 
-            mbedtls_printf("\n");
+            mbedtls_printf( "\n" );
         }
     }
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index 350d8ca51765..6dc783215087 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -3863,11 +3863,11 @@ int main( int argc, char *argv[] )
     {
         size_t j = 0;
 
-        if( (mbedtls_ssl_get_dtls_srtp_protection_profile( &ssl )
-             == MBEDTLS_SRTP_UNSET_PROFILE ) )
+        if( ( mbedtls_ssl_get_dtls_srtp_protection_profile( &ssl )
+                                == MBEDTLS_SRTP_UNSET_PROFILE ) )
         {
-            mbedtls_printf( "    DTLS-SRTP unable to negotiate "
-                            "protection profile\n" );
+            mbedtls_printf( "    Unable to negotiate "
+                            "the use of DTLS-SRTP\n" );
         }
         else
         {
@@ -3890,11 +3890,11 @@ int main( int argc, char *argv[] )
             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    " );
+                mbedtls_printf( "%02x ", dtls_srtp_key_material[j] );
             }
 
-            mbedtls_printf("\n");
+            mbedtls_printf( "\n" );
         }
     }
 #endif /* MBEDTLS_SSL_DTLS_SRTP */

From 4f099264b5a7848289af3a2c3dab11bc6da15115 Mon Sep 17 00:00:00 2001
From: Johan Pascal <johan.pascal@belledonne-communications.com>
Date: Tue, 22 Sep 2020 10:59:26 +0200
Subject: [PATCH 42/63] use_srtp extension shall not interfere in the handshake
 settings

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 library/ssl_srv.c | 29 ++---------------------------
 library/ssl_tls.c | 33 ++++-----------------------------
 2 files changed, 6 insertions(+), 56 deletions(-)

diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index e151ffe89677..f774b407faed 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -3055,39 +3055,14 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
     if( ssl->handshake->sni_authmode != MBEDTLS_SSL_VERIFY_UNSET )
         authmode = ssl->handshake->sni_authmode;
     else
-#endif
-#if defined(MBEDTLS_SSL_DTLS_SRTP)
-    /*
-     * check if we have a chosen srtp protection profile,
-     * force verify mode to be at least OPTIONAL
-     */
-    if ( ssl->dtls_srtp_info.chosen_dtls_srtp_profile != MBEDTLS_SRTP_UNSET_PROFILE &&
-         ssl->conf->authmode == MBEDTLS_SSL_VERIFY_NONE )
-    {
-        authmode = MBEDTLS_SSL_VERIFY_OPTIONAL;
-    }
-    else
 #endif
         authmode = ssl->conf->authmode;
 
     if( !mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) ||
         authmode == MBEDTLS_SSL_VERIFY_NONE )
     {
-#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 )
-        {
-            MBEDTLS_SSL_DEBUG_MSG( 2, ( "should not happen" ) );
-            return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
-        }
-        else
-        {
-#endif
-            MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate request" ) );
-            return( 0 );
-#if defined(MBEDTLS_SSL_DTLS_SRTP)
-        }
-#endif
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate request" ) );
+        return( 0 );
     }
 
     /*
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 696eb85ea9e6..6b084450c53a 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -2088,21 +2088,9 @@ int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl )
 
     if( !mbedtls_ssl_ciphersuite_uses_srv_cert( ciphersuite_info ) )
     {
-#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 )
-        {
-            return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
-        }
-        else
-        {
-#endif /* MBEDTLS_SSL_DTLS_SRTP */
-            MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) );
-            ssl->state++;
-            return( 0 );
-#if defined(MBEDTLS_SSL_DTLS_SRTP)
-        }
-#endif
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) );
+        ssl->state++;
+        return( 0 );
     }
 
 #if defined(MBEDTLS_SSL_CLI_C)
@@ -2727,22 +2715,9 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
 #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
-#if defined(MBEDTLS_SSL_DTLS_SRTP)
-                       : ssl->dtls_srtp_info.chosen_dtls_srtp_profile !=
-                               MBEDTLS_SRTP_UNSET_PROFILE
-                       && ssl->conf->authmode == MBEDTLS_SSL_VERIFY_NONE
-                       ? MBEDTLS_SSL_VERIFY_OPTIONAL
-#endif /* MBEDTLS_SSL_DTLS_SRTP */
                        : ssl->conf->authmode;
 #else
-    const int authmode =
-#if defined(MBEDTLS_SSL_DTLS_SRTP)
-            ssl->dtls_srtp_info.chosen_dtls_srtp_profile !=
-                                           MBEDTLS_SRTP_UNSET_PROFILE &&
-            ssl->conf->authmode == MBEDTLS_SSL_VERIFY_NONE ?
-            MBEDTLS_SSL_VERIFY_OPTIONAL :
-#endif /* MBEDTLS_SSL_DTLS_SRTP */
-            ssl->conf->authmode;
+    const int authmode = ssl->conf->authmode;
 #endif
     void *rs_ctx = NULL;
     mbedtls_x509_crt *chain = NULL;

From 43f9490a525bccfebb352b9823fadbafdf5e008a Mon Sep 17 00:00:00 2001
From: Johan Pascal <johan.pascal@belledonne-communications.com>
Date: Tue, 22 Sep 2020 12:25:52 +0200
Subject: [PATCH 43/63] SRTP profiles definition use macros only

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 include/mbedtls/ssl.h          | 43 ++++++++------------------
 include/mbedtls/ssl_internal.h | 43 +++++---------------------
 library/ssl_cli.c              | 25 ++++++++-------
 library/ssl_srv.c              | 26 ++++++++--------
 library/ssl_tls.c              | 41 +++++++++++--------------
 programs/ssl/ssl_client2.c     | 10 +++---
 programs/ssl/ssl_server2.c     | 10 +++---
 tests/ssl-opt.sh               | 56 +++++++++++++++++-----------------
 8 files changed, 105 insertions(+), 149 deletions(-)

diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index 44530cb243a1..1ded993bc73e 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -414,6 +414,7 @@
 
 #define MBEDTLS_TLS_EXT_RENEGOTIATION_INFO      0xFF01
 
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
 /*
  * Use_srtp extension protection profiles values as defined in
  * http://www.iana.org/assignments/srtp-protection/srtp-protection.xhtml
@@ -422,6 +423,9 @@
 #define MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32     0x0002
 #define MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80          0x0005
 #define MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32          0x0006
+/* This one is not iana defined, but for code readability. */
+#define MBEDTLS_TLS_SRTP_UNSET                      0x0000
+#endif /* MBEDTLS_SSL_DTLS_SRTP*/
 
 /*
  * Size defines
@@ -870,24 +874,15 @@ typedef void mbedtls_ssl_async_cancel_t( mbedtls_ssl_context *ssl );
 #define MBEDTLS_TLS_SRTP_MAX_KEY_MATERIAL_LENGTH    60
 #define MBEDTLS_TLS_SRTP_MAX_MKI_LENGTH             255
 /*
- * List of SRTP profiles for DTLS-SRTP
+ * For code readability use a typedef for DTLS-SRTP profiles
+ * The supported profiles are defines as macro above:
+ * MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80
+ * MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32
+ * MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80
+ * MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32
+ * MBEDTLS_TLS_SRTP_UNSET
  */
-typedef enum
-{
-    MBEDTLS_SRTP_UNSET_PROFILE,
-    MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80,
-    MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32,
-    MBEDTLS_SRTP_NULL_HMAC_SHA1_80,
-    MBEDTLS_SRTP_NULL_HMAC_SHA1_32,
-}
-mbedtls_ssl_srtp_profile;
-
-typedef struct
-{
-    const mbedtls_ssl_srtp_profile   profile;
-    const char                      *name;
-}
-mbedtls_ssl_srtp_profile_info;
+typedef uint16_t mbedtls_ssl_srtp_profile;
 
 typedef struct mbedtls_dtls_srtp_info_t
 {
@@ -3248,23 +3243,11 @@ int mbedtls_ssl_dtls_srtp_set_mki_value( mbedtls_ssl_context *ssl,
  * \param ssl      The SSL context to query.
  *
  * \return         The DTLS SRTP protection profile in use.
- * \return         #MBEDTLS_SRTP_UNSET_PROFILE if the use of SRTP was not negotiated
+ * \return         #MBEDTLS_TLS_SRTP_UNSET if the use of SRTP was not negotiated
  *                 or peer's Hello packet was not parsed yet.
  */
 mbedtls_ssl_srtp_profile mbedtls_ssl_get_dtls_srtp_protection_profile
                                              ( const mbedtls_ssl_context *ssl );
-
-/**
- * \brief                  Utility function to get information on DTLS-SRTP profile.
- *
- * \param profile          The DTLS-SRTP profile id to get info on.
- *
- * \return                 The address of the SRTP profile information structure on
- *                         success.
- * \return                 \c NULL if the protection profile \p profile was not found.
- */
-const mbedtls_ssl_srtp_profile_info *mbedtls_ssl_dtls_srtp_profile_info_from_id
-                                           ( mbedtls_ssl_srtp_profile profile );
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
 
 /**
diff --git a/include/mbedtls/ssl_internal.h b/include/mbedtls/ssl_internal.h
index a4c0467df4ee..e1ba5cdb6a84 100644
--- a/include/mbedtls/ssl_internal.h
+++ b/include/mbedtls/ssl_internal.h
@@ -1096,50 +1096,23 @@ int mbedtls_ssl_check_sig_hash( const mbedtls_ssl_context *ssl,
 #endif
 
 #if defined(MBEDTLS_SSL_DTLS_SRTP)
-static inline uint16_t mbedtls_ssl_get_srtp_profile_iana_value
-                                            ( mbedtls_ssl_srtp_profile profile )
-{
-    uint16_t profile_value = 0xffff;
-    switch( profile )
-    {
-        case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80:
-            profile_value = MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80;
-            break;
-        case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32:
-            profile_value = MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32;
-            break;
-        case MBEDTLS_SRTP_NULL_HMAC_SHA1_80:
-            profile_value = MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80;
-            break;
-        case MBEDTLS_SRTP_NULL_HMAC_SHA1_32:
-            profile_value = MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32;
-            break;
-        default: break;
-    }
-    return( profile_value );
-}
+#if defined(MBEDTLS_DEBUG_C)
+const char *mbedtls_ssl_get_srtp_profile_as_string ( mbedtls_ssl_srtp_profile profile );
+#endif /* MBEDTLS_DEBUG_C */
 
-static inline mbedtls_ssl_srtp_profile mbedtls_ssl_get_srtp_profile_value
-                                                    ( uint16_t srtp_iana_value )
+static inline mbedtls_ssl_srtp_profile mbedtls_ssl_check_srtp_profile_value
+                                                    ( const uint16_t srtp_profile_value )
 {
-    mbedtls_ssl_srtp_profile profile_value = MBEDTLS_SRTP_UNSET_PROFILE;
-    switch( srtp_iana_value )
+    switch( srtp_profile_value )
     {
         case MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80:
-            profile_value = MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80;
-            break;
         case MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32:
-            profile_value = MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32;
-            break;
         case MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80:
-            profile_value = MBEDTLS_SRTP_NULL_HMAC_SHA1_80;
-            break;
         case MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32:
-            profile_value = MBEDTLS_SRTP_NULL_HMAC_SHA1_32;
-            break;
+            return srtp_profile_value;
         default: break;
     }
-    return( profile_value );
+    return( MBEDTLS_TLS_SRTP_UNSET );
 }
 #endif
 
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index b8acc75624d2..185997ddf529 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -811,9 +811,9 @@ static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
          protection_profiles_index < ssl->conf->dtls_srtp_profile_list_len;
          protection_profiles_index++ )
     {
-        profile_value = mbedtls_ssl_get_srtp_profile_iana_value
+        profile_value = mbedtls_ssl_check_srtp_profile_value
                 ( ssl->conf->dtls_srtp_profile_list[protection_profiles_index] );
-        if( profile_value != 0xFFFF )
+        if( profile_value != MBEDTLS_TLS_SRTP_UNSET )
         {
             MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_write_use_srtp_ext, add profile: %04x",
                                         profile_value ) );
@@ -1823,10 +1823,9 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
                                    const unsigned char *buf,
                                    size_t len )
 {
-    mbedtls_ssl_srtp_profile server_protection = MBEDTLS_SRTP_UNSET_PROFILE;
+    mbedtls_ssl_srtp_profile server_protection = MBEDTLS_TLS_SRTP_UNSET;
     size_t i, mki_len = 0;
     uint16_t server_protection_profile_value = 0;
-    const mbedtls_ssl_srtp_profile_info * profile_info;
 
     /* If use_srtp is not configured, just ignore the extension */
     if( ssl->conf->dtls_srtp_profile_list == NULL ||
@@ -1870,14 +1869,16 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
         return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
 
     server_protection_profile_value = ( buf[2] << 8 ) | buf[3];
-    server_protection = mbedtls_ssl_get_srtp_profile_value( server_protection_profile_value );
-    profile_info = mbedtls_ssl_dtls_srtp_profile_info_from_id( server_protection );
-    if( profile_info != NULL )
+    server_protection = mbedtls_ssl_check_srtp_profile_value(
+                    server_protection_profile_value );
+    if( server_protection != MBEDTLS_TLS_SRTP_UNSET )
     {
-        MBEDTLS_SSL_DEBUG_MSG( 3, ( "found srtp profile: %s", profile_info->name ) );
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "found srtp profile: %s",
+                                      mbedtls_ssl_get_srtp_profile_as_string(
+                                              server_protection ) ) );
     }
 
-    ssl->dtls_srtp_info.chosen_dtls_srtp_profile = MBEDTLS_SRTP_UNSET_PROFILE;
+    ssl->dtls_srtp_info.chosen_dtls_srtp_profile = MBEDTLS_TLS_SRTP_UNSET;
 
     /*
      * Check we have the server profile in our list
@@ -1886,13 +1887,15 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
     {
         if( server_protection == ssl->conf->dtls_srtp_profile_list[i] ) {
             ssl->dtls_srtp_info.chosen_dtls_srtp_profile = ssl->conf->dtls_srtp_profile_list[i];
-            MBEDTLS_SSL_DEBUG_MSG( 3, ( "selected srtp profile: %s", profile_info->name ) );
+            MBEDTLS_SSL_DEBUG_MSG( 3, ( "selected srtp profile: %s",
+                                      mbedtls_ssl_get_srtp_profile_as_string(
+                                              server_protection ) ) );
             break;
         }
     }
 
     /* If no match was found : server problem, it shall never answer with incompatible profile */
-    if( ssl->dtls_srtp_info.chosen_dtls_srtp_profile == MBEDTLS_SRTP_UNSET_PROFILE )
+    if( ssl->dtls_srtp_info.chosen_dtls_srtp_profile == MBEDTLS_TLS_SRTP_UNSET )
     {
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index f774b407faed..9dc08d29997a 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -781,10 +781,9 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
                                    const unsigned char *buf,
                                    size_t len )
 {
-    mbedtls_ssl_srtp_profile client_protection = MBEDTLS_SRTP_UNSET_PROFILE;
+    mbedtls_ssl_srtp_profile client_protection = MBEDTLS_TLS_SRTP_UNSET;
     size_t i,j;
     size_t profile_length,mki_length;
-    const mbedtls_ssl_srtp_profile_info *profile_info;
     /*! 2 bytes for profile length and 1 byte for mki len */
     const size_t size_of_lengths = 3;
 
@@ -818,7 +817,7 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
         return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
     }
 
-   ssl->dtls_srtp_info.chosen_dtls_srtp_profile = MBEDTLS_SRTP_UNSET_PROFILE;
+   ssl->dtls_srtp_info.chosen_dtls_srtp_profile = MBEDTLS_TLS_SRTP_UNSET;
 
     /* first 2 bytes are protection profile length(in bytes) */
     profile_length = ( buf[0] << 8 ) | buf[1];
@@ -839,12 +838,13 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
     for( j=0; j < profile_length; j += 2 )
     {
         uint16_t protection_profile_value = buf[j] << 8 | buf[j+1];
-        client_protection = mbedtls_ssl_get_srtp_profile_value( protection_profile_value );
+        client_protection = mbedtls_ssl_check_srtp_profile_value( protection_profile_value );
 
-        profile_info = mbedtls_ssl_dtls_srtp_profile_info_from_id( client_protection );
-        if( profile_info != NULL )
+        if( client_protection != MBEDTLS_TLS_SRTP_UNSET )
         {
-            MBEDTLS_SSL_DEBUG_MSG( 3, ( "found srtp profile: %s", profile_info->name ) );
+            MBEDTLS_SSL_DEBUG_MSG( 3, ( "found srtp profile: %s",
+                                    mbedtls_ssl_get_srtp_profile_as_string(
+                                            client_protection ) ) );
         }
         else
         {
@@ -856,11 +856,13 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
             if( client_protection == ssl->conf->dtls_srtp_profile_list[i] )
             {
                 ssl->dtls_srtp_info.chosen_dtls_srtp_profile = ssl->conf->dtls_srtp_profile_list[i];
-                MBEDTLS_SSL_DEBUG_MSG( 3, ( "selected srtp profile: %s", profile_info->name ) );
+                MBEDTLS_SSL_DEBUG_MSG( 3, ( "selected srtp profile: %s",
+                                            mbedtls_ssl_get_srtp_profile_as_string(
+                                                    client_protection ) ) );
                 break;
             }
         }
-        if( ssl->dtls_srtp_info.chosen_dtls_srtp_profile != MBEDTLS_SRTP_UNSET_PROFILE )
+        if( ssl->dtls_srtp_info.chosen_dtls_srtp_profile != MBEDTLS_TLS_SRTP_UNSET )
             break;
     }
     buf += profile_length; /* buf points to the mki length */
@@ -2639,7 +2641,7 @@ static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
 
     *olen = 0;
 
-    if( ssl->dtls_srtp_info.chosen_dtls_srtp_profile == MBEDTLS_SRTP_UNSET_PROFILE )
+    if( ssl->dtls_srtp_info.chosen_dtls_srtp_profile == MBEDTLS_TLS_SRTP_UNSET )
     {
         return;
     }
@@ -2679,9 +2681,9 @@ static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
     /* protection profile length: 2 */
     buf[4] = 0x00;
     buf[5] = 0x02;
-    profile_value = mbedtls_ssl_get_srtp_profile_iana_value(
+    profile_value = mbedtls_ssl_check_srtp_profile_value(
                                 ssl->dtls_srtp_info.chosen_dtls_srtp_profile );
-    if( profile_value != 0xFFFF )
+    if( profile_value != MBEDTLS_TLS_SRTP_UNSET )
     {
         buf[6] = (unsigned char)( ( profile_value >> 8 ) & 0xFF );
         buf[7] = (unsigned char)( profile_value & 0xFF );
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 6b084450c53a..caaba2428f86 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -4690,29 +4690,24 @@ const char *mbedtls_ssl_get_alpn_protocol( const mbedtls_ssl_context *ssl )
 #endif /* MBEDTLS_SSL_ALPN */
 
 #if defined(MBEDTLS_SSL_DTLS_SRTP)
-static const mbedtls_ssl_srtp_profile_info srtp_profile_definitions[] =
-{
-    { MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80, "MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80" },
-    { MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32, "MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32" },
-    { MBEDTLS_SRTP_NULL_HMAC_SHA1_80, "MBEDTLS_SRTP_NULL_HMAC_SHA1_80" },
-    { MBEDTLS_SRTP_NULL_HMAC_SHA1_32, "MBEDTLS_SRTP_NULL_HMAC_SHA1_32" },
-    { MBEDTLS_SRTP_UNSET_PROFILE, "" }
-};
-
-const mbedtls_ssl_srtp_profile_info *mbedtls_ssl_dtls_srtp_profile_info_from_id( mbedtls_ssl_srtp_profile profile )
+#if defined(MBEDTLS_DEBUG_C)
+const char *mbedtls_ssl_get_srtp_profile_as_string ( mbedtls_ssl_srtp_profile profile )
 {
-    const mbedtls_ssl_srtp_profile_info *cur = srtp_profile_definitions;
-
-    while( cur->profile != MBEDTLS_SRTP_UNSET_PROFILE )
+    switch( profile )
     {
-        if( cur->profile == profile )
-            return( cur );
-
-        cur++;
+        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( NULL );
+    return( "" );
 }
+#endif /* MBEDTLS_DEBUG_C */
 
 void mbedtls_ssl_conf_srtp_mki_value_supported( mbedtls_ssl_config *conf,
                                                 int support_mki_value )
@@ -4758,10 +4753,10 @@ int mbedtls_ssl_conf_dtls_srtp_protection_profiles( mbedtls_ssl_config *conf,
     {
         switch( profiles[i] )
         {
-            case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80:
-            case MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32:
-            case MBEDTLS_SRTP_NULL_HMAC_SHA1_80:
-            case MBEDTLS_SRTP_NULL_HMAC_SHA1_32:
+            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:
                 break;
             default:
                 conf->dtls_srtp_profile_list = NULL;
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index d727ebcad747..33fbc0538ae8 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -1246,10 +1246,10 @@ int main( int argc, char *argv[] )
     const char* dtls_srtp_label = "EXTRACTOR-dtls_srtp";
     dtls_srtp_keys dtls_srtp_keying;
     const mbedtls_ssl_srtp_profile default_profiles[] = {
-        MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80,
-        MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32,
-        MBEDTLS_SRTP_NULL_HMAC_SHA1_80,
-        MBEDTLS_SRTP_NULL_HMAC_SHA1_32
+        MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80,
+        MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32,
+        MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80,
+        MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32
     };
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
 #endif /* MBEDTLS_SSL_EXPORT_KEYS */
@@ -2755,7 +2755,7 @@ int main( int argc, char *argv[] )
         size_t j = 0;
 
         if( ( mbedtls_ssl_get_dtls_srtp_protection_profile( &ssl )
-                                == MBEDTLS_SRTP_UNSET_PROFILE ) )
+                                == MBEDTLS_TLS_SRTP_UNSET ) )
         {
             mbedtls_printf( "    Unable to negotiate "
                             "the use of DTLS-SRTP\n" );
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index 6dc783215087..b6f0736a8ec7 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -1877,10 +1877,10 @@ int main( int argc, char *argv[] )
      const char* dtls_srtp_label = "EXTRACTOR-dtls_srtp";
      dtls_srtp_keys dtls_srtp_keying;
      const mbedtls_ssl_srtp_profile default_profiles[] = {
-         MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80,
-         MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32,
-         MBEDTLS_SRTP_NULL_HMAC_SHA1_80,
-         MBEDTLS_SRTP_NULL_HMAC_SHA1_32
+         MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80,
+         MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32,
+         MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80,
+         MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32
      };
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
 #endif /* MBEDTLS_SSL_EXPORT_KEYS */
@@ -3864,7 +3864,7 @@ int main( int argc, char *argv[] )
         size_t j = 0;
 
         if( ( mbedtls_ssl_get_dtls_srtp_protection_profile( &ssl )
-                                == MBEDTLS_SRTP_UNSET_PROFILE ) )
+                                == MBEDTLS_TLS_SRTP_UNSET ) )
         {
             mbedtls_printf( "    Unable to negotiate "
                             "the use of DTLS-SRTP\n" );
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index b820a735b3a1..be57f9ddd50b 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -1074,7 +1074,7 @@ P_SRV="$P_SRV server_addr=127.0.0.1 server_port=$SRV_PORT"
 P_CLI="$P_CLI server_addr=127.0.0.1 server_port=+SRV_PORT"
 P_PXY="$P_PXY server_addr=127.0.0.1 server_port=$SRV_PORT listen_addr=127.0.0.1 listen_port=$PXY_PORT ${SEED:+"seed=$SEED"}"
 O_SRV="$O_SRV -accept $SRV_PORT -dhparam data_files/dhparams.pem"
-O_CLI="$O_CLI -connect 127.0.0.1:+SRV_PORT"
+O_CLI="$O_CLI -connect localhost:+SRV_PORT"
 G_SRV="$G_SRV -p $SRV_PORT"
 G_CLI="$G_CLI -p +SRV_PORT"
 
@@ -8734,33 +8734,33 @@ run_test  "DTLS-SRTP all profiles supported" \
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
 run_test  "DTLS-SRTP server supports all profiles. Client supports one profile." \
           "$P_SRV dtls=1 use_srtp=1 debug_level=3" \
-          "$P_CLI dtls=1 use_srtp=1 srtp_force_profile=3 debug_level=3" \
+          "$P_CLI dtls=1 use_srtp=1 srtp_force_profile=5 debug_level=3" \
           0 \
           -s "found use_srtp extension" \
-          -s "found srtp profile: MBEDTLS_SRTP_NULL_HMAC_SHA1_80" \
-          -s "selected srtp profile: MBEDTLS_SRTP_NULL_HMAC_SHA1_80" \
+          -s "found srtp profile: MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80" \
+          -s "selected srtp profile: MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80" \
           -s "server hello, adding use_srtp extension" \
           -s "DTLS-SRTP key material is"\
           -c "client hello, adding use_srtp extension" \
           -c "found use_srtp extension" \
-          -c "found srtp profile: MBEDTLS_SRTP_NULL_HMAC_SHA1_80" \
+          -c "found srtp profile: MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80" \
           -c "selected srtp profile" \
           -c "DTLS-SRTP key material is"\
           -C "error"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
 run_test  "DTLS-SRTP server supports one profile. Client supports all profiles." \
-          "$P_SRV dtls=1 use_srtp=1 srtp_force_profile=4 debug_level=3" \
+          "$P_SRV dtls=1 use_srtp=1 srtp_force_profile=6 debug_level=3" \
           "$P_CLI dtls=1 use_srtp=1 debug_level=3" \
           0 \
           -s "found use_srtp extension" \
           -s "found srtp profile" \
-          -s "selected srtp profile: MBEDTLS_SRTP_NULL_HMAC_SHA1_32" \
+          -s "selected srtp profile: MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32" \
           -s "server hello, adding use_srtp extension" \
           -s "DTLS-SRTP key material is"\
           -c "client hello, adding use_srtp extension" \
           -c "found use_srtp extension" \
-          -c "found srtp profile: MBEDTLS_SRTP_NULL_HMAC_SHA1_32" \
+          -c "found srtp profile: MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32" \
           -c "selected srtp profile" \
           -c "DTLS-SRTP key material is"\
           -C "error"
@@ -8771,13 +8771,13 @@ run_test  "DTLS-SRTP server and Client support only one matching profile." \
           "$P_CLI dtls=1 use_srtp=1 srtp_force_profile=2 debug_level=3" \
           0 \
           -s "found use_srtp extension" \
-          -s "found srtp profile: MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32" \
-          -s "selected srtp profile: MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32" \
+          -s "found srtp profile: MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32" \
+          -s "selected srtp profile: MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32" \
           -s "server hello, adding use_srtp extension" \
           -s "DTLS-SRTP key material is"\
           -c "client hello, adding use_srtp extension" \
           -c "found use_srtp extension" \
-          -c "found srtp profile: MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32" \
+          -c "found srtp profile: MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32" \
           -c "selected srtp profile" \
           -c "DTLS-SRTP key material is"\
           -C "error"
@@ -8785,10 +8785,10 @@ run_test  "DTLS-SRTP server and Client support only one matching profile." \
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
 run_test  "DTLS-SRTP server and Client support only one different profile." \
           "$P_SRV dtls=1 use_srtp=1 srtp_force_profile=2 debug_level=3" \
-          "$P_CLI dtls=1 use_srtp=1 srtp_force_profile=4 debug_level=3" \
+          "$P_CLI dtls=1 use_srtp=1 srtp_force_profile=6 debug_level=3" \
           0 \
           -s "found use_srtp extension" \
-          -s "found srtp profile: MBEDTLS_SRTP_NULL_HMAC_SHA1_32" \
+          -s "found srtp profile: MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32" \
           -S "selected srtp profile" \
           -S "server hello, adding use_srtp extension" \
           -S "DTLS-SRTP key material is"\
@@ -8944,7 +8944,7 @@ run_test  "DTLS-SRTP all profiles supported. openssl server" \
           -c "client hello, adding use_srtp extension" \
           -c "found use_srtp extension" \
           -c "found srtp profile" \
-          -c "selected srtp profile: MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80" \
+          -c "selected srtp profile: MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80" \
           -c "DTLS-SRTP key material is"\
           -C "error"
 
@@ -8967,7 +8967,7 @@ run_test  "DTLS-SRTP server supports all profiles. Client supports one profile.
           0 \
           -c "client hello, adding use_srtp extension" \
           -c "found use_srtp extension" \
-          -c "found srtp profile: MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32" \
+          -c "found srtp profile: MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32" \
           -c "selected srtp profile" \
           -c "DTLS-SRTP key material is"\
           -C "error"
@@ -8979,7 +8979,7 @@ run_test  "DTLS-SRTP server supports one profile. Client supports all profiles.
           0 \
           -c "client hello, adding use_srtp extension" \
           -c "found use_srtp extension" \
-          -c "found srtp profile: MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32" \
+          -c "found srtp profile: MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32" \
           -c "selected srtp profile" \
           -c "DTLS-SRTP key material is"\
           -C "error"
@@ -8991,7 +8991,7 @@ run_test  "DTLS-SRTP server and Client support only one matching profile. openss
           0 \
           -c "client hello, adding use_srtp extension" \
           -c "found use_srtp extension" \
-          -c "found srtp profile: MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32" \
+          -c "found srtp profile: MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32" \
           -c "selected srtp profile" \
           -c "DTLS-SRTP key material is"\
           -C "error"
@@ -8999,7 +8999,7 @@ run_test  "DTLS-SRTP server and Client support only one matching profile. openss
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
 run_test  "DTLS-SRTP server and Client support only one different profile. openssl server." \
           "$O_SRV -dtls1 -verify 0 -use_srtp SRTP_AES128_CM_SHA1_32" \
-          "$P_CLI dtls=1 use_srtp=1 srtp_force_profile=4 debug_level=3" \
+          "$P_CLI dtls=1 use_srtp=1 srtp_force_profile=6 debug_level=3" \
           0 \
           -c "client hello, adding use_srtp extension" \
           -C "found use_srtp extension" \
@@ -9067,8 +9067,8 @@ run_test  "DTLS-SRTP server supports all profiles. Client supports one profile.
           "$G_CLI -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_32 --insecure 127.0.0.1" \
           0 \
           -s "found use_srtp extension" \
-          -s "found srtp profile: MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32" \
-          -s "selected srtp profile: MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32" \
+          -s "found srtp profile: MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32" \
+          -s "selected srtp profile: MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32" \
           -s "server hello, adding use_srtp extension" \
           -s "DTLS-SRTP key material is"\
           -c "SRTP profile: SRTP_AES128_CM_HMAC_SHA1_32"
@@ -9076,12 +9076,12 @@ run_test  "DTLS-SRTP server supports all profiles. Client supports one profile.
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
 requires_gnutls
 run_test  "DTLS-SRTP server supports one profile. Client supports all profiles. gnutls client." \
-          "$P_SRV dtls=1 use_srtp=1 srtp_force_profile=4 debug_level=3" \
+          "$P_SRV dtls=1 use_srtp=1 srtp_force_profile=6 debug_level=3" \
           "$G_CLI -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_80:SRTP_AES128_CM_HMAC_SHA1_32:SRTP_NULL_HMAC_SHA1_80:SRTP_NULL_SHA1_32 --insecure 127.0.0.1" \
           0 \
           -s "found use_srtp extension" \
           -s "found srtp profile" \
-          -s "selected srtp profile: MBEDTLS_SRTP_NULL_HMAC_SHA1_32" \
+          -s "selected srtp profile: MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32" \
           -s "server hello, adding use_srtp extension" \
           -s "DTLS-SRTP key material is"\
           -c "SRTP profile: SRTP_NULL_SHA1_32"
@@ -9132,7 +9132,7 @@ run_test  "DTLS-SRTP all profiles supported. gnutls server" \
           -c "client hello, adding use_srtp extension" \
           -c "found use_srtp extension" \
           -c "found srtp profile" \
-          -c "selected srtp profile: MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80" \
+          -c "selected srtp profile: MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80" \
           -c "DTLS-SRTP key material is"\
           -C "error"
 
@@ -9145,7 +9145,7 @@ run_test  "DTLS-SRTP server supports all profiles. Client supports all profiles,
           -c "client hello, adding use_srtp extension" \
           -c "found use_srtp extension" \
           -c "found srtp profile" \
-          -c "selected srtp profile: MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_80" \
+          -c "selected srtp profile: MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80" \
           -c "DTLS-SRTP key material is"\
           -C "error"
 
@@ -9157,7 +9157,7 @@ run_test  "DTLS-SRTP server supports all profiles. Client supports one profile.
           0 \
           -c "client hello, adding use_srtp extension" \
           -c "found use_srtp extension" \
-          -c "found srtp profile: MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32" \
+          -c "found srtp profile: MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32" \
           -c "selected srtp profile" \
           -c "DTLS-SRTP key material is"\
           -C "error"
@@ -9170,7 +9170,7 @@ run_test  "DTLS-SRTP server supports one profile. Client supports all profiles.
           0 \
           -c "client hello, adding use_srtp extension" \
           -c "found use_srtp extension" \
-          -c "found srtp profile: MBEDTLS_SRTP_NULL_HMAC_SHA1_80" \
+          -c "found srtp profile: MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80" \
           -c "selected srtp profile" \
           -c "DTLS-SRTP key material is"\
           -C "error"
@@ -9183,7 +9183,7 @@ run_test  "DTLS-SRTP server and Client support only one matching profile. gnutls
           0 \
           -c "client hello, adding use_srtp extension" \
           -c "found use_srtp extension" \
-          -c "found srtp profile: MBEDTLS_SRTP_AES128_CM_HMAC_SHA1_32" \
+          -c "found srtp profile: MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32" \
           -c "selected srtp profile" \
           -c "DTLS-SRTP key material is"\
           -C "error"
@@ -9192,7 +9192,7 @@ requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
 requires_gnutls
 run_test  "DTLS-SRTP server and Client support only one different profile. gnutls server." \
           "$G_SRV -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_32" \
-          "$P_CLI dtls=1 use_srtp=1 srtp_force_profile=4 debug_level=3" \
+          "$P_CLI dtls=1 use_srtp=1 srtp_force_profile=6 debug_level=3" \
           0 \
           -c "client hello, adding use_srtp extension" \
           -C "found use_srtp extension" \

From 253d0263a67b2e8d0a8555f00583abefaee76e07 Mon Sep 17 00:00:00 2001
From: Johan Pascal <johan.pascal@belledonne-communications.com>
Date: Tue, 22 Sep 2020 13:04:45 +0200
Subject: [PATCH 44/63] set protection profile API gets a
 MBEDTLS_TLS_SRTP_UNSET terminated list

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 include/mbedtls/ssl.h      | 15 +++++++--------
 library/ssl_tls.c          | 32 +++++++++++++++-----------------
 programs/ssl/ssl_client2.c | 15 +++++----------
 programs/ssl/ssl_server2.c | 13 +++++--------
 4 files changed, 32 insertions(+), 43 deletions(-)

diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index 1ded993bc73e..085d27082ab2 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -3204,13 +3204,13 @@ void mbedtls_ssl_conf_srtp_mki_value_supported( mbedtls_ssl_config *conf,
  * \brief                   Set the supported DTLS-SRTP protection profiles.
  *
  * \param conf              SSL configuration
- * \param profiles          List of supported protection profiles,
+ * \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.
- * \param profiles_number   Number of supported profiles.
+ *                          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.
  *
  * \return                  0 on success
  * \return                  #MBEDTLS_ERR_SSL_BAD_INPUT_DATA when the list of
@@ -3218,8 +3218,7 @@ void mbedtls_ssl_conf_srtp_mki_value_supported( mbedtls_ssl_config *conf,
  */
 int mbedtls_ssl_conf_dtls_srtp_protection_profiles
                                ( mbedtls_ssl_config *conf,
-                                 const mbedtls_ssl_srtp_profile *profiles,
-                                 size_t profiles_number );
+                                 const mbedtls_ssl_srtp_profile *profiles );
 
 /**
  * \brief                  Set the mki_value for the current DTLS-SRTP session.
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index caaba2428f86..f6b56f1976e2 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -4735,38 +4735,36 @@ int mbedtls_ssl_dtls_srtp_set_mki_value( mbedtls_ssl_context *ssl,
 }
 
 int mbedtls_ssl_conf_dtls_srtp_protection_profiles( mbedtls_ssl_config *conf,
-                                                    const mbedtls_ssl_srtp_profile *profiles,
-                                                    size_t profiles_number )
+                                                    const mbedtls_ssl_srtp_profile *profiles )
 {
-    size_t i;
-    /*
-     * Check input validity : must be a list of profiles from enumeration.
-     * Maximum length is 4 as only 4 protection profiles are defined.
-     */
-    if( profiles_number > 4 )
-    {
-        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
-    }
+    const mbedtls_ssl_srtp_profile *p;
+    size_t list_size = 0;
 
-
-    for( i=0; i < profiles_number; i++ )
+    /* check the profiles list: all entry must be valid,
+     * its size cannot be more than the total number of supported profiles, currently 4 */
+    for( p = profiles; *p != MBEDTLS_TLS_SRTP_UNSET && list_size < 5; p++ )
     {
-        switch( profiles[i] )
+        switch( *p )
         {
             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:
+                    list_size++;
                 break;
-            default:
+            default: /* unsupported value, stop parsing and set the size to an error value */
+                list_size = 5;
+        }
+    }
+
+    if ( list_size > 4 ) {
                 conf->dtls_srtp_profile_list = NULL;
                 conf->dtls_srtp_profile_list_len = 0;
                 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
-        }
     }
 
     conf->dtls_srtp_profile_list = profiles;
-    conf->dtls_srtp_profile_list_len = profiles_number;
+    conf->dtls_srtp_profile_list_len = list_size;
 
     return( 0 );
 }
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index 33fbc0538ae8..cdedbd290d99 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -1249,7 +1249,8 @@ int main( int argc, char *argv[] )
         MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80,
         MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32,
         MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80,
-        MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32
+        MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32,
+        MBEDTLS_TLS_SRTP_UNSET
     };
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
 #endif /* MBEDTLS_SSL_EXPORT_KEYS */
@@ -2334,18 +2335,12 @@ int main( int argc, char *argv[] )
     {
         if( opt.force_srtp_profile != 0 )
         {
-            const mbedtls_ssl_srtp_profile forced_profile[] = { opt.force_srtp_profile };
-            ret = mbedtls_ssl_conf_dtls_srtp_protection_profiles
-                    ( &conf,
-                     forced_profile,
-                     sizeof( forced_profile ) / sizeof( mbedtls_ssl_srtp_profile ) );
+            const mbedtls_ssl_srtp_profile forced_profile[] = { opt.force_srtp_profile, MBEDTLS_TLS_SRTP_UNSET };
+            ret = mbedtls_ssl_conf_dtls_srtp_protection_profiles ( &conf, forced_profile );
         }
         else
         {
-            ret = mbedtls_ssl_conf_dtls_srtp_protection_profiles
-                    ( &conf,
-                      default_profiles,
-                      sizeof( default_profiles ) / sizeof( mbedtls_ssl_srtp_profile ) );
+            ret = mbedtls_ssl_conf_dtls_srtp_protection_profiles ( &conf, default_profiles );
         }
 
         if( ret != 0 )
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index b6f0736a8ec7..e66ca40413e2 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -1880,7 +1880,8 @@ int main( int argc, char *argv[] )
          MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80,
          MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32,
          MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80,
-         MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32
+         MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32,
+         MBEDTLS_TLS_SRTP_UNSET
      };
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
 #endif /* MBEDTLS_SSL_EXPORT_KEYS */
@@ -3146,16 +3147,12 @@ int main( int argc, char *argv[] )
     {
         if( opt.force_srtp_profile != 0 )
         {
-            const mbedtls_ssl_srtp_profile forced_profile[] = { opt.force_srtp_profile };
-            ret = mbedtls_ssl_conf_dtls_srtp_protection_profiles( &conf,
-                                                                  forced_profile,
-                                                                  sizeof( forced_profile ) / sizeof( mbedtls_ssl_srtp_profile ) );
+            const mbedtls_ssl_srtp_profile forced_profile[] = { opt.force_srtp_profile, MBEDTLS_TLS_SRTP_UNSET };
+            ret = mbedtls_ssl_conf_dtls_srtp_protection_profiles( &conf, forced_profile );
         }
         else
         {
-            ret = mbedtls_ssl_conf_dtls_srtp_protection_profiles( &conf,
-                                                                  default_profiles,
-                                                                  sizeof( default_profiles ) / sizeof( mbedtls_ssl_srtp_profile ) );
+            ret = mbedtls_ssl_conf_dtls_srtp_protection_profiles( &conf, default_profiles );
         }
 
         if( ret != 0 )

From f6417ecf605d7122568fa425c623be80611a838f Mon Sep 17 00:00:00 2001
From: Johan Pascal <johan.pascal@belledonne-communications.com>
Date: Tue, 22 Sep 2020 15:15:19 +0200
Subject: [PATCH 45/63] mki length feats in a uint16_t

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 include/mbedtls/ssl.h | 6 +++---
 library/ssl_cli.c     | 9 +++------
 library/ssl_srv.c     | 3 ++-
 library/ssl_tls.c     | 2 +-
 4 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index 085d27082ab2..066522fe55b2 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -888,10 +888,10 @@ 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];
-    /*! The length of mki_value. */
-    size_t mki_len;
 }
 mbedtls_dtls_srtp_info;
 
@@ -3233,7 +3233,7 @@ int mbedtls_ssl_conf_dtls_srtp_protection_profiles
  */
 int mbedtls_ssl_dtls_srtp_set_mki_value( mbedtls_ssl_context *ssl,
                                          unsigned char *mki_value,
-                                         size_t mki_len );
+                                         uint16_t mki_len );
 /**
  * \brief          Get the negotiated DTLS-SRTP Protection Profile.
  *                 This function should be called after the handshake is
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index 185997ddf529..39547684e45f 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -761,10 +761,8 @@ static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
                                     unsigned char *buf, size_t *olen )
 {
     unsigned char *p = buf;
-    size_t protection_profiles_index = 0;
-    size_t mki_len = 0;
-    size_t ext_len = 0;
-    uint16_t profile_value = 0;
+    size_t protection_profiles_index = 0, ext_len = 0;
+    uint16_t mki_len = 0, profile_value = 0;
 
     *olen = 0;
 
@@ -1843,8 +1841,7 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
      * SRTPProtectionProfile SRTPProtectionProfiles<2..2^16-1>;
      *
      */
-    if( ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED &&
-        ssl->dtls_srtp_info.mki_len != 0 )
+    if( ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED )
     {
         mki_len = ssl->dtls_srtp_info.mki_len;
     }
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index 9dc08d29997a..5c56a70d914b 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -783,7 +783,8 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
 {
     mbedtls_ssl_srtp_profile client_protection = MBEDTLS_TLS_SRTP_UNSET;
     size_t i,j;
-    size_t profile_length,mki_length;
+    size_t profile_length;
+    uint16_t mki_length;
     /*! 2 bytes for profile length and 1 byte for mki len */
     const size_t size_of_lengths = 3;
 
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index f6b56f1976e2..9a669840a489 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -4717,7 +4717,7 @@ void mbedtls_ssl_conf_srtp_mki_value_supported( mbedtls_ssl_config *conf,
 
 int mbedtls_ssl_dtls_srtp_set_mki_value( mbedtls_ssl_context *ssl,
                                          unsigned char *mki_value,
-                                         size_t mki_len )
+                                         uint16_t mki_len )
 {
     if ( mki_len > MBEDTLS_TLS_SRTP_MAX_MKI_LENGTH )
     {

From a455cd9a473fc80d85df8d4bbbc6c48aab44ad89 Mon Sep 17 00:00:00 2001
From: Johan Pascal <johan.pascal@belledonne-communications.com>
Date: Tue, 22 Sep 2020 15:28:11 +0200
Subject: [PATCH 46/63] mbedtls_ssl_get_srtp_profile_as_string declared and
 defined in ssl.h

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 include/mbedtls/ssl.h          | 18 ++++++++++++++++++
 include/mbedtls/ssl_internal.h |  4 ----
 library/ssl_tls.c              | 19 -------------------
 3 files changed, 18 insertions(+), 23 deletions(-)

diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index 066522fe55b2..d0007fc9fb7d 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -3184,6 +3184,24 @@ 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.
diff --git a/include/mbedtls/ssl_internal.h b/include/mbedtls/ssl_internal.h
index e1ba5cdb6a84..1dc9648b0471 100644
--- a/include/mbedtls/ssl_internal.h
+++ b/include/mbedtls/ssl_internal.h
@@ -1096,10 +1096,6 @@ int mbedtls_ssl_check_sig_hash( const mbedtls_ssl_context *ssl,
 #endif
 
 #if defined(MBEDTLS_SSL_DTLS_SRTP)
-#if defined(MBEDTLS_DEBUG_C)
-const char *mbedtls_ssl_get_srtp_profile_as_string ( mbedtls_ssl_srtp_profile profile );
-#endif /* MBEDTLS_DEBUG_C */
-
 static inline mbedtls_ssl_srtp_profile mbedtls_ssl_check_srtp_profile_value
                                                     ( const uint16_t srtp_profile_value )
 {
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 9a669840a489..7c06c3bdab77 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -4690,25 +4690,6 @@ 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)
-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 */
-
 void mbedtls_ssl_conf_srtp_mki_value_supported( mbedtls_ssl_config *conf,
                                                 int support_mki_value )
 {

From e79c1e812147c95572a5abc887f10058ea88f4fc Mon Sep 17 00:00:00 2001
From: Johan Pascal <johan.pascal@belledonne-communications.com>
Date: Tue, 22 Sep 2020 15:51:27 +0200
Subject: [PATCH 47/63] style

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 include/mbedtls/config.h |  4 ++--
 include/mbedtls/ssl.h    |  8 ++++----
 library/ssl_cli.c        | 11 +++++++----
 3 files changed, 13 insertions(+), 10 deletions(-)

diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h
index 7a1a2b1e518b..2b123388eacb 100644
--- a/include/mbedtls/config.h
+++ b/include/mbedtls/config.h
@@ -1817,8 +1817,8 @@
  *
  * Enable support for DTLS-SRTP, RFC5764, use_srtp extension.
  * \note Only the dtls-srtp key material negotiation is supported.
- * Once negotiated, the key should be extracted, and data should be transmitted
- * via an SRTP stack.
+ * Once negotiated, the key should be extracted using mbedtls_ssl_tls_prf()
+ * and data should be transmitted via an SRTP stack.
  *
  * Requires: MBEDTLS_SSL_PROTO_DTLS
  *
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index d0007fc9fb7d..bae5348d35a3 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -3190,13 +3190,13 @@ static inline const char *mbedtls_ssl_get_srtp_profile_as_string ( mbedtls_ssl_s
     switch( profile )
     {
         case MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80:
-            return "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";
+            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";
+            return( "MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80" );
         case MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32:
-            return "MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32";
+            return( "MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32" );
         default: break;
     }
     return( "" );
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index 39547684e45f..0eaeefa10942 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -800,9 +800,9 @@ static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
     *p++ = (unsigned char)( ext_len & 0xFF );
 
     /* protection profile length: 2*(ssl->conf->dtls_srtp_profile_list_len) */
-    *p++ = (unsigned char)( ( ( 2 * (ssl->conf->dtls_srtp_profile_list_len) )
+    *p++ = (unsigned char)( ( ( 2 * ssl->conf->dtls_srtp_profile_list_len )
                               >> 8 ) & 0xFF );
-    *p++ = (unsigned char)( ( 2 * (ssl->conf->dtls_srtp_profile_list_len) )
+    *p++ = (unsigned char)( ( 2 * ssl->conf->dtls_srtp_profile_list_len )
                             & 0xFF );
 
     for( protection_profiles_index=0;
@@ -824,8 +824,11 @@ static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
              * Note: we shall never arrive here as protection profiles
              * is checked by ssl_set_dtls_srtp_protection_profiles function
              */
-            MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, ignore illegal DTLS-SRTP protection profile %d",
-                                        ssl->conf->dtls_srtp_profile_list[protection_profiles_index] ) );
+            MBEDTLS_SSL_DEBUG_MSG( 3,
+                    ( "client hello, "
+                      "ignore illegal DTLS-SRTP protection profile %d",
+                      ssl->conf->dtls_srtp_profile_list[protection_profiles_index]
+                    ) );
         }
     }
 

From aae4d22b166deec4c36bb53e8ad3e333dfda10d9 Mon Sep 17 00:00:00 2001
From: Johan Pascal <johan.pascal@belledonne-communications.com>
Date: Tue, 22 Sep 2020 21:21:39 +0200
Subject: [PATCH 48/63] Improve code readability +micro optimization +style

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 include/mbedtls/ssl.h |  5 ++++-
 library/ssl_cli.c     | 10 ++++++++--
 library/ssl_tls.c     |  6 +++---
 3 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index bae5348d35a3..a6b8f1bf5696 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -873,6 +873,7 @@ typedef void mbedtls_ssl_async_cancel_t( mbedtls_ssl_context *ssl );
 
 #define MBEDTLS_TLS_SRTP_MAX_KEY_MATERIAL_LENGTH    60
 #define MBEDTLS_TLS_SRTP_MAX_MKI_LENGTH             255
+#define MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH    4
 /*
  * For code readability use a typedef for DTLS-SRTP profiles
  * The supported profiles are defines as macro above:
@@ -3185,7 +3186,7 @@ const char *mbedtls_ssl_get_alpn_protocol( const mbedtls_ssl_context *ssl );
 
 #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 )
+static inline const char *mbedtls_ssl_get_srtp_profile_as_string( mbedtls_ssl_srtp_profile profile )
 {
     switch( profile )
     {
@@ -3229,6 +3230,8 @@ void mbedtls_ssl_conf_srtp_mki_value_supported( mbedtls_ssl_config *conf,
  *                          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
  *
  * \return                  0 on success
  * \return                  #MBEDTLS_ERR_SSL_BAD_INPUT_DATA when the list of
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index 0eaeefa10942..b3cfc972cfcd 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -800,8 +800,14 @@ static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
     *p++ = (unsigned char)( ext_len & 0xFF );
 
     /* protection profile length: 2*(ssl->conf->dtls_srtp_profile_list_len) */
-    *p++ = (unsigned char)( ( ( 2 * ssl->conf->dtls_srtp_profile_list_len )
-                              >> 8 ) & 0xFF );
+    /* micro-optimization:
+     * the list size is limited to MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH
+     * which is lower than 127, so the upper byte of the length is always 0
+     * For the documentation, the more generic code is left in comments
+     * *p++ = (unsigned char)( ( ( 2 * ssl->conf->dtls_srtp_profile_list_len )
+     *                        >> 8 ) & 0xFF );
+     */
+    *p++ = 0;
     *p++ = (unsigned char)( ( 2 * ssl->conf->dtls_srtp_profile_list_len )
                             & 0xFF );
 
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 7c06c3bdab77..18a149f0c945 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -4723,7 +4723,7 @@ int mbedtls_ssl_conf_dtls_srtp_protection_profiles( mbedtls_ssl_config *conf,
 
     /* check the profiles list: all entry must be valid,
      * its size cannot be more than the total number of supported profiles, currently 4 */
-    for( p = profiles; *p != MBEDTLS_TLS_SRTP_UNSET && list_size < 5; p++ )
+    for( p = profiles; *p != MBEDTLS_TLS_SRTP_UNSET && list_size <= MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH; p++ )
     {
         switch( *p )
         {
@@ -4734,11 +4734,11 @@ int mbedtls_ssl_conf_dtls_srtp_protection_profiles( mbedtls_ssl_config *conf,
                     list_size++;
                 break;
             default: /* unsupported value, stop parsing and set the size to an error value */
-                list_size = 5;
+                list_size = MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH+1;
         }
     }
 
-    if ( list_size > 4 ) {
+    if ( list_size > MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH ) {
                 conf->dtls_srtp_profile_list = NULL;
                 conf->dtls_srtp_profile_list_len = 0;
                 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );

From 77696eedac32e3f8fc080a4cb4b7418252c69699 Mon Sep 17 00:00:00 2001
From: Johan Pascal <johan.pascal@belledonne-communications.com>
Date: Tue, 22 Sep 2020 21:49:40 +0200
Subject: [PATCH 49/63] Add bound check in the client ssl_write_use_srtp_ext

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 library/ssl_cli.c | 34 +++++++++++++++++++++++++---------
 1 file changed, 25 insertions(+), 9 deletions(-)

diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index b3cfc972cfcd..73d16b3a80d9 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -757,8 +757,10 @@ static int ssl_write_alpn_ext( mbedtls_ssl_context *ssl,
 #endif /* MBEDTLS_SSL_ALPN */
 
 #if defined(MBEDTLS_SSL_DTLS_SRTP)
-static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
-                                    unsigned char *buf, size_t *olen )
+static int ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
+                                    unsigned char *buf,
+                                    const unsigned char *end,
+                                    size_t *olen )
 {
     unsigned char *p = buf;
     size_t protection_profiles_index = 0, ext_len = 0;
@@ -769,14 +771,9 @@ static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
     if( ( ssl->conf->dtls_srtp_profile_list == NULL ) ||
         ( ssl->conf->dtls_srtp_profile_list_len == 0  ) )
     {
-        return;
+        return( 0 );
     }
 
-    MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding use_srtp extension" ) );
-
-    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_USE_SRTP >> 8 ) & 0xFF );
-    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_USE_SRTP      ) & 0xFF );
-
     /* RFC 5764 section 4.1.1
      * uint8 SRTPProtectionProfile[2];
      *
@@ -796,6 +793,18 @@ static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
      */
     ext_len = 2 + 2 * ( ssl->conf->dtls_srtp_profile_list_len ) + 1 + mki_len;
 
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding use_srtp extension" ) );
+
+    /* Check there is room in the buffer for the extension + 4 bytes
+     * - the extension tag (2 bytes)
+     * - the extension length (2 bytes)
+     */
+    MBEDTLS_SSL_CHK_BUF_PTR( p, end, ext_len + 4 );
+
+    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_USE_SRTP >> 8 ) & 0xFF );
+    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_USE_SRTP      ) & 0xFF );
+
+
     *p++ = (unsigned char)( ( ( ext_len & 0xFF00 ) >> 8 ) & 0xFF );
     *p++ = (unsigned char)( ext_len & 0xFF );
 
@@ -860,6 +869,8 @@ static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
      *                         + mki value
      */
     *olen = p - buf;
+
+    return( 0 );
 }
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
 
@@ -1387,7 +1398,12 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
 #if defined(MBEDTLS_SSL_DTLS_SRTP)
     if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
     {
-        ssl_write_use_srtp_ext( ssl, p + 2 + ext_len, &olen );
+        if( ( ret = ssl_write_use_srtp_ext( ssl, p + 2 + ext_len,
+                                       end, &olen ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_use_srtp_ext", ret );
+            return( ret );
+        }
         ext_len += olen;
     }
 #endif

From 842d671316d3261317cda2eea85a07daddea5d48 Mon Sep 17 00:00:00 2001
From: Johan Pascal <jeannotlapin@users.noreply.github.com>
Date: Wed, 23 Sep 2020 13:34:40 +0200
Subject: [PATCH 50/63] Update include/mbedtls/config.h

Co-authored-by: Hanno Becker <hanno.becker@arm.com>
Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 include/mbedtls/config.h | 25 +++++++++++++++++++++----
 1 file changed, 21 insertions(+), 4 deletions(-)

diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h
index 2b123388eacb..2ac2cc696a2b 100644
--- a/include/mbedtls/config.h
+++ b/include/mbedtls/config.h
@@ -1815,10 +1815,27 @@
 /**
  * \def MBEDTLS_SSL_DTLS_SRTP
  *
- * Enable support for DTLS-SRTP, RFC5764, use_srtp extension.
- * \note Only the dtls-srtp key material negotiation is supported.
- * Once negotiated, the key should be extracted using mbedtls_ssl_tls_prf()
- * and data should be transmitted via an SRTP stack.
+ * 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
+ * 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
  *

From d387aa05869eecfe0b52d90a104b3eca676fb03a Mon Sep 17 00:00:00 2001
From: Johan Pascal <johan.pascal@belledonne-communications.com>
Date: Wed, 23 Sep 2020 18:47:56 +0200
Subject: [PATCH 51/63] style + missing cast

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 include/mbedtls/ssl.h      |  1 +
 library/ssl_cli.c          |  8 ++++----
 library/ssl_tls.c          | 11 +++++++----
 programs/ssl/ssl_client2.c |  2 +-
 4 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index a6b8f1bf5696..840722dede99 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -3232,6 +3232,7 @@ void mbedtls_ssl_conf_srtp_mki_value_supported( mbedtls_ssl_config *conf,
  *                          of the SSL configuration structure.
  *                          The list must not hold more than
  *                          MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH elements
+ *                          (excluding the terminating MBEDTLS_TLS_SRTP_UNSET).
  *
  * \return                  0 on success
  * \return                  #MBEDTLS_ERR_SSL_BAD_INPUT_DATA when the list of
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index 73d16b3a80d9..c864cb2c6a0e 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -758,9 +758,9 @@ static int ssl_write_alpn_ext( mbedtls_ssl_context *ssl,
 
 #if defined(MBEDTLS_SSL_DTLS_SRTP)
 static int ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
-                                    unsigned char *buf,
-                                    const unsigned char *end,
-                                    size_t *olen )
+                                   unsigned char *buf,
+                                   const unsigned char *end,
+                                   size_t *olen )
 {
     unsigned char *p = buf;
     size_t protection_profiles_index = 0, ext_len = 0;
@@ -1399,7 +1399,7 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
     if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
     {
         if( ( ret = ssl_write_use_srtp_ext( ssl, p + 2 + ext_len,
-                                       end, &olen ) ) != 0 )
+                                            end, &olen ) ) != 0 )
         {
             MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_use_srtp_ext", ret );
             return( ret );
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 18a149f0c945..58fcab3dd5cb 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -4723,7 +4723,9 @@ int mbedtls_ssl_conf_dtls_srtp_protection_profiles( mbedtls_ssl_config *conf,
 
     /* check the profiles list: all entry must be valid,
      * its size cannot be more than the total number of supported profiles, currently 4 */
-    for( p = profiles; *p != MBEDTLS_TLS_SRTP_UNSET && list_size <= MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH; p++ )
+    for( p = profiles; *p != MBEDTLS_TLS_SRTP_UNSET &&
+                       list_size <= MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH;
+         p++ )
     {
         switch( *p )
         {
@@ -4731,14 +4733,15 @@ int mbedtls_ssl_conf_dtls_srtp_protection_profiles( mbedtls_ssl_config *conf,
             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:
-                    list_size++;
+                list_size++;
                 break;
             default: /* unsupported value, stop parsing and set the size to an error value */
-                list_size = MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH+1;
+                list_size = MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH + 1;
         }
     }
 
-    if ( list_size > MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH ) {
+    if ( list_size > MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH )
+    {
                 conf->dtls_srtp_profile_list = NULL;
                 conf->dtls_srtp_profile_list_len = 0;
                 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index cdedbd290d99..d0f573e27845 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -2614,7 +2614,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( opt.mki ) / 2 ) ) != 0 )
+                                                         (uint16_t) strlen( opt.mki ) / 2 ) ) != 0 )
         {
             mbedtls_printf( " failed\n  ! mbedtls_ssl_dtls_srtp_set_mki_value returned %d\n\n", ret );
             goto exit;

From 39cfd3b96e16fe67ee6e112920ac64ca18ee1a5f Mon Sep 17 00:00:00 2001
From: Johan Pascal <johan.pascal@belledonne-communications.com>
Date: Wed, 23 Sep 2020 18:49:13 +0200
Subject: [PATCH 52/63] interop test: openssl generate the DTLS-SRTP keys
 Missing a command in the test script to compare with peer's output

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 tests/ssl-opt.sh | 28 ++++++++++++++--------------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index be57f9ddd50b..1bba6c6468ed 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -8857,7 +8857,7 @@ run_test  "DTLS-SRTP all profiles supported. server doesn't support mki." \
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
 run_test  "DTLS-SRTP all profiles supported. openssl client." \
           "$P_SRV dtls=1 use_srtp=1 debug_level=3" \
-          "$O_CLI -dtls1 -use_srtp SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32" \
+          "$O_CLI -dtls1 -use_srtp SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32 -keymatexport 'EXTRACTOR-dtls_srtp' -keymatexportlen 60" \
           0 \
           -s "found use_srtp extension" \
           -s "found srtp profile" \
@@ -8869,7 +8869,7 @@ run_test  "DTLS-SRTP all profiles supported. openssl client." \
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
 run_test  "DTLS-SRTP server supports all profiles. Client supports all profiles, in different order. openssl client." \
           "$P_SRV dtls=1 use_srtp=1 debug_level=3" \
-          "$O_CLI -dtls1 -use_srtp SRTP_AES128_CM_SHA1_32:SRTP_AES128_CM_SHA1_80" \
+          "$O_CLI -dtls1 -use_srtp SRTP_AES128_CM_SHA1_32:SRTP_AES128_CM_SHA1_80 -keymatexport 'EXTRACTOR-dtls_srtp' -keymatexportlen 60" \
           0 \
           -s "found use_srtp extension" \
           -s "found srtp profile" \
@@ -8881,7 +8881,7 @@ run_test  "DTLS-SRTP server supports all profiles. Client supports all profiles,
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
 run_test  "DTLS-SRTP server supports all profiles. Client supports one profile. openssl client." \
           "$P_SRV dtls=1 use_srtp=1 debug_level=3" \
-          "$O_CLI -dtls1 -use_srtp SRTP_AES128_CM_SHA1_32" \
+          "$O_CLI -dtls1 -use_srtp SRTP_AES128_CM_SHA1_32 -keymatexport 'EXTRACTOR-dtls_srtp' -keymatexportlen 60" \
           0 \
           -s "found use_srtp extension" \
           -s "found srtp profile" \
@@ -8893,7 +8893,7 @@ run_test  "DTLS-SRTP server supports all profiles. Client supports one profile.
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
 run_test  "DTLS-SRTP server supports one profile. Client supports all profiles. openssl client." \
           "$P_SRV dtls=1 use_srtp=1 srtp_force_profile=2 debug_level=3" \
-          "$O_CLI -dtls1 -use_srtp SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32" \
+          "$O_CLI -dtls1 -use_srtp SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32 -keymatexport 'EXTRACTOR-dtls_srtp' -keymatexportlen 60" \
           0 \
           -s "found use_srtp extension" \
           -s "found srtp profile" \
@@ -8905,7 +8905,7 @@ run_test  "DTLS-SRTP server supports one profile. Client supports all profiles.
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
 run_test  "DTLS-SRTP server and Client support only one matching profile. openssl client." \
           "$P_SRV dtls=1 use_srtp=1 srtp_force_profile=2 debug_level=3" \
-          "$O_CLI -dtls1 -use_srtp SRTP_AES128_CM_SHA1_32" \
+          "$O_CLI -dtls1 -use_srtp SRTP_AES128_CM_SHA1_32 -keymatexport 'EXTRACTOR-dtls_srtp' -keymatexportlen 60" \
           0 \
           -s "found use_srtp extension" \
           -s "found srtp profile" \
@@ -8917,7 +8917,7 @@ run_test  "DTLS-SRTP server and Client support only one matching profile. openss
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
 run_test  "DTLS-SRTP server and Client support only one different profile. openssl client." \
           "$P_SRV dtls=1 use_srtp=1 srtp_force_profile=1 debug_level=3" \
-          "$O_CLI -dtls1 -use_srtp SRTP_AES128_CM_SHA1_32" \
+          "$O_CLI -dtls1 -use_srtp SRTP_AES128_CM_SHA1_32 -keymatexport 'EXTRACTOR-dtls_srtp' -keymatexportlen 60" \
           0 \
           -s "found use_srtp extension" \
           -s "found srtp profile" \
@@ -8929,7 +8929,7 @@ run_test  "DTLS-SRTP server and Client support only one different profile. opens
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
 run_test  "DTLS-SRTP server doesn't support use_srtp extension. openssl client" \
           "$P_SRV dtls=1 debug_level=3" \
-          "$O_CLI -dtls1 -use_srtp SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32" \
+          "$O_CLI -dtls1 -use_srtp SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32 -keymatexport 'EXTRACTOR-dtls_srtp' -keymatexportlen 60" \
           0 \
           -s "found use_srtp extension" \
           -S "server hello, adding use_srtp extension" \
@@ -8938,7 +8938,7 @@ run_test  "DTLS-SRTP server doesn't support use_srtp extension. openssl client"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
 run_test  "DTLS-SRTP all profiles supported. openssl server" \
-          "$O_SRV -dtls1 -verify 0 -use_srtp SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32" \
+          "$O_SRV -dtls1 -verify 0 -use_srtp SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32 -keymatexport 'EXTRACTOR-dtls_srtp' -keymatexportlen 60" \
           "$P_CLI dtls=1 use_srtp=1 debug_level=3" \
           0 \
           -c "client hello, adding use_srtp extension" \
@@ -8950,7 +8950,7 @@ run_test  "DTLS-SRTP all profiles supported. openssl server" \
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
 run_test  "DTLS-SRTP server supports all profiles. Client supports all profiles, in different order. openssl server." \
-          "$O_SRV -dtls1 -verify 0 -use_srtp SRTP_AES128_CM_SHA1_32:SRTP_AES128_CM_SHA1_80" \
+          "$O_SRV -dtls1 -verify 0 -use_srtp SRTP_AES128_CM_SHA1_32:SRTP_AES128_CM_SHA1_80 -keymatexport 'EXTRACTOR-dtls_srtp' -keymatexportlen 60" \
           "$P_CLI dtls=1 use_srtp=1 debug_level=3" \
           0 \
           -c "client hello, adding use_srtp extension" \
@@ -8962,7 +8962,7 @@ run_test  "DTLS-SRTP server supports all profiles. Client supports all profiles,
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
 run_test  "DTLS-SRTP server supports all profiles. Client supports one profile. openssl server." \
-          "$O_SRV -dtls1 -verify 0 -use_srtp SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32" \
+          "$O_SRV -dtls1 -verify 0 -use_srtp SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32 -keymatexport 'EXTRACTOR-dtls_srtp' -keymatexportlen 60" \
           "$P_CLI dtls=1 use_srtp=1 srtp_force_profile=2 debug_level=3" \
           0 \
           -c "client hello, adding use_srtp extension" \
@@ -8974,7 +8974,7 @@ run_test  "DTLS-SRTP server supports all profiles. Client supports one profile.
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
 run_test  "DTLS-SRTP server supports one profile. Client supports all profiles. openssl server." \
-          "$O_SRV -dtls1 -verify 0 -use_srtp SRTP_AES128_CM_SHA1_32" \
+          "$O_SRV -dtls1 -verify 0 -use_srtp SRTP_AES128_CM_SHA1_32 -keymatexport 'EXTRACTOR-dtls_srtp' -keymatexportlen 60" \
           "$P_CLI dtls=1 use_srtp=1 debug_level=3" \
           0 \
           -c "client hello, adding use_srtp extension" \
@@ -8986,7 +8986,7 @@ run_test  "DTLS-SRTP server supports one profile. Client supports all profiles.
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
 run_test  "DTLS-SRTP server and Client support only one matching profile. openssl server." \
-          "$O_SRV -dtls1 -verify 0 -use_srtp SRTP_AES128_CM_SHA1_32" \
+          "$O_SRV -dtls1 -verify 0 -use_srtp SRTP_AES128_CM_SHA1_32 -keymatexport 'EXTRACTOR-dtls_srtp' -keymatexportlen 60" \
           "$P_CLI dtls=1 use_srtp=1 srtp_force_profile=2 debug_level=3" \
           0 \
           -c "client hello, adding use_srtp extension" \
@@ -8998,7 +8998,7 @@ run_test  "DTLS-SRTP server and Client support only one matching profile. openss
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
 run_test  "DTLS-SRTP server and Client support only one different profile. openssl server." \
-          "$O_SRV -dtls1 -verify 0 -use_srtp SRTP_AES128_CM_SHA1_32" \
+          "$O_SRV -dtls1 -verify 0 -use_srtp SRTP_AES128_CM_SHA1_32 -keymatexport 'EXTRACTOR-dtls_srtp' -keymatexportlen 60" \
           "$P_CLI dtls=1 use_srtp=1 srtp_force_profile=6 debug_level=3" \
           0 \
           -c "client hello, adding use_srtp extension" \
@@ -9022,7 +9022,7 @@ run_test  "DTLS-SRTP server doesn't support use_srtp extension. openssl server"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
 run_test  "DTLS-SRTP all profiles supported. server doesn't support mki. openssl server." \
-          "$O_SRV -dtls1 -verify 0 -use_srtp SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32" \
+          "$O_SRV -dtls1 -verify 0 -use_srtp SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32 -keymatexport 'EXTRACTOR-dtls_srtp' -keymatexportlen 60" \
           "$P_CLI dtls=1 use_srtp=1 mki=542310ab34290481 debug_level=3" \
           0 \
           -c "client hello, adding use_srtp extension" \

From 9bc50b01221d7c5e0d20c70b1af9c96567748c04 Mon Sep 17 00:00:00 2001
From: Johan Pascal <johan.pascal@belledonne-communications.com>
Date: Thu, 24 Sep 2020 12:01:13 +0200
Subject: [PATCH 53/63] Test check the key material exported match - include
 interop with openssl client

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 programs/ssl/ssl_client2.c | 10 ++++++++++
 programs/ssl/ssl_server2.c | 10 ++++++++++
 tests/ssl-opt.sh           | 36 ++++++++++++++++++++++++++++++++++++
 3 files changed, 56 insertions(+)

diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index d0f573e27845..759603a8faa4 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -2779,7 +2779,17 @@ int main( int argc, char *argv[] )
                     mbedtls_printf( "\n    " );
                 mbedtls_printf( "%02x ", dtls_srtp_key_material[j] );
             }
+            mbedtls_printf( "\n" );
 
+            /* produce a less readable output used to perform automatic checks
+             * - compare client and server output
+             * - interop test with openssl which client produces this kind of output
+             */
+            mbedtls_printf( "    Keying material: " );
+            for( j = 0; j < sizeof( dtls_srtp_key_material ); j++ )
+            {
+                mbedtls_printf( "%02X", dtls_srtp_key_material[j] );
+            }
             mbedtls_printf( "\n" );
         }
     }
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index e66ca40413e2..9cef27523e21 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -3890,7 +3890,17 @@ int main( int argc, char *argv[] )
                     mbedtls_printf( "\n    " );
                 mbedtls_printf( "%02x ", dtls_srtp_key_material[j] );
             }
+            mbedtls_printf( "\n" );
 
+            /* produce a less readable output used to perform automatic checks
+             * - compare client and server output
+             * - interop test with openssl which client produces this kind of output
+             */
+            mbedtls_printf( "    Keying material: " );
+            for( j = 0; j < sizeof( dtls_srtp_key_material ); j++ )
+            {
+                mbedtls_printf( "%02X", dtls_srtp_key_material[j] );
+            }
             mbedtls_printf( "\n" );
         }
     }
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index 1bba6c6468ed..533422579bd4 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -634,6 +634,23 @@ detect_dtls() {
     fi
 }
 
+# Compare file content
+# Usage: find_in_both pattern file1 file2
+# extract from file1 the first line matching the pattern
+# check in file2 that the same line can be found
+find_in_both() {
+        srv_pattern=$(grep -m 1 "$1" "$2");
+        if [ -z "$srv_pattern" ]; then
+                return 1;
+        fi
+
+        if grep "$srv_pattern" $3 >/dev/null; then :
+                       return 0;
+        else
+                return 1;
+        fi
+}
+
 # Usage: run_test name [-p proxy_cmd] srv_cmd cli_cmd cli_exit [option [...]]
 # Options:  -s pattern  pattern that must be present in server output
 #           -c pattern  pattern that must be present in client output
@@ -643,6 +660,7 @@ detect_dtls() {
 #           -C pattern  pattern that must be absent in client output
 #           -U pattern  lines after pattern must be unique in server output
 #           -F call shell function on server output
+#           -g call shell function on server and client output
 run_test() {
     NAME="$1"
     shift 1
@@ -865,6 +883,12 @@ run_test() {
                     return
                 fi
                 ;;
+            "-g")
+                if ! eval "$2 '$SRV_OUT' '$CLI_OUT'"; then
+                    fail "function call to '$2' failed on Server and Client output"
+                    return
+                fi
+                ;;
 
             *)
                 echo "Unknown test: $1" >&2
@@ -8729,8 +8753,10 @@ run_test  "DTLS-SRTP all profiles supported" \
           -c "found srtp profile" \
           -c "selected srtp profile" \
           -c "DTLS-SRTP key material is"\
+          -g "find_in_both '^ *Keying material: [0-9A-F]*$'"\
           -C "error"
 
+
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
 run_test  "DTLS-SRTP server supports all profiles. Client supports one profile." \
           "$P_SRV dtls=1 use_srtp=1 debug_level=3" \
@@ -8746,6 +8772,7 @@ run_test  "DTLS-SRTP server supports all profiles. Client supports one profile."
           -c "found srtp profile: MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80" \
           -c "selected srtp profile" \
           -c "DTLS-SRTP key material is"\
+          -g "find_in_both '^ *Keying material: [0-9A-F]*$'"\
           -C "error"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
@@ -8763,6 +8790,7 @@ run_test  "DTLS-SRTP server supports one profile. Client supports all profiles."
           -c "found srtp profile: MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32" \
           -c "selected srtp profile" \
           -c "DTLS-SRTP key material is"\
+          -g "find_in_both '^ *Keying material: [0-9A-F]*$'"\
           -C "error"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
@@ -8780,6 +8808,7 @@ run_test  "DTLS-SRTP server and Client support only one matching profile." \
           -c "found srtp profile: MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32" \
           -c "selected srtp profile" \
           -c "DTLS-SRTP key material is"\
+          -g "find_in_both '^ *Keying material: [0-9A-F]*$'"\
           -C "error"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
@@ -8832,6 +8861,7 @@ run_test  "DTLS-SRTP all profiles supported. mki used" \
           -c "dumping 'sending mki' (8 bytes)" \
           -c "dumping 'received mki' (8 bytes)" \
           -c "DTLS-SRTP key material is"\
+          -g "find_in_both '^ *Keying material: [0-9A-F]*$'"\
           -C "error"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
@@ -8850,6 +8880,7 @@ run_test  "DTLS-SRTP all profiles supported. server doesn't support mki." \
           -c "found srtp profile" \
           -c "selected srtp profile" \
           -c "DTLS-SRTP key material is"\
+          -g "find_in_both '^ *Keying material: [0-9A-F]*$'"\
           -c "dumping 'sending mki' (8 bytes)" \
           -C "dumping 'received mki' (8 bytes)" \
           -C "error"
@@ -8864,6 +8895,7 @@ run_test  "DTLS-SRTP all profiles supported. openssl client." \
           -s "selected srtp profile" \
           -s "server hello, adding use_srtp extension" \
           -s "DTLS-SRTP key material is"\
+          -g "find_in_both '^ *Keying material: [0-9A-F]*$'"\
           -c "SRTP Extension negotiated, profile=SRTP_AES128_CM_SHA1_80"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
@@ -8876,6 +8908,7 @@ run_test  "DTLS-SRTP server supports all profiles. Client supports all profiles,
           -s "selected srtp profile" \
           -s "server hello, adding use_srtp extension" \
           -s "DTLS-SRTP key material is"\
+          -g "find_in_both '^ *Keying material: [0-9A-F]*$'"\
           -c "SRTP Extension negotiated, profile=SRTP_AES128_CM_SHA1_32"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
@@ -8888,6 +8921,7 @@ run_test  "DTLS-SRTP server supports all profiles. Client supports one profile.
           -s "selected srtp profile" \
           -s "server hello, adding use_srtp extension" \
           -s "DTLS-SRTP key material is"\
+          -g "find_in_both '^ *Keying material: [0-9A-F]*$'"\
           -c "SRTP Extension negotiated, profile=SRTP_AES128_CM_SHA1_32"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
@@ -8900,6 +8934,7 @@ run_test  "DTLS-SRTP server supports one profile. Client supports all profiles.
           -s "selected srtp profile" \
           -s "server hello, adding use_srtp extension" \
           -s "DTLS-SRTP key material is"\
+          -g "find_in_both '^ *Keying material: [0-9A-F]*$'"\
           -c "SRTP Extension negotiated, profile=SRTP_AES128_CM_SHA1_32"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
@@ -8912,6 +8947,7 @@ run_test  "DTLS-SRTP server and Client support only one matching profile. openss
           -s "selected srtp profile" \
           -s "server hello, adding use_srtp extension" \
           -s "DTLS-SRTP key material is"\
+          -g "find_in_both '^ *Keying material: [0-9A-F]*$'"\
           -c "SRTP Extension negotiated, profile=SRTP_AES128_CM_SHA1_32"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP

From 104031547ffd4975ca6eaa6feb27b412b429552a Mon Sep 17 00:00:00 2001
From: Johan Pascal <johan.pascal@belledonne-communications.com>
Date: Fri, 9 Oct 2020 20:43:51 +0200
Subject: [PATCH 54/63] style

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 tests/ssl-opt.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index 533422579bd4..f84c48540efd 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -645,7 +645,7 @@ find_in_both() {
         fi
 
         if grep "$srv_pattern" $3 >/dev/null; then :
-                       return 0;
+                return 0;
         else
                 return 1;
         fi

From 76fdf1d60e93a4acb2653ec91e23180c02e142d3 Mon Sep 17 00:00:00 2001
From: Johan Pascal <johan.pascal@belledonne-communications.com>
Date: Thu, 22 Oct 2020 23:31:00 +0200
Subject: [PATCH 55/63] Minor fix and improvements

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 include/mbedtls/ssl.h      | 51 +++++++++++++++++++++-----------------
 library/ssl_cli.c          | 19 ++++++++------
 library/ssl_srv.c          | 32 +++++++++++++-----------
 library/ssl_tls.c          | 16 ++++++------
 programs/ssl/ssl_client2.c |  6 +++++
 programs/ssl/ssl_server2.c |  6 +++++
 6 files changed, 77 insertions(+), 53 deletions(-)

diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index 840722dede99..84082f3af522 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -414,19 +414,6 @@
 
 #define MBEDTLS_TLS_EXT_RENEGOTIATION_INFO      0xFF01
 
-#if defined(MBEDTLS_SSL_DTLS_SRTP)
-/*
- * Use_srtp extension protection profiles values as defined in
- * http://www.iana.org/assignments/srtp-protection/srtp-protection.xhtml
- */
-#define MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80     0x0001
-#define MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32     0x0002
-#define MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80          0x0005
-#define MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32          0x0006
-/* This one is not iana defined, but for code readability. */
-#define MBEDTLS_TLS_SRTP_UNSET                      0x0000
-#endif /* MBEDTLS_SSL_DTLS_SRTP*/
-
 /*
  * Size defines
  */
@@ -871,18 +858,24 @@ typedef void mbedtls_ssl_async_cancel_t( mbedtls_ssl_context *ssl );
 
 #if defined(MBEDTLS_SSL_DTLS_SRTP)
 
-#define MBEDTLS_TLS_SRTP_MAX_KEY_MATERIAL_LENGTH    60
 #define MBEDTLS_TLS_SRTP_MAX_MKI_LENGTH             255
 #define MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH    4
 /*
  * For code readability use a typedef for DTLS-SRTP profiles
- * The supported profiles are defines as macro above:
- * MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80
- * MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32
- * MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80
- * MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32
- * MBEDTLS_TLS_SRTP_UNSET
+ *
+ * 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;
 
 typedef struct mbedtls_dtls_srtp_info_t
@@ -2096,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
@@ -3249,6 +3244,11 @@ int mbedtls_ssl_conf_dtls_srtp_protection_profiles
  * \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
@@ -3258,12 +3258,17 @@ int mbedtls_ssl_dtls_srtp_set_mki_value( mbedtls_ssl_context *ssl,
                                          uint16_t mki_len );
 /**
  * \brief          Get the negotiated DTLS-SRTP Protection Profile.
- *                 This function should be called after the handshake is
- *                 completed.
+ *
+ * \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.
  *
- * \return         The DTLS SRTP protection profile in use.
+ * \return         The DTLS SRTP protection profile in use. The return type is
+ *                 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
  * \return         #MBEDTLS_TLS_SRTP_UNSET if the use of SRTP was not negotiated
  *                 or peer's Hello packet was not parsed yet.
  */
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index c864cb2c6a0e..234098a7fb19 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -837,13 +837,14 @@ static int ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
         {
             /*
              * Note: we shall never arrive here as protection profiles
-             * is checked by ssl_set_dtls_srtp_protection_profiles function
+             * is checked by mbedtls_ssl_conf_dtls_srtp_protection_profiles function
              */
             MBEDTLS_SSL_DEBUG_MSG( 3,
                     ( "client hello, "
-                      "ignore illegal DTLS-SRTP protection profile %d",
+                      "illegal DTLS-SRTP protection profile %d",
                       ssl->conf->dtls_srtp_profile_list[protection_profiles_index]
                     ) );
+            return( MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED );
         }
     }
 
@@ -1872,11 +1873,12 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
     }
 
     /*
-     * Length is 5 and optional mki_value : one protection profile(2 bytes)
-     *                                      + length(2 bytes) + mki_len(1 byte)
+     * Length is 5 + optional mki_value : one protection profile length (2 bytes)
+     *                                      + protection profile (2 bytes)
+     *                                      + mki_len(1 byte)
      *                                      and optional srtp_mki
      */
-    if( ( len != 5 ) && ( len != ( 5 + mki_len ) ) )
+    if( len != ( buf[4] + 5u ) )
         return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
 
     /*
@@ -2509,8 +2511,11 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
         case MBEDTLS_TLS_EXT_ALPN:
             MBEDTLS_SSL_DEBUG_MSG( 3, ( "found alpn extension" ) );
 
-            if( ( ret = ssl_parse_alpn_ext( ssl, ext + 4, ext_size ) ) != 0 )
-                return( ret );
+            if ( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+            {
+                if( ( ret = ssl_parse_alpn_ext( ssl, ext + 4, ext_size ) ) != 0 )
+                    return( ret );
+            }
 
             break;
 #endif /* MBEDTLS_SSL_ALPN */
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index 5c56a70d914b..007d9e41af21 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -810,8 +810,9 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
      * Min length is 5: at least one protection profile(2 bytes)
      *                  and length(2 bytes) + srtp_mki length(1 byte)
      * Check here that we have at least 2 bytes of protection profiles length
+     * and one of srtp_mki length
      */
-    if( len < 2 )
+    if( len < size_of_lengths )
     {
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
@@ -824,8 +825,8 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
     profile_length = ( buf[0] << 8 ) | buf[1];
     buf += 2;
 
-    /* check the buffer size: at least profiles + profile and mki length */
-    if( profile_length + size_of_lengths > len ||
+    /* The profile length cannot be bigger than input buffer size - lengths fields */
+    if( profile_length > len - size_of_lengths ||
         profile_length % 2 != 0 ) /* profiles are 2 bytes long, so the length must be even */
     {
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
@@ -836,9 +837,9 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
      * parse the extension list values are defined in
      * http://www.iana.org/assignments/srtp-protection/srtp-protection.xhtml
      */
-    for( j=0; j < profile_length; j += 2 )
+    for( j = 0; j < profile_length; j += 2 )
     {
-        uint16_t protection_profile_value = buf[j] << 8 | buf[j+1];
+        uint16_t protection_profile_value = buf[j] << 8 | buf[j + 1];
         client_protection = mbedtls_ssl_check_srtp_profile_value( protection_profile_value );
 
         if( client_protection != MBEDTLS_TLS_SRTP_UNSET )
@@ -884,10 +885,7 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
     {
         ssl->dtls_srtp_info.mki_len = mki_length;
 
-        for( i=0; i < mki_length; i++ )
-        {
-            ssl->dtls_srtp_info.mki_value[i] = buf[i];
-        }
+        memcpy(ssl->dtls_srtp_info.mki_value, buf, mki_length);
 
         MBEDTLS_SSL_DEBUG_BUF( 3, "using mki",  ssl->dtls_srtp_info.mki_value,
                                                 ssl->dtls_srtp_info.mki_len );
@@ -2067,9 +2065,12 @@ static int ssl_parse_client_hello( mbedtls_ssl_context *ssl )
             case MBEDTLS_TLS_EXT_USE_SRTP:
                 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found use_srtp extension" ) );
 
-                ret = ssl_parse_use_srtp_ext( ssl, ext + 4, ext_size );
-                if ( ret != 0 )
-                    return( ret );
+                if ( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+                {
+                    ret = ssl_parse_use_srtp_ext( ssl, ext + 4, ext_size );
+                    if ( ret != 0 )
+                        return( ret );
+                }
                 break;
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
 
@@ -2991,8 +2992,11 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl )
 #endif
 
 #if defined(MBEDTLS_SSL_DTLS_SRTP)
-    ssl_write_use_srtp_ext( ssl, p + 2 + ext_len, &olen );
-    ext_len += olen;
+    if ( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    {
+        ssl_write_use_srtp_ext( ssl, p + 2 + ext_len, &olen );
+        ext_len += olen;
+    }
 #endif
 
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, total extension length: %d", ext_len ) );
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 58fcab3dd5cb..a9e5523f68ef 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -4727,16 +4727,14 @@ int mbedtls_ssl_conf_dtls_srtp_protection_profiles( mbedtls_ssl_config *conf,
                        list_size <= MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH;
          p++ )
     {
-        switch( *p )
+        if ( mbedtls_ssl_check_srtp_profile_value( *p ) != MBEDTLS_TLS_SRTP_UNSET )
         {
-            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:
-                list_size++;
-                break;
-            default: /* unsupported value, stop parsing and set the size to an error value */
-                list_size = MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH + 1;
+            list_size++;
+        }
+        else
+        {
+            /* unsupported value, stop parsing and set the size to an error value */
+            list_size = MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH + 1;
         }
     }
 
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index 759603a8faa4..c70346a74358 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -680,6 +680,12 @@ static int nss_keylog_export( void *p_expkey,
 }
 
 #if defined( MBEDTLS_SSL_DTLS_SRTP )
+/* Supported SRTP mode needs a maximum of :
+ * - 16 bytes for key (AES-128)
+ * - 14 bytes SALT
+ * One for sender, one for receiver context
+ */
+#define MBEDTLS_TLS_SRTP_MAX_KEY_MATERIAL_LENGTH    60
 typedef struct dtls_srtp_keys
 {
     unsigned char master_secret[48];
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index 9cef27523e21..97929cd65e3a 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -782,6 +782,12 @@ static int nss_keylog_export( void *p_expkey,
 }
 
 #if defined( MBEDTLS_SSL_DTLS_SRTP )
+/* Supported SRTP mode needs a maximum of :
+ * - 16 bytes for key (AES-128)
+ * - 14 bytes SALT
+ * One for sender, one for receiver context
+ */
+#define MBEDTLS_TLS_SRTP_MAX_KEY_MATERIAL_LENGTH    60
 typedef struct dtls_srtp_keys
 {
     unsigned char master_secret[48];

From adbd9449ecad5ff011a3eb57cd2548900d421603 Mon Sep 17 00:00:00 2001
From: Johan Pascal <johan.pascal@belledonne-communications.com>
Date: Mon, 26 Oct 2020 21:24:25 +0100
Subject: [PATCH 56/63] More minor fix

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 library/ssl_cli.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index 234098a7fb19..ddbe5ca67deb 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -1878,7 +1878,7 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
      *                                      + mki_len(1 byte)
      *                                      and optional srtp_mki
      */
-    if( len != ( buf[4] + 5u ) )
+    if( ( len < 5 ) || ( len != ( buf[4] + 5u ) ) )
         return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
 
     /*
@@ -2524,8 +2524,11 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
         case MBEDTLS_TLS_EXT_USE_SRTP:
             MBEDTLS_SSL_DEBUG_MSG( 3, ( "found use_srtp extension" ) );
 
-            if( ( ret = ssl_parse_use_srtp_ext( ssl, ext + 4, ext_size ) ) != 0 )
-                return( ret );
+            if ( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+            {
+                if( ( ret = ssl_parse_use_srtp_ext( ssl, ext + 4, ext_size ) ) != 0 )
+                    return( ret );
+            }
 
             break;
 #endif /* MBEDTLS_SSL_DTLS_SRTP */

From 20c7db3a678b840be578cd3e1a7044d20a23158d Mon Sep 17 00:00:00 2001
From: Johan Pascal <johan.pascal@belledonne-communications.com>
Date: Mon, 26 Oct 2020 22:45:58 +0100
Subject: [PATCH 57/63] API modified so server side can get mki value + client
 side discards self mki if server does not support it

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 include/mbedtls/ssl.h      | 17 ++++++++++++-----
 library/ssl_cli.c          |  8 ++++++++
 library/ssl_tls.c          |  6 +++---
 programs/ssl/ssl_client2.c | 18 +++++++++++++++++-
 programs/ssl/ssl_server2.c | 19 ++++++++++++++++++-
 tests/ssl-opt.sh           |  5 +++++
 6 files changed, 63 insertions(+), 10 deletions(-)

diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index 84082f3af522..398eb012a359 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -3257,7 +3257,8 @@ 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 Protection Profile.
+ * \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
@@ -3265,14 +3266,20 @@ int mbedtls_ssl_dtls_srtp_set_mki_value( mbedtls_ssl_context *ssl,
  *
  * \param ssl      The SSL context to query.
  *
- * \return         The DTLS SRTP protection profile in use. The return type is
- *                 a direct mapping of the iana defined value for protection
+ * \return         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
- * \return         #MBEDTLS_TLS_SRTP_UNSET if the use of SRTP was not negotiated
+ *                 #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). These informations are valid only
+ *                 if the protection profile returned is not MBEDTLS_TLS_SRTP_UNSET.
+ *                 Ownership of the returned structure is kept by the ssl context,
+ *                 the caller must duplicate any information that must live longer than
+ *                 the context (typically MKI size and value if any)
  */
-mbedtls_ssl_srtp_profile mbedtls_ssl_get_dtls_srtp_protection_profile
+const mbedtls_dtls_srtp_info *mbedtls_ssl_get_dtls_srtp_negotiation_result
                                              ( const mbedtls_ssl_context *ssl );
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
 
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index ddbe5ca67deb..56a71c696c9f 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -1925,6 +1925,14 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
                                         MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
         return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
     }
+
+    /* If server does not use mki in its reply, make sure the client won't keep
+     * one as negotiated */
+    if( len == 5 )
+    {
+        ssl->dtls_srtp_info.mki_len = 0;
+    }
+
     /*
      * RFC5764:
      *  If the client detects a nonzero-length MKI in the server's response
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index a9e5523f68ef..cee8ba132894 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -4751,10 +4751,10 @@ int mbedtls_ssl_conf_dtls_srtp_protection_profiles( mbedtls_ssl_config *conf,
     return( 0 );
 }
 
-mbedtls_ssl_srtp_profile
-     mbedtls_ssl_get_dtls_srtp_protection_profile( const mbedtls_ssl_context *ssl )
+const mbedtls_dtls_srtp_info *
+     mbedtls_ssl_get_dtls_srtp_negotiation_result( const mbedtls_ssl_context *ssl )
 {
-    return( ssl->dtls_srtp_info.chosen_dtls_srtp_profile );
+    return( &( ssl->dtls_srtp_info ) );
 }
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
 
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index c70346a74358..d53a40af8f0d 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -2754,8 +2754,10 @@ int main( int argc, char *argv[] )
     else if( opt.use_srtp != 0  )
     {
         size_t j = 0;
+        const mbedtls_dtls_srtp_info *dtls_srtp_negotiation_result =
+                        mbedtls_ssl_get_dtls_srtp_negotiation_result( &ssl );
 
-        if( ( mbedtls_ssl_get_dtls_srtp_protection_profile( &ssl )
+        if( ( dtls_srtp_negotiation_result->chosen_dtls_srtp_profile
                                 == MBEDTLS_TLS_SRTP_UNSET ) )
         {
             mbedtls_printf( "    Unable to negotiate "
@@ -2797,6 +2799,20 @@ int main( int argc, char *argv[] )
                 mbedtls_printf( "%02X", dtls_srtp_key_material[j] );
             }
             mbedtls_printf( "\n" );
+
+            if ( dtls_srtp_negotiation_result->mki_len > 0 )
+            {
+                mbedtls_printf( "    DTLS-SRTP mki value: " );
+                for( j = 0; j < dtls_srtp_negotiation_result->mki_len; j++ )
+                {
+                    mbedtls_printf( "%02X", dtls_srtp_negotiation_result->mki_value[j] );
+                }
+            }
+            else
+            {
+                mbedtls_printf( "    DTLS-SRTP no mki value negociated" );
+            }
+            mbedtls_printf( "\n" );
         }
     }
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index 97929cd65e3a..126a64c0d27b 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -3865,8 +3865,10 @@ int main( int argc, char *argv[] )
     else if( opt.use_srtp != 0  )
     {
         size_t j = 0;
+        const mbedtls_dtls_srtp_info *dtls_srtp_negotiation_result =
+                        mbedtls_ssl_get_dtls_srtp_negotiation_result( &ssl );
 
-        if( ( mbedtls_ssl_get_dtls_srtp_protection_profile( &ssl )
+        if( ( dtls_srtp_negotiation_result->chosen_dtls_srtp_profile
                                 == MBEDTLS_TLS_SRTP_UNSET ) )
         {
             mbedtls_printf( "    Unable to negotiate "
@@ -3908,6 +3910,21 @@ int main( int argc, char *argv[] )
                 mbedtls_printf( "%02X", dtls_srtp_key_material[j] );
             }
             mbedtls_printf( "\n" );
+
+            if ( dtls_srtp_negotiation_result->mki_len > 0 )
+            {
+                mbedtls_printf( "    DTLS-SRTP mki value: " );
+                for( j = 0; j < dtls_srtp_negotiation_result->mki_len; j++ )
+                {
+                    mbedtls_printf( "%02X", dtls_srtp_negotiation_result->mki_value[j] );
+                }
+            }
+            else
+            {
+                mbedtls_printf( "    DTLS-SRTP no mki value negociated" );
+            }
+            mbedtls_printf( "\n" );
+
         }
     }
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index f84c48540efd..210108df394b 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -8862,6 +8862,7 @@ run_test  "DTLS-SRTP all profiles supported. mki used" \
           -c "dumping 'received mki' (8 bytes)" \
           -c "DTLS-SRTP key material is"\
           -g "find_in_both '^ *Keying material: [0-9A-F]*$'"\
+          -g "find_in_both '^ *DTLS-SRTP mki value: [0-9A-F]*$'"\
           -C "error"
 
 requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
@@ -8874,12 +8875,14 @@ run_test  "DTLS-SRTP all profiles supported. server doesn't support mki." \
           -s "selected srtp profile" \
           -s "server hello, adding use_srtp extension" \
           -s "DTLS-SRTP key material is"\
+          -s "DTLS-SRTP no mki value negociated"\
           -S "dumping 'using mki' (8 bytes)" \
           -c "client hello, adding use_srtp extension" \
           -c "found use_srtp extension" \
           -c "found srtp profile" \
           -c "selected srtp profile" \
           -c "DTLS-SRTP key material is"\
+          -c "DTLS-SRTP no mki value negociated"\
           -g "find_in_both '^ *Keying material: [0-9A-F]*$'"\
           -c "dumping 'sending mki' (8 bytes)" \
           -C "dumping 'received mki' (8 bytes)" \
@@ -9066,6 +9069,7 @@ run_test  "DTLS-SRTP all profiles supported. server doesn't support mki. openssl
           -c "found srtp profile" \
           -c "selected srtp profile" \
           -c "DTLS-SRTP key material is"\
+          -c "DTLS-SRTP no mki value negociated"\
           -c "dumping 'sending mki' (8 bytes)" \
           -C "dumping 'received mki' (8 bytes)" \
           -C "error"
@@ -9261,6 +9265,7 @@ run_test  "DTLS-SRTP all profiles supported. mki used. gnutls server." \
           -c "found srtp profile" \
           -c "selected srtp profile" \
           -c "DTLS-SRTP key material is"\
+          -c "DTLS-SRTP mki value:"\
           -c "dumping 'sending mki' (8 bytes)" \
           -c "dumping 'received mki' (8 bytes)" \
           -C "error"

From 275874bc47a50771e7f92a4f5da28fcb3b4fbb1c Mon Sep 17 00:00:00 2001
From: Johan Pascal <johan.pascal@belledonne-communications.com>
Date: Tue, 27 Oct 2020 10:43:53 +0100
Subject: [PATCH 58/63] Fix previous commit

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 library/ssl_cli.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index 56a71c696c9f..a3e027e1d1d2 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -2519,11 +2519,8 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
         case MBEDTLS_TLS_EXT_ALPN:
             MBEDTLS_SSL_DEBUG_MSG( 3, ( "found alpn extension" ) );
 
-            if ( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
-            {
-                if( ( ret = ssl_parse_alpn_ext( ssl, ext + 4, ext_size ) ) != 0 )
-                    return( ret );
-            }
+            if( ( ret = ssl_parse_alpn_ext( ssl, ext + 4, ext_size ) ) != 0 )
+                return( ret );
 
             break;
 #endif /* MBEDTLS_SSL_ALPN */

From 0dbcd1d3f094c5ffd491b479b15efe3dbe08496d Mon Sep 17 00:00:00 2001
From: Johan Pascal <johan.pascal@belledonne-communications.com>
Date: Wed, 28 Oct 2020 11:03:07 +0100
Subject: [PATCH 59/63] Make API safer

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 include/mbedtls/ssl.h      |  5 +----
 library/ssl_tls.c          | 10 ++++++++--
 programs/ssl/ssl_client2.c | 10 +++++-----
 programs/ssl/ssl_server2.c | 10 +++++-----
 4 files changed, 19 insertions(+), 16 deletions(-)

diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index 398eb012a359..4805c67b3da8 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -3275,11 +3275,8 @@ int mbedtls_ssl_dtls_srtp_set_mki_value( mbedtls_ssl_context *ssl,
  *                 or peer's Hello packet was not parsed yet.
  *                 - mki size and value (if size is > 0). These informations are valid only
  *                 if the protection profile returned is not MBEDTLS_TLS_SRTP_UNSET.
- *                 Ownership of the returned structure is kept by the ssl context,
- *                 the caller must duplicate any information that must live longer than
- *                 the context (typically MKI size and value if any)
  */
-const mbedtls_dtls_srtp_info *mbedtls_ssl_get_dtls_srtp_negotiation_result
+mbedtls_dtls_srtp_info mbedtls_ssl_get_dtls_srtp_negotiation_result
                                              ( const mbedtls_ssl_context *ssl );
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
 
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index cee8ba132894..0739b8f05a8d 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -4751,10 +4751,16 @@ int mbedtls_ssl_conf_dtls_srtp_protection_profiles( mbedtls_ssl_config *conf,
     return( 0 );
 }
 
-const mbedtls_dtls_srtp_info *
+mbedtls_dtls_srtp_info
      mbedtls_ssl_get_dtls_srtp_negotiation_result( const mbedtls_ssl_context *ssl )
 {
-    return( &( ssl->dtls_srtp_info ) );
+    mbedtls_dtls_srtp_info ret = ssl->dtls_srtp_info;
+    /* discard the mki if there is no chosen profile */
+    if ( ret.chosen_dtls_srtp_profile == MBEDTLS_TLS_SRTP_UNSET )
+    {
+        ret.mki_len = 0;
+    }
+    return( ret );
 }
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
 
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index d53a40af8f0d..2a605078901d 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -2754,10 +2754,10 @@ int main( int argc, char *argv[] )
     else if( opt.use_srtp != 0  )
     {
         size_t j = 0;
-        const mbedtls_dtls_srtp_info *dtls_srtp_negotiation_result =
+        mbedtls_dtls_srtp_info dtls_srtp_negotiation_result =
                         mbedtls_ssl_get_dtls_srtp_negotiation_result( &ssl );
 
-        if( ( dtls_srtp_negotiation_result->chosen_dtls_srtp_profile
+        if( ( dtls_srtp_negotiation_result.chosen_dtls_srtp_profile
                                 == MBEDTLS_TLS_SRTP_UNSET ) )
         {
             mbedtls_printf( "    Unable to negotiate "
@@ -2800,12 +2800,12 @@ int main( int argc, char *argv[] )
             }
             mbedtls_printf( "\n" );
 
-            if ( dtls_srtp_negotiation_result->mki_len > 0 )
+            if ( dtls_srtp_negotiation_result.mki_len > 0 )
             {
                 mbedtls_printf( "    DTLS-SRTP mki value: " );
-                for( j = 0; j < dtls_srtp_negotiation_result->mki_len; j++ )
+                for( j = 0; j < dtls_srtp_negotiation_result.mki_len; j++ )
                 {
-                    mbedtls_printf( "%02X", dtls_srtp_negotiation_result->mki_value[j] );
+                    mbedtls_printf( "%02X", dtls_srtp_negotiation_result.mki_value[j] );
                 }
             }
             else
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index 126a64c0d27b..81721bbcadef 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -3865,10 +3865,10 @@ int main( int argc, char *argv[] )
     else if( opt.use_srtp != 0  )
     {
         size_t j = 0;
-        const mbedtls_dtls_srtp_info *dtls_srtp_negotiation_result =
+        mbedtls_dtls_srtp_info dtls_srtp_negotiation_result =
                         mbedtls_ssl_get_dtls_srtp_negotiation_result( &ssl );
 
-        if( ( dtls_srtp_negotiation_result->chosen_dtls_srtp_profile
+        if( ( dtls_srtp_negotiation_result.chosen_dtls_srtp_profile
                                 == MBEDTLS_TLS_SRTP_UNSET ) )
         {
             mbedtls_printf( "    Unable to negotiate "
@@ -3911,12 +3911,12 @@ int main( int argc, char *argv[] )
             }
             mbedtls_printf( "\n" );
 
-            if ( dtls_srtp_negotiation_result->mki_len > 0 )
+            if ( dtls_srtp_negotiation_result.mki_len > 0 )
             {
                 mbedtls_printf( "    DTLS-SRTP mki value: " );
-                for( j = 0; j < dtls_srtp_negotiation_result->mki_len; j++ )
+                for( j = 0; j < dtls_srtp_negotiation_result.mki_len; j++ )
                 {
-                    mbedtls_printf( "%02X", dtls_srtp_negotiation_result->mki_value[j] );
+                    mbedtls_printf( "%02X", dtls_srtp_negotiation_result.mki_value[j] );
                 }
             }
             else

From 2258a4f481ede36323b3ced8d76b869fb4921c75 Mon Sep 17 00:00:00 2001
From: Johan Pascal <johan.pascal@belledonne-communications.com>
Date: Wed, 28 Oct 2020 13:53:09 +0100
Subject: [PATCH 60/63] Do not return a structure, use a return parameter

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 include/mbedtls/ssl.h      | 40 ++++++++++++++++++--------------------
 library/ssl_tls.c          | 17 +++++++++-------
 programs/ssl/ssl_client2.c |  4 ++--
 programs/ssl/ssl_server2.c |  4 ++--
 4 files changed, 33 insertions(+), 32 deletions(-)

diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index 4805c67b3da8..1b4e163f614a 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -3257,27 +3257,25 @@ 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.
- *
- * \return         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). These informations are valid only
- *                 if the protection profile returned is not MBEDTLS_TLS_SRTP_UNSET.
- */
-mbedtls_dtls_srtp_info mbedtls_ssl_get_dtls_srtp_negotiation_result
-                                             ( const mbedtls_ssl_context *ssl );
+ * \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 */
 
 /**
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 0739b8f05a8d..8dec7f10a750 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -4751,16 +4751,19 @@ int mbedtls_ssl_conf_dtls_srtp_protection_profiles( mbedtls_ssl_config *conf,
     return( 0 );
 }
 
-mbedtls_dtls_srtp_info
-     mbedtls_ssl_get_dtls_srtp_negotiation_result( const mbedtls_ssl_context *ssl )
+void mbedtls_ssl_get_dtls_srtp_negotiation_result( const mbedtls_ssl_context *ssl, mbedtls_dtls_srtp_info *dtls_srtp_info )
 {
-    mbedtls_dtls_srtp_info ret = ssl->dtls_srtp_info;
-    /* discard the mki if there is no chosen profile */
-    if ( ret.chosen_dtls_srtp_profile == MBEDTLS_TLS_SRTP_UNSET )
+    dtls_srtp_info->chosen_dtls_srtp_profile = ssl->dtls_srtp_info.chosen_dtls_srtp_profile;
+    /* do not copy the mki value if there is no chosen profile */
+    if ( dtls_srtp_info->chosen_dtls_srtp_profile == MBEDTLS_TLS_SRTP_UNSET )
     {
-        ret.mki_len = 0;
+        dtls_srtp_info->mki_len = 0;
+    }
+    else
+    {
+        dtls_srtp_info->mki_len = ssl->dtls_srtp_info.mki_len;
+        memcpy( dtls_srtp_info->mki_value, ssl->dtls_srtp_info.mki_value, ssl->dtls_srtp_info.mki_len );
     }
-    return( ret );
 }
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
 
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index 2a605078901d..e78c087ffda0 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -2754,8 +2754,8 @@ int main( int argc, char *argv[] )
     else if( opt.use_srtp != 0  )
     {
         size_t j = 0;
-        mbedtls_dtls_srtp_info dtls_srtp_negotiation_result =
-                        mbedtls_ssl_get_dtls_srtp_negotiation_result( &ssl );
+        mbedtls_dtls_srtp_info dtls_srtp_negotiation_result;
+        mbedtls_ssl_get_dtls_srtp_negotiation_result( &ssl, &dtls_srtp_negotiation_result );
 
         if( ( dtls_srtp_negotiation_result.chosen_dtls_srtp_profile
                                 == MBEDTLS_TLS_SRTP_UNSET ) )
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index 81721bbcadef..7383d8885825 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -3865,8 +3865,8 @@ int main( int argc, char *argv[] )
     else if( opt.use_srtp != 0  )
     {
         size_t j = 0;
-        mbedtls_dtls_srtp_info dtls_srtp_negotiation_result =
-                        mbedtls_ssl_get_dtls_srtp_negotiation_result( &ssl );
+        mbedtls_dtls_srtp_info dtls_srtp_negotiation_result;
+        mbedtls_ssl_get_dtls_srtp_negotiation_result( &ssl, &dtls_srtp_negotiation_result );
 
         if( ( dtls_srtp_negotiation_result.chosen_dtls_srtp_profile
                                 == MBEDTLS_TLS_SRTP_UNSET ) )

From 5ef72d214f0b2525a0f89ae390267e583f2f42ba Mon Sep 17 00:00:00 2001
From: Johan Pascal <johan.pascal@belledonne-communications.com>
Date: Wed, 28 Oct 2020 17:05:47 +0100
Subject: [PATCH 61/63] Style and typos

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 library/ssl_cli.c          |  3 ++-
 library/ssl_srv.c          |  8 ++++----
 library/ssl_tls.c          | 14 ++++++++------
 programs/ssl/ssl_client2.c |  5 +++--
 programs/ssl/ssl_server2.c |  2 +-
 tests/ssl-opt.sh           |  6 +++---
 6 files changed, 21 insertions(+), 17 deletions(-)

diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index a3e027e1d1d2..223f582c492e 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -1909,7 +1909,8 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
      */
     for( i=0; i < ssl->conf->dtls_srtp_profile_list_len; i++)
     {
-        if( server_protection == ssl->conf->dtls_srtp_profile_list[i] ) {
+        if( server_protection == ssl->conf->dtls_srtp_profile_list[i] )
+        {
             ssl->dtls_srtp_info.chosen_dtls_srtp_profile = ssl->conf->dtls_srtp_profile_list[i];
             MBEDTLS_SSL_DEBUG_MSG( 3, ( "selected srtp profile: %s",
                                       mbedtls_ssl_get_srtp_profile_as_string(
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index 007d9e41af21..60de57b1cf09 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -885,7 +885,7 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
     {
         ssl->dtls_srtp_info.mki_len = mki_length;
 
-        memcpy(ssl->dtls_srtp_info.mki_value, buf, mki_length);
+        memcpy( ssl->dtls_srtp_info.mki_value, buf, mki_length );
 
         MBEDTLS_SSL_DEBUG_BUF( 3, "using mki",  ssl->dtls_srtp_info.mki_value,
                                                 ssl->dtls_srtp_info.mki_len );
@@ -2065,10 +2065,10 @@ static int ssl_parse_client_hello( mbedtls_ssl_context *ssl )
             case MBEDTLS_TLS_EXT_USE_SRTP:
                 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found use_srtp extension" ) );
 
-                if ( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+                if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
                 {
                     ret = ssl_parse_use_srtp_ext( ssl, ext + 4, ext_size );
-                    if ( ret != 0 )
+                    if( ret != 0 )
                         return( ret );
                 }
                 break;
@@ -2992,7 +2992,7 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl )
 #endif
 
 #if defined(MBEDTLS_SSL_DTLS_SRTP)
-    if ( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
     {
         ssl_write_use_srtp_ext( ssl, p + 2 + ext_len, &olen );
         ext_len += olen;
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 8dec7f10a750..7cb5b8ccf748 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -4700,7 +4700,7 @@ int mbedtls_ssl_dtls_srtp_set_mki_value( mbedtls_ssl_context *ssl,
                                          unsigned char *mki_value,
                                          uint16_t mki_len )
 {
-    if ( mki_len > MBEDTLS_TLS_SRTP_MAX_MKI_LENGTH )
+    if( mki_len > MBEDTLS_TLS_SRTP_MAX_MKI_LENGTH )
     {
         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
     }
@@ -4727,7 +4727,7 @@ int mbedtls_ssl_conf_dtls_srtp_protection_profiles( mbedtls_ssl_config *conf,
                        list_size <= MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH;
          p++ )
     {
-        if ( mbedtls_ssl_check_srtp_profile_value( *p ) != MBEDTLS_TLS_SRTP_UNSET )
+        if( mbedtls_ssl_check_srtp_profile_value( *p ) != MBEDTLS_TLS_SRTP_UNSET )
         {
             list_size++;
         }
@@ -4738,7 +4738,7 @@ int mbedtls_ssl_conf_dtls_srtp_protection_profiles( mbedtls_ssl_config *conf,
         }
     }
 
-    if ( list_size > MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH )
+    if( list_size > MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH )
     {
                 conf->dtls_srtp_profile_list = NULL;
                 conf->dtls_srtp_profile_list_len = 0;
@@ -4751,18 +4751,20 @@ int mbedtls_ssl_conf_dtls_srtp_protection_profiles( mbedtls_ssl_config *conf,
     return( 0 );
 }
 
-void mbedtls_ssl_get_dtls_srtp_negotiation_result( const mbedtls_ssl_context *ssl, mbedtls_dtls_srtp_info *dtls_srtp_info )
+void mbedtls_ssl_get_dtls_srtp_negotiation_result( const mbedtls_ssl_context *ssl,
+                                                   mbedtls_dtls_srtp_info *dtls_srtp_info )
 {
     dtls_srtp_info->chosen_dtls_srtp_profile = ssl->dtls_srtp_info.chosen_dtls_srtp_profile;
     /* do not copy the mki value if there is no chosen profile */
-    if ( dtls_srtp_info->chosen_dtls_srtp_profile == MBEDTLS_TLS_SRTP_UNSET )
+    if( dtls_srtp_info->chosen_dtls_srtp_profile == MBEDTLS_TLS_SRTP_UNSET )
     {
         dtls_srtp_info->mki_len = 0;
     }
     else
     {
         dtls_srtp_info->mki_len = ssl->dtls_srtp_info.mki_len;
-        memcpy( dtls_srtp_info->mki_value, ssl->dtls_srtp_info.mki_value, ssl->dtls_srtp_info.mki_len );
+        memcpy( dtls_srtp_info->mki_value, ssl->dtls_srtp_info.mki_value,
+                ssl->dtls_srtp_info.mki_len );
     }
 }
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index e78c087ffda0..dd274700c527 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -2341,7 +2341,8 @@ int main( int argc, char *argv[] )
     {
         if( opt.force_srtp_profile != 0 )
         {
-            const mbedtls_ssl_srtp_profile forced_profile[] = { opt.force_srtp_profile, MBEDTLS_TLS_SRTP_UNSET };
+            const mbedtls_ssl_srtp_profile forced_profile[] =
+                                        { opt.force_srtp_profile, MBEDTLS_TLS_SRTP_UNSET };
             ret = mbedtls_ssl_conf_dtls_srtp_protection_profiles ( &conf, forced_profile );
         }
         else
@@ -2810,7 +2811,7 @@ int main( int argc, char *argv[] )
             }
             else
             {
-                mbedtls_printf( "    DTLS-SRTP no mki value negociated" );
+                mbedtls_printf( "    DTLS-SRTP no mki value negotiated" );
             }
             mbedtls_printf( "\n" );
         }
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index 7383d8885825..dcb215d4e2c8 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -3921,7 +3921,7 @@ int main( int argc, char *argv[] )
             }
             else
             {
-                mbedtls_printf( "    DTLS-SRTP no mki value negociated" );
+                mbedtls_printf( "    DTLS-SRTP no mki value negotiated" );
             }
             mbedtls_printf( "\n" );
 
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index 210108df394b..59e79744f3e4 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -8875,14 +8875,14 @@ run_test  "DTLS-SRTP all profiles supported. server doesn't support mki." \
           -s "selected srtp profile" \
           -s "server hello, adding use_srtp extension" \
           -s "DTLS-SRTP key material is"\
-          -s "DTLS-SRTP no mki value negociated"\
+          -s "DTLS-SRTP no mki value negotiated"\
           -S "dumping 'using mki' (8 bytes)" \
           -c "client hello, adding use_srtp extension" \
           -c "found use_srtp extension" \
           -c "found srtp profile" \
           -c "selected srtp profile" \
           -c "DTLS-SRTP key material is"\
-          -c "DTLS-SRTP no mki value negociated"\
+          -c "DTLS-SRTP no mki value negotiated"\
           -g "find_in_both '^ *Keying material: [0-9A-F]*$'"\
           -c "dumping 'sending mki' (8 bytes)" \
           -C "dumping 'received mki' (8 bytes)" \
@@ -9069,7 +9069,7 @@ run_test  "DTLS-SRTP all profiles supported. server doesn't support mki. openssl
           -c "found srtp profile" \
           -c "selected srtp profile" \
           -c "DTLS-SRTP key material is"\
-          -c "DTLS-SRTP no mki value negociated"\
+          -c "DTLS-SRTP no mki value negotiated"\
           -c "dumping 'sending mki' (8 bytes)" \
           -C "dumping 'received mki' (8 bytes)" \
           -C "error"

From c3ccd98a916a10d3b400df5e189a9ef895d342ba Mon Sep 17 00:00:00 2001
From: Johan Pascal <johan.pascal@belledonne-communications.com>
Date: Wed, 28 Oct 2020 17:18:18 +0100
Subject: [PATCH 62/63] Check transport in the extension parser/writer

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 library/ssl_cli.c | 30 +++++++++++++-----------------
 library/ssl_srv.c | 24 ++++++++++--------------
 2 files changed, 23 insertions(+), 31 deletions(-)

diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index 223f582c492e..76be8ab07b18 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -768,8 +768,9 @@ static int ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
 
     *olen = 0;
 
-    if( ( ssl->conf->dtls_srtp_profile_list == NULL ) ||
-        ( ssl->conf->dtls_srtp_profile_list_len == 0  ) )
+    if( ( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ) ||
+        ( ssl->conf->dtls_srtp_profile_list == NULL ) ||
+        ( ssl->conf->dtls_srtp_profile_list_len == 0 ) )
     {
         return( 0 );
     }
@@ -1397,16 +1398,13 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
 #endif
 
 #if defined(MBEDTLS_SSL_DTLS_SRTP)
-    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    if( ( ret = ssl_write_use_srtp_ext( ssl, p + 2 + ext_len,
+                                        end, &olen ) ) != 0 )
     {
-        if( ( ret = ssl_write_use_srtp_ext( ssl, p + 2 + ext_len,
-                                            end, &olen ) ) != 0 )
-        {
-            MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_use_srtp_ext", ret );
-            return( ret );
-        }
-        ext_len += olen;
+        MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_use_srtp_ext", ret );
+        return( ret );
     }
+    ext_len += olen;
 #endif
 
 #if defined(MBEDTLS_SSL_SESSION_TICKETS)
@@ -1852,8 +1850,9 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
     uint16_t server_protection_profile_value = 0;
 
     /* If use_srtp is not configured, just ignore the extension */
-    if( ssl->conf->dtls_srtp_profile_list == NULL ||
-        ssl->conf->dtls_srtp_profile_list_len == 0  )
+    if( ( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ) ||
+        ( ssl->conf->dtls_srtp_profile_list == NULL ) ||
+        ( ssl->conf->dtls_srtp_profile_list_len == 0 ) )
         return( 0 );
 
     /* RFC 5764 section 4.1.1
@@ -2530,11 +2529,8 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
         case MBEDTLS_TLS_EXT_USE_SRTP:
             MBEDTLS_SSL_DEBUG_MSG( 3, ( "found use_srtp extension" ) );
 
-            if ( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
-            {
-                if( ( ret = ssl_parse_use_srtp_ext( ssl, ext + 4, ext_size ) ) != 0 )
-                    return( ret );
-            }
+            if( ( ret = ssl_parse_use_srtp_ext( ssl, ext + 4, ext_size ) ) != 0 )
+                return( ret );
 
             break;
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index 60de57b1cf09..070a5915f76b 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -789,8 +789,9 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
     const size_t size_of_lengths = 3;
 
     /* If use_srtp is not configured, just ignore the extension */
-    if( ssl->conf->dtls_srtp_profile_list == NULL ||
-        ssl->conf->dtls_srtp_profile_list_len == 0 )
+    if( ( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ) ||
+        ( ssl->conf->dtls_srtp_profile_list == NULL ) ||
+        ( ssl->conf->dtls_srtp_profile_list_len == 0 ) )
     {
         return( 0 );
     }
@@ -2065,12 +2066,9 @@ static int ssl_parse_client_hello( mbedtls_ssl_context *ssl )
             case MBEDTLS_TLS_EXT_USE_SRTP:
                 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found use_srtp extension" ) );
 
-                if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
-                {
-                    ret = ssl_parse_use_srtp_ext( ssl, ext + 4, ext_size );
-                    if( ret != 0 )
-                        return( ret );
-                }
+                ret = ssl_parse_use_srtp_ext( ssl, ext + 4, ext_size );
+                if( ret != 0 )
+                    return( ret );
                 break;
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
 
@@ -2643,7 +2641,8 @@ static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
 
     *olen = 0;
 
-    if( ssl->dtls_srtp_info.chosen_dtls_srtp_profile == MBEDTLS_TLS_SRTP_UNSET )
+    if( ( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ) ||
+        ( ssl->dtls_srtp_info.chosen_dtls_srtp_profile == MBEDTLS_TLS_SRTP_UNSET ) )
     {
         return;
     }
@@ -2992,11 +2991,8 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl )
 #endif
 
 #if defined(MBEDTLS_SSL_DTLS_SRTP)
-    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
-    {
-        ssl_write_use_srtp_ext( ssl, p + 2 + ext_len, &olen );
-        ext_len += olen;
-    }
+    ssl_write_use_srtp_ext( ssl, p + 2 + ext_len, &olen );
+    ext_len += olen;
 #endif
 
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, total extension length: %d", ext_len ) );

From 5fbe9e7ac089f310370ee6905c9c1aa7ef5fb746 Mon Sep 17 00:00:00 2001
From: Johan Pascal <johan.pascal@belledonne-communications.com>
Date: Thu, 29 Oct 2020 10:49:21 +0100
Subject: [PATCH 63/63] remove useless parentheses

Signed-off-by: Johan Pascal <johan.pascal@belledonne-communications.com>
---
 programs/ssl/ssl_client2.c | 4 ++--
 programs/ssl/ssl_server2.c | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index dd274700c527..54cdd7d32a65 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -2758,8 +2758,8 @@ int main( int argc, char *argv[] )
         mbedtls_dtls_srtp_info dtls_srtp_negotiation_result;
         mbedtls_ssl_get_dtls_srtp_negotiation_result( &ssl, &dtls_srtp_negotiation_result );
 
-        if( ( dtls_srtp_negotiation_result.chosen_dtls_srtp_profile
-                                == MBEDTLS_TLS_SRTP_UNSET ) )
+        if( dtls_srtp_negotiation_result.chosen_dtls_srtp_profile
+                                == MBEDTLS_TLS_SRTP_UNSET )
         {
             mbedtls_printf( "    Unable to negotiate "
                             "the use of DTLS-SRTP\n" );
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index dcb215d4e2c8..ec3d6ade5823 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -3868,8 +3868,8 @@ int main( int argc, char *argv[] )
         mbedtls_dtls_srtp_info dtls_srtp_negotiation_result;
         mbedtls_ssl_get_dtls_srtp_negotiation_result( &ssl, &dtls_srtp_negotiation_result );
 
-        if( ( dtls_srtp_negotiation_result.chosen_dtls_srtp_profile
-                                == MBEDTLS_TLS_SRTP_UNSET ) )
+        if( dtls_srtp_negotiation_result.chosen_dtls_srtp_profile
+                                == MBEDTLS_TLS_SRTP_UNSET )
         {
             mbedtls_printf( "    Unable to negotiate "
                             "the use of DTLS-SRTP\n" );