Skip to content
Merged
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
4 changes: 2 additions & 2 deletions srtp/srtp.c
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ static srtp_err_status_t srtp_cryptex_unprotect_init(
size_t *enc_start)
{
if (stream->use_cryptex && hdr->x == 1) {
uint16_t profile = srtp_get_rtp_hdr_xtnd_profile(hdr, rtp);
uint16_t profile = srtp_get_rtp_hdr_xtnd_profile(hdr, srtp);
*inuse = profile == cryptex_one_byte_profile ||
profile == cryptex_two_byte_profile;
} else {
Expand All @@ -255,7 +255,7 @@ static srtp_err_status_t srtp_cryptex_unprotect_init(

if (*inuse) {
*enc_start -=
(srtp_get_rtp_hdr_xtnd_len(hdr, rtp) - octets_in_rtp_xtn_hdr);
(srtp_get_rtp_hdr_xtnd_len(hdr, srtp) - octets_in_rtp_xtn_hdr);
if (*inplace) {
*enc_start -= (hdr->cc * 4);
}
Expand Down
95 changes: 95 additions & 0 deletions test/srtp_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ srtp_err_status_t srtp_test_set_sender_roc(void);

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_cryptex_not_in_place_distinct_buffer(void);

srtp_err_status_t srtp_test_missing_session_keys(void);

Expand Down Expand Up @@ -1002,6 +1003,15 @@ int main(int argc, char *argv[])
exit(1);
}

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

printf("testing missing session keys handling()...");
if (srtp_test_missing_session_keys() == srtp_err_status_ok) {
printf("passed\n");
Expand Down Expand Up @@ -3381,6 +3391,91 @@ srtp_err_status_t srtp_validate_cryptex(void)
return srtp_err_status_ok;
}

/*
* srtp_test_cryptex_not_in_place_distinct_buffer() unprotects a Cryptex
* (RFC 9335) packet using the not-in-place form of the API, with an output
* buffer that is genuinely distinct from the input buffer and does not
* already contain a copy of the ciphertext.
*
* srtp_unprotect() documents that rtp "can be the same as srtp to support
* in-place io", so a separate buffer is a supported calling mode. The
* existing not-in-place coverage in this driver copies the packet into a
* scratch input buffer and passes the original packet buffer as the output,
* so the output buffer happens to hold the ciphertext already. That masks
* any read of the header extension from the output buffer instead of the
* input buffer.
*/
srtp_err_status_t srtp_test_cryptex_not_in_place_distinct_buffer(void)
{
// clang-format off
/* Plaintext packet with 1-byte header extension */
const char *plaintext_ref =
"900f1235"
"decafbad"
"cafebabe"
"bede0001"
"51000200"
"abababab"
"abababab"
"abababab"
"abababab";

/* AES-CTR/HMAC-SHA1 Cryptex ciphertext of the packet above */
const char *ciphertext_ref =
"900f1235"
"decafbad"
"cafebabe"
"c0de0001"
"eb923652"
"51c3e036"
"f8de27e9"
"c27ee3e0"
"b4651d9f"
"bc4218a7"
"0244522f"
"34a5";
// clang-format on

srtp_t srtp_recv;
srtp_policy_t policy;
uint8_t reference[1400];
uint8_t ciphertext[1400];
uint8_t output[1400];
size_t ref_len, enc_len, out_len;

ref_len = hex_string_to_octet_string(reference, plaintext_ref,
sizeof(reference)) /
2;
enc_len = hex_string_to_octet_string(ciphertext, ciphertext_ref,
sizeof(ciphertext)) /
2;

CHECK_OK(srtp_policy_create(&policy));
CHECK_OK(srtp_policy_set_profile(policy, srtp_profile_aes128_cm_sha1_80));
CHECK_OK(srtp_policy_set_ssrc(policy,
(srtp_ssrc_t){ ssrc_specific, 0xcafebabe }));
CHECK_OK(policy_set_key(policy, test_key));
CHECK_OK(srtp_policy_set_cryptex(policy, true));

CHECK_OK(srtp_create(&srtp_recv, policy));

/*
* The output buffer is deliberately not seeded with the ciphertext. A
* caller that hands libsrtp a fresh output buffer is doing nothing wrong.
*/
memset(output, 0, sizeof(output));
out_len = sizeof(output);

CHECK_OK(srtp_unprotect(srtp_recv, ciphertext, enc_len, output, &out_len));
CHECK(out_len == ref_len);
CHECK_BUFFER_EQUAL(output, reference, ref_len);

CHECK_OK(srtp_dealloc(srtp_recv));
srtp_policy_destroy(policy);

return srtp_err_status_ok;
}

srtp_err_status_t srtp_test_cryptex_csrc_but_no_extension_header(void)
{
// clang-format off
Expand Down
Loading