double srtp_bits_per_second(int msg_len_octets, const srtp_policy_t *policy) { srtp_t srtp; srtp_hdr_t *mesg; int i; clock_t timer; int num_trials = 100000; int len; uint32_t ssrc; err_status_t status; /* * allocate and initialize an srtp session */ status = srtp_create(&srtp, policy); if (status) { printf("error: srtp_create() failed with error code %d\n", status); exit(1); } /* * if the ssrc is unspecified, use a predetermined one */ if (policy->ssrc.type != ssrc_specific) { ssrc = 0xdeadbeef; } else { ssrc = policy->ssrc.value; } /* * create a test packet */ mesg = srtp_create_test_packet(msg_len_octets, ssrc); if (mesg == NULL) return 0.0; /* indicate failure by returning zero */ timer = clock(); for (i=0; i < num_trials; i++) { err_status_t status; len = msg_len_octets + 12; /* add in rtp header length */ /* srtp protect message */ status = srtp_protect(srtp, mesg, &len); if (status) { printf("error: srtp_protect() failed with error code %d\n", status); exit(1); } /* increment message number */ mesg->seq = htons(ntohs(mesg->seq) + 1); } timer = clock() - timer; free(mesg); return (double) (msg_len_octets) * 8 * num_trials * CLOCKS_PER_SEC / timer; }
double srtp_rejections_per_second(int msg_len_octets, const srtp_policy_t *policy) { srtp_ctx_t *srtp; srtp_hdr_t *mesg; int i; int len; clock_t timer; int num_trials = 1000000; uint32_t ssrc = policy->ssrc.value; err_status_t status; /* * allocate and initialize an srtp session */ status = srtp_create(&srtp, policy); if (status) { printf("error: srtp_create() failed with error code %d\n", status); exit(1); } mesg = srtp_create_test_packet(msg_len_octets, ssrc); if (mesg == NULL) return 0.0; /* indicate failure by returning zero */ len = msg_len_octets; srtp_protect(srtp, (srtp_hdr_t *)mesg, &len); timer = clock(); for (i=0; i < num_trials; i++) { len = msg_len_octets; srtp_unprotect(srtp, (srtp_hdr_t *)mesg, &len); } timer = clock() - timer; free(mesg); return (double) num_trials * CLOCKS_PER_SEC / timer; }
err_status_t srtcp_test(const srtp_policy_t *policy) { int i; srtp_t srtcp_sender; srtp_t srtcp_rcvr; err_status_t status = err_status_ok; srtp_hdr_t *hdr, *hdr2; uint8_t hdr_enc[64]; uint8_t *pkt_end; int msg_len_octets, msg_len_enc; int len; int tag_length = policy->rtp.auth_tag_len; uint32_t ssrc; srtp_policy_t *rcvr_policy; err_check(srtp_create(&srtcp_sender, policy)); /* print out policy */ err_check(srtp_session_print_policy(srtcp_sender)); /* * initialize data buffer, using the ssrc in the policy unless that * value is a wildcard, in which case we'll just use an arbitrary * one */ if (policy->ssrc.type != ssrc_specific) ssrc = 0xdecafbad; else ssrc = policy->ssrc.value; msg_len_octets = 28; hdr = srtp_create_test_packet(msg_len_octets, ssrc); if (hdr == NULL) return err_status_alloc_fail; hdr2 = srtp_create_test_packet(msg_len_octets, ssrc); if (hdr2 == NULL) { free(hdr); return err_status_alloc_fail; } /* set message length */ len = msg_len_octets; debug_print(mod_driver, "before protection:\n%s", srtp_packet_to_string(hdr, len)); #if PRINT_REFERENCE_PACKET debug_print(mod_driver, "reference packet before protection:\n%s", octet_string_hex_string((uint8_t *)hdr, len)); #endif err_check(srtp_protect_rtcp(srtcp_sender, hdr, &len)); debug_print(mod_driver, "after protection:\n%s", srtp_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)); #endif /* save protected message and length */ memcpy(hdr_enc, hdr, len); msg_len_enc = len; /* * check for overrun of the srtp_protect() 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 * protect function is overwriting the end of the packet. */ pkt_end = (uint8_t *)hdr + sizeof(srtp_hdr_t) + msg_len_octets + tag_length; for (i = 0; i < 4; i++) if (pkt_end[i] != 0xff) { fprintf(stdout, "overwrite in srtp_protect_rtcp() function " "(expected %x, found %x in trailing octet %d)\n", 0xff, ((uint8_t *)hdr)[i], i); free(hdr); free(hdr2); return err_status_algo_fail; } /* * if the policy includes confidentiality, check that ciphertext is * different than plaintext * * Note that this check will give false negatives, with some small * probability, especially if the packets are short. For that * reason, we skip this check if the plaintext is less than four * octets long. */ if ((policy->rtp.sec_serv & sec_serv_conf) && (msg_len_octets >= 4)) { printf("testing that ciphertext is distinct from plaintext..."); status = err_status_algo_fail; for (i=12; i < msg_len_octets+12; i++) if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) { status = err_status_ok; } if (status) { printf("failed\n"); free(hdr); free(hdr2); return status; } printf("passed\n"); } /* * if the policy uses a 'wildcard' ssrc, then we need to make a copy * of the policy that changes the direction to inbound * * we always copy the policy into the rcvr_policy, since otherwise * the compiler would fret about the constness of the policy */ rcvr_policy = malloc(sizeof(srtp_policy_t)); if (rcvr_policy == NULL) return err_status_alloc_fail; memcpy(rcvr_policy, policy, sizeof(srtp_policy_t)); if (policy->ssrc.type == ssrc_any_outbound) { rcvr_policy->ssrc.type = ssrc_any_inbound; } err_check(srtp_create(&srtcp_rcvr, rcvr_policy)); err_check(srtp_unprotect_rtcp(srtcp_rcvr, hdr, &len)); debug_print(mod_driver, "after unprotection:\n%s", srtp_packet_to_string(hdr, len)); /* verify that the unprotected packet matches the origial one */ for (i=0; i < msg_len_octets; i++) if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) { fprintf(stdout, "mismatch at octet %d\n", i); status = err_status_algo_fail; } if (status) { free(hdr); free(hdr2); return status; } /* * if the policy includes authentication, then test for false positives */ if (policy->rtp.sec_serv & sec_serv_auth) { char *data = ((char *)hdr) + 12; printf("testing for false positives in replay check..."); /* set message length */ len = msg_len_enc; /* unprotect a second time - should fail with a replay error */ status = srtp_unprotect_rtcp(srtcp_rcvr, hdr_enc, &len); if (status != err_status_replay_fail) { printf("failed with error code %d\n", status); free(hdr); free(hdr2); return status; } else { printf("passed\n"); } printf("testing for false positives in auth check..."); /* increment sequence number in header */ hdr->seq++; /* set message length */ len = msg_len_octets; /* apply protection */ err_check(srtp_protect_rtcp(srtcp_sender, hdr, &len)); /* flip bits in packet */ data[0] ^= 0xff; /* unprotect, and check for authentication failure */ status = srtp_unprotect_rtcp(srtcp_rcvr, hdr, &len); if (status != err_status_auth_fail) { printf("failed\n"); free(hdr); free(hdr2); return status; } else { printf("passed\n"); } } err_check(srtp_dealloc(srtcp_sender)); err_check(srtp_dealloc(srtcp_rcvr)); free(hdr); free(hdr2); return err_status_ok; }
srtp_err_status_t test_dtls_srtp(void) { srtp_hdr_t *test_packet; int test_packet_len = 80; srtp_t s; srtp_policy_t policy; uint8_t key[SRTP_MAX_KEY_LEN]; uint8_t salt[SRTP_MAX_KEY_LEN]; unsigned int key_len, salt_len; srtp_profile_t profile; srtp_err_status_t err; /* create a 'null' SRTP session */ err = srtp_create(&s, NULL); if (err) return err; /* * verify that packet-processing functions behave properly - we * expect that these functions will return srtp_err_status_no_ctx */ test_packet = srtp_create_test_packet(80, 0xa5a5a5a5); if (test_packet == NULL) return srtp_err_status_alloc_fail; err = srtp_protect(s, test_packet, &test_packet_len); if (err != srtp_err_status_no_ctx) { printf("wrong return value from srtp_protect() (got code %d)\n", err); return srtp_err_status_fail; } err = srtp_unprotect(s, test_packet, &test_packet_len); if (err != srtp_err_status_no_ctx) { printf("wrong return value from srtp_unprotect() (got code %d)\n", err); return srtp_err_status_fail; } err = srtp_protect_rtcp(s, test_packet, &test_packet_len); if (err != srtp_err_status_no_ctx) { printf("wrong return value from srtp_protect_rtcp() (got code %d)\n", err); return srtp_err_status_fail; } err = srtp_unprotect_rtcp(s, test_packet, &test_packet_len); if (err != srtp_err_status_no_ctx) { printf("wrong return value from srtp_unprotect_rtcp() (got code %d)\n", err); return srtp_err_status_fail; } /* * set keys to known values for testing */ profile = srtp_profile_aes128_cm_sha1_80; key_len = srtp_profile_get_master_key_length(profile); salt_len = srtp_profile_get_master_salt_length(profile); memset(key, 0xff, key_len); memset(salt, 0xee, salt_len); srtp_append_salt_to_key(key, key_len, salt, salt_len); policy.key = key; /* initialize SRTP policy from profile */ err = srtp_crypto_policy_set_from_profile_for_rtp(&policy.rtp, profile); if (err) return err; err = srtp_crypto_policy_set_from_profile_for_rtcp(&policy.rtcp, profile); if (err) return err; policy.ssrc.type = ssrc_any_inbound; policy.ekt = NULL; policy.window_size = 128; policy.allow_repeat_tx = 0; policy.next = NULL; err = srtp_add_stream(s, &policy); if (err) return err; err = srtp_dealloc(s); if (err) return err; free(test_packet); return srtp_err_status_ok; }