Commit 8ec13a7e authored by Pascal Buhler's avatar Pascal Buhler

remove srtp_stream_free use srtp_stream_dealloc instead

logic in srtp_stream_free was not correct and could result
in memory access errors, srtp_stream_dealloc can safely be used
instead and is "more" correct.
parent 6f6fdbed
......@@ -147,53 +147,141 @@ unsigned int srtp_get_version()
return rv;
}
/* Release (maybe partially allocated) stream. */
static void srtp_stream_free(srtp_stream_ctx_t *str)
srtp_err_status_t srtp_stream_dealloc(srtp_stream_ctx_t *stream,
const srtp_stream_ctx_t *stream_template)
{
srtp_err_status_t status;
unsigned int i = 0;
srtp_session_keys_t *session_keys = NULL;
srtp_session_keys_t *template_session_keys = NULL;
if (str->session_keys) {
for (i = 0; i < str->num_master_keys; i++) {
session_keys = &str->session_keys[i];
/*
* we use a conservative deallocation strategy - if any deallocation
* fails, then we report that fact without trying to deallocate
* anything else
*/
if (stream->session_keys) {
for (i = 0; i < stream->num_master_keys; i++) {
session_keys = &stream->session_keys[i];
if (session_keys->rtp_xtn_hdr_cipher) {
srtp_cipher_dealloc(session_keys->rtp_xtn_hdr_cipher);
if (stream_template) {
template_session_keys = &stream_template->session_keys[i];
} else {
template_session_keys = NULL;
}
if (session_keys->rtcp_cipher) {
srtp_cipher_dealloc(session_keys->rtcp_cipher);
/*
* deallocate cipher, if it is not the same as that in template
*/
if (template_session_keys &&
session_keys->rtp_cipher == template_session_keys->rtp_cipher) {
/* do nothing */
} else if (session_keys->rtp_cipher) {
status = srtp_cipher_dealloc(session_keys->rtp_cipher);
if (status)
return status;
}
/*
* deallocate auth function, if it is not the same as that in
* template
*/
if (template_session_keys &&
session_keys->rtp_auth == template_session_keys->rtp_auth) {
/* do nothing */
} else if (session_keys->rtp_auth) {
status = srtp_auth_dealloc(session_keys->rtp_auth);
if (status)
return status;
}
if (session_keys->rtcp_auth) {
srtp_auth_dealloc(session_keys->rtcp_auth);
if (template_session_keys &&
session_keys->rtp_xtn_hdr_cipher ==
template_session_keys->rtp_xtn_hdr_cipher) {
/* do nothing */
} else if (session_keys->rtp_xtn_hdr_cipher) {
status = srtp_cipher_dealloc(session_keys->rtp_xtn_hdr_cipher);
if (status)
return status;
}
if (session_keys->rtp_cipher) {
srtp_cipher_dealloc(session_keys->rtp_cipher);
/*
* deallocate rtcp cipher, if it is not the same as that in
* template
*/
if (template_session_keys &&
session_keys->rtcp_cipher ==
template_session_keys->rtcp_cipher) {
/* do nothing */
} else if (session_keys->rtcp_cipher) {
status = srtp_cipher_dealloc(session_keys->rtcp_cipher);
if (status)
return status;
}
if (session_keys->rtp_auth) {
srtp_auth_dealloc(session_keys->rtp_auth);
/*
* deallocate rtcp auth function, if it is not the same as that in
* template
*/
if (template_session_keys &&
session_keys->rtcp_auth == template_session_keys->rtcp_auth) {
/* do nothing */
} else if (session_keys->rtcp_auth) {
status = srtp_auth_dealloc(session_keys->rtcp_auth);
if (status)
return status;
}
/*
* zeroize the salt value
*/
octet_string_set_to_zero(session_keys->salt, SRTP_AEAD_SALT_LEN);
octet_string_set_to_zero(session_keys->c_salt, SRTP_AEAD_SALT_LEN);
if (session_keys->mki_id) {
octet_string_set_to_zero(session_keys->mki_id,
session_keys->mki_size);
srtp_crypto_free(session_keys->mki_id);
session_keys->mki_id = NULL;
}
if (session_keys->limit) {
/*
* deallocate key usage limit, if it is not the same as that in
* template
*/
if (template_session_keys &&
session_keys->limit == template_session_keys->limit) {
/* do nothing */
} else if (session_keys->limit) {
srtp_crypto_free(session_keys->limit);
}
}
}
srtp_crypto_free(str->session_keys);
if (stream_template &&
stream->session_keys == stream_template->session_keys) {
/* do nothing */
} else {
srtp_crypto_free(stream->session_keys);
}
if (str->enc_xtn_hdr) {
srtp_crypto_free(str->enc_xtn_hdr);
status = srtp_rdbx_dealloc(&stream->rtp_rdbx);
if (status)
return status;
/* DAM - need to deallocate EKT here */
if (stream_template &&
stream->enc_xtn_hdr == stream_template->enc_xtn_hdr) {
/* do nothing */
} else if (stream->enc_xtn_hdr) {
srtp_crypto_free(stream->enc_xtn_hdr);
}
srtp_crypto_free(str);
/* deallocate srtp stream context */
srtp_crypto_free(stream);
return srtp_err_status_ok;
}
srtp_err_status_t srtp_stream_alloc(srtp_stream_ctx_t **str_ptr,
......@@ -233,7 +321,7 @@ srtp_err_status_t srtp_stream_alloc(srtp_stream_ctx_t **str_ptr,
sizeof(srtp_session_keys_t) * str->num_master_keys);
if (str->session_keys == NULL) {
srtp_stream_free(str);
srtp_stream_dealloc(str, NULL);
return srtp_err_status_alloc_fail;
}
......@@ -245,7 +333,7 @@ srtp_err_status_t srtp_stream_alloc(srtp_stream_ctx_t **str_ptr,
p->rtp.cipher_type, &session_keys->rtp_cipher,
p->rtp.cipher_key_len, p->rtp.auth_tag_len);
if (stat) {
srtp_stream_free(str);
srtp_stream_dealloc(str, NULL);
return stat;
}
......@@ -254,7 +342,7 @@ srtp_err_status_t srtp_stream_alloc(srtp_stream_ctx_t **str_ptr,
p->rtp.auth_type, &session_keys->rtp_auth, p->rtp.auth_key_len,
p->rtp.auth_tag_len);
if (stat) {
srtp_stream_free(str);
srtp_stream_dealloc(str, NULL);
return stat;
}
......@@ -266,7 +354,7 @@ srtp_err_status_t srtp_stream_alloc(srtp_stream_ctx_t **str_ptr,
p->rtcp.cipher_type, &session_keys->rtcp_cipher,
p->rtcp.cipher_key_len, p->rtcp.auth_tag_len);
if (stat) {
srtp_stream_free(str);
srtp_stream_dealloc(str, NULL);
return stat;
}
......@@ -275,7 +363,7 @@ srtp_err_status_t srtp_stream_alloc(srtp_stream_ctx_t **str_ptr,
p->rtcp.auth_type, &session_keys->rtcp_auth, p->rtcp.auth_key_len,
p->rtcp.auth_tag_len);
if (stat) {
srtp_stream_free(str);
srtp_stream_dealloc(str, NULL);
return stat;
}
......@@ -285,7 +373,7 @@ srtp_err_status_t srtp_stream_alloc(srtp_stream_ctx_t **str_ptr,
session_keys->limit = (srtp_key_limit_ctx_t *)srtp_crypto_alloc(
sizeof(srtp_key_limit_ctx_t));
if (session_keys->limit == NULL) {
srtp_stream_free(str);
srtp_stream_dealloc(str, NULL);
return srtp_err_status_alloc_fail;
}
}
......@@ -293,7 +381,7 @@ 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_free(str);
srtp_stream_dealloc(str, NULL);
return stat;
}
......@@ -304,7 +392,7 @@ srtp_err_status_t srtp_stream_alloc(srtp_stream_ctx_t **str_ptr,
str->enc_xtn_hdr = (int *)srtp_crypto_alloc(p->enc_xtn_hdr_count *
sizeof(p->enc_xtn_hdr[0]));
if (!str->enc_xtn_hdr) {
srtp_stream_free(str);
srtp_stream_dealloc(str, NULL);
return srtp_err_status_alloc_fail;
}
memcpy(str->enc_xtn_hdr, p->enc_xtn_hdr,
......@@ -338,7 +426,7 @@ srtp_err_status_t srtp_stream_alloc(srtp_stream_ctx_t **str_ptr,
enc_xtn_hdr_cipher_type, &session_keys->rtp_xtn_hdr_cipher,
enc_xtn_hdr_cipher_key_len, 0);
if (stat) {
srtp_stream_free(str);
srtp_stream_dealloc(str, NULL);
return stat;
}
}
......@@ -355,138 +443,6 @@ srtp_err_status_t srtp_stream_alloc(srtp_stream_ctx_t **str_ptr,
return srtp_err_status_ok;
}
srtp_err_status_t srtp_stream_dealloc(srtp_stream_ctx_t *stream,
srtp_stream_ctx_t *stream_template)
{
srtp_err_status_t status;
unsigned int i = 0;
srtp_session_keys_t *session_keys = NULL;
srtp_session_keys_t *template_session_keys = NULL;
/*
* we use a conservative deallocation strategy - if any deallocation
* fails, then we report that fact without trying to deallocate
* anything else
*/
for (i = 0; i < stream->num_master_keys; i++) {
session_keys = &stream->session_keys[i];
if (stream_template) {
template_session_keys = &stream_template->session_keys[i];
} else {
template_session_keys = NULL;
}
/*
* deallocate cipher, if it is not the same as that in template
*/
if (template_session_keys &&
session_keys->rtp_cipher == template_session_keys->rtp_cipher) {
/* do nothing */
} else {
status = srtp_cipher_dealloc(session_keys->rtp_cipher);
if (status)
return status;
}
/*
* deallocate auth function, if it is not the same as that in template
*/
if (template_session_keys &&
session_keys->rtp_auth == template_session_keys->rtp_auth) {
/* do nothing */
} else {
status = srtp_auth_dealloc(session_keys->rtp_auth);
if (status)
return status;
}
if (template_session_keys &&
session_keys->rtp_xtn_hdr_cipher ==
template_session_keys->rtp_xtn_hdr_cipher) {
/* do nothing */
} else if (session_keys->rtp_xtn_hdr_cipher) {
status = srtp_cipher_dealloc(session_keys->rtp_xtn_hdr_cipher);
if (status)
return status;
}
/*
* deallocate rtcp cipher, if it is not the same as that in
* template
*/
if (template_session_keys &&
session_keys->rtcp_cipher == template_session_keys->rtcp_cipher) {
/* do nothing */
} else {
status = srtp_cipher_dealloc(session_keys->rtcp_cipher);
if (status)
return status;
}
/*
* deallocate rtcp auth function, if it is not the same as that in
* template
*/
if (template_session_keys &&
session_keys->rtcp_auth == template_session_keys->rtcp_auth) {
/* do nothing */
} else {
status = srtp_auth_dealloc(session_keys->rtcp_auth);
if (status)
return status;
}
/*
* zeroize the salt value
*/
octet_string_set_to_zero(session_keys->salt, SRTP_AEAD_SALT_LEN);
octet_string_set_to_zero(session_keys->c_salt, SRTP_AEAD_SALT_LEN);
if (session_keys->mki_id) {
octet_string_set_to_zero(session_keys->mki_id,
session_keys->mki_size);
srtp_crypto_free(session_keys->mki_id);
session_keys->mki_id = NULL;
}
/*
* deallocate key usage limit, if it is not the same as that in template
*/
if (template_session_keys &&
session_keys->limit == template_session_keys->limit) {
/* do nothing */
} else {
srtp_crypto_free(session_keys->limit);
}
}
if (stream_template &&
stream->session_keys == stream_template->session_keys) {
/* do nothing */
} else {
srtp_crypto_free(stream->session_keys);
}
status = srtp_rdbx_dealloc(&stream->rtp_rdbx);
if (status)
return status;
/* DAM - need to deallocate EKT here */
if (stream_template &&
stream->enc_xtn_hdr == stream_template->enc_xtn_hdr) {
/* do nothing */
} else if (stream->enc_xtn_hdr) {
srtp_crypto_free(stream->enc_xtn_hdr);
}
/* deallocate srtp stream context */
srtp_crypto_free(stream);
return srtp_err_status_ok;
}
/*
* srtp_stream_clone(stream_template, new) allocates a new stream and
* initializes it using the cipher and auth of the stream_template
......@@ -518,7 +474,7 @@ srtp_err_status_t srtp_stream_clone(const srtp_stream_ctx_t *stream_template,
sizeof(srtp_session_keys_t) * str->num_master_keys);
if (str->session_keys == NULL) {
srtp_stream_free(*str_ptr);
srtp_stream_dealloc(*str_ptr, stream_template);
*str_ptr = NULL;
return srtp_err_status_alloc_fail;
}
......@@ -543,7 +499,7 @@ srtp_err_status_t srtp_stream_clone(const srtp_stream_ctx_t *stream_template,
srtp_crypto_alloc(template_session_keys->mki_size);
if (session_keys->mki_id == NULL) {
srtp_stream_free(*str_ptr);
srtp_stream_dealloc(*str_ptr, stream_template);
*str_ptr = NULL;
return srtp_err_status_init_fail;
}
......@@ -560,7 +516,7 @@ srtp_err_status_t srtp_stream_clone(const srtp_stream_ctx_t *stream_template,
status = srtp_key_limit_clone(template_session_keys->limit,
&session_keys->limit);
if (status) {
srtp_stream_free(*str_ptr);
srtp_stream_dealloc(*str_ptr, stream_template);
*str_ptr = NULL;
return status;
}
......@@ -570,7 +526,7 @@ srtp_err_status_t srtp_stream_clone(const srtp_stream_ctx_t *stream_template,
status = srtp_rdbx_init(
&str->rtp_rdbx, srtp_rdbx_get_window_size(&stream_template->rtp_rdbx));
if (status) {
srtp_stream_free(*str_ptr);
srtp_stream_dealloc(*str_ptr, stream_template);
*str_ptr = NULL;
return status;
}
......@@ -2891,7 +2847,7 @@ srtp_err_status_t srtp_add_stream(srtp_t session, const srtp_policy_t *policy)
/* initialize stream */
status = srtp_stream_init(tmp, policy);
if (status) {
srtp_stream_free(tmp);
srtp_stream_dealloc(tmp, NULL);
return status;
}
......@@ -2906,7 +2862,7 @@ srtp_err_status_t srtp_add_stream(srtp_t session, const srtp_policy_t *policy)
switch (policy->ssrc.type) {
case (ssrc_any_outbound):
if (session->stream_template) {
srtp_stream_free(tmp);
srtp_stream_dealloc(tmp, NULL);
return srtp_err_status_bad_param;
}
session->stream_template = tmp;
......@@ -2914,7 +2870,7 @@ srtp_err_status_t srtp_add_stream(srtp_t session, const srtp_policy_t *policy)
break;
case (ssrc_any_inbound):
if (session->stream_template) {
srtp_stream_free(tmp);
srtp_stream_dealloc(tmp, NULL);
return srtp_err_status_bad_param;
}
session->stream_template = tmp;
......@@ -2926,7 +2882,7 @@ srtp_err_status_t srtp_add_stream(srtp_t session, const srtp_policy_t *policy)
break;
case (ssrc_undefined):
default:
srtp_stream_free(tmp);
srtp_stream_dealloc(tmp, NULL);
return srtp_err_status_bad_param;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment