Skip to content

Commit 0e613d9

Browse files
authored
Merge pull request #801 from pabuhler/cryptex-disable
support disabling cryptex
2 parents 661818b + 41f0d7d commit 0e613d9

3 files changed

Lines changed: 108 additions & 11 deletions

File tree

include/srtp.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1748,20 +1748,22 @@ srtp_err_status_t srtp_get_stream_roc(srtp_t session,
17481748
uint32_t *roc);
17491749

17501750
/**
1751-
* @brief srtp_set_stream_use_cryptex(session, ssrc)
1751+
* @brief srtp_set_stream_use_cryptex(session, ssrc, enable)
17521752
*
17531753
* Enable cryptex, RFC 9335, processing for the stream identified by the given
17541754
* SSRC. For wildcard SSRC types the cryptex setting is applied to the session
17551755
* template and any streams created from it.
17561756
*
17571757
* @param session is the SRTP session containing the stream to update.
17581758
* @param ssrc describes the SSRC to enable cryptex for.
1759+
* @param enable whether to enable sending and receiving cryptex.
17591760
*
17601761
* @returns srtp_err_status_ok on success, or srtp_err_status_bad_param if the
17611762
* stream or template cannot be found for the given SSRC.
17621763
*/
17631764
srtp_err_status_t srtp_set_stream_use_cryptex(srtp_t session,
1764-
const srtp_ssrc_t *ssrc);
1765+
const srtp_ssrc_t *ssrc,
1766+
int enable);
17651767

17661768
/**
17671769
* @}

srtp/srtp.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5127,14 +5127,15 @@ static int set_cryptex_from_template_cb(srtp_stream_t stream, void *raw_data)
51275127
*/
51285128
if (stream->session_keys[0].rtp_auth ==
51295129
data->template->session_keys[0].rtp_auth) {
5130-
stream->use_cryptex = 1;
5130+
stream->use_cryptex = data->template->use_cryptex;
51315131
}
51325132

51335133
return 0;
51345134
}
51355135

