[Build-System] Update libsrtp to 2.4.0

This commit is contained in:
Andrey Volk committed 2021-08-28 23:54:38 +03:00
1 parent 641fcd2b26
commit bddff9a2f1
95 files changed
+5998 -3870

No files matched your search

-281
View File
@@ -1,281 +0,0 @@
/*
* ekt.c
*
* Encrypted Key Transport for SRTP
*
* David McGrew
* Cisco Systems, Inc.
*/
/*
*
* Copyright (c) 2001-2017 Cisco Systems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* Neither the name of the Cisco Systems, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "srtp_priv.h"
#include "err.h"
#include "ekt.h"
extern srtp_debug_module_t mod_srtp;
/*
* The EKT Authentication Tag format.
*
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* : Base Authentication Tag :
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* : Encrypted Master Key :
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Rollover Counter |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Initial Sequence Number | Security Parameter Index |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*
*/
#define EKT_OCTETS_AFTER_BASE_TAG 24
#define EKT_OCTETS_AFTER_EMK 8
#define EKT_OCTETS_AFTER_ROC 4
#define EKT_SPI_LEN 2
unsigned srtp_ekt_octets_after_base_tag(srtp_ekt_stream_t ekt)
{
/*
* if the pointer ekt is NULL, then EKT is not in effect, so we
* indicate this by returning zero
*/
if (!ekt)
return 0;
switch (ekt->data->ekt_cipher_type) {
case SRTP_EKT_CIPHER_AES_128_ECB:
return 16 + EKT_OCTETS_AFTER_EMK;
break;
default:
break;
}
return 0;
}
static inline srtp_ekt_spi_t srtcp_packet_get_ekt_spi(
const uint8_t *packet_start,
unsigned pkt_octet_len)
{
const uint8_t *spi_location;
spi_location = packet_start + (pkt_octet_len - EKT_SPI_LEN);
return *((const srtp_ekt_spi_t *)spi_location);
}
static inline uint32_t srtcp_packet_get_ekt_roc(const uint8_t *packet_start,
unsigned pkt_octet_len)
{
const uint8_t *roc_location;
roc_location = packet_start + (pkt_octet_len - EKT_OCTETS_AFTER_ROC);
return *((const uint32_t *)roc_location);
}
static inline const uint8_t *srtcp_packet_get_emk_location(
const uint8_t *packet_start,
unsigned pkt_octet_len)
{
const uint8_t *location;
location = packet_start + (pkt_octet_len - EKT_OCTETS_AFTER_BASE_TAG);
return location;
}
srtp_err_status_t srtp_ekt_alloc(srtp_ekt_stream_t *stream_data,
srtp_ekt_policy_t policy)
{
/*
* if the policy pointer is NULL, then EKT is not in use
* so we just set the EKT stream data pointer to NULL
*/
if (!policy) {
*stream_data = NULL;
return srtp_err_status_ok;
}
/* TODO */
*stream_data = NULL;
return srtp_err_status_ok;
}
srtp_err_status_t srtp_ekt_stream_init_from_policy(
srtp_ekt_stream_t stream_data,
srtp_ekt_policy_t policy)
{
if (!stream_data)
return srtp_err_status_ok;
return srtp_err_status_ok;
}
void aes_decrypt_with_raw_key(void *ciphertext, const void *key, int key_len)
{
#ifndef OPENSSL
// FIXME: need to get this working through the crypto module interface
srtp_aes_expanded_key_t expanded_key;
srtp_aes_expand_decryption_key(key, key_len, &expanded_key);
srtp_aes_decrypt(ciphertext, &expanded_key);
#endif
}
/*
* The function srtp_stream_init_from_ekt() initializes a stream using
* the EKT data from an SRTCP trailer.
*/
srtp_err_status_t srtp_stream_init_from_ekt(srtp_stream_t stream,
const void *srtcp_hdr,
unsigned pkt_octet_len)
{
srtp_err_status_t err;
const uint8_t *master_key;
srtp_policy_t srtp_policy;
uint32_t roc;
/*
* NOTE: at present, we only support a single ekt_policy at a time.
*/
if (stream->ekt->data->spi !=
srtcp_packet_get_ekt_spi(srtcp_hdr, pkt_octet_len))
return srtp_err_status_no_ctx;
if (stream->ekt->data->ekt_cipher_type != SRTP_EKT_CIPHER_AES_128_ECB)
return srtp_err_status_bad_param;
/* decrypt the Encrypted Master Key field */
master_key = srtcp_packet_get_emk_location(srtcp_hdr, pkt_octet_len);
/* FIX!? This decrypts the master key in-place, and never uses it */
/* FIX!? It's also passing to ekt_dec_key (which is an aes_expanded_key_t)
* to a function which expects a raw (unexpanded) key */
aes_decrypt_with_raw_key((void *)master_key,
&stream->ekt->data->ekt_dec_key, 16);
/* set the SRTP ROC */
roc = srtcp_packet_get_ekt_roc(srtcp_hdr, pkt_octet_len);
err = srtp_rdbx_set_roc(&stream->rtp_rdbx, roc);
if (err)
return err;
err = srtp_stream_init(stream, &srtp_policy);
if (err)
return err;
return srtp_err_status_ok;
}
void srtp_ekt_write_data(srtp_ekt_stream_t ekt,
uint8_t *base_tag,
unsigned base_tag_len,
int *packet_len,
srtp_xtd_seq_num_t pkt_index)
{
uint32_t roc;
uint16_t isn;
unsigned emk_len;
uint8_t *packet;
/* if the pointer ekt is NULL, then EKT is not in effect */
if (!ekt) {
debug_print(mod_srtp, "EKT not in use", NULL);
return;
}
/* write zeros into the location of the base tag */
octet_string_set_to_zero(base_tag, base_tag_len);
packet = base_tag + base_tag_len;
/* copy encrypted master key into packet */
emk_len = srtp_ekt_octets_after_base_tag(ekt);
memcpy(packet, ekt->encrypted_master_key, emk_len);
debug_print(mod_srtp, "writing EKT EMK: %s,",
srtp_octet_string_hex_string(packet, emk_len));
packet += emk_len;
/* copy ROC into packet */
roc = (uint32_t)(pkt_index >> 16);
*((uint32_t *)packet) = be32_to_cpu(roc);
debug_print(mod_srtp, "writing EKT ROC: %s,",
srtp_octet_string_hex_string(packet, sizeof(roc)));
packet += sizeof(roc);
/* copy ISN into packet */
isn = (uint16_t)pkt_index;
*((uint16_t *)packet) = htons(isn);
debug_print(mod_srtp, "writing EKT ISN: %s,",
srtp_octet_string_hex_string(packet, sizeof(isn)));
packet += sizeof(isn);
/* copy SPI into packet */
*((uint16_t *)packet) = htons(ekt->data->spi);
debug_print(mod_srtp, "writing EKT SPI: %s,",
srtp_octet_string_hex_string(packet, sizeof(ekt->data->spi)));
/* increase packet length appropriately */
*packet_len += EKT_OCTETS_AFTER_EMK + emk_len;
}
/*
* The function call srtcp_ekt_trailer(ekt, auth_len, auth_tag )
*
* If the pointer ekt is NULL, then the other inputs are unaffected.
*
* auth_tag is a pointer to the pointer to the location of the
* authentication tag in the packet. If EKT is in effect, then the
* auth_tag pointer is set to the location
*/
void srtcp_ekt_trailer(srtp_ekt_stream_t ekt,
unsigned *auth_len,
void **auth_tag,
void *tag_copy)
{
/*
* if there is no EKT policy, then the other inputs are unaffected
*/
if (!ekt)
return;
/* copy auth_tag into temporary location */
}
+124 -163
View File
@@ -48,15 +48,15 @@
#include "srtp_priv.h"
#include "crypto_types.h"
#include "err.h"
#include "ekt.h" /* for SRTP Encrypted Key Transport */
#include "alloc.h" /* for srtp_crypto_alloc() */
#ifdef OPENSSL
#include "aes_gcm_ossl.h" /* for AES GCM mode */
#ifdef GCM
#include "aes_gcm.h" /* for AES GCM mode */
#endif
#ifdef OPENSSL_KDF
#include <openssl/kdf.h>
#include "aes_icm_ossl.h" /* for AES GCM mode */
#endif
#include "aes_icm_ext.h"
#endif
#include <limits.h>
@@ -81,13 +81,14 @@ srtp_debug_module_t mod_srtp = {
static srtp_err_status_t srtp_validate_rtp_header(void *rtp_hdr,
int *pkt_octet_len)
{
srtp_hdr_t *hdr = (srtp_hdr_t *)rtp_hdr;
int rtp_header_len;
if (*pkt_octet_len < octets_in_rtp_header)
return srtp_err_status_bad_param;
srtp_hdr_t *hdr = (srtp_hdr_t *)rtp_hdr;
/* Check RTP header length */
int rtp_header_len = octets_in_rtp_header + 4 * hdr->cc;
rtp_header_len = octets_in_rtp_header + 4 * hdr->cc;
if (hdr->x == 1)
rtp_header_len += octets_in_rtp_extn_hdr;
@@ -264,8 +265,6 @@ srtp_err_status_t srtp_stream_dealloc(srtp_stream_ctx_t *stream,
if (status)
return status;
/* DAM - need to deallocate EKT here */
if (stream_template &&
stream->enc_xtn_hdr == stream_template->enc_xtn_hdr) {
/* do nothing */
@@ -279,6 +278,15 @@ srtp_err_status_t srtp_stream_dealloc(srtp_stream_ctx_t *stream,
return srtp_err_status_ok;
}
static srtp_err_status_t srtp_valid_policy(const srtp_policy_t *p)
{
if (p != NULL && p->deprecated_ekt != NULL) {
return srtp_err_status_bad_param;
}
return srtp_err_status_ok;
}
srtp_err_status_t srtp_stream_alloc(srtp_stream_ctx_t **str_ptr,
const srtp_policy_t *p)
{
@@ -287,6 +295,11 @@ srtp_err_status_t srtp_stream_alloc(srtp_stream_ctx_t **str_ptr,
unsigned int i = 0;
srtp_session_keys_t *session_keys = NULL;
stat = srtp_valid_policy(p);
if (stat != srtp_err_status_ok) {
return stat;
}
/*
* This function allocates the stream context, rtp and rtcp ciphers
* and auth functions, and key limit structure. If there is a
@@ -373,13 +386,6 @@ srtp_err_status_t srtp_stream_alloc(srtp_stream_ctx_t **str_ptr,
}
}
/* allocate ekt data associated with stream */
stat = srtp_ekt_alloc(&str->ekt, p->ekt);
if (stat) {
srtp_stream_dealloc(str, NULL);
return stat;
}
if (p->enc_xtn_hdr && p->enc_xtn_hdr_count > 0) {
srtp_cipher_type_id_t enc_xtn_hdr_cipher_type;
int enc_xtn_hdr_cipher_key_len;
@@ -539,9 +545,6 @@ srtp_err_status_t srtp_stream_clone(const srtp_stream_ctx_t *stream_template,
str->rtp_services = stream_template->rtp_services;
str->rtcp_services = stream_template->rtcp_services;
/* 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;
@@ -677,6 +680,8 @@ static srtp_err_status_t srtp_kdf_init(srtp_kdf_t *kdf,
int key_len)
{
srtp_cipher_type_id_t cipher_id;
srtp_err_status_t stat;
switch (key_len) {
case SRTP_AES_ICM_256_KEY_LEN_WSALT:
cipher_id = SRTP_AES_ICM_256;
@@ -692,7 +697,6 @@ static srtp_err_status_t srtp_kdf_init(srtp_kdf_t *kdf,
break;
}
srtp_err_status_t stat;
stat = srtp_crypto_kernel_alloc_cipher(cipher_id, &kdf->cipher, key_len, 0);
if (stat)
return stat;
@@ -959,7 +963,7 @@ srtp_err_status_t srtp_stream_init_keys(srtp_stream_ctx_t *srtp,
* to generate the salt value
*/
if (rtp_salt_len > 0) {
debug_print(mod_srtp, "found rtp_salt_len > 0, generating salt", NULL);
debug_print0(mod_srtp, "found rtp_salt_len > 0, generating salt");
/* generate encryption salt, put after encryption key */
stat = srtp_kdf_generate(&kdf, label_rtp_salt,
@@ -1067,9 +1071,8 @@ srtp_err_status_t srtp_stream_init_keys(srtp_stream_ctx_t *srtp,
* 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);
debug_print0(mod_srtp,
"found rtp_xtn_hdr_salt_len > 0, generating salt");
/* generate encryption salt, put after encryption key */
stat = srtp_kdf_generate(xtn_hdr_kdf, label_rtp_header_salt,
@@ -1150,8 +1153,7 @@ srtp_err_status_t srtp_stream_init_keys(srtp_stream_ctx_t *srtp,
* to generate the salt value
*/
if (rtcp_salt_len > 0) {
debug_print(mod_srtp, "found rtcp_salt_len > 0, generating rtcp salt",
NULL);
debug_print0(mod_srtp, "found rtcp_salt_len > 0, generating rtcp salt");
/* generate encryption salt, put after encryption key */
stat = srtp_kdf_generate(&kdf, label_rtcp_salt,
@@ -1216,6 +1218,11 @@ srtp_err_status_t srtp_stream_init(srtp_stream_ctx_t *srtp,
{
srtp_err_status_t err;
err = srtp_valid_policy(p);
if (err != srtp_err_status_ok) {
return err;
}
debug_print(mod_srtp, "initializing stream (SSRC: 0x%08x)", p->ssrc.value);
/* initialize replay database */
@@ -1275,16 +1282,6 @@ srtp_err_status_t srtp_stream_init(srtp_stream_ctx_t *srtp,
return err;
}
/*
* if EKT is in use, then initialize the EKT data associated with
* the stream
*/
err = srtp_ekt_stream_init_from_policy(srtp->ekt, p->ekt);
if (err) {
srtp_rdbx_dealloc(&srtp->rtp_rdbx);
return err;
}
return srtp_err_status_ok;
}
@@ -1421,7 +1418,7 @@ static srtp_err_status_t srtp_process_header_encryption(
xtn_hdr_data++;
}
}
} else if ((ntohs(xtn_hdr->profile_specific) & 0x1fff) == 0x100) {
} else if ((ntohs(xtn_hdr->profile_specific) & 0xfff0) == 0x1000) {
/* RFC 5285, section 4.3. Two-Byte Header */
while (xtn_hdr_data + 1 < xtn_hdr_end) {
uint8_t xid = *xtn_hdr_data;
@@ -1667,7 +1664,7 @@ static srtp_err_status_t srtp_get_est_pkt_index(srtp_hdr_t *hdr,
debug_print2(mod_srtp, "estimated u_packet index: %08x%08x", high32(*est),
low32(*est));
#else
debug_print(mod_srtp, "estimated u_packet index: %016llx", *est);
debug_print(mod_srtp, "estimated u_packet index: %016" PRIx64, *est);
#endif
return result;
}
@@ -1697,7 +1694,7 @@ static srtp_err_status_t srtp_protect_aead(srtp_ctx_t *ctx,
unsigned int mki_size = 0;
uint8_t *mki_location = NULL;
debug_print(mod_srtp, "function srtp_protect_aead", NULL);
debug_print0(mod_srtp, "function srtp_protect_aead");
/*
* update the key usage limit, and check it to make sure that we
@@ -1756,7 +1753,7 @@ static srtp_err_status_t srtp_protect_aead(srtp_ctx_t *ctx,
debug_print2(mod_srtp, "estimated packet index: %08x%08x", high32(est),
low32(est));
#else
debug_print(mod_srtp, "estimated packet index: %016llx", est);
debug_print(mod_srtp, "estimated packet index: %016" PRIx64, est);
#endif
/*
@@ -1858,13 +1855,13 @@ static srtp_err_status_t srtp_unprotect_aead(srtp_ctx_t *ctx,
unsigned int aad_len;
srtp_hdr_xtnd_t *xtn_hdr = NULL;
debug_print(mod_srtp, "function srtp_unprotect_aead", NULL);
debug_print0(mod_srtp, "function srtp_unprotect_aead");
#ifdef NO_64BIT_MATH
debug_print2(mod_srtp, "estimated u_packet index: %08x%08x", high32(est),
low32(est));
#else
debug_print(mod_srtp, "estimated u_packet index: %016llx", est);
debug_print(mod_srtp, "estimated u_packet index: %016" PRIx64, est);
#endif
/* get tag length from stream */
@@ -2059,7 +2056,7 @@ srtp_err_status_t srtp_protect_mki(srtp_ctx_t *ctx,
uint8_t *mki_location = NULL;
int advance_packet_index = 0;
debug_print(mod_srtp, "function srtp_protect", NULL);
debug_print0(mod_srtp, "function srtp_protect");
/* we assume the hdr is 32-bit aligned to start */
@@ -2230,7 +2227,7 @@ srtp_err_status_t srtp_protect_mki(srtp_ctx_t *ctx,
debug_print2(mod_srtp, "estimated packet index: %08x%08x", high32(est),
low32(est));
#else
debug_print(mod_srtp, "estimated packet index: %016llx", est);
debug_print(mod_srtp, "estimated packet index: %016" PRIx64, est);
#endif
/*
@@ -2336,7 +2333,7 @@ srtp_err_status_t srtp_protect_mki(srtp_ctx_t *ctx,
return status;
/* run auth func over ROC, put result into auth_tag */
debug_print(mod_srtp, "estimated packet index: %016llx", est);
debug_print(mod_srtp, "estimated packet index: %016" PRIx64, est);
status = srtp_auth_compute(session_keys->rtp_auth, (uint8_t *)&est, 4,
auth_tag);
debug_print(mod_srtp, "srtp auth tag: %s",
@@ -2389,7 +2386,7 @@ srtp_err_status_t srtp_unprotect_mki(srtp_ctx_t *ctx,
uint32_t roc_to_set = 0;
uint16_t seq_to_set = 0;
debug_print(mod_srtp, "function srtp_unprotect", NULL);
debug_print0(mod_srtp, "function srtp_unprotect");
/* we assume the hdr is 32-bit aligned to start */
@@ -2458,7 +2455,7 @@ srtp_err_status_t srtp_unprotect_mki(srtp_ctx_t *ctx,
debug_print2(mod_srtp, "estimated u_packet index: %08x%08x", high32(est),
low32(est));
#else
debug_print(mod_srtp, "estimated u_packet index: %016llx", est);
debug_print(mod_srtp, "estimated u_packet index: %016" PRIx64, est);
#endif
/* Determine if MKI is being used and what session keys should be used */
@@ -2600,8 +2597,10 @@ srtp_err_status_t srtp_unprotect_mki(srtp_ctx_t *ctx,
return status;
/* now compute auth function over packet */
srtp_auth_update(session_keys->rtp_auth, (uint8_t *)auth_start,
status = srtp_auth_update(session_keys->rtp_auth, (uint8_t *)auth_start,
*pkt_octet_len - tag_len - mki_size);
if (status)
return status;
/* run auth func over ROC, then write tmp tag */
status = srtp_auth_compute(session_keys->rtp_auth, (uint8_t *)&est, 4,
@@ -2614,7 +2613,7 @@ srtp_err_status_t srtp_unprotect_mki(srtp_ctx_t *ctx,
if (status)
return srtp_err_status_auth_fail;
if (octet_string_is_eq(tmp_tag, auth_tag, tag_len))
if (srtp_octet_string_is_eq(tmp_tag, auth_tag, tag_len))
return srtp_err_status_auth_fail;
}
@@ -2750,25 +2749,6 @@ srtp_err_status_t srtp_shutdown()
return srtp_err_status_ok;
}
/*
* The following code is under consideration for removal. See
* SRTP_MAX_TRAILER_LEN
*/
#if 0
/*
* srtp_get_trailer_length(&a) returns the number of octets that will
* be added to an RTP packet by the SRTP processing. This value
* is constant for a given srtp_stream_t (i.e. between initializations).
*/
int
srtp_get_trailer_length(const srtp_stream_t s) {
return srtp_auth_get_tag_length(s->rtp_auth);
}
#endif
/*
* srtp_get_stream(ssrc) returns a pointer to the stream corresponding
* to ssrc, or NULL if no stream exists for that ssrc
@@ -2831,6 +2811,11 @@ srtp_err_status_t srtp_add_stream(srtp_t session, const srtp_policy_t *policy)
srtp_err_status_t status;
srtp_stream_t tmp;
status = srtp_valid_policy(policy);
if (status != srtp_err_status_ok) {
return status;
}
/* sanity check arguments */
if ((session == NULL) || (policy == NULL) ||
(!srtp_validate_policy_master_keys(policy)))
@@ -2893,6 +2878,11 @@ srtp_err_status_t srtp_create(srtp_t *session, /* handle for session */
srtp_err_status_t stat;
srtp_ctx_t *ctx;
stat = srtp_valid_policy(policy);
if (stat != srtp_err_status_ok) {
return stat;
}
/* sanity check arguments */
if (session == NULL)
return srtp_err_status_bad_param;
@@ -2963,6 +2953,11 @@ srtp_err_status_t srtp_update(srtp_t session, const srtp_policy_t *policy)
{
srtp_err_status_t stat;
stat = srtp_valid_policy(policy);
if (stat != srtp_err_status_ok) {
return stat;
}
/* sanity check arguments */
if ((session == NULL) || (policy == NULL) ||
(!srtp_validate_policy_master_keys(policy))) {
@@ -2988,6 +2983,11 @@ static srtp_err_status_t update_template_streams(srtp_t session,
srtp_stream_t new_stream_template;
srtp_stream_t new_stream_list = NULL;
status = srtp_valid_policy(policy);
if (status != srtp_err_status_ok) {
return status;
}
if (session->stream_template == NULL) {
return srtp_err_status_bad_param;
}
@@ -3086,6 +3086,11 @@ static srtp_err_status_t update_stream(srtp_t session,
srtp_rdb_t old_rtcp_rdb;
srtp_stream_t stream;
status = srtp_valid_policy(policy);
if (status != srtp_err_status_ok) {
return status;
}
stream = srtp_get_stream(session, htonl(policy->ssrc.value));
if (stream == NULL) {
return srtp_err_status_bad_param;
@@ -3122,6 +3127,11 @@ srtp_err_status_t srtp_update_stream(srtp_t session,
{
srtp_err_status_t status;
status = srtp_valid_policy(policy);
if (status != srtp_err_status_ok) {
return status;
}
/* sanity check arguments */
if ((session == NULL) || (policy == NULL) ||
(!srtp_validate_policy_master_keys(policy)))
@@ -3285,7 +3295,6 @@ void srtp_crypto_policy_set_aes_cm_256_null_auth(srtp_crypto_policy_t *p)
p->sec_serv = sec_serv_conf;
}
#ifdef OPENSSL
void srtp_crypto_policy_set_aes_cm_192_hmac_sha1_80(srtp_crypto_policy_t *p)
{
/*
@@ -3407,8 +3416,6 @@ void srtp_crypto_policy_set_aes_gcm_256_16_auth(srtp_crypto_policy_t *p)
p->sec_serv = sec_serv_conf_and_auth;
}
#endif
/*
* secure rtcp functions
*/
@@ -3496,7 +3503,8 @@ static srtp_err_status_t srtp_protect_rtcp_aead(
{
srtcp_hdr_t *hdr = (srtcp_hdr_t *)rtcp_hdr;
uint32_t *enc_start; /* pointer to start of encrypted portion */
uint32_t *trailer; /* pointer to start of trailer */
uint32_t *trailer_p; /* pointer to start of trailer */
uint32_t trailer; /* trailer value */
unsigned int enc_octet_len = 0; /* number of octets in encrypted portion */
uint8_t *auth_tag = NULL; /* location of auth_tag within packet */
srtp_err_status_t status;
@@ -3519,18 +3527,15 @@ static srtp_err_status_t srtp_protect_rtcp_aead(
/* NOTE: hdr->length is not usable - it refers to only the first
* RTCP report in the compound packet!
*/
/* NOTE: trailer is 32-bit aligned because RTCP 'packets' are always
* multiples of 32-bits (RFC 3550 6.1)
*/
trailer = (uint32_t *)((char *)enc_start + enc_octet_len + tag_len);
trailer_p = (uint32_t *)((char *)enc_start + enc_octet_len + tag_len);
if (stream->rtcp_services & sec_serv_conf) {
*trailer = htonl(SRTCP_E_BIT); /* set encrypt bit */
trailer = htonl(SRTCP_E_BIT); /* set encrypt bit */
} else {
enc_start = NULL;
enc_octet_len = 0;
/* 0 is network-order independant */
*trailer = 0x00000000; /* set encrypt bit */
trailer = 0x00000000; /* set encrypt bit */
}
mki_size = srtp_inject_mki((uint8_t *)hdr + *pkt_octet_len + tag_len +
@@ -3554,9 +3559,11 @@ static srtp_err_status_t srtp_protect_rtcp_aead(
return status;
}
seq_num = srtp_rdb_get_value(&stream->rtcp_rdb);
*trailer |= htonl(seq_num);
trailer |= htonl(seq_num);
debug_print(mod_srtp, "srtcp index: %x", seq_num);
memcpy(trailer_p, &trailer, sizeof(trailer));
/*
* Calculate and set the IV
*/
@@ -3598,7 +3605,7 @@ static srtp_err_status_t srtp_protect_rtcp_aead(
/*
* Process the sequence# as AAD
*/
tseq = *trailer;
tseq = trailer;
status = srtp_cipher_set_aad(session_keys->rtcp_cipher, (uint8_t *)&tseq,
sizeof(srtcp_trailer_t));
if (status) {
@@ -3667,7 +3674,8 @@ static srtp_err_status_t srtp_unprotect_rtcp_aead(
{
srtcp_hdr_t *hdr = (srtcp_hdr_t *)srtcp_hdr;
uint32_t *enc_start; /* pointer to start of encrypted portion */
uint32_t *trailer; /* pointer to start of trailer */
uint32_t *trailer_p; /* pointer to start of trailer */
uint32_t trailer; /* trailer value */
unsigned int enc_octet_len = 0; /* number of octets in encrypted portion */
uint8_t *auth_tag = NULL; /* location of auth_tag within packet */
srtp_err_status_t status;
@@ -3693,12 +3701,10 @@ static srtp_err_status_t srtp_unprotect_rtcp_aead(
*/
/* This should point trailer to the word past the end of the normal data. */
/* This would need to be modified for optional mikey data */
/*
* NOTE: trailer is 32-bit aligned because RTCP 'packets' are always
* multiples of 32-bits (RFC 3550 6.1)
*/
trailer = (uint32_t *)((char *)hdr + *pkt_octet_len -
sizeof(srtcp_trailer_t) - mki_size);
trailer_p = (uint32_t *)((char *)hdr + *pkt_octet_len -
sizeof(srtcp_trailer_t) - mki_size);
memcpy(&trailer, trailer_p, sizeof(trailer));
/*
* We pass the tag down to the cipher when doing GCM mode
*/
@@ -3707,7 +3713,7 @@ static srtp_err_status_t srtp_unprotect_rtcp_aead(
auth_tag = (uint8_t *)hdr + *pkt_octet_len - tag_len - mki_size -
sizeof(srtcp_trailer_t);
if (*((unsigned char *)trailer) & SRTCP_E_BYTE_BIT) {
if (*((unsigned char *)trailer_p) & SRTCP_E_BYTE_BIT) {
enc_start = (uint32_t *)hdr + uint32s_in_rtcp_header;
} else {
enc_octet_len = 0;
@@ -3718,7 +3724,7 @@ static srtp_err_status_t srtp_unprotect_rtcp_aead(
* check the sequence number for replays
*/
/* this is easier than dealing with bitfield access */
seq_num = ntohl(*trailer) & SRTCP_INDEX_MASK;
seq_num = ntohl(trailer) & SRTCP_INDEX_MASK;
debug_print(mod_srtp, "srtcp index: %x", seq_num);
status = srtp_rdb_check(&stream->rtcp_rdb, seq_num);
if (status) {
@@ -3768,7 +3774,7 @@ static srtp_err_status_t srtp_unprotect_rtcp_aead(
/*
* Process the sequence# as AAD
*/
tseq = *trailer;
tseq = trailer;
status = srtp_cipher_set_aad(session_keys->rtcp_cipher, (uint8_t *)&tseq,
sizeof(srtcp_trailer_t));
if (status) {
@@ -3866,7 +3872,8 @@ srtp_err_status_t srtp_protect_rtcp_mki(srtp_t ctx,
srtcp_hdr_t *hdr = (srtcp_hdr_t *)rtcp_hdr;
uint32_t *enc_start; /* pointer to start of encrypted portion */
uint32_t *auth_start; /* pointer to start of auth. portion */
uint32_t *trailer; /* pointer to start of trailer */
uint32_t *trailer_p; /* pointer to start of trailer */
uint32_t trailer; /* trailer value */
unsigned int enc_octet_len = 0; /* number of octets in encrypted portion */
uint8_t *auth_tag = NULL; /* location of auth_tag within packet */
srtp_err_status_t status;
@@ -3959,19 +3966,15 @@ srtp_err_status_t srtp_protect_rtcp_mki(srtp_t ctx,
* NOTE: hdr->length is not usable - it refers to only the first RTCP report
* in the compound packet!
*/
/*
* NOTE: trailer is 32-bit aligned because RTCP 'packets' are always
* multiples of 32-bits (RFC 3550 6.1)
*/
trailer = (uint32_t *)((char *)enc_start + enc_octet_len);
trailer_p = (uint32_t *)((char *)enc_start + enc_octet_len);
if (stream->rtcp_services & sec_serv_conf) {
*trailer = htonl(SRTCP_E_BIT); /* set encrypt bit */
trailer = htonl(SRTCP_E_BIT); /* set encrypt bit */
} else {
enc_start = NULL;
enc_octet_len = 0;
/* 0 is network-order independant */
*trailer = 0x00000000; /* set encrypt bit */
trailer = 0x00000000; /* set encrypt bit */
}
mki_size = srtp_inject_mki((uint8_t *)hdr + *pkt_octet_len +
@@ -3987,10 +3990,6 @@ srtp_err_status_t srtp_protect_rtcp_mki(srtp_t ctx,
auth_tag =
(uint8_t *)hdr + *pkt_octet_len + sizeof(srtcp_trailer_t) + mki_size;
/* perform EKT processing if needed */
srtp_ekt_write_data(stream->ekt, auth_tag, tag_len, pkt_octet_len,
srtp_rdbx_get_packet_index(&stream->rtp_rdbx));
/*
* check sequence number for overruns, and copy it into the packet
* if its value isn't too big
@@ -3999,9 +3998,11 @@ srtp_err_status_t srtp_protect_rtcp_mki(srtp_t ctx,
if (status)
return status;
seq_num = srtp_rdb_get_value(&stream->rtcp_rdb);
*trailer |= htonl(seq_num);
trailer |= htonl(seq_num);
debug_print(mod_srtp, "srtcp index: %x", seq_num);
memcpy(trailer_p, &trailer, sizeof(trailer));
/*
* if we're using rindael counter mode, set nonce and seq
*/
@@ -4059,7 +4060,9 @@ srtp_err_status_t srtp_protect_rtcp_mki(srtp_t ctx,
}
/* initialize auth func context */
srtp_auth_start(session_keys->rtcp_auth);
status = srtp_auth_start(session_keys->rtcp_auth);
if (status)
return status;
/*
* run auth func over packet (including trailer), and write the
@@ -4097,11 +4100,11 @@ srtp_err_status_t srtp_unprotect_rtcp_mki(srtp_t ctx,
srtcp_hdr_t *hdr = (srtcp_hdr_t *)srtcp_hdr;
uint32_t *enc_start; /* pointer to start of encrypted portion */
uint32_t *auth_start; /* pointer to start of auth. portion */
uint32_t *trailer; /* pointer to start of trailer */
uint32_t *trailer_p; /* pointer to start of trailer */
uint32_t trailer; /* trailer value */
unsigned int enc_octet_len = 0; /* number of octets in encrypted portion */
uint8_t *auth_tag = NULL; /* location of auth_tag within packet */
uint8_t tmp_tag[SRTP_MAX_TAG_LEN];
uint8_t tag_copy[SRTP_MAX_TAG_LEN];
srtp_err_status_t status;
unsigned int auth_len;
int tag_len;
@@ -4139,23 +4142,6 @@ srtp_err_status_t srtp_unprotect_rtcp_mki(srtp_t ctx,
if (ctx->stream_template != NULL) {
stream = ctx->stream_template;
/*
* check to see if stream_template has an EKT data structure, in
* which case we initialize the template using the EKT policy
* referenced by that data (which consists of decrypting the
* master key from the EKT field)
*
* this function initializes a *provisional* stream, and this
* stream should not be accepted until and unless the packet
* passes its authentication check
*/
if (stream->ekt != NULL) {
status = srtp_stream_init_from_ekt(stream, srtcp_hdr,
*pkt_octet_len);
if (status)
return status;
}
debug_print(mod_srtp,
"srtcp using provisional stream (SSRC: 0x%08x)",
ntohl(hdr->ssrc));
@@ -4215,14 +4201,12 @@ srtp_err_status_t srtp_unprotect_rtcp_mki(srtp_t ctx,
*/
/* This should point trailer to the word past the end of the normal data. */
/* This would need to be modified for optional mikey data */
/*
* NOTE: trailer is 32-bit aligned because RTCP 'packets' are always
* multiples of 32-bits (RFC 3550 6.1)
*/
trailer = (uint32_t *)((char *)hdr + *pkt_octet_len -
(tag_len + mki_size + sizeof(srtcp_trailer_t)));
trailer_p = (uint32_t *)((char *)hdr + *pkt_octet_len -
(tag_len + mki_size + sizeof(srtcp_trailer_t)));
memcpy(&trailer, trailer_p, sizeof(trailer));
e_bit_in_packet =
(*((unsigned char *)trailer) & SRTCP_E_BYTE_BIT) == SRTCP_E_BYTE_BIT;
(*((unsigned char *)trailer_p) & SRTCP_E_BYTE_BIT) == SRTCP_E_BYTE_BIT;
if (e_bit_in_packet != sec_serv_confidentiality) {
return srtp_err_status_cant_check;
}
@@ -4247,26 +4231,11 @@ srtp_err_status_t srtp_unprotect_rtcp_mki(srtp_t ctx,
auth_len = *pkt_octet_len - tag_len - mki_size;
auth_tag = (uint8_t *)hdr + auth_len + mki_size;
/*
* if EKT is in use, then we make a copy of the tag from the packet,
* and then zeroize the location of the base tag
*
* we first re-position the auth_tag pointer so that it points to
* the base tag
*/
if (stream->ekt) {
auth_tag -= srtp_ekt_octets_after_base_tag(stream->ekt);
memcpy(tag_copy, auth_tag, tag_len);
octet_string_set_to_zero(auth_tag, tag_len);
auth_tag = tag_copy;
auth_len += tag_len;
}
/*
* check the sequence number for replays
*/
/* this is easier than dealing with bitfield access */
seq_num = ntohl(*trailer) & SRTCP_INDEX_MASK;
seq_num = ntohl(trailer) & SRTCP_INDEX_MASK;
debug_print(mod_srtp, "srtcp index: %x", seq_num);
status = srtp_rdb_check(&stream->rtcp_rdb, seq_num);
if (status)
@@ -4302,7 +4271,9 @@ srtp_err_status_t srtp_unprotect_rtcp_mki(srtp_t ctx,
return srtp_err_status_cipher_fail;
/* initialize auth func context */
srtp_auth_start(session_keys->rtcp_auth);
status = srtp_auth_start(session_keys->rtcp_auth);
if (status)
return status;
/* run auth func over packet, put result into tmp_tag */
status = srtp_auth_compute(session_keys->rtcp_auth, (uint8_t *)auth_start,
@@ -4315,7 +4286,7 @@ srtp_err_status_t srtp_unprotect_rtcp_mki(srtp_t ctx,
/* compare the tag just computed with the one in the packet */
debug_print(mod_srtp, "srtcp tag from packet: %s",
srtp_octet_string_hex_string(auth_tag, tag_len));
if (octet_string_is_eq(tmp_tag, auth_tag, tag_len))
if (srtp_octet_string_is_eq(tmp_tag, auth_tag, tag_len))
return srtp_err_status_auth_fail;
/*
@@ -4346,12 +4317,6 @@ srtp_err_status_t srtp_unprotect_rtcp_mki(srtp_t ctx,
/* decrease the packet length by the length of the mki_size */
*pkt_octet_len -= mki_size;
/*
* if EKT is in effect, subtract the EKT data out of the packet
* length
*/
*pkt_octet_len -= srtp_ekt_octets_after_base_tag(stream->ekt);
/*
* verify that stream is for received traffic - this check will
* detect SSRC collisions, since a stream that appears in both
@@ -4418,10 +4383,6 @@ void *srtp_get_user_data(srtp_t ctx)
return ctx->user_data;
}
/*
* dtls keying for srtp
*/
srtp_err_status_t srtp_crypto_policy_set_from_profile_for_rtp(
srtp_crypto_policy_t *policy,
srtp_profile_t profile)
@@ -4437,7 +4398,7 @@ srtp_err_status_t srtp_crypto_policy_set_from_profile_for_rtp(
case srtp_profile_null_sha1_80:
srtp_crypto_policy_set_null_cipher_hmac_sha1_80(policy);
break;
#if defined(OPENSSL)
#ifdef GCM
case srtp_profile_aead_aes_128_gcm:
srtp_crypto_policy_set_aes_gcm_128_16_auth(policy);
break;
@@ -4471,7 +4432,7 @@ srtp_err_status_t srtp_crypto_policy_set_from_profile_for_rtcp(
case srtp_profile_null_sha1_80:
srtp_crypto_policy_set_null_cipher_hmac_sha1_80(policy);
break;
#if defined(OPENSSL)
#ifdef GCM
case srtp_profile_aead_aes_128_gcm:
srtp_crypto_policy_set_aes_gcm_128_16_auth(policy);
break;
@@ -4552,10 +4513,10 @@ srtp_err_status_t stream_get_protect_trailer_length(srtp_stream_ctx_t *stream,
uint32_t mki_index,
uint32_t *length)
{
*length = 0;
srtp_session_keys_t *session_key;
*length = 0;
if (use_mki) {
if (mki_index >= stream->num_master_keys) {
return srtp_err_status_bad_mki;