Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
43 changes: 43 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,44 @@ 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:
case ssrc_any_outbound: {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not clear what the behavior should be for ssrc_any_outbound, maybe return srtp_err_status_bad_param?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

error sounds fine

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;
}
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
45 changes: 45 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,41 @@ 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_specific;
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));
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