aboutsummaryrefslogtreecommitdiff
path: root/srtp
diff options
context:
space:
mode:
authorRyan Hooper <ryhooper@cisco.com>2016-12-22 16:22:47 -0500
committerRyan Hooper <ryhooper@cisco.com>2016-12-22 16:22:47 -0500
commit89a288b48749ba311858717f2dedc5ce43a2f4bf (patch)
tree4b249da996c5b5910e1c961bd53285076b31af3d /srtp
parentfe5d8b82702174eb1f6a3e945fbc8ec4a529175c (diff)
downloadlibsrtp2-89a288b48749ba311858717f2dedc5ce43a2f4bf.tar.gz
Made the Master Keys Dynamic instead of caping them at only 4 master keys. Also kept key around in the policy to keep as much backward compatiblity as possible
Diffstat (limited to 'srtp')
-rw-r--r--srtp/srtp.c115
1 files changed, 76 insertions, 39 deletions
diff --git a/srtp/srtp.c b/srtp/srtp.c
index 27f164c..fc3a444 100644
--- a/srtp/srtp.c
+++ b/srtp/srtp.c
@@ -178,6 +178,8 @@ srtp_stream_free(srtp_stream_ctx_t *str) {
}
}
+ srtp_crypto_free(str->session_keys);
+
if (str->enc_xtn_hdr) {
srtp_crypto_free(str->enc_xtn_hdr);
}
@@ -212,7 +214,16 @@ srtp_stream_alloc(srtp_stream_ctx_t **str_ptr,
memset(str, 0, sizeof(srtp_stream_ctx_t));
*str_ptr = str;
- str->num_master_keys = p->num_master_keys;
+ /* To keep backwards API compatible if someone is using multiple master
+ * keys then key should be set to NULL
+ */
+ if (p->key != NULL) {
+ str->num_master_keys = 1;
+ } else {
+ str->num_master_keys = p->num_master_keys;
+ }
+
+ str->session_keys = (srtp_session_keys_t *)srtp_crypto_alloc(sizeof(srtp_session_keys_t) * str->num_master_keys);
for (i = 0; i < str->num_master_keys; i++) {
session_keys = &str->session_keys[i];
@@ -477,6 +488,7 @@ srtp_stream_clone(const srtp_stream_ctx_t *stream_template,
*str_ptr = str;
str->num_master_keys = stream_template->num_master_keys;
+ str->session_keys = (srtp_session_keys_t *)srtp_crypto_alloc(sizeof(srtp_session_keys_t) * str->num_master_keys);
for (i = 0; i < stream_template->num_master_keys; i++){
session_keys = &str->session_keys[i];
@@ -490,15 +502,17 @@ srtp_stream_clone(const srtp_stream_ctx_t *stream_template,
session_keys->rtcp_auth = template_session_keys->rtcp_auth;
session_keys->mki_size = template_session_keys->mki_size;
- session_keys->mki_id = srtp_crypto_alloc(template_session_keys->mki_size);
+ if (template_session_keys->mki_size == 0) {
+ session_keys->mki_id = NULL;
+ } else {
+ session_keys->mki_id = srtp_crypto_alloc(template_session_keys->mki_size);
- if (session_keys->mki_id == NULL) {
- return srtp_err_status_init_fail;
+ if (session_keys->mki_id == NULL) {
+ return srtp_err_status_init_fail;
+ }
+ memset(session_keys->mki_id, 0x0, session_keys->mki_size);
+ memcpy(session_keys->mki_id, template_session_keys->mki_id, session_keys->mki_size);
}
-
- memset(session_keys->mki_id, 0x0, session_keys->mki_size);
- memcpy(session_keys->mki_id, template_session_keys->mki_id, session_keys->mki_size);
-
/* Copy the salt values */
memcpy(session_keys->salt, template_session_keys->salt, SRTP_AEAD_SALT_LEN);
memcpy(session_keys->c_salt, template_session_keys->c_salt, SRTP_AEAD_SALT_LEN);
@@ -540,7 +554,6 @@ srtp_stream_clone(const srtp_stream_ctx_t *stream_template,
/* defensive coding */
str->next = NULL;
-
return srtp_err_status_ok;
}
@@ -739,12 +752,19 @@ srtp_validate_policy_master_keys(const srtp_policy_t *policy)
{
int i = 0;
- if (policy->num_master_keys <= 0)
- return 0;
-
- for (i = 0; i < policy->num_master_keys; i++) {
- if (policy->keys[i].key == NULL)
+ if (policy->key == NULL) {
+ if (policy->num_master_keys <= 0)
return 0;
+
+ if (policy->num_master_keys > SRTP_MAX_NUM_MASTER_KEYS)
+ return 0;
+
+ for (i = 0; i < policy->num_master_keys; i++) {
+ if (policy->keys[i]->key == NULL)
+ return 0;
+ if (policy->keys[i]->mki_size > SRTP_MAX_MKI_LEN)
+ return 0;
+ }
}
return 1;
@@ -758,6 +778,7 @@ srtp_get_session_keys_with_mki_index(srtp_stream_ctx_t *stream, unsigned int use
return &stream->session_keys[mki_index];
}
}
+
return &stream->session_keys[0];
}
@@ -779,18 +800,29 @@ srtp_inject_mki(uint8_t *mki_tag_location, srtp_session_keys_t* session_keys, un
}
srtp_err_status_t
-srtp_stream_init_all_master_keys(srtp_stream_ctx_t *srtp, const srtp_master_key_t keys[SRTP_MAX_NUM_MASTER_KEYS],
+srtp_stream_init_all_master_keys(srtp_stream_ctx_t *srtp,
+ unsigned char *key,
+ srtp_master_key_t **keys,
const unsigned int max_master_keys) {
int i = 0;
srtp_err_status_t status = srtp_err_status_ok;
+ srtp_master_key_t single_master_key;
+
+ if ( key != NULL ) {
+ srtp->num_master_keys = 1;
+ single_master_key.key = key;
+ single_master_key.mki_id = NULL;
+ single_master_key.mki_size = 0;
+ status = srtp_stream_init_keys(srtp, &single_master_key, 0);
+ } else {
+ srtp->num_master_keys = max_master_keys;
- srtp->num_master_keys = max_master_keys;
-
- for (i = 0; i < srtp->num_master_keys && i < SRTP_MAX_NUM_MASTER_KEYS; i++) {
- status = srtp_stream_init_keys(srtp, keys[i], i);
+ for (i = 0; i < srtp->num_master_keys && i < SRTP_MAX_NUM_MASTER_KEYS; i++) {
+ status = srtp_stream_init_keys(srtp, keys[i], i);
- if (status) {
- return status;
+ if (status) {
+ return status;
+ }
}
}
@@ -798,7 +830,7 @@ srtp_stream_init_all_master_keys(srtp_stream_ctx_t *srtp, const srtp_master_key_
}
srtp_err_status_t
-srtp_stream_init_keys(srtp_stream_ctx_t *srtp, const srtp_master_key_t master_key, const unsigned int current_mki_index) {
+srtp_stream_init_keys(srtp_stream_ctx_t *srtp, srtp_master_key_t *master_key, const unsigned int current_mki_index) {
srtp_err_status_t stat;
srtp_kdf_t kdf;
uint8_t tmp_key[MAX_SRTP_KEY_LEN];
@@ -806,24 +838,26 @@ srtp_stream_init_keys(srtp_stream_ctx_t *srtp, const srtp_master_key_t master_ke
int rtp_base_key_len, rtp_salt_len;
int rtcp_base_key_len, rtcp_salt_len;
srtp_session_keys_t *session_keys = NULL;
- unsigned char *key = master_key.key;
+ unsigned char *key = master_key->key;
/* If RTP or RTCP have a key length > AES-128, assume matching kdf. */
/* TODO: kdf algorithm, master key length, and master salt length should
* be part of srtp_policy_t. */
-
session_keys = &srtp->session_keys[current_mki_index];
- session_keys->mki_id = srtp_crypto_alloc(master_key.mki_size);
+ if ( master_key->mki_size != 0 ) {
+ session_keys->mki_id = srtp_crypto_alloc(master_key->mki_size);
- if (session_keys->mki_id == NULL) {
- return srtp_err_status_init_fail;
+ if (session_keys->mki_id == NULL) {
+ return srtp_err_status_init_fail;
+ }
+ memset(session_keys->mki_id, 0x0, master_key->mki_size);
+ memcpy(session_keys->mki_id, master_key->mki_id, master_key->mki_size);
+ } else {
+ session_keys->mki_id = NULL;
}
- memset(session_keys->mki_id, 0x0, master_key.mki_size);
- memcpy(session_keys->mki_id, master_key.mki_id, master_key.mki_size);
-
- session_keys->mki_size = master_key.mki_size;
+ session_keys->mki_size = master_key->mki_size;
rtp_keylen = srtp_cipher_get_key_length(session_keys->rtp_cipher);
rtcp_keylen = srtp_cipher_get_key_length(session_keys->rtcp_cipher);
@@ -1150,7 +1184,7 @@ srtp_stream_init(srtp_stream_ctx_t *srtp,
/* DAM - no RTCP key limit at present */
/* initialize keys */
- err = srtp_stream_init_all_master_keys(srtp, p->keys, p->num_master_keys);
+ err = srtp_stream_init_all_master_keys(srtp, p->key, p->keys, p->num_master_keys);
if (err) {
srtp_rdbx_dealloc(&srtp->rtp_rdbx);
return err;
@@ -1427,12 +1461,14 @@ srtp_get_session_keys(srtp_stream_ctx_t *stream, uint8_t* hdr, const unsigned in
base_mki_start_location -= tag_len;
for (i = 0; i < stream->num_master_keys; i++) {
- *mki_size = stream->session_keys[i].mki_size;
- mki_start_location = base_mki_start_location - *mki_size;
-
- if ( mki_start_location >= *mki_size &&
- memcmp(hdr + mki_start_location, stream->session_keys[i].mki_id, *mki_size) == 0 ) {
- return &stream->session_keys[i];
+ if (stream->session_keys[i].mki_size != 0) {
+ *mki_size = stream->session_keys[i].mki_size;
+ mki_start_location = base_mki_start_location - *mki_size;
+
+ if ( mki_start_location >= *mki_size &&
+ memcmp(hdr + mki_start_location, stream->session_keys[i].mki_id, *mki_size) == 0 ) {
+ return &stream->session_keys[i];
+ }
}
}
@@ -1857,6 +1893,7 @@ srtp_unprotect_aead (srtp_ctx_t *ctx, srtp_stream_ctx_t *stream, int delta,
* srtp_protect() and srtp_unprotect() will fail this test in one of
* those functions.
*/
+
if (stream->direction != dir_srtp_sender) {
if (stream->direction == dir_unknown) {
stream->direction = dir_srtp_sender;
@@ -4129,7 +4166,7 @@ srtp_get_protect_data_added_length(const srtp_policy_t *policy,
if (mki_index > policy->num_master_keys)
return srtp_err_status_bad_mki;
- *length += policy->keys[mki_index].mki_size;
+ *length += policy->keys[mki_index]->mki_size;
}
if (is_rtcp) {