Skip to content

Commit

Permalink
Merge pull request #725 from fippo/roc-mismatch-test
Browse files Browse the repository at this point in the history
add test for ROC mіsmatch
  • Loading branch information
pabuhler authored Nov 13, 2024
2 parents e9a4c68 + ba6a14f commit 3c0b0f9
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 4 deletions.
2 changes: 1 addition & 1 deletion format.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ done
m=`git ls-files -m`
if [ -n "$m" ]; then
v=`$CLANG_FORMAT -version`
echo "Fromatting required when checking with $v"
echo "Formatting required when checking with $v"
echo
echo "The following files required formatting:"
for f in $m; do
Expand Down
105 changes: 102 additions & 3 deletions test/srtp_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ srtp_err_status_t srtp_test_get_roc(void);

srtp_err_status_t srtp_test_set_receiver_roc(void);

srtp_err_status_t srtp_test_roc_mismatch(void);

srtp_err_status_t srtp_test_set_sender_roc(void);

double srtp_bits_per_second(size_t msg_len_octets, const srtp_policy_t *policy);
Expand Down Expand Up @@ -841,6 +843,14 @@ int main(int argc, char *argv[])
exit(1);
}

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

printf("testing srtp_test_set_sender_roc()...");
if (srtp_test_set_sender_roc() == srtp_err_status_ok) {
printf("passed\n");
Expand Down Expand Up @@ -4021,7 +4031,7 @@ srtp_err_status_t srtp_test_out_of_order_after_rollover(void)
uint32_t i;
uint32_t stream_roc;

/* Create sender */
/* Create the sender */
memset(&sender_policy, 0, sizeof(sender_policy));
#ifdef GCM
srtp_crypto_policy_set_aes_gcm_128_16_auth(&sender_policy.rtp);
Expand Down Expand Up @@ -4311,7 +4321,7 @@ static srtp_err_status_t test_set_receiver_roc(uint32_t packets,
size_t protected_msg_len_octets_1;
size_t protected_msg_len_octets_2;

/* Create sender */
/* Create the sender */
memset(&sender_policy, 0, sizeof(sender_policy));
#ifdef GCM
srtp_crypto_policy_set_aes_gcm_128_16_auth(&sender_policy.rtp);
Expand Down Expand Up @@ -4472,7 +4482,7 @@ static srtp_err_status_t test_set_sender_roc(uint16_t seq, uint32_t roc_to_set)
size_t msg_len_octets = 32;
size_t protected_msg_len_octets;

/* Create sender */
/* Create the sender */
memset(&sender_policy, 0, sizeof(sender_policy));
#ifdef GCM
srtp_crypto_policy_set_aes_gcm_128_16_auth(&sender_policy.rtp);
Expand Down Expand Up @@ -4670,6 +4680,95 @@ srtp_err_status_t srtp_test_set_sender_roc(void)
return srtp_err_status_ok;
}

/* This test illustrates how the ROC can be mismatched between
* sender and receiver when a packets are lost before the initial
* sequence number wraparound. In a nutshell:
* - Sender encrypts sequence numbers 65535, 0, 1, ...
* - Receiver only receives 1 initially.
* In that state the receiver will assume the sender used ROC=0 to
* encrypt the packet with sequence number 0.
* This is a long-standing problem that is best avoided by a choice
* of initial sequence number in the lower half of the sequence number
* space.
*/
srtp_err_status_t srtp_test_roc_mismatch(void)
{
srtp_policy_t sender_policy;
srtp_t sender_session;

srtp_policy_t receiver_policy;
srtp_t receiver_session;

const uint32_t num_pkts = 3;
uint8_t *pkts[3];
size_t pkt_len_octets[3];

const uint16_t seq = 0xffff;
uint32_t i;

/* Create the sender */
memset(&sender_policy, 0, sizeof(sender_policy));
#ifdef GCM
srtp_crypto_policy_set_aes_gcm_128_16_auth(&sender_policy.rtp);
srtp_crypto_policy_set_aes_gcm_128_16_auth(&sender_policy.rtcp);
sender_policy.key = test_key_gcm;
#else
srtp_crypto_policy_set_rtp_default(&sender_policy.rtp);
srtp_crypto_policy_set_rtcp_default(&sender_policy.rtcp);
sender_policy.key = test_key;
#endif
sender_policy.ssrc.type = ssrc_specific;
sender_policy.ssrc.value = 0xcafebabe;
sender_policy.window_size = 128;

CHECK_OK(srtp_create(&sender_session, &sender_policy));

/* Create the receiver */
memset(&receiver_policy, 0, sizeof(receiver_policy));
#ifdef GCM
srtp_crypto_policy_set_aes_gcm_128_16_auth(&receiver_policy.rtp);
srtp_crypto_policy_set_aes_gcm_128_16_auth(&receiver_policy.rtcp);
receiver_policy.key = test_key_gcm;
#else
srtp_crypto_policy_set_rtp_default(&receiver_policy.rtp);
srtp_crypto_policy_set_rtcp_default(&receiver_policy.rtcp);
receiver_policy.key = test_key;
#endif
receiver_policy.ssrc.type = ssrc_specific;
receiver_policy.ssrc.value = sender_policy.ssrc.value;
receiver_policy.window_size = 128;

CHECK_OK(srtp_create(&receiver_session, &receiver_policy));

/* Create and protect packets to get to get ROC == 1 */
for (i = 0; i < num_pkts; i++) {
pkts[i] = create_rtp_test_packet(64, sender_policy.ssrc.value,
(uint16_t)(seq + i), 0, false,
&pkt_len_octets[i], NULL);
CHECK_OK(
call_srtp_protect(sender_session, pkts[i], &pkt_len_octets[i], 0));
}

/* Decrypt in reverse order (1, 65535) */
CHECK_RETURN(
call_srtp_unprotect(receiver_session, pkts[2], &pkt_len_octets[2]),
srtp_err_status_auth_fail);
CHECK_OK(
call_srtp_unprotect(receiver_session, pkts[0], &pkt_len_octets[0]));
/* After decryption of the previous ROC rollover will work as expected */
/* Only pkts[1] is checked since that is not modified by the attempt to
* decryption. */
CHECK_OK(
call_srtp_unprotect(receiver_session, pkts[1], &pkt_len_octets[1]));

for (i = 0; i < num_pkts; i++) {
free(pkts[i]);
}
CHECK_OK(srtp_dealloc(sender_session));
CHECK_OK(srtp_dealloc(receiver_session));
return srtp_err_status_ok;
}

/*
* srtp policy definitions - these definitions are used above
*/
Expand Down

0 comments on commit 3c0b0f9

Please sign in to comment.