Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Some srtp_driver fixes #662

Merged
merged 2 commits into from
Dec 12, 2023
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
21 changes: 19 additions & 2 deletions include/srtp.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand Down
109 changes: 92 additions & 17 deletions test/srtp_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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)
{
Expand All @@ -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)
{
Expand Down Expand Up @@ -1239,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");
}
Expand All @@ -1258,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");
}
Expand All @@ -1283,7 +1326,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;
Expand Down Expand Up @@ -1312,21 +1355,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",
Expand All @@ -1335,7 +1378,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));
Expand All @@ -1346,7 +1389,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
Expand Down Expand Up @@ -1416,9 +1459,9 @@ 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 */
/* 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);
Expand Down Expand Up @@ -1448,16 +1491,13 @@ 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");
}

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));
Expand All @@ -1468,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");
}
Expand Down Expand Up @@ -1641,6 +1682,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
Expand Down Expand Up @@ -2137,6 +2206,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;
}
Expand Down
Loading