mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-02 04:22:27 +00:00
mikey: Add support for GCM (RFC 7714)
The MIKEY details can be found in RFC 7714 section "14.3. MIKEY"
This commit is contained in:
parent
4320a31bd9
commit
7806285a10
2 changed files with 109 additions and 33 deletions
|
@ -2154,30 +2154,79 @@ parse_error:
|
|||
#define HMAC_32_KEY_LEN 4
|
||||
#define HMAC_80_KEY_LEN 10
|
||||
|
||||
static guint8
|
||||
enc_key_length_from_cipher_name (const gchar * cipher)
|
||||
static gboolean
|
||||
auth_alg_from_cipher_name (const gchar * cipher, guint8 * auth_alg)
|
||||
{
|
||||
if (g_strcmp0 (cipher, "aes-128-icm") == 0)
|
||||
return AES_128_KEY_LEN;
|
||||
*auth_alg = GST_MIKEY_MAC_HMAC_SHA_1_160;
|
||||
else if (g_strcmp0 (cipher, "aes-256-icm") == 0)
|
||||
return AES_256_KEY_LEN;
|
||||
*auth_alg = GST_MIKEY_MAC_HMAC_SHA_1_160;
|
||||
else if (g_strcmp0 (cipher, "aes-128-gcm") == 0)
|
||||
*auth_alg = GST_MIKEY_MAC_NULL;
|
||||
else if (g_strcmp0 (cipher, "aes-256-gcm") == 0)
|
||||
*auth_alg = GST_MIKEY_MAC_NULL;
|
||||
else {
|
||||
GST_ERROR ("encryption algorithm '%s' not supported", cipher);
|
||||
return 0;
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static guint8
|
||||
auth_key_length_from_auth_name (const gchar * auth)
|
||||
static gboolean
|
||||
enc_alg_from_cipher_name (const gchar * cipher, guint8 * enc_alg)
|
||||
{
|
||||
if (g_strcmp0 (auth, "hmac-sha1-32") == 0)
|
||||
return HMAC_32_KEY_LEN;
|
||||
else if (g_strcmp0 (auth, "hmac-sha1-80") == 0)
|
||||
return HMAC_80_KEY_LEN;
|
||||
if (g_strcmp0 (cipher, "aes-128-icm") == 0)
|
||||
*enc_alg = GST_MIKEY_ENC_AES_CM_128;
|
||||
else if (g_strcmp0 (cipher, "aes-256-icm") == 0)
|
||||
*enc_alg = GST_MIKEY_ENC_AES_CM_128;
|
||||
else if (g_strcmp0 (cipher, "aes-128-gcm") == 0)
|
||||
*enc_alg = GST_MIKEY_ENC_AES_GCM_128;
|
||||
else if (g_strcmp0 (cipher, "aes-256-gcm") == 0)
|
||||
*enc_alg = GST_MIKEY_ENC_AES_GCM_128;
|
||||
else {
|
||||
GST_ERROR ("authentication algorithm '%s' not supported", auth);
|
||||
return 0;
|
||||
GST_ERROR ("encryption algorithm '%s' not supported", cipher);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
enc_key_length_from_cipher_name (const gchar * cipher, guint8 * enc_key_length)
|
||||
{
|
||||
if (g_strcmp0 (cipher, "aes-128-icm") == 0)
|
||||
*enc_key_length = AES_128_KEY_LEN;
|
||||
else if (g_strcmp0 (cipher, "aes-256-icm") == 0)
|
||||
*enc_key_length = AES_256_KEY_LEN;
|
||||
else if (g_strcmp0 (cipher, "aes-128-gcm") == 0)
|
||||
*enc_key_length = AES_128_KEY_LEN;
|
||||
else if (g_strcmp0 (cipher, "aes-256-gcm") == 0)
|
||||
*enc_key_length = AES_256_KEY_LEN;
|
||||
else {
|
||||
GST_ERROR ("encryption algorithm '%s' not supported", cipher);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
auth_key_length_from_auth_cipher_name (const gchar * auth, const gchar * cipher,
|
||||
guint8 * length)
|
||||
{
|
||||
if (g_strcmp0 (cipher, "aes-128-gcm") == 0
|
||||
|| g_strcmp0 (cipher, "aes-256-gcm") == 0) {
|
||||
*length = 0;
|
||||
} else {
|
||||
if (g_strcmp0 (auth, "hmac-sha1-32") == 0) {
|
||||
*length = HMAC_32_KEY_LEN;
|
||||
} else if (g_strcmp0 (auth, "hmac-sha1-80") == 0) {
|
||||
*length = HMAC_80_KEY_LEN;
|
||||
} else {
|
||||
GST_ERROR ("authentication algorithm '%s' not supported", auth);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2200,6 +2249,10 @@ gst_mikey_message_new_from_caps (GstCaps * caps)
|
|||
GstMIKEYMessage *msg;
|
||||
GstMIKEYPayload *payload, *pkd;
|
||||
guint8 byte;
|
||||
guint8 enc_alg;
|
||||
guint8 auth_alg;
|
||||
guint8 enc_key_length;
|
||||
guint8 auth_key_length;
|
||||
GstStructure *s;
|
||||
GstMapInfo info;
|
||||
GstBuffer *srtpkey;
|
||||
|
@ -2242,6 +2295,14 @@ gst_mikey_message_new_from_caps (GstCaps * caps)
|
|||
if (auth == NULL)
|
||||
auth = srtcpauth;
|
||||
|
||||
/* get cipher and auth values */
|
||||
if (!enc_alg_from_cipher_name (cipher, &enc_alg) ||
|
||||
!auth_alg_from_cipher_name (cipher, &auth_alg) ||
|
||||
!enc_key_length_from_cipher_name (cipher, &enc_key_length) ||
|
||||
!auth_key_length_from_auth_cipher_name (auth, cipher, &auth_key_length)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
msg = gst_mikey_message_new ();
|
||||
/* unencrypted MIKEY message, we send this over TLS so this is allowed */
|
||||
gst_mikey_message_set_info (msg, GST_MIKEY_VERSION, GST_MIKEY_TYPE_PSK_INIT,
|
||||
|
@ -2256,21 +2317,18 @@ gst_mikey_message_new_from_caps (GstCaps * caps)
|
|||
payload = gst_mikey_payload_new (GST_MIKEY_PT_SP);
|
||||
gst_mikey_payload_sp_set (payload, 0, GST_MIKEY_SEC_PROTO_SRTP);
|
||||
|
||||
/* only AES-CM is supported */
|
||||
byte = 1;
|
||||
gst_mikey_payload_sp_add_param (payload, GST_MIKEY_SP_SRTP_ENC_ALG, 1, &byte);
|
||||
/* AES-CM or AES-GCM is supported */
|
||||
gst_mikey_payload_sp_add_param (payload, GST_MIKEY_SP_SRTP_ENC_ALG, 1,
|
||||
&enc_alg);
|
||||
/* encryption key length */
|
||||
byte = enc_key_length_from_cipher_name (cipher);
|
||||
gst_mikey_payload_sp_add_param (payload, GST_MIKEY_SP_SRTP_ENC_KEY_LEN, 1,
|
||||
&byte);
|
||||
/* only HMAC-SHA1 */
|
||||
byte = 1;
|
||||
&enc_key_length);
|
||||
/* HMAC-SHA1 or NULL in case of GCM */
|
||||
gst_mikey_payload_sp_add_param (payload, GST_MIKEY_SP_SRTP_AUTH_ALG, 1,
|
||||
&byte);
|
||||
&auth_alg);
|
||||
/* authentication key length */
|
||||
byte = auth_key_length_from_auth_name (auth);
|
||||
gst_mikey_payload_sp_add_param (payload, GST_MIKEY_SP_SRTP_AUTH_KEY_LEN, 1,
|
||||
&byte);
|
||||
&auth_key_length);
|
||||
/* we enable encryption on RTP and RTCP */
|
||||
byte = 1;
|
||||
gst_mikey_payload_sp_add_param (payload, GST_MIKEY_SP_SRTP_SRTP_ENC, 1,
|
||||
|
@ -2330,6 +2388,7 @@ gst_mikey_message_to_caps (const GstMIKEYMessage * msg, GstCaps * caps)
|
|||
if ((payload = gst_mikey_message_find_payload (msg, GST_MIKEY_PT_SP, 0))) {
|
||||
GstMIKEYPayloadSP *p = (GstMIKEYPayloadSP *) payload;
|
||||
guint len, i;
|
||||
guint enc_alg = GST_MIKEY_ENC_NULL;
|
||||
|
||||
if (p->proto != GST_MIKEY_SEC_PROTO_SRTP)
|
||||
goto done;
|
||||
|
@ -2341,14 +2400,18 @@ gst_mikey_message_to_caps (const GstMIKEYMessage * msg, GstCaps * caps)
|
|||
|
||||
switch (param->type) {
|
||||
case GST_MIKEY_SP_SRTP_ENC_ALG:
|
||||
enc_alg = param->val[0];
|
||||
switch (param->val[0]) {
|
||||
case 0:
|
||||
case GST_MIKEY_ENC_NULL:
|
||||
srtp_cipher = "null";
|
||||
break;
|
||||
case 2:
|
||||
case 1:
|
||||
case GST_MIKEY_ENC_AES_CM_128:
|
||||
case GST_MIKEY_ENC_AES_KW_128:
|
||||
srtp_cipher = "aes-128-icm";
|
||||
break;
|
||||
case GST_MIKEY_ENC_AES_GCM_128:
|
||||
srtp_cipher = "aes-128-gcm";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -2356,10 +2419,20 @@ gst_mikey_message_to_caps (const GstMIKEYMessage * msg, GstCaps * caps)
|
|||
case GST_MIKEY_SP_SRTP_ENC_KEY_LEN:
|
||||
switch (param->val[0]) {
|
||||
case AES_128_KEY_LEN:
|
||||
srtp_cipher = "aes-128-icm";
|
||||
if (enc_alg == GST_MIKEY_ENC_AES_CM_128 ||
|
||||
enc_alg == GST_MIKEY_ENC_AES_KW_128) {
|
||||
srtp_cipher = "aes-128-icm";
|
||||
} else if (enc_alg == GST_MIKEY_ENC_AES_GCM_128) {
|
||||
srtp_cipher = "aes-128-gcm";
|
||||
}
|
||||
break;
|
||||
case AES_256_KEY_LEN:
|
||||
srtp_cipher = "aes-256-icm";
|
||||
if (enc_alg == GST_MIKEY_ENC_AES_CM_128 ||
|
||||
enc_alg == GST_MIKEY_ENC_AES_KW_128) {
|
||||
srtp_cipher = "aes-256-icm";
|
||||
} else if (enc_alg == GST_MIKEY_ENC_AES_GCM_128) {
|
||||
srtp_cipher = "aes-256-gcm";
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -2367,11 +2440,10 @@ gst_mikey_message_to_caps (const GstMIKEYMessage * msg, GstCaps * caps)
|
|||
break;
|
||||
case GST_MIKEY_SP_SRTP_AUTH_ALG:
|
||||
switch (param->val[0]) {
|
||||
case 0:
|
||||
case GST_MIKEY_MAC_NULL:
|
||||
srtp_auth = "null";
|
||||
break;
|
||||
case 2:
|
||||
case 1:
|
||||
case GST_MIKEY_MAC_HMAC_SHA_1_160:
|
||||
srtp_auth = "hmac-sha1-80";
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -219,6 +219,7 @@ gst_mikey_payload_copy (const GstMIKEYPayload * payload)
|
|||
* @GST_MIKEY_ENC_NULL: no encryption
|
||||
* @GST_MIKEY_ENC_AES_CM_128: AES-CM using a 128-bit key
|
||||
* @GST_MIKEY_ENC_AES_KW_128: AES Key Wrap using a 128-bit key
|
||||
* @GST_MIKEY_ENC_AES_GCM_128: AES-GCM using a 128-bit key
|
||||
*
|
||||
* The encryption algorithm used to encrypt the Encr data field
|
||||
*/
|
||||
|
@ -226,7 +227,8 @@ typedef enum
|
|||
{
|
||||
GST_MIKEY_ENC_NULL = 0,
|
||||
GST_MIKEY_ENC_AES_CM_128 = 1,
|
||||
GST_MIKEY_ENC_AES_KW_128 = 2
|
||||
GST_MIKEY_ENC_AES_KW_128 = 2,
|
||||
GST_MIKEY_ENC_AES_GCM_128 = 6
|
||||
} GstMIKEYEncAlg;
|
||||
|
||||
/**
|
||||
|
@ -393,6 +395,7 @@ typedef enum
|
|||
* @GST_MIKEY_SP_SRTP_SRTP_AUTH: SRTP authentication off/on, 0 if off, 1 if on
|
||||
* @GST_MIKEY_SP_SRTP_AUTH_TAG_LEN: Authentication tag length
|
||||
* @GST_MIKEY_SP_SRTP_SRTP_PREFIX_LEN: SRTP prefix length
|
||||
* @GST_MIKEY_SP_SRTP_AEAD_AUTH_TAG_LEN: AEAD authentication tag length
|
||||
*
|
||||
* This policy specifies the parameters for SRTP and SRTCP
|
||||
*/
|
||||
|
@ -410,7 +413,8 @@ typedef enum
|
|||
GST_MIKEY_SP_SRTP_FEC_ORDER = 9,
|
||||
GST_MIKEY_SP_SRTP_SRTP_AUTH = 10,
|
||||
GST_MIKEY_SP_SRTP_AUTH_TAG_LEN = 11,
|
||||
GST_MIKEY_SP_SRTP_SRTP_PREFIX_LEN = 12
|
||||
GST_MIKEY_SP_SRTP_SRTP_PREFIX_LEN = 12,
|
||||
GST_MIKEY_SP_SRTP_AEAD_AUTH_TAG_LEN = 20
|
||||
} GstMIKEYSecSRTP;
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue