From ae906a3123a40fe68e83d09e5bacbb24943aa236 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pascal=20B=C3=BChler?= Date: Sun, 23 Nov 2025 22:40:56 +0100 Subject: [PATCH 1/2] backport cryptex to v2 branch This backports cryptex support added in #551 (76f23aa). The tests are nearly unchanged but the code was slightly simplified as non-in-place io is not supported in the v2 branch. #777 --- include/srtp.h | 5 +- include/srtp_priv.h | 1 + srtp/srtp.c | 210 ++++++++++++++ test/srtp_driver.c | 653 +++++++++++++++++++++++++++++++++++++++++++- test/util.c | 108 ++++++++ test/util.h | 33 +++ 6 files changed, 1008 insertions(+), 2 deletions(-) diff --git a/include/srtp.h b/include/srtp.h index 73a38b3c8..a2379b648 100644 --- a/include/srtp.h +++ b/include/srtp.h @@ -211,8 +211,9 @@ typedef enum { /**< invalid */ srtp_err_status_pkt_idx_old = 26, /**< packet index is too old to */ /**< consider */ - srtp_err_status_pkt_idx_adv = 27 /**< packet index advanced, reset */ + srtp_err_status_pkt_idx_adv = 27, /**< packet index advanced, reset */ /**< needed */ + srtp_err_status_cryptex_err = 28 /**< cryptex error */ } srtp_err_status_t; typedef struct srtp_ctx_t_ srtp_ctx_t; @@ -350,6 +351,8 @@ typedef struct srtp_policy_t { int *enc_xtn_hdr; /**< List of header ids to encrypt. */ int enc_xtn_hdr_count; /**< Number of entries in list of header */ /**< ids. */ + int use_cryptex; /**< Encrypt header block and CSRCs with */ + /**< cryptex. */ struct srtp_policy_t *next; /**< Pointer to next stream policy. */ } srtp_policy_t; diff --git a/include/srtp_priv.h b/include/srtp_priv.h index 8e7848989..47b4c3eb1 100644 --- a/include/srtp_priv.h +++ b/include/srtp_priv.h @@ -143,6 +143,7 @@ typedef struct srtp_stream_ctx_t_ { int allow_repeat_tx; int *enc_xtn_hdr; int enc_xtn_hdr_count; + int use_cryptex; uint32_t pending_roc; /* The next and prev pointers are here to allow for a stream list to be diff --git a/srtp/srtp.c b/srtp/srtp.c index 9990f1743..3b7740886 100644 --- a/srtp/srtp.c +++ b/srtp/srtp.c @@ -77,6 +77,12 @@ srtp_debug_module_t mod_srtp = { #define octets_in_rtcp_header 8 #define octets_in_rtp_xtn_hdr 4 +static const uint16_t xtn_hdr_one_byte_profile = 0xbede; +static const uint16_t xtn_hdr_two_byte_profile = 0x1000; + +static const uint16_t cryptex_one_byte_profile = 0xc0de; +static const uint16_t cryptex_two_byte_profile = 0xc2de; + static uint32_t srtp_get_rtp_hdr_len(const srtp_hdr_t *hdr) { return octets_in_rtp_header + 4 * hdr->cc; @@ -133,6 +139,134 @@ static srtp_err_status_t srtp_validate_rtp_header(const void *rtp_hdr, return srtp_err_status_ok; } +static uint16_t srtp_get_rtp_xtn_hdr_profile(const srtp_hdr_t *hdr, + const uint8_t *rtp) +{ + const srtp_hdr_xtnd_t *xtn_hdr = + (const srtp_hdr_xtnd_t *)(rtp + srtp_get_rtp_hdr_len(hdr)); + return ntohs(xtn_hdr->profile_specific); +} + +static void srtp_cryptex_adjust_buffer(const srtp_hdr_t *hdr, uint8_t *rtp) +{ + if (hdr->cc) { + uint8_t tmp[4]; + uint8_t *ptr = rtp + srtp_get_rtp_hdr_len(hdr); + size_t cc_list_size = hdr->cc * 4; + memcpy(tmp, ptr, 4); + ptr -= cc_list_size; + memmove(ptr + 4, ptr, cc_list_size); + memcpy(ptr, tmp, 4); + } +} + +static void srtp_cryptex_restore_buffer(const srtp_hdr_t *hdr, uint8_t *rtp) +{ + if (hdr->cc) { + uint8_t tmp[4]; + uint8_t *ptr = rtp + octets_in_rtp_header; + size_t cc_list_size = hdr->cc * 4; + memcpy(tmp, ptr, 4); + memmove(ptr, ptr + 4, cc_list_size); + ptr += cc_list_size; + memcpy(ptr, tmp, 4); + } +} + +static srtp_err_status_t srtp_cryptex_protect_init( + const srtp_stream_ctx_t *stream, + srtp_hdr_t *hdr, + int *inuse, + uint8_t **enc_start) +{ + if (stream->use_cryptex && (stream->rtp_services & sec_serv_conf)) { + if (hdr->cc && hdr->x == 0) { + /* Cryptex can only encrypt CSRCs if header extension is present */ + return srtp_err_status_cryptex_err; + } + *inuse = hdr->x == 1; + } else { + *inuse = 0; + } + + if (*inuse) { + srtp_hdr_xtnd_t *xtn_hdr = srtp_get_rtp_xtn_hdr(hdr); + *enc_start -= + (srtp_get_rtp_xtn_hdr_len(xtn_hdr) - octets_in_rtp_xtn_hdr); + *enc_start -= (hdr->cc * 4); + } + + return srtp_err_status_ok; +} + +static srtp_err_status_t srtp_cryptex_protect(srtp_hdr_t *hdr, uint8_t *rtp) +{ + srtp_hdr_xtnd_t *xtn_hdr = srtp_get_rtp_xtn_hdr(hdr); + uint16_t profile = ntohs(xtn_hdr->profile_specific); + if (profile == xtn_hdr_one_byte_profile) { + xtn_hdr->profile_specific = htons(cryptex_one_byte_profile); + } else if (profile == xtn_hdr_two_byte_profile) { + xtn_hdr->profile_specific = htons(cryptex_two_byte_profile); + } else { + return srtp_err_status_parse_err; + } + + srtp_cryptex_adjust_buffer(hdr, rtp); + + return srtp_err_status_ok; +} + +static void srtp_cryptex_protect_cleanup(const srtp_hdr_t *hdr, uint8_t *rtp) +{ + srtp_cryptex_restore_buffer(hdr, rtp); +} + +static srtp_err_status_t srtp_cryptex_unprotect_init( + const srtp_stream_ctx_t *stream, + srtp_hdr_t *hdr, + uint8_t *rtp, + int *inuse, + uint8_t **enc_start) +{ + if (stream->use_cryptex && hdr->x == 1) { + uint16_t profile = srtp_get_rtp_xtn_hdr_profile(hdr, rtp); + *inuse = profile == cryptex_one_byte_profile || + profile == cryptex_two_byte_profile; + } else { + *inuse = 0; + } + + if (*inuse) { + srtp_hdr_xtnd_t *xtn_hdr = srtp_get_rtp_xtn_hdr(hdr); + *enc_start -= + (srtp_get_rtp_xtn_hdr_len(xtn_hdr) - octets_in_rtp_xtn_hdr); + *enc_start -= (hdr->cc * 4); + } + + return srtp_err_status_ok; +} + +static srtp_err_status_t srtp_cryptex_unprotect(const srtp_hdr_t *hdr, + uint8_t *rtp) +{ + srtp_cryptex_adjust_buffer(hdr, rtp); + + return srtp_err_status_ok; +} + +static void srtp_cryptex_unprotect_cleanup(srtp_hdr_t *hdr, uint8_t *rtp) +{ + srtp_cryptex_restore_buffer(hdr, rtp); + + srtp_hdr_xtnd_t *xtn_hdr = srtp_get_rtp_xtn_hdr(hdr); + uint16_t profile = ntohs(xtn_hdr->profile_specific); + if (profile == cryptex_one_byte_profile) { + xtn_hdr->profile_specific = htons(xtn_hdr_one_byte_profile); + } else if (profile == cryptex_two_byte_profile) { + xtn_hdr->profile_specific = htons(xtn_hdr_two_byte_profile); + } +} + const char *srtp_get_version_string(void) { /* @@ -507,6 +641,8 @@ static srtp_err_status_t srtp_stream_alloc(srtp_stream_ctx_t **str_ptr, str->enc_xtn_hdr_count = 0; } + str->use_cryptex = p->use_cryptex; + return srtp_err_status_ok; } @@ -615,6 +751,7 @@ static srtp_err_status_t srtp_stream_clone( /* copy information about extensions header encryption */ str->enc_xtn_hdr = stream_template->enc_xtn_hdr; str->enc_xtn_hdr_count = stream_template->enc_xtn_hdr_count; + str->use_cryptex = stream_template->use_cryptex; /* defensive coding */ str->next = NULL; @@ -1894,6 +2031,12 @@ static srtp_err_status_t srtp_protect_aead(srtp_ctx_t *ctx, xtn_hdr = srtp_get_rtp_xtn_hdr(hdr); enc_start += srtp_get_rtp_xtn_hdr_len(xtn_hdr); } + + int cryptex_inuse = 0; + status = srtp_cryptex_protect_init(stream, hdr, &cryptex_inuse, &enc_start); + if (status) { + return status; + } /* note: the passed size is without the auth tag */ if (!(enc_start <= (uint8_t *)hdr + *pkt_octet_len)) return srtp_err_status_parse_err; @@ -1967,6 +2110,13 @@ static srtp_err_status_t srtp_protect_aead(srtp_ctx_t *ctx, } } + if (cryptex_inuse) { + status = srtp_cryptex_protect(hdr, (uint8_t *)hdr); + if (status) { + return status; + } + } + /* * Set the AAD over the RTP header */ @@ -1996,6 +2146,10 @@ static srtp_err_status_t srtp_protect_aead(srtp_ctx_t *ctx, mki_location = (uint8_t *)hdr + *pkt_octet_len + tag_len; mki_size = srtp_inject_mki(mki_location, session_keys, use_mki); + if (cryptex_inuse) { + srtp_cryptex_protect_cleanup(hdr, (uint8_t *)hdr); + } + /* increase the packet length by the length of the auth tag */ *pkt_octet_len += tag_len; @@ -2076,6 +2230,14 @@ static srtp_err_status_t srtp_unprotect_aead(srtp_ctx_t *ctx, xtn_hdr = srtp_get_rtp_xtn_hdr(hdr); enc_start += srtp_get_rtp_xtn_hdr_len(xtn_hdr); } + + int cryptex_inuse = 0; + status = srtp_cryptex_unprotect_init(stream, hdr, (uint8_t *)hdr, + &cryptex_inuse, &enc_start); + if (status) { + return status; + } + if (!(enc_start <= (uint8_t *)hdr + (*pkt_octet_len - tag_len - mki_size))) return srtp_err_status_parse_err; /* @@ -2111,6 +2273,13 @@ static srtp_err_status_t srtp_unprotect_aead(srtp_ctx_t *ctx, break; } + if (cryptex_inuse) { + status = srtp_cryptex_unprotect(hdr, (uint8_t *)hdr); + if (status) { + return status; + } + } + /* * Set the AAD for AES-GCM, which is the RTP header */ @@ -2139,6 +2308,10 @@ static srtp_err_status_t srtp_unprotect_aead(srtp_ctx_t *ctx, } } + if (cryptex_inuse) { + srtp_cryptex_unprotect_cleanup(hdr, (uint8_t *)hdr); + } + /* * verify that stream is for received traffic - this check will * detect SSRC collisions, since a stream that appears in both @@ -2240,6 +2413,7 @@ srtp_err_status_t srtp_protect_mki(srtp_ctx_t *ctx, unsigned int mki_size = 0; srtp_session_keys_t *session_keys = NULL; uint8_t *mki_location = NULL; + int cryptex_inuse = 0; debug_print0(mod_srtp, "function srtp_protect"); @@ -2355,6 +2529,13 @@ srtp_err_status_t srtp_protect_mki(srtp_ctx_t *ctx, xtn_hdr = srtp_get_rtp_xtn_hdr(hdr); enc_start += srtp_get_rtp_xtn_hdr_len(xtn_hdr); } + + status = + srtp_cryptex_protect_init(stream, hdr, &cryptex_inuse, &enc_start); + if (status) { + return status; + } + /* note: the passed size is without the auth tag */ if (!(enc_start <= (uint8_t *)hdr + *pkt_octet_len)) return srtp_err_status_parse_err; @@ -2489,6 +2670,13 @@ srtp_err_status_t srtp_protect_mki(srtp_ctx_t *ctx, } } + if (cryptex_inuse) { + status = srtp_cryptex_protect(hdr, (uint8_t *)hdr); + if (status) { + return status; + } + } + /* if we're encrypting, exor keystream into the message */ if (enc_start) { status = srtp_cipher_encrypt(session_keys->rtp_cipher, enc_start, @@ -2497,6 +2685,10 @@ srtp_err_status_t srtp_protect_mki(srtp_ctx_t *ctx, return srtp_err_status_cipher_fail; } + if (cryptex_inuse) { + srtp_cryptex_protect_cleanup(hdr, (uint8_t *)hdr); + } + /* * if we're authenticating, run authentication function and put result * into the auth_tag @@ -2566,6 +2758,7 @@ srtp_err_status_t srtp_unprotect_mki(srtp_ctx_t *ctx, int advance_packet_index = 0; uint32_t roc_to_set = 0; uint16_t seq_to_set = 0; + int cryptex_inuse = 0; debug_print0(mod_srtp, "function srtp_unprotect"); @@ -2726,6 +2919,12 @@ srtp_err_status_t srtp_unprotect_mki(srtp_ctx_t *ctx, xtn_hdr = srtp_get_rtp_xtn_hdr(hdr); enc_start += srtp_get_rtp_xtn_hdr_len(xtn_hdr); } + + status = srtp_cryptex_unprotect_init(stream, hdr, (uint8_t *)hdr, + &cryptex_inuse, &enc_start); + if (status) { + return status; + } if (!(enc_start <= (uint8_t *)hdr + (*pkt_octet_len - tag_len - mki_size))) return srtp_err_status_parse_err; @@ -2822,6 +3021,13 @@ srtp_err_status_t srtp_unprotect_mki(srtp_ctx_t *ctx, } } + if (cryptex_inuse) { + status = srtp_cryptex_unprotect(hdr, (uint8_t *)hdr); + if (status) { + return status; + } + } + /* if we're decrypting, add keystream into ciphertext */ if (enc_start) { status = srtp_cipher_decrypt(session_keys->rtp_cipher, enc_start, @@ -2830,6 +3036,10 @@ srtp_err_status_t srtp_unprotect_mki(srtp_ctx_t *ctx, return srtp_err_status_cipher_fail; } + if (cryptex_inuse) { + srtp_cryptex_unprotect_cleanup(hdr, (uint8_t *)hdr); + } + /* * verify that stream is for received traffic - this check will * detect SSRC collisions, since a stream that appears in both diff --git a/test/srtp_driver.c b/test/srtp_driver.c index f544544d9..73ba49d20 100644 --- a/test/srtp_driver.c +++ b/test/srtp_driver.c @@ -66,10 +66,13 @@ srtp_err_status_t srtp_validate_null_sha1_80(void); srtp_err_status_t srtp_validate_null_null(void); +srtp_err_status_t srtp_validate_cryptex(void); + #ifdef GCM srtp_err_status_t srtp_validate_gcm(void); -#endif +srtp_err_status_t srtp_validate_gcm_cryptex(void); +#endif srtp_err_status_t srtp_validate_encrypted_extensions_headers(void); #ifdef GCM @@ -108,6 +111,8 @@ srtp_err_status_t srtp_test_set_receiver_roc(void); srtp_err_status_t srtp_test_set_sender_roc(void); +srtp_err_status_t srtp_test_cryptex_csrc_but_no_extension_header(void); + double srtp_bits_per_second(int msg_len_octets, const srtp_policy_t *policy); double srtp_rejections_per_second(int msg_len_octets, @@ -136,6 +141,12 @@ srtp_err_status_t srtp_stream_list_test(void); #define TEST_MKI_ID_SIZE 4 +typedef struct test_vectors_t { + const char *name; + char *plaintext; + char *ciphertext; +} test_vectors_t; + extern uint8_t test_key[46]; extern uint8_t test_key_2[46]; extern uint8_t test_mki_id[TEST_MKI_ID_SIZE]; @@ -481,6 +492,15 @@ int main(int argc, char *argv[]) exit(1); } + printf("testing srtp_protect and srtp_unprotect against " + "reference cryptex packet\n"); + if (srtp_validate_cryptex() == srtp_err_status_ok) { + printf("passed\n\n"); + } else { + printf("failed\n"); + exit(1); + } + #ifdef GCM printf("testing srtp_protect and srtp_unprotect against " "reference packet using GCM\n"); @@ -490,6 +510,15 @@ int main(int argc, char *argv[]) printf("failed\n"); exit(1); } + + printf("testing srtp_protect and srtp_unprotect against " + "reference cryptex packet using GCM\n"); + if (srtp_validate_gcm_cryptex() == srtp_err_status_ok) { + printf("passed\n\n"); + } else { + printf("failed\n"); + exit(1); + } #endif printf("testing srtp_protect and srtp_unprotect against " @@ -636,6 +665,15 @@ int main(int argc, char *argv[]) printf("failed\n"); exit(1); } + + printf("testing cryptex_csrc_but_no_extension_header()..."); + if (srtp_test_cryptex_csrc_but_no_extension_header() == + srtp_err_status_ok) { + printf("passed\n"); + } else { + printf("failed\n"); + exit(1); + } } if (do_stream_list) { @@ -2260,6 +2298,320 @@ srtp_err_status_t srtp_validate_null_null(void) return srtp_err_status_ok; } +/* + * srtp_validate_cryptex() verifies the correctness of libsrtp by comparing + * some computed packets against some pre-computed reference values. + * These packets were made with the default SRTP policy. + */ +srtp_err_status_t srtp_validate_cryptex(void) +{ + // clang-format off + /* Plaintext packet with 1-byte header extension */ + char *srtp_1bytehdrext_ref = + "900f1235" + "decafbad" + "cafebabe" + "bede0001" + "51000200" + "abababab" + "abababab" + "abababab" + "abababab"; + + /* AES-CTR/HMAC-SHA1 Ciphertext packet with 1-byte header extension */ + char *srtp_1bytehdrext_cryptex = + "900f1235" + "decafbad" + "cafebabe" + "c0de0001" + "eb923652" + "51c3e036" + "f8de27e9" + "c27ee3e0" + "b4651d9f" + "bc4218a7" + "0244522f" + "34a5"; + + /* Plaintext packet with 2-byte header extension */ + char *srtp_2bytehdrext_ref = + "900f1236" + "decafbad" + "cafebabe" + "10000001" + "05020002" + "abababab" + "abababab" + "abababab" + "abababab"; + + /* AES-CTR/HMAC-SHA1 Ciphertext packet with 2-byte header extension */ + char *srtp_2bytehdrext_cryptex = + "900f1236" + "decafbad" + "cafebabe" + "c2de0001" + "4ed9cc4e" + "6a712b30" + "96c5ca77" + "339d4204" + "ce0d7739" + "6cab6958" + "5fbce381" + "94a5"; + + /* Plaintext packet with 1-byte header extension and CSRC fields. */ + char *srtp_1bytehdrext_cc_ref = + "920f1238" + "decafbad" + "cafebabe" + "0001e240" + "0000b26e" + "bede0001" + "51000200" + "abababab" + "abababab" + "abababab" + "abababab"; + + char *srtp_1bytehdrext_cc_cryptex = + "920f1238" + "decafbad" + "cafebabe" + "8bb6e12b" + "5cff16dd" + "c0de0001" + "92838c8c" + "09e58393" + "e1de3a9a" + "74734d67" + "45671338" + "c3acf11d" + "a2df8423" + "bee0"; + + /* Plaintext packet with 2-byte header extension and CSRC fields. */ + char *srtp_2bytehdrext_cc_ref = + "920f1239" + "decafbad" + "cafebabe" + "0001e240" + "0000b26e" + "10000001" + "05020002" + "abababab" + "abababab" + "abababab" + "abababab"; + + char *srtp_2bytehdrext_cc_cryptex = + "920f1239" + "decafbad" + "cafebabe" + "f70e513e" + "b90b9b25" + "c2de0001" + "bbed4848" + "faa64466" + "5f3d7f34" + "125914e9" + "f4d0ae92" + "3c6f479b" + "95a0f7b5" + "3133"; + + /* Plaintext packet with empty 1-byte header extension and CSRC fields. */ + char *srtp_1byte_empty_hdrext_cc_ref = + "920f123a" + "decafbad" + "cafebabe" + "0001e240" + "0000b26e" + "bede0000" + "abababab" + "abababab" + "abababab" + "abababab"; + + char *srtp_1byte_empty_hdrext_cc_cryptex = + "920f123a" + "decafbad" + "cafebabe" + "7130b6ab" + "fe2ab0e3" + "c0de0000" + "e3d9f64b" + "25c9e74c" + "b4cf8e43" + "fb92e378" + "1c2c0cea" + "b6b3a499" + "a14c"; + + /* Plaintext packet with empty 2-byte header extension and CSRC fields. */ + char *srtp_2byte_empty_hdrext_cc_ref = + "920f123b" + "decafbad" + "cafebabe" + "0001e240" + "0000b26e" + "10000000" + "abababab" + "abababab" + "abababab" + "abababab"; + + char *srtp_2byte_empty_hdrext_cc_cryptex = + "920f123b" + "decafbad" + "cafebabe" + "cbf24c12" + "4330e1c8" + "c2de0000" + "599dd45b" + "c9d687b6" + "03e8b59d" + "771fd38e" + "88b170e0" + "cd31e125" + "eabe"; + + // clang-format on + + const struct test_vectors_t vectors[6] = { + { "Plaintext packet with 1-byte header extension", srtp_1bytehdrext_ref, + srtp_1bytehdrext_cryptex }, + { "Plaintext packet with 2-byte header extension", srtp_2bytehdrext_ref, + srtp_2bytehdrext_cryptex }, + { "Plaintext packet with 1-byte header extension and CSRC fields", + srtp_1bytehdrext_cc_ref, srtp_1bytehdrext_cc_cryptex }, + { "Plaintext packet with 2-byte header extension and CSRC fields", + srtp_2bytehdrext_cc_ref, srtp_2bytehdrext_cc_cryptex }, + { "Plaintext packet with empty 1-byte header extension and CSRC fields", + srtp_1byte_empty_hdrext_cc_ref, srtp_1byte_empty_hdrext_cc_cryptex }, + { "Plaintext packet with empty 2-byte header extension and CSRC fields", + srtp_2byte_empty_hdrext_cc_ref, srtp_2byte_empty_hdrext_cc_cryptex }, + }; + const size_t num_vectors = sizeof(vectors) / sizeof(vectors[0]); + + srtp_t srtp_snd, srtp_recv; + int len, ref_len, enc_len; + srtp_policy_t policy; + + /* + * create a session with a single stream using the default srtp + * policy and with the SSRC value 0xcafebabe + */ + 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.use_cryptex = 1; + policy.next = NULL; + + for (size_t i = 0; i < num_vectors; ++i) { + char packet[1400]; + char reference[1400]; + char ciphertext[1400]; + + /* Initialize reference test vectors */ + ref_len = hex_string_to_octet_string(reference, vectors[i].plaintext, + sizeof(reference)) / + 2; + enc_len = hex_string_to_octet_string(ciphertext, vectors[i].ciphertext, + sizeof(ciphertext)) / + 2; + + /* Initialize test packet */ + len = ref_len; + memcpy(packet, reference, len); + printf("%s\n", vectors[i].name); + /* + * protect plaintext, then compare with ciphertext + */ + debug_print(mod_driver, "test vector: %s\n", vectors[i].name); + + CHECK_OK(srtp_create(&srtp_snd, &policy)); + + CHECK_OK(srtp_protect(srtp_snd, packet, &len)); + CHECK(len == enc_len); + + debug_print(mod_driver, "ciphertext:\n %s", + octet_string_hex_string(packet, len)); + debug_print(mod_driver, "ciphertext reference:\n %s", + octet_string_hex_string(ciphertext, len)); + + CHECK_BUFFER_EQUAL(packet, ciphertext, len); + + CHECK_OK(srtp_dealloc(srtp_snd)); + + CHECK_OK(srtp_create(&srtp_recv, &policy)); + + /* + * unprotect ciphertext, then compare with plaintext + */ + CHECK_OK(srtp_unprotect(srtp_recv, packet, &len)); + CHECK(len == ref_len); + + CHECK_BUFFER_EQUAL(packet, reference, len); + + CHECK_OK(srtp_dealloc(srtp_recv)); + } + + return srtp_err_status_ok; +} + +srtp_err_status_t srtp_test_cryptex_csrc_but_no_extension_header(void) +{ + // clang-format off + /* Plaintext packet with no header extension but CSRC fields. */ + char *srtp_cc_ref = + "820f1238" + "decafbad" + "cafebabe" + "0001e240" + "0000b26e" + "abababab" + "abababab" + "abababab" + "abababab"; + // clang-format on + + /* + * create a session with a single stream using the default srtp + * policy and with the SSRC value 0xcafebabe + */ + 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.use_cryptex = 1; + policy.next = NULL; + + srtp_t srtp_snd; + CHECK_OK(srtp_create(&srtp_snd, &policy)); + + char packet[1400]; + int packet_len = + hex_string_to_octet_string(packet, srtp_cc_ref, sizeof(packet)) / 2; + + CHECK_RETURN(srtp_protect(srtp_snd, packet, &packet_len), + srtp_err_status_cryptex_err); + + CHECK_OK(srtp_dealloc(srtp_snd)); + + return srtp_err_status_ok; +} + #ifdef GCM /* * srtp_validate_gcm() verifies the correctness of libsrtp by comparing @@ -2428,6 +2780,293 @@ srtp_err_status_t srtp_validate_gcm(void) return srtp_err_status_ok; } + +/* + * srtp_validate_gcm() verifies the correctness of libsrtp by comparing + * an computed packet against the known ciphertext for the plaintext. + */ +srtp_err_status_t srtp_validate_gcm_cryptex(void) +{ + // clang-format off + unsigned char test_key_gcm_cryptex[28] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab + }; + + /* Plaintext packet with 1-byte header extension */ + char *srtp_1bytehdrext_ref = + "900f1235" + "decafbad" + "cafebabe" + "bede0001" + "51000200" + "abababab" + "abababab" + "abababab" + "abababab"; + + /* GCM Ciphertext packet with 1-byte header extension */ + char *srtp_1bytehdrext_cryptex_gcm = + "900f1235" + "decafbad" + "cafebabe" + "c0de0001" + "39972dc9" + "572c4d99" + "e8fc355d" + "e743fb2e" + "94f9d8ff" + "54e72f41" + "93bbc5c7" + "4ffab0fa" + "9fa0fbeb"; + + /* Plaintext packet with 2-byte header extension */ + char *srtp_2bytehdrext_ref = + "900f1236" + "decafbad" + "cafebabe" + "10000001" + "05020002" + "abababab" + "abababab" + "abababab" + "abababab"; + + /* GCM Ciphertext packet with 2-byte header extension */ + char *srtp_2bytehdrext_cryptex_gcm = + "900f1236" + "decafbad" + "cafebabe" + "c2de0001" + "bb75a4c5" + "45cd1f41" + "3bdb7daa" + "2b1e3263" + "de313667" + "c9632490" + "81b35a65" + "f5cb6c88" + "b394235f"; + + /* Plaintext packet with 1-byte header extension and CSRC fields. */ + char *srtp_1bytehdrext_cc_ref = + "920f1238" + "decafbad" + "cafebabe" + "0001e240" + "0000b26e" + "bede0001" + "51000200" + "abababab" + "abababab" + "abababab" + "abababab"; + + char *srtp_1bytehdrext_cc_cryptex_gcm = + "920f1238" + "decafbad" + "cafebabe" + "63bbccc4" + "a7f695c4" + "c0de0001" + "8ad7c71f" + "ac70a80c" + "92866b4c" + "6ba98546" + "ef913586" + "e95ffaaf" + "fe956885" + "bb0647a8" + "bc094ac8"; + + + /* Plaintext packet with 2-byte header extension and CSRC fields. */ + char *srtp_2bytehdrext_cc_ref = + "920f1239" + "decafbad" + "cafebabe" + "0001e240" + "0000b26e" + "10000001" + "05020002" + "abababab" + "abababab" + "abababab" + "abababab"; + + char *srtp_2bytehdrext_cc_cryptex_gcm = + "920f1239" + "decafbad" + "cafebabe" + "3680524f" + "8d312b00" + "c2de0001" + "c78d1200" + "38422bc1" + "11a7187a" + "18246f98" + "0c059cc6" + "bc9df8b6" + "26394eca" + "344e4b05" + "d80fea83"; + + /* Plaintext packet with empty 1-byte header extension and CSRC fields. */ + char *srtp_1byte_empty_hdrext_cc_ref = + "920f123a" + "decafbad" + "cafebabe" + "0001e240" + "0000b26e" + "bede0000" + "abababab" + "abababab" + "abababab" + "abababab"; + + char *srtp_1byte_empty_hdrext_cc_cryptex_gcm = + "920f123a" + "decafbad" + "cafebabe" + "15b6bb43" + "37906fff" + "c0de0000" + "b7b96453" + "7a2b03ab" + "7ba5389c" + "e9331712" + "6b5d974d" + "f30c6884" + "dcb651c5" + "e120c1da"; + + /* Plaintext packet with empty 2-byte header extension and CSRC fields. */ + char *srtp_2byte_empty_hdrext_cc_ref = + "920f123b" + "decafbad" + "cafebabe" + "0001e240" + "0000b26e" + "10000000" + "abababab" + "abababab" + "abababab" + "abababab"; + + char *srtp_2byte_empty_hdrext_cc_cryptex_gcm = + "920f123b" + "decafbad" + "cafebabe" + "dcb38c9e" + "48bf95f4" + "c2de0000" + "61ee432c" + "f9203170" + "76613258" + "d3ce4236" + "c06ac429" + "681ad084" + "13512dc9" + "8b5207d8"; + // clang-format on + + const struct test_vectors_t vectors[6] = { + { "Plaintext packet with 1-byte header extension", srtp_1bytehdrext_ref, + srtp_1bytehdrext_cryptex_gcm }, + { "Plaintext packet with 2-byte header extension", srtp_2bytehdrext_ref, + srtp_2bytehdrext_cryptex_gcm }, + { "Plaintext packet with 1-byte header extension and CSRC fields", + srtp_1bytehdrext_cc_ref, srtp_1bytehdrext_cc_cryptex_gcm }, + { "Plaintext packet with 2-byte header extension and CSRC fields", + srtp_2bytehdrext_cc_ref, srtp_2bytehdrext_cc_cryptex_gcm }, + { "Plaintext packet with empty 1-byte header extension and CSRC fields", + srtp_1byte_empty_hdrext_cc_ref, + srtp_1byte_empty_hdrext_cc_cryptex_gcm }, + { "Plaintext packet with empty 2-byte header extension and CSRC fields", + srtp_2byte_empty_hdrext_cc_ref, + srtp_2byte_empty_hdrext_cc_cryptex_gcm }, + }; + const size_t num_vectors = sizeof(vectors) / sizeof(vectors[0]); + + srtp_t srtp_snd, srtp_recv; + int len, ref_len, enc_len; + srtp_policy_t policy; + + /* + * create a session with a single stream using the default srtp + * policy and with the SSRC value 0xcafebabe + */ + memset(&policy, 0, sizeof(policy)); + srtp_crypto_policy_set_aes_gcm_128_16_auth(&policy.rtp); + srtp_crypto_policy_set_aes_gcm_128_16_auth(&policy.rtcp); + policy.ssrc.type = ssrc_specific; + policy.ssrc.value = 0xcafebabe; + policy.key = test_key_gcm_cryptex; + policy.window_size = 128; + policy.allow_repeat_tx = 0; + policy.use_cryptex = 1; + policy.next = NULL; + + CHECK_OK(srtp_create(&srtp_snd, &policy)); + + for (size_t i = 0; i < num_vectors; ++i) { + char packet[1400]; + char reference[1400]; + char ciphertext[1400]; + + /* Initialize reference test vectors */ + ref_len = hex_string_to_octet_string(reference, vectors[i].plaintext, + sizeof(reference)) / + 2; + enc_len = hex_string_to_octet_string(ciphertext, vectors[i].ciphertext, + sizeof(ciphertext)) / + 2; + + /* Initialize test packet */ + len = ref_len; + memcpy(packet, reference, len); + printf("%s\n", vectors[i].name); + /* + * protect plaintext, then compare with ciphertext + */ + debug_print(mod_driver, "test vector: %s\n", vectors[i].name); + + CHECK_OK(srtp_protect(srtp_snd, packet, &len)); + CHECK(len == enc_len); + + debug_print(mod_driver, "ciphertext:\n %s", + octet_string_hex_string(packet, len)); + debug_print(mod_driver, "ciphertext reference:\n %s", + octet_string_hex_string(ciphertext, len)); + + CHECK_BUFFER_EQUAL(packet, ciphertext, len); + + /* + * create a receiver session context comparable to the one created + * above - we need to do this so that the replay checking doesn't + * complain + */ + CHECK_OK(srtp_create(&srtp_recv, &policy)); + + /* + * unprotect ciphertext, then compare with plaintext + */ + CHECK_OK(srtp_unprotect(srtp_recv, packet, &len)); + CHECK(len == ref_len); + + CHECK_BUFFER_EQUAL(packet, reference, len); + + CHECK_OK(srtp_dealloc(srtp_recv)); + } + + CHECK_OK(srtp_dealloc(srtp_snd)); + + return srtp_err_status_ok; +} + #endif /* @@ -4310,6 +4949,7 @@ const srtp_policy_t default_policy = { 0, /* retransmission not allowed */ NULL, /* no encrypted extension headers */ 0, /* list of encrypted extension headers is empty */ + 0, /* no cryptex */ NULL }; @@ -4339,6 +4979,7 @@ const srtp_policy_t aes_only_policy = { 0, /* retransmission not allowed */ NULL, /* no encrypted extension headers */ 0, /* list of encrypted extension headers is empty */ + 0, /* no cryptex */ NULL }; @@ -4368,6 +5009,7 @@ const srtp_policy_t hmac_only_policy = { 0, /* retransmission not allowed */ NULL, /* no encrypted extension headers */ 0, /* list of encrypted extension headers is empty */ + 0, /* no cryptex */ NULL }; @@ -4400,6 +5042,7 @@ const srtp_policy_t aes128_gcm_8_policy = { 0, /* retransmission not allowed */ NULL, /* no encrypted extension headers */ 0, /* list of encrypted extension headers is empty */ + 0, /* no cryptex */ NULL }; @@ -4431,6 +5074,7 @@ const srtp_policy_t aes128_gcm_8_cauth_policy = { 0, /* retransmission not allowed */ NULL, /* no encrypted extension headers */ 0, /* list of encrypted extension headers is empty */ + 0, /* no cryptex */ NULL }; @@ -4462,6 +5106,7 @@ const srtp_policy_t aes256_gcm_8_policy = { 0, /* retransmission not allowed */ NULL, /* no encrypted extension headers */ 0, /* list of encrypted extension headers is empty */ + 0, /* no cryptex */ NULL }; @@ -4493,6 +5138,7 @@ const srtp_policy_t aes256_gcm_8_cauth_policy = { 0, /* retransmission not allowed */ NULL, /* no encrypted extension headers */ 0, /* list of encrypted extension headers is empty */ + 0, /* no cryptex */ NULL }; #endif @@ -4523,6 +5169,7 @@ const srtp_policy_t null_policy = { 0, /* retransmission not allowed */ NULL, /* no encrypted extension headers */ 0, /* list of encrypted extension headers is empty */ + 0, /* no cryptex */ NULL }; @@ -4592,6 +5239,7 @@ const srtp_policy_t aes_256_hmac_policy = { 0, /* retransmission not allowed */ NULL, /* no encrypted extension headers */ 0, /* list of encrypted extension headers is empty */ + 0, /* no cryptex */ NULL }; @@ -4624,6 +5272,7 @@ const srtp_policy_t aes_256_hmac_32_policy = { 0, /* retransmission not allowed */ NULL, /* no encrypted extension headers */ 0, /* list of encrypted extension headers is empty */ + 0, /* no cryptex */ NULL }; @@ -4655,6 +5304,7 @@ const srtp_policy_t hmac_only_with_ekt_policy = { 0, /* retransmission not allowed */ NULL, /* no encrypted extension headers */ 0, /* list of encrypted extension headers is empty */ + 0, /* no cryptex */ NULL }; @@ -4721,6 +5371,7 @@ const srtp_policy_t wildcard_policy = { 0, /* retransmission not allowed */ NULL, /* no encrypted extension headers */ 0, /* list of encrypted extension headers is empty */ + 0, /* no cryptex */ NULL }; diff --git a/test/util.c b/test/util.c index ac2d9a2b7..de95749e2 100644 --- a/test/util.c +++ b/test/util.c @@ -48,9 +48,117 @@ #include #include +#include +#include + /* include space for null terminator */ static char bit_string[MAX_PRINT_STRING_LEN + 1]; +#define ERR_STATUS_STRING(STATUS) \ + case srtp_err_status_##STATUS: \ + return #STATUS + +const char *err_status_string(srtp_err_status_t status) +{ + switch (status) { + ERR_STATUS_STRING(ok); + ERR_STATUS_STRING(fail); + ERR_STATUS_STRING(bad_param); + ERR_STATUS_STRING(alloc_fail); + ERR_STATUS_STRING(dealloc_fail); + ERR_STATUS_STRING(init_fail); + ERR_STATUS_STRING(terminus); + ERR_STATUS_STRING(auth_fail); + ERR_STATUS_STRING(cipher_fail); + ERR_STATUS_STRING(replay_fail); + ERR_STATUS_STRING(replay_old); + ERR_STATUS_STRING(algo_fail); + ERR_STATUS_STRING(no_such_op); + ERR_STATUS_STRING(no_ctx); + ERR_STATUS_STRING(cant_check); + ERR_STATUS_STRING(key_expired); + ERR_STATUS_STRING(socket_err); + ERR_STATUS_STRING(signal_err); + ERR_STATUS_STRING(nonce_bad); + ERR_STATUS_STRING(read_fail); + ERR_STATUS_STRING(write_fail); + ERR_STATUS_STRING(parse_err); + ERR_STATUS_STRING(encode_err); + ERR_STATUS_STRING(semaphore_err); + ERR_STATUS_STRING(pfkey_err); + ERR_STATUS_STRING(bad_mki); + ERR_STATUS_STRING(pkt_idx_old); + ERR_STATUS_STRING(pkt_idx_adv); + ERR_STATUS_STRING(cryptex_err); + } + return "unkown srtp_err_status"; +} + +void check_ok_impl(srtp_err_status_t status, const char *file, int line) +{ + if (status != srtp_err_status_ok) { + fflush(stdout); + fprintf(stderr, + "\nerror at %s:%d, unexpected srtp failure: %d (\"%s\")\n", + file, line, status, err_status_string(status)); + fflush(stderr); + exit(1); + } +} + +void check_return_impl(srtp_err_status_t status, + srtp_err_status_t expected, + const char *file, + int line) +{ + if (status != expected) { + fflush(stdout); + fprintf(stderr, + "\nerror at %s:%d, unexpected srtp status: %d != %d (\"%s\" != " + "\"%s\")\n", + file, line, status, expected, err_status_string(status), + err_status_string(expected)); + fflush(stderr); + exit(1); + } +} + +void check_impl(int condition, + const char *file, + int line, + const char *condition_str) +{ + if (!condition) { + fflush(stdout); + fprintf(stderr, "\nerror at %s:%d, %s)\n", file, line, condition_str); + fflush(stderr); + exit(1); + } +} + +void check_buffer_equal_impl(const char *buffer1, + const char *buffer2, + int buffer_length, + const char *file, + int line) +{ + for (int i = 0; i < buffer_length; i++) { + if (buffer1[i] != buffer2[i]) { + fflush(stdout); + fprintf(stderr, + "\nerror at %s:%d, buffer1 != buffer2 at index: %i (%x != " + "%x)\n", + file, line, i, buffer1[i], buffer2[i]); + fprintf(stderr, "buffer1 = %s\n", + octet_string_hex_string(buffer1, buffer_length)); + fprintf(stderr, "buffer2 = %s\n", + octet_string_hex_string(buffer2, buffer_length)); + fflush(stderr); + exit(1); + } + } +} + static inline int hex_char_to_nibble(uint8_t c) { switch (c) { diff --git a/test/util.h b/test/util.h index d04b279b3..b375a91fa 100644 --- a/test/util.h +++ b/test/util.h @@ -44,6 +44,39 @@ #ifndef SRTP_TEST_UTIL_H #define SRTP_TEST_UTIL_H +#include "srtp.h" + +// test check macros and functions +void check_ok_impl(srtp_err_status_t status, const char *file, int line); +void check_return_impl(srtp_err_status_t status, + srtp_err_status_t expected, + const char *file, + int line); +void check_impl(int condition, + const char *file, + int line, + const char *condition_str); +void check_buffer_equal_impl(const char *buffer1, + const char *buffer2, + int buffer_length, + const char *file, + int line); +void check_overrun_impl(const char *buffer, + int offset, + int buffer_length, + const char *file, + int line); +void overrun_check_prepare(char *buffer, int offset, int buffer_len); + +#define CHECK_OK(status) check_ok_impl((status), __FILE__, __LINE__) +#define CHECK_RETURN(status, expected) \ + check_return_impl((status), (expected), __FILE__, __LINE__) +#define CHECK(condition) check_impl((condition), __FILE__, __LINE__, #condition) +#define CHECK_BUFFER_EQUAL(buffer1, buffer2, length) \ + check_buffer_equal_impl((buffer1), (buffer2), (length), __FILE__, __LINE__) +#define CHECK_OVERRUN(buffer, offset, length) \ + check_overrun_impl((buffer), (offset), (length), __FILE__, __LINE__) + #define MAX_PRINT_STRING_LEN 1024 int hex_string_to_octet_string(char *raw, char *hex, int len); From b456da919d0fde1a376cc36252e5466c4e6f5412 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pascal=20B=C3=BChler?= Date: Wed, 26 Nov 2025 11:27:21 +0100 Subject: [PATCH 2/2] Add cryptex setter API to avoid srtp_policy_t ABI change --- include/srtp.h | 18 ++++++++++++-- srtp/srtp.c | 60 +++++++++++++++++++++++++++++++++++++++++++++- test/srtp_driver.c | 20 ++++------------ 3 files changed, 80 insertions(+), 18 deletions(-) diff --git a/include/srtp.h b/include/srtp.h index a2379b648..2a7337e62 100644 --- a/include/srtp.h +++ b/include/srtp.h @@ -351,8 +351,6 @@ typedef struct srtp_policy_t { int *enc_xtn_hdr; /**< List of header ids to encrypt. */ int enc_xtn_hdr_count; /**< Number of entries in list of header */ /**< ids. */ - int use_cryptex; /**< Encrypt header block and CSRCs with */ - /**< cryptex. */ struct srtp_policy_t *next; /**< Pointer to next stream policy. */ } srtp_policy_t; @@ -1749,6 +1747,22 @@ srtp_err_status_t srtp_get_stream_roc(srtp_t session, uint32_t ssrc, uint32_t *roc); +/** + * @brief srtp_set_stream_use_cryptex(session, ssrc) + * + * Enable cryptex processing for the stream identified by the given SSRC. For + * wildcard SSRC types the 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 enable cryptex for. + * + * @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_use_cryptex(srtp_t session, + const srtp_ssrc_t *ssrc); + /** * @} */ diff --git a/srtp/srtp.c b/srtp/srtp.c index 3b7740886..4fdcb14a1 100644 --- a/srtp/srtp.c +++ b/srtp/srtp.c @@ -641,7 +641,7 @@ static srtp_err_status_t srtp_stream_alloc(srtp_stream_ctx_t **str_ptr, str->enc_xtn_hdr_count = 0; } - str->use_cryptex = p->use_cryptex; + str->use_cryptex = 0; return srtp_err_status_ok; } @@ -5113,6 +5113,64 @@ srtp_err_status_t srtp_get_stream_roc(srtp_t session, return srtp_err_status_ok; } +struct set_cryptex_from_template_data { + const srtp_stream_ctx_t *template; +}; + +static int set_cryptex_from_template_cb(srtp_stream_t stream, void *raw_data) +{ + struct set_cryptex_from_template_data *data = + (struct set_cryptex_from_template_data *)raw_data; + + /* + * Streams cloned from the template share auth cipher pointers with it, + * so use that to identify clones that need updating. + */ + if (stream->session_keys[0].rtp_auth == + data->template->session_keys[0].rtp_auth) { + stream->use_cryptex = 1; + } + + return 0; +} + +srtp_err_status_t srtp_set_stream_use_cryptex(srtp_t session, + const srtp_ssrc_t *ssrc) +{ + 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->use_cryptex = 1; + break; + case ssrc_any_inbound: + case ssrc_any_outbound: { + struct set_cryptex_from_template_data data; + + if (session->stream_template == NULL) { + return srtp_err_status_bad_param; + } + session->stream_template->use_cryptex = 1; + 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 */ diff --git a/test/srtp_driver.c b/test/srtp_driver.c index 73ba49d20..76df0d952 100644 --- a/test/srtp_driver.c +++ b/test/srtp_driver.c @@ -2510,7 +2510,6 @@ srtp_err_status_t srtp_validate_cryptex(void) policy.key = test_key; policy.window_size = 128; policy.allow_repeat_tx = 0; - policy.use_cryptex = 1; policy.next = NULL; for (size_t i = 0; i < num_vectors; ++i) { @@ -2536,6 +2535,7 @@ srtp_err_status_t srtp_validate_cryptex(void) debug_print(mod_driver, "test vector: %s\n", vectors[i].name); CHECK_OK(srtp_create(&srtp_snd, &policy)); + CHECK_OK(srtp_set_stream_use_cryptex(srtp_snd, &policy.ssrc)); CHECK_OK(srtp_protect(srtp_snd, packet, &len)); CHECK(len == enc_len); @@ -2550,6 +2550,7 @@ srtp_err_status_t srtp_validate_cryptex(void) CHECK_OK(srtp_dealloc(srtp_snd)); CHECK_OK(srtp_create(&srtp_recv, &policy)); + CHECK_OK(srtp_set_stream_use_cryptex(srtp_recv, &policy.ssrc)); /* * unprotect ciphertext, then compare with plaintext @@ -2594,11 +2595,11 @@ srtp_err_status_t srtp_test_cryptex_csrc_but_no_extension_header(void) policy.key = test_key; policy.window_size = 128; policy.allow_repeat_tx = 0; - policy.use_cryptex = 1; policy.next = NULL; srtp_t srtp_snd; CHECK_OK(srtp_create(&srtp_snd, &policy)); + CHECK_OK(srtp_set_stream_use_cryptex(srtp_snd, &policy.ssrc)); char packet[1400]; int packet_len = @@ -3007,10 +3008,10 @@ srtp_err_status_t srtp_validate_gcm_cryptex(void) policy.key = test_key_gcm_cryptex; policy.window_size = 128; policy.allow_repeat_tx = 0; - policy.use_cryptex = 1; policy.next = NULL; CHECK_OK(srtp_create(&srtp_snd, &policy)); + CHECK_OK(srtp_set_stream_use_cryptex(srtp_snd, &policy.ssrc)); for (size_t i = 0; i < num_vectors; ++i) { char packet[1400]; @@ -3050,6 +3051,7 @@ srtp_err_status_t srtp_validate_gcm_cryptex(void) * complain */ CHECK_OK(srtp_create(&srtp_recv, &policy)); + CHECK_OK(srtp_set_stream_use_cryptex(srtp_recv, &policy.ssrc)); /* * unprotect ciphertext, then compare with plaintext @@ -4949,7 +4951,6 @@ const srtp_policy_t default_policy = { 0, /* retransmission not allowed */ NULL, /* no encrypted extension headers */ 0, /* list of encrypted extension headers is empty */ - 0, /* no cryptex */ NULL }; @@ -4979,7 +4980,6 @@ const srtp_policy_t aes_only_policy = { 0, /* retransmission not allowed */ NULL, /* no encrypted extension headers */ 0, /* list of encrypted extension headers is empty */ - 0, /* no cryptex */ NULL }; @@ -5009,7 +5009,6 @@ const srtp_policy_t hmac_only_policy = { 0, /* retransmission not allowed */ NULL, /* no encrypted extension headers */ 0, /* list of encrypted extension headers is empty */ - 0, /* no cryptex */ NULL }; @@ -5042,7 +5041,6 @@ const srtp_policy_t aes128_gcm_8_policy = { 0, /* retransmission not allowed */ NULL, /* no encrypted extension headers */ 0, /* list of encrypted extension headers is empty */ - 0, /* no cryptex */ NULL }; @@ -5074,7 +5072,6 @@ const srtp_policy_t aes128_gcm_8_cauth_policy = { 0, /* retransmission not allowed */ NULL, /* no encrypted extension headers */ 0, /* list of encrypted extension headers is empty */ - 0, /* no cryptex */ NULL }; @@ -5106,7 +5103,6 @@ const srtp_policy_t aes256_gcm_8_policy = { 0, /* retransmission not allowed */ NULL, /* no encrypted extension headers */ 0, /* list of encrypted extension headers is empty */ - 0, /* no cryptex */ NULL }; @@ -5138,7 +5134,6 @@ const srtp_policy_t aes256_gcm_8_cauth_policy = { 0, /* retransmission not allowed */ NULL, /* no encrypted extension headers */ 0, /* list of encrypted extension headers is empty */ - 0, /* no cryptex */ NULL }; #endif @@ -5169,7 +5164,6 @@ const srtp_policy_t null_policy = { 0, /* retransmission not allowed */ NULL, /* no encrypted extension headers */ 0, /* list of encrypted extension headers is empty */ - 0, /* no cryptex */ NULL }; @@ -5239,7 +5233,6 @@ const srtp_policy_t aes_256_hmac_policy = { 0, /* retransmission not allowed */ NULL, /* no encrypted extension headers */ 0, /* list of encrypted extension headers is empty */ - 0, /* no cryptex */ NULL }; @@ -5272,7 +5265,6 @@ const srtp_policy_t aes_256_hmac_32_policy = { 0, /* retransmission not allowed */ NULL, /* no encrypted extension headers */ 0, /* list of encrypted extension headers is empty */ - 0, /* no cryptex */ NULL }; @@ -5304,7 +5296,6 @@ const srtp_policy_t hmac_only_with_ekt_policy = { 0, /* retransmission not allowed */ NULL, /* no encrypted extension headers */ 0, /* list of encrypted extension headers is empty */ - 0, /* no cryptex */ NULL }; @@ -5371,7 +5362,6 @@ const srtp_policy_t wildcard_policy = { 0, /* retransmission not allowed */ NULL, /* no encrypted extension headers */ 0, /* list of encrypted extension headers is empty */ - 0, /* no cryptex */ NULL };