srtp: Add support for GCM (RFC 7714)

The GCM support in libsrtp have been there for a while and
it can be useful for some applications.

Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/issues/913
This commit is contained in:
Ulf Olsson 2019-03-06 07:36:44 +01:00 committed by Tim-Philipp Müller
parent aaee282051
commit b2d0795185
5 changed files with 46 additions and 9 deletions

View file

@ -219,6 +219,12 @@ set_crypto_policy_cipher_auth (GstSrtpCipherType cipher,
case GST_SRTP_CIPHER_AES_256_ICM: case GST_SRTP_CIPHER_AES_256_ICM:
policy->cipher_type = SRTP_AES_ICM_256; policy->cipher_type = SRTP_AES_ICM_256;
break; break;
case GST_SRTP_CIPHER_AES_128_GCM:
policy->cipher_type = SRTP_AES_GCM_128;
break;
case GST_SRTP_CIPHER_AES_256_GCM:
policy->cipher_type = SRTP_AES_GCM_256;
break;
case GST_SRTP_CIPHER_NULL: case GST_SRTP_CIPHER_NULL:
policy->cipher_type = SRTP_NULL_CIPHER; policy->cipher_type = SRTP_NULL_CIPHER;
break; break;
@ -242,7 +248,12 @@ set_crypto_policy_cipher_auth (GstSrtpCipherType cipher,
case GST_SRTP_AUTH_NULL: case GST_SRTP_AUTH_NULL:
policy->auth_type = SRTP_NULL_AUTH; policy->auth_type = SRTP_NULL_AUTH;
policy->auth_key_len = 0; policy->auth_key_len = 0;
policy->auth_tag_len = 0; if (cipher == GST_SRTP_CIPHER_AES_128_GCM
|| cipher == GST_SRTP_CIPHER_AES_256_GCM) {
policy->auth_tag_len = 16;
} else {
policy->auth_tag_len = 0;
}
break; break;
} }
@ -268,8 +279,13 @@ cipher_key_size (GstSrtpCipherType cipher)
case GST_SRTP_CIPHER_AES_256_ICM: case GST_SRTP_CIPHER_AES_256_ICM:
size = SRTP_AES_ICM_256_KEY_LEN_WSALT; size = SRTP_AES_ICM_256_KEY_LEN_WSALT;
break; break;
case GST_SRTP_CIPHER_AES_128_GCM:
size = SRTP_AES_GCM_128_KEY_LEN_WSALT;
break;
case GST_SRTP_CIPHER_AES_256_GCM:
size = SRTP_AES_GCM_256_KEY_LEN_WSALT;
break;
case GST_SRTP_CIPHER_NULL: case GST_SRTP_CIPHER_NULL:
size = 0;
break; break;
default: default:
g_assert_not_reached (); g_assert_not_reached ();

View file

@ -60,13 +60,18 @@
#else #else
# include <srtp/srtp.h> # include <srtp/srtp.h>
# include <srtp/srtp_priv.h> # include <srtp/srtp_priv.h>
# include <srtp/crypto_types.h>
# define srtp_crypto_policy_t crypto_policy_t # define srtp_crypto_policy_t crypto_policy_t
# define SRTP_AES_ICM_128 AES_ICM # define SRTP_AES_ICM_128 AES_ICM
# define SRTP_AES_ICM_256 AES_ICM # define SRTP_AES_ICM_256 AES_ICM
# define SRTP_AES_GCM_128 AES_128_GCM
# define SRTP_AES_GCM_256 AES_256_GCM
# define SRTP_NULL_CIPHER NULL_CIPHER # define SRTP_NULL_CIPHER NULL_CIPHER
# define SRTP_AES_ICM_128_KEY_LEN_WSALT 30 # define SRTP_AES_ICM_128_KEY_LEN_WSALT 30
# define SRTP_AES_ICM_256_KEY_LEN_WSALT 46 # define SRTP_AES_ICM_256_KEY_LEN_WSALT 46
# define SRTP_AES_GCM_128_KEY_LEN_WSALT AES_128_GCM_KEYSIZE_WSALT
# define SRTP_AES_GCM_256_KEY_LEN_WSALT AES_256_GCM_KEYSIZE_WSALT
# define SRTP_HMAC_SHA1 HMAC_SHA1 # define SRTP_HMAC_SHA1 HMAC_SHA1
# define SRTP_NULL_AUTH NULL_AUTH # define SRTP_NULL_AUTH NULL_AUTH
# define srtp_err_status_t err_status_t # define srtp_err_status_t err_status_t