51365136
srtp_err_status_t srtp_set_stream_use_cryptex(srtp_t session,
5137-
const srtp_ssrc_t *ssrc)
5137+
const srtp_ssrc_t *ssrc,
5138+
int enable)
51385139
{
51395140
srtp_stream_t stream;
51405141

@@ -5148,7 +5149,7 @@ srtp_err_status_t srtp_set_stream_use_cryptex(srtp_t session,
51485149
if (stream == NULL) {
51495150
return srtp_err_status_bad_param;
51505151
}
5151-
stream->use_cryptex = 1;
5152+
stream->use_cryptex = enable != 0;
51525153
break;
51535154
case ssrc_any_inbound:
51545155
case ssrc_any_outbound: {
@@ -5157,7 +5158,7 @@ srtp_err_status_t srtp_set_stream_use_cryptex(srtp_t session,
51575158
if (session->stream_template == NULL) {
51585159
return srtp_err_status_bad_param;
51595160
}
5160-
session->stream_template->use_cryptex = 1;
5161+
session->stream_template->use_cryptex = enable != 0;
51615162
data.template = session->stream_template;
51625163
srtp_stream_list_for_each(session->stream_list,
51635164
set_cryptex_from_template_cb, &data);

test/srtp_driver.c

Lines changed: 99 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,8 @@ srtp_err_status_t srtp_test_set_sender_roc(void);
113113

114114
srtp_err_status_t srtp_test_cryptex_csrc_but_no_extension_header(void);
115115

116+
srtp_err_status_t srtp_test_cryptex_disable(void);
117+
116118
double srtp_bits_per_second(int msg_len_octets, const srtp_policy_t *policy);
117119

118120
double srtp_rejections_per_second(int msg_len_octets,
@@ -674,6 +676,14 @@ int main(int argc, char *argv[])
674676
printf("failed\n");
675677
exit(1);
676678
}
679+
680+
printf("testing cryptex_disable()...");
681+
if (srtp_test_cryptex_disable() == srtp_err_status_ok) {
682+
printf("passed\n");
683+
} else {
684+
printf("failed\n");
685+
exit(1);
686+
}
677687
}
678688

679689
if (do_stream_list) {
@@ -940,6 +950,20 @@ srtp_hdr_t *srtp_create_test_packet_ext_hdr(int pkt_octet_len,
940950
return hdr;
941951
}
942952

953+
static uint16_t srtp_get_xtn_profile(const uint8_t *packet)
954+
{
955+
const srtp_hdr_t *hdr = (const srtp_hdr_t *)packet;
956+
const srtp_hdr_xtnd_t *xtn_hdr;
957+
958+
if (!hdr->x) {
959+
return 0;
960+
}
961+
962+
xtn_hdr = (const srtp_hdr_xtnd_t *)(packet + sizeof(srtp_hdr_t) +
963+
(hdr->cc * sizeof(uint32_t)));
964+
return ntohs(xtn_hdr->profile_specific);
965+
}
966+
943967
void srtp_do_timing(const srtp_policy_t *policy)
944968
{
945969
int len;
@@ -2535,7 +2559,7 @@ srtp_err_status_t srtp_validate_cryptex(void)
25352559
debug_print(mod_driver, "test vector: %s\n", vectors[i].name);
25362560

25372561
CHECK_OK(srtp_create(&srtp_snd, &policy));
2538-
CHECK_OK(srtp_set_stream_use_cryptex(srtp_snd, &policy.ssrc));
2562+
CHECK_OK(srtp_set_stream_use_cryptex(srtp_snd, &policy.ssrc, 1));
25392563

25402564
CHECK_OK(srtp_protect(srtp_snd, packet, &len));
25412565
CHECK(len == enc_len);
@@ -2550,7 +2574,7 @@ srtp_err_status_t srtp_validate_cryptex(void)
25502574
CHECK_OK(srtp_dealloc(srtp_snd));
25512575

25522576
CHECK_OK(srtp_create(&srtp_recv, &policy));
2553-
CHECK_OK(srtp_set_stream_use_cryptex(srtp_recv, &policy.ssrc));
2577+
CHECK_OK(srtp_set_stream_use_cryptex(srtp_recv, &policy.ssrc, 1));
25542578

25552579
/*
25562580
* unprotect ciphertext, then compare with plaintext
@@ -2599,7 +2623,7 @@ srtp_err_status_t srtp_test_cryptex_csrc_but_no_extension_header(void)
25992623

26002624
srtp_t srtp_snd;
26012625
CHECK_OK(srtp_create(&srtp_snd, &policy));
2602-
CHECK_OK(srtp_set_stream_use_cryptex(srtp_snd, &policy.ssrc));
2626+
CHECK_OK(srtp_set_stream_use_cryptex(srtp_snd, &policy.ssrc, 1));
26032627

26042628
char packet[1400];
26052629
int packet_len =
@@ -2613,6 +2637,76 @@ srtp_err_status_t srtp_test_cryptex_csrc_but_no_extension_header(void)
26132637
return srtp_err_status_ok;
26142638
}
26152639

2640+
srtp_err_status_t srtp_test_cryptex_disable(void)
2641+
{
2642+
srtp_policy_t policy;
2643+
memset(&policy, 0, sizeof(policy));
2644+
srtp_crypto_policy_set_rtp_default(&policy.rtp);
2645+
srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
2646+
policy.ssrc.type = ssrc_specific;
2647+
policy.ssrc.value = 0xcafebabe;
2648+
policy.key = test_key;
2649+
policy.window_size = 128;
2650+
policy.allow_repeat_tx = 0;
2651+
policy.next = NULL;
2652+
2653+
srtp_t srtp_snd, srtp_recv;
2654+
CHECK_OK(srtp_create(&srtp_snd, &policy));
2655+
CHECK_OK(srtp_set_stream_use_cryptex(srtp_snd, &policy.ssrc, 1));
2656+
CHECK_OK(srtp_create(&srtp_recv, &policy));
2657+
CHECK_OK(srtp_set_stream_use_cryptex(srtp_recv, &policy.ssrc, 1));
2658+
2659+
int packet_len;
2660+
srtp_hdr_t *packet =
2661+
srtp_create_test_packet_ext_hdr(100, policy.ssrc.value, &packet_len);
2662+
uint8_t clear_text[1400];
2663+
memcpy(clear_text, packet, packet_len);
2664+
int clear_text_len = packet_len;
2665+
2666+
CHECK_OK(srtp_protect(srtp_snd, packet, &packet_len));
2667+
CHECK(packet_len > clear_text_len);
2668+
CHECK(srtp_octet_string_is_eq((uint8_t *)packet, clear_text,
2669+
clear_text_len) != 0);
2670+
2671+
// clear text uses original one byte header extension profile
2672+
CHECK(srtp_get_xtn_profile(clear_text) == 0xbede);
2673+
// packet uses cryptex one byte header extension profile
2674+
CHECK(srtp_get_xtn_profile((uint8_t *)packet) == 0xc0de);
2675+
2676+
CHECK_OK(srtp_unprotect(srtp_recv, packet, &packet_len));
2677+
CHECK(packet_len == clear_text_len);
2678+
CHECK_BUFFER_EQUAL((char *)packet, (char *)clear_text, clear_text_len);
2679+
2680+
// update squence number for next packet
2681+
srtp_hdr_t *hdr = (srtp_hdr_t *)packet;
2682+
hdr->seq = htons(ntohs(hdr->seq) + 1);
2683+
memcpy(clear_text, packet, packet_len);
2684+
2685+
// disbale cryptex at sender only
2686+
CHECK_OK(srtp_set_stream_use_cryptex(srtp_snd, &policy.ssrc, 0));
2687+
2688+
CHECK_OK(srtp_protect(srtp_snd, packet, &packet_len));
2689+
CHECK(packet_len > clear_text_len);
2690+
CHECK(srtp_octet_string_is_eq((uint8_t *)packet, clear_text,
2691+
clear_text_len) != 0);
2692+
2693+
// both use original one byte header extension profile as cryptex is
2694+
// disabled
2695+
CHECK(srtp_get_xtn_profile(clear_text) == 0xbede);
2696+
CHECK(srtp_get_xtn_profile((uint8_t *)packet) == 0xbede);
2697+
2698+
// unprotect should work as cryptex is detected dynamically
2699+
CHECK_OK(srtp_unprotect(srtp_recv, packet, &packet_len));
2700+
CHECK(packet_len == clear_text_len);
2701+
CHECK_BUFFER_EQUAL((char *)packet, (char *)clear_text, clear_text_len);
2702+
2703+
free(packet);
2704+
CHECK_OK(srtp_dealloc(srtp_snd));
2705+
CHECK_OK(srtp_dealloc(srtp_recv));
2706+
2707+
return srtp_err_status_ok;
2708+
}
2709+
26162710
#ifdef GCM
26172711
/*
26182712
* srtp_validate_gcm() verifies the correctness of libsrtp by comparing
@@ -3011,7 +3105,7 @@ srtp_err_status_t srtp_validate_gcm_cryptex(void)
30113105
policy.next = NULL;
30123106

30133107
CHECK_OK(srtp_create(&srtp_snd, &policy));
3014-
CHECK_OK(srtp_set_stream_use_cryptex(srtp_snd, &policy.ssrc));
3108+
CHECK_OK(srtp_set_stream_use_cryptex(srtp_snd, &policy.ssrc, 1));
30153109

30163110
for (size_t i = 0; i < num_vectors; ++i) {
30173111
char packet[1400];
@@ -3051,7 +3145,7 @@ srtp_err_status_t srtp_validate_gcm_cryptex(void)
30513145
* complain
30523146
*/
30533147
CHECK_OK(srtp_create(&srtp_recv, &policy));
3054-
CHECK_OK(srtp_set_stream_use_cryptex(srtp_recv, &policy.ssrc));
3148+
CHECK_OK(srtp_set_stream_use_cryptex(srtp_recv, &policy.ssrc, 1));
30553149

30563150
/*
30573151
* unprotect ciphertext, then compare with plaintext

0 commit comments

Comments
 (0)