Skip to content

Commit 696f132

Browse files
committed
Add API to require cryptex
allowing applications to reject packets not using cryptex using srtp_set_stream_require_cryptex(...) as described in https://datatracker.ietf.org/doc/html/rfc9335#section-5.2 Fixes #804 (for 2_x_dev)
1 parent 24b3bf8 commit 696f132

4 files changed

Lines changed: 107 additions & 0 deletions

File tree

include/srtp.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1765,6 +1765,24 @@ srtp_err_status_t srtp_set_stream_use_cryptex(srtp_t session,
17651765
const srtp_ssrc_t *ssrc,
17661766
int enable);
17671767

1768+
/**
1769+
* @brief srtp_set_stream_require_cryptex(session, ssrc, enable)
1770+
*
1771+
* Require cryptex, RFC 9335, processing for the stream identified by the given
1772+
* SSRC. For wildcard SSRC types the require cryptex setting is applied to the
1773+
* session template and any streams created from it.
1774+
*
1775+
* @param session is the SRTP session containing the stream to update.
1776+
* @param ssrc describes the SSRC to require cryptex for.
1777+
* @param enable whether to require sending and receiving cryptex.
1778+
*
1779+
* @returns srtp_err_status_ok on success, or srtp_err_status_bad_param if the
1780+
* stream or template cannot be found for the given SSRC.
1781+
*/
1782+
srtp_err_status_t srtp_set_stream_require_cryptex(srtp_t session,
1783+
const srtp_ssrc_t *ssrc,
1784+
int enable);
1785+
17681786
/**
17691787
* @}
17701788
*/

include/srtp_priv.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ typedef struct srtp_stream_ctx_t_ {
146146
int *enc_xtn_hdr;
147147
int enc_xtn_hdr_count;
148148
int use_cryptex;
149+
int require_cryptex;
149150
uint32_t pending_roc;
150151
/*
151152
The next and prev pointers are here to allow for a stream list to be

srtp/srtp.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,10 @@ static srtp_err_status_t srtp_cryptex_unprotect_init(
235235
*inuse = 0;
236236
}
237237

238+
if (stream->require_cryptex && !*inuse && hdr->x == 1) {
239+
return srtp_err_status_cryptex_err;
240+
}
241+
238242
if (*inuse) {
239243
srtp_hdr_xtnd_t *xtn_hdr = srtp_get_rtp_xtn_hdr(hdr);
240244
*enc_start -=
@@ -5128,6 +5132,7 @@ static int set_cryptex_from_template_cb(srtp_stream_t stream, void *raw_data)
51285132
if (stream->session_keys[0].rtp_auth ==
51295133
data->template->session_keys[0].rtp_auth) {
51305134
stream->use_cryptex = data->template->use_cryptex;
5135+
stream->require_cryptex = data->template->require_cryptex;
51315136
}
51325137

51335138
return 0;
@@ -5171,6 +5176,44 @@ srtp_err_status_t srtp_set_stream_use_cryptex(srtp_t session,
51715176
return srtp_err_status_ok;
51725177
}
51735178

5179+
srtp_err_status_t srtp_set_stream_require_cryptex(srtp_t session,
5180+
const srtp_ssrc_t *ssrc,
5181+
int enable)
5182+
{
5183+
srtp_stream_t stream;
5184+
5185+
if (session == NULL || ssrc == NULL) {
5186+
return srtp_err_status_bad_param;
5187+
}
5188+
5189+
switch (ssrc->type) {
5190+
case ssrc_specific:
5191+
stream = srtp_get_stream(session, htonl(ssrc->value));
5192+
if (stream == NULL) {
5193+
return srtp_err_status_bad_param;
5194+
}
5195+
stream->require_cryptex = enable != 0;
5196+
break;
5197+
case ssrc_any_inbound:
5198+
case ssrc_any_outbound: {
5199+
struct set_cryptex_from_template_data data;
5200+
5201+
if (session->stream_template == NULL) {
5202+
return srtp_err_status_bad_param;
5203+
}
5204+
session->stream_template->require_cryptex = enable != 0;
5205+
data.template = session->stream_template;
5206+
srtp_stream_list_for_each(session->stream_list,
5207+
set_cryptex_from_template_cb, &data);
5208+
break;
5209+
}
5210+
default:
5211+
return srtp_err_status_bad_param;
5212+
}
5213+
5214+
return srtp_err_status_ok;
5215+
}
5216+
51745217
#ifndef SRTP_NO_STREAM_LIST
51755218

51765219
/* in the default implementation, we have an intrusive doubly-linked list */

test/srtp_driver.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,8 @@ srtp_err_status_t srtp_test_cryptex_csrc_but_no_extension_header(void);
115115

116116
srtp_err_status_t srtp_test_cryptex_disable(void);
117117

118+
srtp_err_status_t srtp_test_require_cryptex(void);
119+
118120
double srtp_bits_per_second(int msg_len_octets, const srtp_policy_t *policy);
119121

120122
double srtp_rejections_per_second(int msg_len_octets,
@@ -684,6 +686,14 @@ int main(int argc, char *argv[])
684686
printf("failed\n");
685687
exit(1);
686688
}
689+
690+
printf("testing require_cryptex()...");
691+
if (srtp_test_require_cryptex() == srtp_err_status_ok) {
692+
printf("passed\n");
693+
} else {
694+
printf("failed\n");
695+
exit(1);
696+
}
687697
}
688698

689699
if (do_stream_list) {
@@ -2707,6 +2717,41 @@ srtp_err_status_t srtp_test_cryptex_disable(void)
27072717
return srtp_err_status_ok;
27082718
}
27092719

2720+
srtp_err_status_t srtp_test_require_cryptex(void)
2721+
{
2722+
srtp_policy_t policy;
2723+
memset(&policy, 0, sizeof(policy));
2724+
srtp_crypto_policy_set_rtp_default(&policy.rtp);
2725+
srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
2726+
policy.ssrc.type = ssrc_specific;
2727+
policy.ssrc.value = 0xcafebabe;
2728+
policy.key = test_key;
2729+
policy.window_size = 128;
2730+
policy.allow_repeat_tx = 0;
2731+
policy.next = NULL;
2732+
2733+
srtp_t srtp_snd, srtp_recv;
2734+
CHECK_OK(srtp_create(&srtp_snd, &policy));
2735+
CHECK_OK(srtp_set_stream_use_cryptex(srtp_snd, &policy.ssrc, 0));
2736+
CHECK_OK(srtp_create(&srtp_recv, &policy));
2737+
CHECK_OK(srtp_set_stream_require_cryptex(srtp_recv, &policy.ssrc, 1));
2738+
2739+
int packet_len;
2740+
srtp_hdr_t *packet =
2741+
srtp_create_test_packet_ext_hdr(100, policy.ssrc.value, &packet_len);
2742+
2743+
CHECK_OK(srtp_protect(srtp_snd, packet, &packet_len));
2744+
2745+
CHECK_RETURN(srtp_unprotect(srtp_recv, packet, &packet_len),
2746+
srtp_err_status_cryptex_err);
2747+
2748+
CHECK_OK(srtp_dealloc(srtp_snd));
2749+
CHECK_OK(srtp_dealloc(srtp_recv));
2750+
free(packet);
2751+
2752+
return srtp_err_status_ok;
2753+
}
2754+
27102755
#ifdef GCM
27112756
/*
27122757
* srtp_validate_gcm() verifies the correctness of libsrtp by comparing

0 commit comments

Comments
 (0)