View file

@ -583,8 +583,13 @@ get_stream_from_caps (GstSrtpDec * filter, GstCaps * caps, guint32 ssrc)
goto error; goto error;
} }
if (stream->rtcp_cipher != SRTP_NULL_CIPHER && /* RFC 3711 says in "3. SRTP Framework" that SRTCP message authentication
stream->rtcp_auth == SRTP_NULL_AUTH) { * is MANDATORY. In case of GCM let the pipeline handle any errors.
*/
if (stream->rtcp_cipher != GST_SRTP_CIPHER_AES_128_GCM
&& stream->rtcp_cipher != GST_SRTP_CIPHER_AES_256_GCM
&& stream->rtcp_cipher != GST_SRTP_CIPHER_NULL
&& stream->rtcp_auth == GST_SRTP_AUTH_NULL) {
GST_WARNING_OBJECT (filter, GST_WARNING_OBJECT (filter,
"Cannot have SRTP NULL authentication with a not-NULL encryption" "Cannot have SRTP NULL authentication with a not-NULL encryption"
" cipher."); " cipher.");
@ -930,6 +935,7 @@ update_session_stream_from_caps (GstSrtpDec * filter, guint32 ssrc,
err = init_session_stream (filter, ssrc, stream); err = init_session_stream (filter, ssrc, stream);
if (err != srtp_err_status_ok) { if (err != srtp_err_status_ok) {
GST_WARNING_OBJECT (filter, "Failed to create the stream (err: %d)", err);
if (stream->key) if (stream->key)
gst_buffer_unref (stream->key); gst_buffer_unref (stream->key);
g_slice_free (GstSrtpDecSsrcStream, stream); g_slice_free (GstSrtpDecSsrcStream, stream);

View file

@ -490,8 +490,10 @@ static void
gst_srtp_enc_reset_no_lock (GstSrtpEnc * filter) gst_srtp_enc_reset_no_lock (GstSrtpEnc * filter)
{ {
if (!filter->first_session) { if (!filter->first_session) {
srtp_dealloc (filter->session); if (filter->session) {
filter->session = NULL; srtp_dealloc (filter->session);
filter->session = NULL;
}
g_hash_table_remove_all (filter->ssrcs_set); g_hash_table_remove_all (filter->ssrcs_set);
} }
@ -1374,8 +1376,14 @@ gst_srtp_enc_change_state (GstElement * element, GstStateChange transition)
} }
} }
} }
if ((filter->rtcp_cipher != SRTP_NULL_CIPHER)
&& (filter->rtcp_auth == SRTP_NULL_AUTH)) { /* RFC 3711 says in "3. SRTP Framework" that SRTCP message authentication
* is MANDATORY. In case of GCM let the pipeline handle any errors.
*/
if (filter->rtcp_cipher != GST_SRTP_CIPHER_AES_128_GCM
&& filter->rtcp_cipher != GST_SRTP_CIPHER_AES_256_GCM
&& filter->rtcp_cipher != GST_SRTP_CIPHER_NULL
&& filter->rtcp_auth == GST_SRTP_AUTH_NULL) {
GST_ERROR_OBJECT (filter, GST_ERROR_OBJECT (filter,
"RTCP authentication can't be NULL if encryption is not NULL."); "RTCP authentication can't be NULL if encryption is not NULL.");
return GST_STATE_CHANGE_FAILURE; return GST_STATE_CHANGE_FAILURE;

View file

@ -49,7 +49,9 @@ typedef enum
{ {
GST_SRTP_CIPHER_NULL, GST_SRTP_CIPHER_NULL,
GST_SRTP_CIPHER_AES_128_ICM, GST_SRTP_CIPHER_AES_128_ICM,
GST_SRTP_CIPHER_AES_256_ICM GST_SRTP_CIPHER_AES_256_ICM,
GST_SRTP_CIPHER_AES_128_GCM,
GST_SRTP_CIPHER_AES_256_GCM
} GstSrtpCipherType; } GstSrtpCipherType;
typedef enum typedef enum