From 8f12a96c342ce2b095f739db8c89d9e29199267b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pascal=20B=C3=BChler?= Date: Thu, 30 Nov 2023 14:20:34 +0100 Subject: [PATCH 1/2] fixup testing of rtcp Use a more correct RTCP test packet and support proper printing of RTCP packets. --- include/srtp.h | 21 +++++++++- test/srtp_driver.c | 97 ++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 104 insertions(+), 14 deletions(-) diff --git a/include/srtp.h b/include/srtp.h index 3a3cf4bc9..40b0c783f 100644 --- a/include/srtp.h +++ b/include/srtp.h @@ -93,6 +93,23 @@ extern "C" { */ #define SRTP_MAX_TRAILER_LEN (SRTP_MAX_TAG_LEN + SRTP_MAX_MKI_LEN) +/** + * SRTP_SRCTP_INDEX_LEN is the size the SRTCP index which is + * 4 bytes + */ +#define SRTP_SRCTP_INDEX_LEN 4 + +/** + * SRTP_MAX_SRTCP_TRAILER_LEN is the maximum length of the SRTCP trailer + * (index, authentication tag and MKI) supported by libSRTP. This value is + * the maximum number of octets that will be added to an RTCP packet by + * srtp_protect_rtcp(). + * + * @brief the maximum number of octets added by srtp_protect(). + */ +#define SRTP_MAX_SRTCP_TRAILER_LEN \ + (SRTP_SRCTP_INDEX_LEN + SRTP_MAX_TAG_LEN + SRTP_MAX_MKI_LEN) + /** * SRTP_MAX_NUM_MASTER_KEYS is the maximum number of Master keys for * MKI supported by libSRTP. @@ -1289,7 +1306,7 @@ void srtp_append_salt_to_key(unsigned char *key, * packet, and assumes that the RTCP packet is aligned on a 32-bit * boundary. * - * @warning This function assumes that it can write SRTP_MAX_TRAILER_LEN+4 + * @warning This function assumes that it can write SRTP_MAX_SRTCP_TRAILER_LEN * into the location in memory immediately following the RTCP packet. * Callers MUST ensure that this much writable memory is available in * the buffer that holds the RTCP packet. @@ -1330,7 +1347,7 @@ srtp_err_status_t srtp_protect_rtcp(srtp_t ctx, * packet, and assumes that the RTCP packet is aligned on a 32-bit * boundary. * - * @warning This function assumes that it can write SRTP_MAX_TRAILER_LEN+4 + * @warning This function assumes that it can write SRTP_MAX_SRTCP_TRAILER_LEN * into the location in memory immediately following the RTCP packet. * Callers MUST ensure that this much writable memory is available in * the buffer that holds the RTCP packet. diff --git a/test/srtp_driver.c b/test/srtp_driver.c index ad722bb6f..7951aa587 100644 --- a/test/srtp_driver.c +++ b/test/srtp_driver.c @@ -122,6 +122,7 @@ srtp_err_status_t srtp_session_print_policy(srtp_t srtp); srtp_err_status_t srtp_print_policy(const srtp_policy_t *policy); char *srtp_packet_to_string(srtp_hdr_t *hdr, int packet_len); +char *srtp_rtcp_packet_to_string(srtcp_hdr_t *hdr, int pkt_octet_len); double mips_estimate(int num_trials, int *ignore); @@ -751,6 +752,47 @@ srtp_hdr_t *srtp_create_test_packet(int pkt_octet_len, return hdr; } +srtcp_hdr_t *srtp_create_rtcp_test_packet(int pkt_octet_len, + uint32_t ssrc, + int *pkt_len) +{ + int i; + uint8_t *buffer; + srtcp_hdr_t *hdr; + int bytes_in_hdr = 8; + + /* allocate memory for test packet */ + hdr = (srtcp_hdr_t *)malloc(pkt_octet_len + bytes_in_hdr + + SRTP_MAX_SRTCP_TRAILER_LEN + 4); + if (!hdr) { + return NULL; + } + + hdr->version = 2; /* RTP version two */ + hdr->p = 0; /* no padding needed */ + hdr->rc = 0; /* no reports */ + hdr->pt = 0xc8; /* sender report (200) */ + hdr->len = ((bytes_in_hdr + pkt_octet_len) % 4) - 1; + hdr->ssrc = htonl(ssrc); /* synch. source */ + + buffer = (uint8_t *)hdr; + buffer += bytes_in_hdr; + + /* set data to 0xab */ + for (i = 0; i < pkt_octet_len; i++) { + *buffer++ = 0xab; + } + + /* set post-data value to 0xffff to enable overrun checking */ + for (i = 0; i < SRTP_MAX_SRTCP_TRAILER_LEN + 4; i++) { + *buffer++ = 0xff; + } + + *pkt_len = bytes_in_hdr + pkt_octet_len; + + return hdr; +} + static srtp_hdr_t *srtp_create_test_packet_extended(int pkt_octet_len, uint32_t ssrc, uint16_t seq, @@ -1008,7 +1050,7 @@ srtp_err_status_t srtp_test_call_protect(srtp_t srtp_sender, } srtp_err_status_t srtp_test_call_protect_rtcp(srtp_t srtp_sender, - srtp_hdr_t *hdr, + srtcp_hdr_t *hdr, int *len, int mki_index) { @@ -1032,7 +1074,7 @@ srtp_err_status_t srtp_test_call_unprotect(srtp_t srtp_sender, } srtp_err_status_t srtp_test_call_unprotect_rtcp(srtp_t srtp_sender, - srtp_hdr_t *hdr, + srtcp_hdr_t *hdr, int *len, int use_mki) { @@ -1283,7 +1325,7 @@ srtp_err_status_t srtcp_test(const srtp_policy_t *policy, int mki_index) srtp_t srtcp_sender; srtp_t srtcp_rcvr; srtp_err_status_t status = srtp_err_status_ok; - srtp_hdr_t *hdr, *hdr2; + srtcp_hdr_t *hdr, *hdr2; uint8_t hdr_enc[64]; uint8_t *pkt_end; int msg_len_octets, msg_len_enc, msg_len; @@ -1312,21 +1354,21 @@ srtp_err_status_t srtcp_test(const srtp_policy_t *policy, int mki_index) ssrc = policy->ssrc.value; } msg_len_octets = 28; - hdr = srtp_create_test_packet(msg_len_octets, ssrc, &len); + hdr = srtp_create_rtcp_test_packet(msg_len_octets, ssrc, &len); /* save message len */ msg_len = len; if (hdr == NULL) { return srtp_err_status_alloc_fail; } - hdr2 = srtp_create_test_packet(msg_len_octets, ssrc, &len2); + hdr2 = srtp_create_rtcp_test_packet(msg_len_octets, ssrc, &len2); if (hdr2 == NULL) { free(hdr); return srtp_err_status_alloc_fail; } debug_print(mod_driver, "before protection:\n%s", - srtp_packet_to_string(hdr, len)); + srtp_rtcp_packet_to_string(hdr, len)); #if PRINT_REFERENCE_PACKET debug_print(mod_driver, "reference packet before protection:\n%s", @@ -1335,7 +1377,7 @@ srtp_err_status_t srtcp_test(const srtp_policy_t *policy, int mki_index) err_check(srtp_test_call_protect_rtcp(srtcp_sender, hdr, &len, mki_index)); debug_print(mod_driver, "after protection:\n%s", - srtp_packet_to_string(hdr, len)); + srtp_rtcp_packet_to_string(hdr, len)); #if PRINT_REFERENCE_PACKET debug_print(mod_driver, "after protection:\n%s", octet_string_hex_string((uint8_t *)hdr, len)); @@ -1346,7 +1388,7 @@ srtp_err_status_t srtcp_test(const srtp_policy_t *policy, int mki_index) msg_len_enc = len; /* - * check for overrun of the srtp_protect() function + * check for overrun of the srtp_protect_rtcp() function * * The packet is followed by a value of 0xfffff; if the value of the * data following the packet is different, then we know that the @@ -1416,7 +1458,7 @@ srtp_err_status_t srtcp_test(const srtp_policy_t *policy, int mki_index) err_check(srtp_test_call_unprotect_rtcp(srtcp_rcvr, hdr, &len, use_mki)); debug_print(mod_driver, "after unprotection:\n%s", - srtp_packet_to_string(hdr, len)); + srtp_rtcp_packet_to_string(hdr, len)); /* verify that the unprotected packet matches the origial one */ for (i = 0; i < len; i++) { @@ -1455,9 +1497,6 @@ srtp_err_status_t srtcp_test(const srtp_policy_t *policy, int mki_index) printf("testing for false positives in auth check..."); - /* increment sequence number in header */ - hdr->seq++; - /* apply protection */ err_check( srtp_test_call_protect_rtcp(srtcp_sender, hdr, &len, mki_index)); @@ -1641,6 +1680,34 @@ char *srtp_packet_to_string(srtp_hdr_t *hdr, int pkt_octet_len) return packet_string; } +char *srtp_rtcp_packet_to_string(srtcp_hdr_t *hdr, int pkt_octet_len) +{ + int octets_in_rtcp_header = 8; + uint8_t *data = ((uint8_t *)hdr) + octets_in_rtcp_header; + int hex_len = pkt_octet_len - octets_in_rtcp_header; + + /* sanity checking */ + if ((hdr == NULL) || (pkt_octet_len > MTU)) { + return NULL; + } + + /* write packet into string */ + snprintf(packet_string, sizeof(packet_string), + "(s)rtcp packet: {\n" + " version:\t%d\n" + " p:\t\t%d\n" + " rc:\t\t%d\n" + " pt:\t\t%x\n" + " len:\t\t%x\n" + " ssrc:\t%x\n" + " data:\t%s\n" + "} (%d octets in total)\n", + hdr->version, hdr->p, hdr->rc, hdr->pt, hdr->len, hdr->ssrc, + octet_string_hex_string(data, hex_len), pkt_octet_len); + + return packet_string; +} + /* * mips_estimate() is a simple function to estimate the number of * instructions per second that the host can perform. note that this @@ -2137,6 +2204,12 @@ srtp_err_status_t srtp_validate_gcm(void) return status; } + debug_print(mod_driver, "srtcp plain:\n %s", + octet_string_hex_string(srtcp_ciphertext, len)); + debug_print(mod_driver, "srtcp plain reference:\n %s", + octet_string_hex_string(rtcp_plaintext_ref, + sizeof(rtcp_plaintext_ref))); + if (srtp_octet_string_is_eq(srtcp_ciphertext, rtcp_plaintext_ref, len)) { return srtp_err_status_fail; } From f0a3f9c10fbb354bc4fe221c6f4134643a7f9d9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pascal=20B=C3=BChler?= Date: Tue, 5 Dec 2023 13:53:12 +0100 Subject: [PATCH 2/2] ensure test fails if unexpected result --- test/srtp_driver.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/test/srtp_driver.c b/test/srtp_driver.c index 7951aa587..7307e1629 100644 --- a/test/srtp_driver.c +++ b/test/srtp_driver.c @@ -1281,7 +1281,7 @@ srtp_err_status_t srtp_test(const srtp_policy_t *policy, free(hdr); free(hdr2); free(rcvr_policy); - return status; + return srtp_err_status_algo_fail; } else { printf("passed\n"); } @@ -1300,11 +1300,12 @@ srtp_err_status_t srtp_test(const srtp_policy_t *policy, /* unprotect, and check for authentication failure */ status = srtp_test_call_unprotect(srtp_rcvr, hdr, &len, use_mki); if (status != srtp_err_status_auth_fail) { + printf("failed with error code %d\n", status); printf("failed\n"); free(hdr); free(hdr2); free(rcvr_policy); - return status; + return srtp_err_status_algo_fail; } else { printf("passed\n"); } @@ -1460,7 +1461,7 @@ srtp_err_status_t srtcp_test(const srtp_policy_t *policy, int mki_index) debug_print(mod_driver, "after unprotection:\n%s", srtp_rtcp_packet_to_string(hdr, len)); - /* verify that the unprotected packet matches the origial one */ + /* verify that the unprotected packet matches the original one */ for (i = 0; i < len; i++) { if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) { fprintf(stdout, "mismatch at octet %d\n", i); @@ -1490,7 +1491,7 @@ srtp_err_status_t srtcp_test(const srtp_policy_t *policy, int mki_index) free(hdr); free(hdr2); free(rcvr_policy); - return status; + return srtp_err_status_algo_fail; } else { printf("passed\n"); } @@ -1507,11 +1508,12 @@ srtp_err_status_t srtcp_test(const srtp_policy_t *policy, int mki_index) /* unprotect, and check for authentication failure */ status = srtp_test_call_unprotect_rtcp(srtcp_rcvr, hdr, &len, use_mki); if (status != srtp_err_status_auth_fail) { + printf("failed with error code %d\n", status); printf("failed\n"); free(hdr); free(hdr2); free(rcvr_policy); - return status; + return srtp_err_status_algo_fail; } else { printf("passed\n"); }