srtp: add 256-bit key support

* ext/srtp/gstsrtp.[ch]: added GST_SRTP_CIPHER_AES_256_ICM to
  GstSrtpCipherType and new function cipher_key_size.

* ext/srtp/gstsrtpenc.c: maximum key size is now 46 characters (14 for
  the salt plus the key). If different ciphers are chosen for RTP and
  RTCP the maximum needed key size is expected.

* ext/srtp/gstsrtpdec.c: minor documentation updates.

https://bugzilla.gnome.org/show_bug.cgi?id=720434
This commit is contained in:
Aleix Conchillo Flaqué 2013-12-13 14:16:49 -08:00 committed by Olivier Crête
parent b3910cabaf
commit fefd021ee2
4 changed files with 85 additions and 21 deletions

View file

@ -177,9 +177,13 @@ set_crypto_policy_cipher_auth (GstSrtpCipherType cipher,
{ {
switch (cipher) { switch (cipher) {
case GST_SRTP_CIPHER_AES_128_ICM: case GST_SRTP_CIPHER_AES_128_ICM:
policy->cipher_type = AES_128_ICM; policy->cipher_type = AES_ICM;
policy->cipher_key_len = 30; policy->cipher_key_len = 30;
break; break;
case GST_SRTP_CIPHER_AES_256_ICM:
policy->cipher_type = AES_ICM;
policy->cipher_key_len = 46;
break;
case GST_SRTP_CIPHER_NULL: case GST_SRTP_CIPHER_NULL:
policy->cipher_type = NULL_CIPHER; policy->cipher_type = NULL_CIPHER;
policy->cipher_key_len = 0; policy->cipher_key_len = 0;
@ -216,6 +220,28 @@ set_crypto_policy_cipher_auth (GstSrtpCipherType cipher,
policy->sec_serv = sec_serv_conf_and_auth; policy->sec_serv = sec_serv_conf_and_auth;
} }
guint
cipher_key_size (GstSrtpCipherType cipher)
{
guint size = 0;
switch (cipher) {
case GST_SRTP_CIPHER_AES_128_ICM:
size = 30;
break;
case GST_SRTP_CIPHER_AES_256_ICM:
size = 46;
break;
case GST_SRTP_CIPHER_NULL:
size = 0;
break;
default:
g_assert_not_reached ();
}
return size;
}
static gboolean static gboolean
plugin_init (GstPlugin * plugin) plugin_init (GstPlugin * plugin)
{ {

View file

@ -52,7 +52,8 @@
typedef enum 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
} GstSrtpCipherType; } GstSrtpCipherType;
typedef enum typedef enum
@ -73,5 +74,6 @@ gint enum_value_from_nick (GType enum_gtype, const gchar *nick);
void set_crypto_policy_cipher_auth (GstSrtpCipherType cipher, void set_crypto_policy_cipher_auth (GstSrtpCipherType cipher,
GstSrtpAuthType auth, crypto_policy_t * policy); GstSrtpAuthType auth, crypto_policy_t * policy);
guint cipher_key_size (GstSrtpCipherType cipher);
#endif /* __GST_SRTP_H__ */ #endif /* __GST_SRTP_H__ */

View file

@ -65,13 +65,13 @@
* mecanisms available are : * mecanisms available are :
* *
* Encryption * Encryption
* - AES_128_ICM (default, maximum security) * - AES_ICM 256 bits (maximum security)
* - STRONGHOLD_CIPHER (same as AES_128_ICM) * - AES_ICM 128 bits (default)
* - NULL * - NULL
* *
* Authentication * Authentication
* - HMAC_SHA1 (default, maximum protection) * - HMAC_SHA1 80 bits (default, maximum protection)
* - STRONGHOLD_AUTH (same as HMAC_SHA1) * - HMAC_SHA1 32 bits
* - NULL * - NULL
* *
* Note that for SRTP protection, authentication is mandatory (non-null) * Note that for SRTP protection, authentication is mandatory (non-null)

View file

@ -62,17 +62,18 @@
* uses the default RTP and RTCP encryption and authentication mechanisms, * uses the default RTP and RTCP encryption and authentication mechanisms,
* unless the user has set the relevant properties first. It also uses * unless the user has set the relevant properties first. It also uses
* a master key that MUST be set by property (key) at the beginning. The * a master key that MUST be set by property (key) at the beginning. The
* master key must be of a maximum length of 30 characters. The * master key must be of a maximum length of 46 characters (14 characters
* encryption and authentication mecanisms available are : * for the salt plus the key). The encryption and authentication mecanisms
* available are :
* *
* Encryption (properties rtp-cipher and rtcp-cipher) * Encryption (properties rtp-cipher and rtcp-cipher)
* - AES_128_ICM (default, maximum security) * - AES_ICM 256 bits (maximum security)
* - STRONGHOLD_CIPHER (same as AES_128_ICM) * - AES_ICM 128 bits (default)
* - NULL * - NULL
* *
* Authentication (properties rtp-auth and rtcp-auth) * Authentication (properties rtp-auth and rtcp-auth)
* - HMAC_SHA1 (default, maximum protection) * - HMAC_SHA1 80 bits (default, maximum protection)
* - STRONGHOLD_AUTH (same as HMAC_SHA1) * - HMAC_SHA1 32 bits
* - NULL * - NULL
* *
* Note that for SRTP protection, authentication is mandatory (non-null) * Note that for SRTP protection, authentication is mandatory (non-null)
@ -110,6 +111,12 @@
GST_DEBUG_CATEGORY_STATIC (gst_srtp_enc_debug); GST_DEBUG_CATEGORY_STATIC (gst_srtp_enc_debug);
#define GST_CAT_DEFAULT gst_srtp_enc_debug #define GST_CAT_DEFAULT gst_srtp_enc_debug
/* 128 bit key size: 14 (salt) + 16 */
#define MASTER_128_KEY_SIZE 30
/* 256 bit key size: 14 (salt) + 16 + 16 */
#define MASTER_256_KEY_SIZE 46
/* Properties default values */ /* Properties default values */
#define DEFAULT_MASTER_KEY NULL #define DEFAULT_MASTER_KEY NULL
#define DEFAULT_RTP_CIPHER GST_SRTP_CIPHER_AES_128_ICM #define DEFAULT_RTP_CIPHER GST_SRTP_CIPHER_AES_128_ICM
@ -259,8 +266,9 @@ gst_srtp_enc_class_init (GstSrtpEncClass * klass)
/* Install properties */ /* Install properties */
g_object_class_install_property (gobject_class, PROP_MKEY, g_object_class_install_property (gobject_class, PROP_MKEY,
g_param_spec_boxed ("key", "Key", "Master key (of " g_param_spec_boxed ("key", "Key", "Master key (minimum of "
G_STRINGIFY (SRTP_MASTER_KEY_LEN) " bytes)", G_STRINGIFY (MASTER_128_KEY_SIZE) " and maximum of "
G_STRINGIFY (MASTER_256_KEY_SIZE) " bytes)",
GST_TYPE_BUFFER, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_TYPE_BUFFER, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
GST_PARAM_MUTABLE_PLAYING)); GST_PARAM_MUTABLE_PLAYING));
g_object_class_install_property (gobject_class, PROP_RTP_CIPHER, g_object_class_install_property (gobject_class, PROP_RTP_CIPHER,
@ -315,6 +323,36 @@ gst_srtp_enc_init (GstSrtpEnc * filter)
filter->ssrcs_set = g_hash_table_new (g_direct_hash, g_direct_equal); filter->ssrcs_set = g_hash_table_new (g_direct_hash, g_direct_equal);
} }
static guint
max_cipher_key_size (GstSrtpEnc * filter)
{
guint rtp_size, rtcp_size;
rtp_size = cipher_key_size (filter->rtp_cipher);
rtcp_size = cipher_key_size (filter->rtcp_cipher);
return (rtp_size > rtcp_size) ? rtp_size : rtcp_size;
}
static gboolean
check_key_size (GstSrtpEnc * filter)
{
guint expected;
gboolean res;
expected = max_cipher_key_size (filter);
res = gst_buffer_get_size (filter->key) == expected;
if (!res) {
GST_ELEMENT_ERROR (filter, LIBRARY, SETTINGS,
("Master key size is wrong"),
("Expected master key of %d bytes, but received %" G_GSIZE_FORMAT
" bytes", expected, gst_buffer_get_size (filter->key)));
}
return res;
}
/* Create stream /* Create stream
*/ */
@ -342,13 +380,8 @@ check_new_stream_locked (GstSrtpEnc * filter, guint32 ssrc)
("Cipher is not NULL, key must be set")); ("Cipher is not NULL, key must be set"));
return FALSE; return FALSE;
} }
if (gst_buffer_get_size (filter->key) != SRTP_MASTER_KEY_LEN) { if (!check_key_size (filter)) {
GST_OBJECT_UNLOCK (filter); GST_OBJECT_UNLOCK (filter);
GST_ELEMENT_ERROR (filter, LIBRARY, SETTINGS,
("Master key size is wrong"),
("Expected master key of %d bytes, but received %" G_GSIZE_FORMAT
" bytes", SRTP_MASTER_KEY_LEN,
gst_buffer_get_size (filter->key)));
return FALSE; return FALSE;
} }
} }
@ -870,6 +903,7 @@ static void
gst_srtp_enc_replace_random_key (GstSrtpEnc * filter) gst_srtp_enc_replace_random_key (GstSrtpEnc * filter)
{ {
guint i; guint i;
guint key_size;
GstMapInfo map; GstMapInfo map;
GST_DEBUG_OBJECT (filter, "Generating random key"); GST_DEBUG_OBJECT (filter, "Generating random key");
@ -877,7 +911,9 @@ gst_srtp_enc_replace_random_key (GstSrtpEnc * filter)
if (filter->key) if (filter->key)
gst_buffer_unref (filter->key); gst_buffer_unref (filter->key);
filter->key = gst_buffer_new_allocate (NULL, 16 + 14, NULL); key_size = max_cipher_key_size (filter);
filter->key = gst_buffer_new_allocate (NULL, key_size, NULL);
gst_buffer_map (filter->key, &map, GST_MAP_WRITE); gst_buffer_map (filter->key, &map, GST_MAP_WRITE);
for (i = 0; i < map.size; i += 4) for (i = 0; i < map.size; i += 4)