Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions include/srtp.h
Original file line number Diff line number Diff line change
Expand Up @@ -1765,6 +1765,24 @@ srtp_err_status_t srtp_set_stream_use_cryptex(srtp_t session,
const srtp_ssrc_t *ssrc,
int enable);

/**
* @brief srtp_set_stream_require_cryptex(session, ssrc, enable)
*
* Require cryptex, RFC 9335, processing for the stream identified by the given
* SSRC. For wildcard SSRC types the require cryptex setting is applied to the
* session template and any streams created from it.
*
* @param session is the SRTP session containing the stream to update.
* @param ssrc describes the SSRC to require cryptex for.
* @param enable whether to require sending and receiving cryptex.
*
* @returns srtp_err_status_ok on success, or srtp_err_status_bad_param if the
* stream or template cannot be found for the given SSRC.
*/
srtp_err_status_t srtp_set_stream_require_cryptex(srtp_t session,
const srtp_ssrc_t *ssrc,
int enable);

/**
* @}
*/
Expand Down
1 change: 1 addition & 0 deletions include/srtp_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ typedef struct srtp_stream_ctx_t_ {
int *enc_xtn_hdr;
int enc_xtn_hdr_count;
int use_cryptex;
int require_cryptex;
uint32_t pending_roc;
/*
The next and prev pointers are here to allow for a stream list to be
Expand Down
44 changes: 44 additions & 0 deletions srtp/srtp.c
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,10 @@ static srtp_err_status_t srtp_cryptex_unprotect_init(
*inuse = 0;
}

if (stream->require_cryptex && !*inuse && hdr->x == 1) {
return srtp_err_status_cryptex_err;
}

if (*inuse) {
srtp_hdr_xtnd_t *xtn_hdr = srtp_get_rtp_xtn_hdr(hdr);
*enc_start -=
Expand Down Expand Up @@ -5128,6 +5132,7 @@ static int set_cryptex_from_template_cb(srtp_stream_t stream, void *raw_data)
if (stream->session_keys[0].rtp_auth ==
data->template->session_keys[0].rtp_auth) {
stream->use_cryptex = data->template->use_cryptex;
stream->require_cryptex = data->template->require_cryptex;
}

return 0;
Expand Down Expand Up @@ -5171,6 +5176,45 @@ srtp_err_status_t srtp_set_stream_use_cryptex(srtp_t session,
return srtp_err_status_ok;
}

srtp_err_status_t srtp_set_stream_require_cryptex(srtp_t session,
const srtp_ssrc_t *ssrc,
int enable)
{
srtp_stream_t stream;

if (session == NULL || ssrc == NULL) {
return srtp_err_status_bad_param;
}

switch (ssrc->type) {
case ssrc_specific:
stream = srtp_get_stream(session, htonl(ssrc->value));
if (stream == NULL) {
return srtp_err_status_bad_param;
}
stream->require_cryptex = enable != 0;
break;
case ssrc_any_inbound: {
struct set_cryptex_from_template_data data;

if (session->stream_template == NULL) {
return srtp_err_status_bad_param;
}
session->stream_template->require_cryptex = enable != 0;
data.template = session->stream_template;
srtp_stream_list_for_each(session->stream_list,
set_cryptex_from_template_cb, &data);
break;
}
case ssrc_any_outbound:
// Requiring cryptex is not possible for outbound SSRCs, fall through.
default:
return srtp_err_status_bad_param;
}

return srtp_err_status_ok;
}

#ifndef SRTP_NO_STREAM_LIST

/* in the default implementation, we have an intrusive doubly-linked list */
Expand Down
51 changes: 51 additions & 0 deletions test/srtp_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ srtp_err_status_t srtp_test_cryptex_csrc_but_no_extension_header(void);

srtp_err_status_t srtp_test_cryptex_disable(void);

srtp_err_status_t srtp_test_require_cryptex(void);

double srtp_bits_per_second(int msg_len_octets, const srtp_policy_t *policy);

double srtp_rejections_per_second(int msg_len_octets,
Expand Down Expand Up @@ -684,6 +686,14 @@ int main(int argc, char *argv[])
printf("failed\n");
exit(1);
}

printf("testing require_cryptex()...");
if (srtp_test_require_cryptex() == srtp_err_status_ok) {
printf("passed\n");
} else {
printf("failed\n");
exit(1);
}
}

if (do_stream_list) {
Expand Down Expand Up @@ -2707,6 +2717,47 @@ srtp_err_status_t srtp_test_cryptex_disable(void)
return srtp_err_status_ok;
}

srtp_err_status_t srtp_test_require_cryptex(void)
{
srtp_policy_t policy;
memset(&policy, 0, sizeof(policy));
srtp_crypto_policy_set_rtp_default(&policy.rtp);
srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
policy.ssrc.type = ssrc_any_outbound;
policy.ssrc.value = 0xcafebabe;
policy.key = test_key;
policy.window_size = 128;
policy.allow_repeat_tx = 0;
policy.next = NULL;

srtp_t srtp_snd, srtp_recv;
CHECK_OK(srtp_create(&srtp_snd, &policy));
CHECK_OK(srtp_set_stream_use_cryptex(srtp_snd, &policy.ssrc, 0));
/*
* requiring cryptex is not defined for the outbound wildcard ssrc.
*/
CHECK_RETURN(srtp_set_stream_require_cryptex(srtp_snd, &policy.ssrc, 1),
srtp_err_status_bad_param);
policy.ssrc.type = ssrc_any_inbound;
CHECK_OK(srtp_create(&srtp_recv, &policy));
CHECK_OK(srtp_set_stream_require_cryptex(srtp_recv, &policy.ssrc, 1));

int packet_len;
srtp_hdr_t *packet =
srtp_create_test_packet_ext_hdr(100, policy.ssrc.value, &packet_len);

CHECK_OK(srtp_protect(srtp_snd, packet, &packet_len));

CHECK_RETURN(srtp_unprotect(srtp_recv, packet, &packet_len),
srtp_err_status_cryptex_err);

CHECK_OK(srtp_dealloc(srtp_snd));
CHECK_OK(srtp_dealloc(srtp_recv));
free(packet);

return srtp_err_status_ok;
}

#ifdef GCM
/*
* srtp_validate_gcm() verifies the correctness of libsrtp by comparing
Expand Down
Loading