summaryrefslogtreecommitdiff
path: root/chromium/third_party/libsrtp
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@theqtcompany.com>2016-07-14 17:41:05 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2016-08-04 12:37:36 +0000
commit399c965b6064c440ddcf4015f5f8e9d131c7a0a6 (patch)
tree6b06b60ff365abef0e13b3503d593a0df48d20e8 /chromium/third_party/libsrtp
parent7366110654eec46f21b6824f302356426f48cd74 (diff)
downloadqtwebengine-chromium-399c965b6064c440ddcf4015f5f8e9d131c7a0a6.tar.gz
BASELINE: Update Chromium to 52.0.2743.76 and Ninja to 1.7.1
Change-Id: I382f51b959689505a60f8b707255ecb344f7d8b4 Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/third_party/libsrtp')
-rw-r--r--chromium/third_party/libsrtp/BUILD.gn8
-rw-r--r--chromium/third_party/libsrtp/srtp/crypto/kernel/crypto_kernel.c14
-rw-r--r--chromium/third_party/libsrtp/srtp/include/srtp.h2
-rw-r--r--chromium/third_party/libsrtp/srtp/include/srtp_priv.h3
-rw-r--r--chromium/third_party/libsrtp/srtp/srtp/srtp.c366
5 files changed, 383 insertions, 10 deletions
diff --git a/chromium/third_party/libsrtp/BUILD.gn b/chromium/third_party/libsrtp/BUILD.gn
index 1da354e5565..6f3e0017f9b 100644
--- a/chromium/third_party/libsrtp/BUILD.gn
+++ b/chromium/third_party/libsrtp/BUILD.gn
@@ -67,6 +67,14 @@ config("libsrtp_config") {
# srtp test applications and libjingle.
defines += [ "CPU_CISC" ]
}
+ if (current_cpu == "mipsel" || current_cpu == "arm" || current_cpu == "x86") {
+ # Define FORCE_64BIT_ALIGN to avoid alignment-related-crashes like
+ # crbug/414919. Without this, aes_cbc_alloc will allocate an
+ # aes_cbc_ctx_t not 64-bit aligned and the v128_t members of
+ # aes_cbc_ctx_t will not be 64-bit aligned, which breaks the
+ # compiler optimizations that assume 64-bit alignment of v128_t.
+ defines += [ "FORCE_64BIT_ALIGN" ]
+ }
}
static_library("libsrtp") {
diff --git a/chromium/third_party/libsrtp/srtp/crypto/kernel/crypto_kernel.c b/chromium/third_party/libsrtp/srtp/crypto/kernel/crypto_kernel.c
index f01a72a57e2..518cd1e6151 100644
--- a/chromium/third_party/libsrtp/srtp/crypto/kernel/crypto_kernel.c
+++ b/chromium/third_party/libsrtp/srtp/crypto/kernel/crypto_kernel.c
@@ -76,6 +76,10 @@ extern cipher_type_t aes_icm;
#ifndef OPENSSL
extern cipher_type_t aes_cbc;
#else
+#ifndef SRTP_NO_AES192
+extern cipher_type_t aes_icm_192;
+#endif
+extern cipher_type_t aes_icm_256;
extern cipher_type_t aes_gcm_128_openssl;
extern cipher_type_t aes_gcm_256_openssl;
#endif
@@ -170,6 +174,16 @@ crypto_kernel_init() {
if (status)
return status;
#else
+#ifndef SRTP_NO_AES192
+ status = crypto_kernel_load_cipher_type(&aes_icm_192, AES_192_ICM);
+ if (status) {
+ return status;
+ }
+#endif
+ status = crypto_kernel_load_cipher_type(&aes_icm_256, AES_256_ICM);
+ if (status) {
+ return status;
+ }
status = crypto_kernel_load_cipher_type(&aes_gcm_128_openssl, AES_128_GCM);
if (status) {
return status;
diff --git a/chromium/third_party/libsrtp/srtp/include/srtp.h b/chromium/third_party/libsrtp/srtp/include/srtp.h
index 81af5198a6c..b9bf1eb3745 100644
--- a/chromium/third_party/libsrtp/srtp/include/srtp.h
+++ b/chromium/third_party/libsrtp/srtp/include/srtp.h
@@ -242,6 +242,8 @@ typedef struct srtp_policy_t {
* transmissions must have the same RTP
* payload, or a severe security weakness
* is introduced!) */
+ int *enc_xtn_hdr; /**< List of header ids to encrypt. */
+ int enc_xtn_hdr_count; /**< Number of entries in list of header ids. */
struct srtp_policy_t *next; /**< Pointer to next stream policy. */
} srtp_policy_t;
diff --git a/chromium/third_party/libsrtp/srtp/include/srtp_priv.h b/chromium/third_party/libsrtp/srtp/include/srtp_priv.h
index 170df5b1701..540ed08a901 100644
--- a/chromium/third_party/libsrtp/srtp/include/srtp_priv.h
+++ b/chromium/third_party/libsrtp/srtp/include/srtp_priv.h
@@ -219,6 +219,7 @@ typedef enum direction_t {
typedef struct srtp_stream_ctx_t {
uint32_t ssrc;
cipher_t *rtp_cipher;
+ cipher_t *rtp_xtn_hdr_cipher;
auth_t *rtp_auth;
rdbx_t rtp_rdbx;
sec_serv_t rtp_services;
@@ -232,6 +233,8 @@ typedef struct srtp_stream_ctx_t {
ekt_stream_t ekt;
uint8_t salt[SRTP_AEAD_SALT_LEN]; /* used with GCM mode for SRTP */
uint8_t c_salt[SRTP_AEAD_SALT_LEN]; /* used with GCM mode for SRTCP */
+ int *enc_xtn_hdr;
+ int enc_xtn_hdr_count;
struct srtp_stream_ctx_t *next; /* linked list of streams */
} srtp_stream_ctx_t;
diff --git a/chromium/third_party/libsrtp/srtp/srtp/srtp.c b/chromium/third_party/libsrtp/srtp/srtp/srtp.c
index 36a450055bc..c6743fa66f6 100644
--- a/chromium/third_party/libsrtp/srtp/srtp/srtp.c
+++ b/chromium/third_party/libsrtp/srtp/srtp/srtp.c
@@ -229,6 +229,61 @@ srtp_stream_alloc(srtp_stream_ctx_t **str_ptr,
return stat;
}
+ if (p->enc_xtn_hdr && p->enc_xtn_hdr_count > 0) {
+ cipher_type_id_t enc_xtn_hdr_cipher_type;
+ int enc_xtn_hdr_cipher_key_len;
+
+ str->enc_xtn_hdr = (int*) crypto_alloc(p->enc_xtn_hdr_count * sizeof(p->enc_xtn_hdr[0]));
+ if (!str->enc_xtn_hdr) {
+ auth_dealloc(str->rtcp_auth);
+ cipher_dealloc(str->rtcp_cipher);
+ auth_dealloc(str->rtp_auth);
+ cipher_dealloc(str->rtp_cipher);
+ crypto_free(str->limit);
+ crypto_free(str);
+ return err_status_alloc_fail;
+ }
+ memcpy(str->enc_xtn_hdr, p->enc_xtn_hdr, p->enc_xtn_hdr_count * sizeof(p->enc_xtn_hdr[0]));
+ str->enc_xtn_hdr_count = p->enc_xtn_hdr_count;
+
+ /* For GCM ciphers, the corresponding ICM cipher is used for header extensions encryption. */
+ switch (p->rtp.cipher_type) {
+ case AES_128_GCM:
+ enc_xtn_hdr_cipher_type = AES_128_ICM;
+ enc_xtn_hdr_cipher_key_len = 30;
+ break;
+ case AES_256_GCM:
+ enc_xtn_hdr_cipher_type = AES_256_ICM;
+ enc_xtn_hdr_cipher_key_len = 46;
+ break;
+ default:
+ enc_xtn_hdr_cipher_type = p->rtp.cipher_type;
+ enc_xtn_hdr_cipher_key_len = p->rtp.cipher_key_len;
+ break;
+ }
+
+ /* allocate cipher for extensions header encryption */
+ stat = crypto_kernel_alloc_cipher(enc_xtn_hdr_cipher_type,
+ &str->rtp_xtn_hdr_cipher,
+ enc_xtn_hdr_cipher_key_len,
+ 0);
+
+ if (stat) {
+ crypto_free(str->enc_xtn_hdr);
+ auth_dealloc(str->rtcp_auth);
+ cipher_dealloc(str->rtcp_cipher);
+ auth_dealloc(str->rtp_auth);
+ cipher_dealloc(str->rtp_cipher);
+ crypto_free(str->limit);
+ crypto_free(str);
+ return stat;
+ }
+ } else {
+ str->rtp_xtn_hdr_cipher = NULL;
+ str->enc_xtn_hdr = NULL;
+ str->enc_xtn_hdr_count = 0;
+ }
+
return err_status_ok;
}
@@ -270,6 +325,15 @@ srtp_stream_dealloc(srtp_t session, srtp_stream_ctx_t *stream) {
crypto_free(stream->limit);
}
+ if (session->stream_template
+ && stream->rtp_xtn_hdr_cipher == session->stream_template->rtp_xtn_hdr_cipher) {
+ /* do nothing */
+ } else if (stream->rtp_xtn_hdr_cipher) {
+ status = cipher_dealloc(stream->rtp_xtn_hdr_cipher);
+ if (status)
+ return status;
+ }
+
/*
* deallocate rtcp cipher, if it is not the same as that in
* template
@@ -302,6 +366,13 @@ srtp_stream_dealloc(srtp_t session, srtp_stream_ctx_t *stream) {
/* DAM - need to deallocate EKT here */
+ if (session->stream_template
+ && stream->enc_xtn_hdr == session->stream_template->enc_xtn_hdr) {
+ /* do nothing */
+ } else if (stream->enc_xtn_hdr) {
+ crypto_free(stream->enc_xtn_hdr);
+ }
+
/*
* zeroize the salt value
*/
@@ -342,6 +413,7 @@ srtp_stream_clone(const srtp_stream_ctx_t *stream_template,
/* set cipher and auth pointers to those of the template */
str->rtp_cipher = stream_template->rtp_cipher;
str->rtp_auth = stream_template->rtp_auth;
+ str->rtp_xtn_hdr_cipher = stream_template->rtp_xtn_hdr_cipher;
str->rtcp_cipher = stream_template->rtcp_cipher;
str->rtcp_auth = stream_template->rtcp_auth;
@@ -375,6 +447,10 @@ srtp_stream_clone(const srtp_stream_ctx_t *stream_template,
/* set pointer to EKT data associated with stream */
str->ekt = stream_template->ekt;
+ /* copy information about extensions header encryption */
+ str->enc_xtn_hdr = stream_template->enc_xtn_hdr;
+ str->enc_xtn_hdr_count = stream_template->enc_xtn_hdr_count;
+
/* Copy the salt values */
memcpy(str->salt, stream_template->salt, SRTP_AEAD_SALT_LEN);
memcpy(str->c_salt, stream_template->c_salt, SRTP_AEAD_SALT_LEN);
@@ -408,7 +484,9 @@ typedef enum {
label_rtp_salt = 0x02,
label_rtcp_encryption = 0x03,
label_rtcp_msg_auth = 0x04,
- label_rtcp_salt = 0x05
+ label_rtcp_salt = 0x05,
+ label_rtp_header_encryption = 0x06,
+ label_rtp_header_salt = 0x07
} srtp_prf_label;
@@ -593,6 +671,88 @@ srtp_stream_init_keys(srtp_stream_ctx_t *srtp, const void *key) {
return err_status_init_fail;
}
+ if (srtp->rtp_xtn_hdr_cipher) {
+ /* generate extensions header encryption key */
+ int rtp_xtn_hdr_keylen;
+ int rtp_xtn_hdr_base_key_len;
+ int rtp_xtn_hdr_salt_len;
+ srtp_kdf_t tmp_kdf;
+ srtp_kdf_t *xtn_hdr_kdf;
+
+ if (srtp->rtp_xtn_hdr_cipher->type != srtp->rtp_cipher->type) {
+ /* With GCM ciphers, the header extensions are still encrypted using the corresponding ICM cipher. */
+ /* See https://tools.ietf.org/html/draft-ietf-avtcore-srtp-aes-gcm-17#section-8.3 */
+ uint8_t tmp_xtn_hdr_key[MAX_SRTP_KEY_LEN];
+ rtp_xtn_hdr_keylen = cipher_get_key_length(srtp->rtp_xtn_hdr_cipher);
+ rtp_xtn_hdr_base_key_len = base_key_length(srtp->rtp_xtn_hdr_cipher->type, rtp_xtn_hdr_keylen);
+ rtp_xtn_hdr_salt_len = rtp_xtn_hdr_keylen - rtp_xtn_hdr_base_key_len;
+ memset(tmp_xtn_hdr_key, 0x0, MAX_SRTP_KEY_LEN);
+ memcpy(tmp_xtn_hdr_key, key, (rtp_xtn_hdr_base_key_len + rtp_xtn_hdr_salt_len));
+ xtn_hdr_kdf = &tmp_kdf;
+
+ /* initialize KDF state */
+ stat = srtp_kdf_init(xtn_hdr_kdf, AES_ICM, (const uint8_t *)tmp_xtn_hdr_key, kdf_keylen);
+ octet_string_set_to_zero(tmp_xtn_hdr_key, MAX_SRTP_KEY_LEN);
+ if (stat) {
+ return err_status_init_fail;
+ }
+ } else {
+ /* Reuse main KDF. */
+ rtp_xtn_hdr_keylen = rtp_keylen;
+ rtp_xtn_hdr_base_key_len = rtp_base_key_len;
+ rtp_xtn_hdr_salt_len = rtp_salt_len;
+ xtn_hdr_kdf = &kdf;
+ }
+
+ stat = srtp_kdf_generate(xtn_hdr_kdf, label_rtp_header_encryption,
+ tmp_key, rtp_xtn_hdr_base_key_len);
+ if (stat) {
+ /* zeroize temp buffer */
+ octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
+ return err_status_init_fail;
+ }
+ debug_print(mod_srtp, "extensions cipher key: %s",
+ octet_string_hex_string(tmp_key, rtp_xtn_hdr_base_key_len));
+
+ /*
+ * if the cipher in the srtp context uses a salt, then we need
+ * to generate the salt value
+ */
+ if (rtp_xtn_hdr_salt_len > 0) {
+ debug_print(mod_srtp, "found rtp_xtn_hdr_salt_len > 0, generating salt", NULL);
+
+ /* generate encryption salt, put after encryption key */
+ stat = srtp_kdf_generate(xtn_hdr_kdf, label_rtp_header_salt,
+ tmp_key + rtp_xtn_hdr_base_key_len, rtp_xtn_hdr_salt_len);
+ if (stat) {
+ /* zeroize temp buffer */
+ octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
+ return err_status_init_fail;
+ }
+ }
+ if (rtp_xtn_hdr_salt_len > 0) {
+ debug_print(mod_srtp, "extensions cipher salt: %s",
+ octet_string_hex_string(tmp_key + rtp_xtn_hdr_base_key_len, rtp_xtn_hdr_salt_len));
+ }
+
+ /* initialize extensions header cipher */
+ stat = cipher_init(srtp->rtp_xtn_hdr_cipher, tmp_key);
+ if (stat) {
+ /* zeroize temp buffer */
+ octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
+ return err_status_init_fail;
+ }
+
+ if (xtn_hdr_kdf != &kdf) {
+ /* release memory for custom header extension encryption kdf */
+ stat = srtp_kdf_clear(xtn_hdr_kdf);
+ if (stat) {
+ octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
+ return err_status_init_fail;
+ }
+ }
+ }
+
/* generate authentication key */
stat = srtp_kdf_generate(&kdf, label_rtp_msg_auth,
tmp_key, auth_get_key_length(srtp->rtp_auth));
@@ -829,6 +989,119 @@ srtp_stream_init(srtp_stream_ctx_t *srtp,
return err_status_ok;
}
+
+/*
+ * Check if the given extension header id is / should be encrypted.
+ * Returns 1 if yes, otherwise 0.
+ */
+static int
+srtp_protect_extension_header(srtp_stream_ctx_t *stream, int id) {
+ int* enc_xtn_hdr = stream->enc_xtn_hdr;
+ int count = stream->enc_xtn_hdr_count;
+
+ if (!enc_xtn_hdr || count <= 0) {
+ return 0;
+ }
+
+ while (count > 0) {
+ if (*enc_xtn_hdr == id) {
+ return 1;
+ }
+
+ enc_xtn_hdr++;
+ count--;
+ }
+ return 0;
+}
+
+
+/*
++ * extensions header encryption RFC 6904
+ */
+static err_status_t
+srtp_process_header_encryption(srtp_stream_ctx_t *stream, srtp_hdr_xtnd_t *xtn_hdr) {
+ err_status_t status;
+ uint8_t keystream[257]; /* Maximum 2 bytes header + 255 bytes data. */
+ int keystream_pos;
+ uint8_t* xtn_hdr_data = ((uint8_t *)xtn_hdr) + octets_in_rtp_extn_hdr;
+ uint8_t* xtn_hdr_end = xtn_hdr_data + (ntohs(xtn_hdr->length) * sizeof(uint32_t));
+
+ if (ntohs(xtn_hdr->profile_specific) == 0xbede) {
+ /* RFC 5285, section 4.2. One-Byte Header */
+ while (xtn_hdr_data < xtn_hdr_end) {
+ uint8_t xid = (*xtn_hdr_data & 0xf0) >> 4;
+ unsigned int xlen = (*xtn_hdr_data & 0x0f) + 1;
+ uint32_t xlen_with_header = 1+xlen;
+ xtn_hdr_data++;
+
+ if (xtn_hdr_data + xlen > xtn_hdr_end)
+ return err_status_parse_err;
+
+ if (xid == 15) {
+ /* found header 15, stop further processing. */
+ break;
+ }
+
+ status = cipher_output(stream->rtp_xtn_hdr_cipher, keystream, xlen_with_header);
+ if (status)
+ return err_status_cipher_fail;
+
+ if (srtp_protect_extension_header(stream, xid)) {
+ keystream_pos = 1;
+ while (xlen > 0) {
+ *xtn_hdr_data ^= keystream[keystream_pos++];
+ xtn_hdr_data++;
+ xlen--;
+ }
+ } else {
+ xtn_hdr_data += xlen;
+ }
+
+ /* skip padding bytes. */
+ while (xtn_hdr_data < xtn_hdr_end && *xtn_hdr_data == 0) {
+ xtn_hdr_data++;
+ }
+ }
+ } else if ((ntohs(xtn_hdr->profile_specific) & 0x1fff) == 0x100) {
+ /* RFC 5285, section 4.3. Two-Byte Header */
+ while (xtn_hdr_data + 1 < xtn_hdr_end) {
+ uint8_t xid = *xtn_hdr_data;
+ unsigned int xlen = *(xtn_hdr_data+1);
+ uint32_t xlen_with_header = 2+xlen;
+ xtn_hdr_data += 2;
+
+ if (xtn_hdr_data + xlen > xtn_hdr_end)
+ return err_status_parse_err;
+
+ status = cipher_output(stream->rtp_xtn_hdr_cipher, keystream, xlen_with_header);
+ if (status)
+ return err_status_cipher_fail;
+
+ if (xlen > 0 && srtp_protect_extension_header(stream, xid)) {
+ keystream_pos = 2;
+ while (xlen > 0) {
+ *xtn_hdr_data ^= keystream[keystream_pos++];
+ xtn_hdr_data++;
+ xlen--;
+ }
+ } else {
+ xtn_hdr_data += xlen;
+ }
+
+ /* skip padding bytes. */
+ while (xtn_hdr_data < xtn_hdr_end && *xtn_hdr_data == 0) {
+ xtn_hdr_data++;
+ }
+ }
+ } else {
+ /* unsupported extension header format. */
+ return err_status_parse_err;
+ }
+
+ return err_status_ok;
+}
+
+
/*
* AEAD uses a new IV formation method. This function implements
* section 9.1 from draft-ietf-avtcore-srtp-aes-gcm-07.txt. The
@@ -916,6 +1189,7 @@ srtp_protect_aead (srtp_ctx_t *ctx, srtp_stream_ctx_t *stream,
int tag_len;
v128_t iv;
unsigned int aad_len;
+ srtp_hdr_xtnd_t *xtn_hdr = NULL;
debug_print(mod_srtp, "function srtp_protect_aead", NULL);
@@ -947,7 +1221,7 @@ srtp_protect_aead (srtp_ctx_t *ctx, srtp_stream_ctx_t *stream,
*/
enc_start = (uint32_t*)hdr + uint32s_in_rtp_header + hdr->cc;
if (hdr->x == 1) {
- srtp_hdr_xtnd_t *xtn_hdr = (srtp_hdr_xtnd_t*)enc_start;
+ xtn_hdr = (srtp_hdr_xtnd_t*)enc_start;
enc_start += (ntohs(xtn_hdr->length) + 1);
}
if (!((uint8_t*)enc_start <= (uint8_t*)hdr + *pkt_octet_len))
@@ -980,10 +1254,6 @@ srtp_protect_aead (srtp_ctx_t *ctx, srtp_stream_ctx_t *stream,
* AEAD uses a new IV formation method
*/
srtp_calc_aead_iv(stream, &iv, &est, hdr);
- status = cipher_set_iv(stream->rtp_cipher, &iv, direction_encrypt);
- if (status) {
- return err_status_cipher_fail;
- }
/* shift est, put into network byte order */
#ifdef NO_64BIT_MATH
@@ -994,6 +1264,27 @@ srtp_protect_aead (srtp_ctx_t *ctx, srtp_stream_ctx_t *stream,
est = be64_to_cpu(est << 16);
#endif
+ status = cipher_set_iv(stream->rtp_cipher, &iv, direction_encrypt);
+ if (!status && stream->rtp_xtn_hdr_cipher) {
+ iv.v32[0] = 0;
+ iv.v32[1] = hdr->ssrc;
+ iv.v64[1] = est;
+ status = cipher_set_iv(stream->rtp_xtn_hdr_cipher, (uint8_t*)&iv, direction_encrypt);
+ }
+ if (status) {
+ return err_status_cipher_fail;
+ }
+
+ if (xtn_hdr && stream->rtp_xtn_hdr_cipher) {
+ /*
+ * extensions header encryption RFC 6904
+ */
+ status = srtp_process_header_encryption(stream, xtn_hdr);
+ if (status) {
+ return status;
+ }
+ }
+
/*
* Set the AAD over the RTP header
*/
@@ -1045,6 +1336,7 @@ srtp_unprotect_aead (srtp_ctx_t *ctx, srtp_stream_ctx_t *stream, int delta,
err_status_t status;
int tag_len;
unsigned int aad_len;
+ srtp_hdr_xtnd_t *xtn_hdr = NULL;
debug_print(mod_srtp, "function srtp_unprotect_aead", NULL);
@@ -1074,7 +1366,7 @@ srtp_unprotect_aead (srtp_ctx_t *ctx, srtp_stream_ctx_t *stream, int delta,
*/
enc_start = (uint32_t*)hdr + uint32s_in_rtp_header + hdr->cc;
if (hdr->x == 1) {
- srtp_hdr_xtnd_t *xtn_hdr = (srtp_hdr_xtnd_t*)enc_start;
+ xtn_hdr = (srtp_hdr_xtnd_t*)enc_start;
enc_start += (ntohs(xtn_hdr->length) + 1);
}
if (!((uint8_t*)enc_start <= (uint8_t*)hdr + (*pkt_octet_len - tag_len)))
@@ -1117,6 +1409,17 @@ srtp_unprotect_aead (srtp_ctx_t *ctx, srtp_stream_ctx_t *stream, int delta,
*/
aad_len = (uint8_t *)enc_start - (uint8_t *)hdr;
status = cipher_set_aad(stream->rtp_cipher, (uint8_t*)hdr, aad_len);
+ if (!status && stream->rtp_xtn_hdr_cipher) {
+ iv.v32[0] = 0;
+ iv.v32[1] = hdr->ssrc;
+#ifdef NO_64BIT_MATH
+ iv.v64[1] = be64_to_cpu(make64((high32(est) << 16) | (low32(est) >> 16),
+ low32(est) << 16));
+#else
+ iv.v64[1] = be64_to_cpu(est << 16);
+#endif
+ status = cipher_set_iv(stream->rtp_xtn_hdr_cipher, (uint8_t*)&iv, direction_encrypt);
+ }
if (status) {
return ( err_status_cipher_fail);
}
@@ -1129,6 +1432,16 @@ srtp_unprotect_aead (srtp_ctx_t *ctx, srtp_stream_ctx_t *stream, int delta,
return status;
}
+ if (xtn_hdr && stream->rtp_xtn_hdr_cipher) {
+ /*
+ * extensions header encryption RFC 6904
+ */
+ status = srtp_process_header_encryption(stream, xtn_hdr);
+ if (status) {
+ return status;
+ }
+ }
+
/*
* verify that stream is for received traffic - this check will
* detect SSRC collisions, since a stream that appears in both
@@ -1203,6 +1516,7 @@ srtp_unprotect_aead (srtp_ctx_t *ctx, srtp_stream_ctx_t *stream, int delta,
int tag_len;
srtp_stream_ctx_t *stream;
int prefix_len;
+ srtp_hdr_xtnd_t *xtn_hdr = NULL;
debug_print(mod_srtp, "function srtp_protect", NULL);
@@ -1305,7 +1619,7 @@ srtp_unprotect_aead (srtp_ctx_t *ctx, srtp_stream_ctx_t *stream, int delta,
if (stream->rtp_services & sec_serv_conf) {
enc_start = (uint32_t *)hdr + uint32s_in_rtp_header + hdr->cc;
if (hdr->x == 1) {
- srtp_hdr_xtnd_t *xtn_hdr = (srtp_hdr_xtnd_t *)enc_start;
+ xtn_hdr = (srtp_hdr_xtnd_t *)enc_start;
enc_start += (ntohs(xtn_hdr->length) + 1);
}
if (!((uint8_t*)enc_start <= (uint8_t*)hdr + *pkt_octet_len))
@@ -1365,7 +1679,9 @@ srtp_unprotect_aead (srtp_ctx_t *ctx, srtp_stream_ctx_t *stream, int delta,
iv.v64[1] = be64_to_cpu(est << 16);
#endif
status = cipher_set_iv(stream->rtp_cipher, &iv, direction_encrypt);
-
+ if (!status && stream->rtp_xtn_hdr_cipher) {
+ status = cipher_set_iv(stream->rtp_xtn_hdr_cipher, (uint8_t*)&iv, direction_encrypt);
+ }
} else {
v128_t iv;
@@ -1378,6 +1694,9 @@ srtp_unprotect_aead (srtp_ctx_t *ctx, srtp_stream_ctx_t *stream, int delta,
#endif
iv.v64[1] = be64_to_cpu(est);
status = cipher_set_iv(stream->rtp_cipher, &iv, direction_encrypt);
+ if (!status && stream->rtp_xtn_hdr_cipher) {
+ status = cipher_set_iv(stream->rtp_xtn_hdr_cipher, (uint8_t*)&iv, direction_encrypt);
+ }
}
if (status)
return err_status_cipher_fail;
@@ -1407,6 +1726,16 @@ srtp_unprotect_aead (srtp_ctx_t *ctx, srtp_stream_ctx_t *stream, int delta,
}
}
+ if (xtn_hdr && stream->rtp_xtn_hdr_cipher) {
+ /*
+ * extensions header encryption RFC 6904
+ */
+ status = srtp_process_header_encryption(stream, xtn_hdr);
+ if (status) {
+ return status;
+ }
+ }
+
/* if we're encrypting, exor keystream into the message */
if (enc_start) {
status = cipher_encrypt(stream->rtp_cipher,
@@ -1464,6 +1793,7 @@ srtp_unprotect(srtp_ctx_t *ctx, void *srtp_hdr, int *pkt_octet_len) {
srtp_stream_ctx_t *stream;
uint8_t tmp_tag[SRTP_MAX_TAG_LEN];
int tag_len, prefix_len;
+ srtp_hdr_xtnd_t *xtn_hdr = NULL;
debug_print(mod_srtp, "function srtp_unprotect", NULL);
@@ -1557,6 +1887,9 @@ srtp_unprotect(srtp_ctx_t *ctx, void *srtp_hdr, int *pkt_octet_len) {
iv.v64[1] = be64_to_cpu(est << 16);
#endif
status = cipher_set_iv(stream->rtp_cipher, &iv, direction_decrypt);
+ if (!status && stream->rtp_xtn_hdr_cipher) {
+ status = cipher_set_iv(stream->rtp_xtn_hdr_cipher, (uint8_t*)&iv, direction_decrypt);
+ }
} else {
/* no particular format - set the iv to the pakcet index */
@@ -1568,6 +1901,9 @@ srtp_unprotect(srtp_ctx_t *ctx, void *srtp_hdr, int *pkt_octet_len) {
#endif
iv.v64[1] = be64_to_cpu(est);
status = cipher_set_iv(stream->rtp_cipher, &iv, direction_decrypt);
+ if (!status && stream->rtp_xtn_hdr_cipher) {
+ status = cipher_set_iv(stream->rtp_xtn_hdr_cipher, (uint8_t*)&iv, direction_decrypt);
+ }
}
if (status)
return err_status_cipher_fail;
@@ -1592,7 +1928,7 @@ srtp_unprotect(srtp_ctx_t *ctx, void *srtp_hdr, int *pkt_octet_len) {
if (stream->rtp_services & sec_serv_conf) {
enc_start = (uint32_t *)hdr + uint32s_in_rtp_header + hdr->cc;
if (hdr->x == 1) {
- srtp_hdr_xtnd_t *xtn_hdr = (srtp_hdr_xtnd_t *)enc_start;
+ xtn_hdr = (srtp_hdr_xtnd_t *)enc_start;
enc_start += (ntohs(xtn_hdr->length) + 1);
}
if (!((uint8_t*)enc_start <= (uint8_t*)hdr + (*pkt_octet_len - tag_len)))
@@ -1679,6 +2015,16 @@ srtp_unprotect(srtp_ctx_t *ctx, void *srtp_hdr, int *pkt_octet_len) {
break;
}
+ if (xtn_hdr && stream->rtp_xtn_hdr_cipher) {
+ /*
+ * extensions header encryption RFC 6904
+ */
+ status = srtp_process_header_encryption(stream, xtn_hdr);
+ if (status) {
+ return status;
+ }
+ }
+
/* if we're decrypting, add keystream into ciphertext */
if (enc_start) {
status = cipher_decrypt(stream->rtp_cipher,