4
* a test driver for libSRTP
11
* Copyright (c) 2001-2006, Cisco Systems, Inc.
12
* All rights reserved.
14
* Redistribution and use in source and binary forms, with or without
15
* modification, are permitted provided that the following conditions
18
* Redistributions of source code must retain the above copyright
19
* notice, this list of conditions and the following disclaimer.
21
* Redistributions in binary form must reproduce the above
22
* copyright notice, this list of conditions and the following
23
* disclaimer in the documentation and/or other materials provided
24
* with the distribution.
26
* Neither the name of the Cisco Systems, Inc. nor the names of its
27
* contributors may be used to endorse or promote products derived
28
* from this software without specific prior written permission.
30
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
31
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
32
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
33
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
34
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
35
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
36
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
37
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
40
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
41
* OF THE POSSIBILITY OF SUCH DAMAGE.
46
#include <string.h> /* for memcpy() */
47
#include <time.h> /* for clock() */
48
#include <stdlib.h> /* for malloc(), free() */
49
#include <stdio.h> /* for print(), fflush() */
50
#include "getopt_s.h" /* for local getopt() */
52
#include "srtp_priv.h"
54
#ifdef HAVE_NETINET_IN_H
55
# include <netinet/in.h>
56
#elif defined HAVE_WINSOCK2_H
57
# include <winsock2.h>
60
#define PRINT_REFERENCE_PACKET 1
66
srtp_create_big_policy(srtp_policy_t **list);
69
srtp_test_remove_stream(void);
72
srtp_bits_per_second(int msg_len_octets, const srtp_policy_t *policy);
75
srtp_rejections_per_second(int msg_len_octets, const srtp_policy_t *policy);
78
srtp_do_timing(const srtp_policy_t *policy);
81
srtp_do_rejection_timing(const srtp_policy_t *policy);
84
srtp_test(const srtp_policy_t *policy);
87
srtcp_test(const srtp_policy_t *policy);
90
srtp_session_print_policy(srtp_t srtp);
93
srtp_print_policy(const srtp_policy_t *policy);
96
srtp_packet_to_string(srtp_hdr_t *hdr, int packet_len);
99
mips_estimate(int num_trials, int *ignore);
101
extern uint8_t test_key[30];
104
usage(char *prog_name) {
105
printf("usage: %s [ -t ][ -c ][ -v ][-d <debug_module> ]* [ -l ]\n"
106
" -t run timing test\n"
107
" -r run rejection timing test\n"
108
" -c run codec timing test\n"
109
" -v run validation tests\n"
110
" -d <mod> turn on debugging module <mod>\n"
111
" -l list debugging modules\n", prog_name);
116
* The policy_array is a null-terminated array of policy structs. it
117
* is declared at the end of this file
120
extern const srtp_policy_t *policy_array[];
123
/* the wildcard_policy is declared below; it has a wildcard ssrc */
125
extern const srtp_policy_t wildcard_policy;
128
* mod_driver debug module - debugging module for this test driver
130
* we use the crypto_kernel debugging system in this driver, which
131
* makes the interface uniform and increases portability
134
debug_module_t mod_driver = {
135
0, /* debugging is off by default */
136
"driver" /* printable name for module */
140
main (int argc, char *argv[]) {
142
unsigned do_timing_test = 0;
143
unsigned do_rejection_test = 0;
144
unsigned do_codec_timing = 0;
145
unsigned do_validation = 0;
146
unsigned do_list_mods = 0;
150
* verify that the compiler has interpreted the header data
151
* structure srtp_hdr_t correctly
153
if (sizeof(srtp_hdr_t) != 12) {
154
printf("error: srtp_hdr_t has incorrect size"
155
"(size is %ld bytes, expected 12)\n",
160
/* initialize srtp library */
161
status = srtp_init();
163
printf("error: srtp init failed with error code %d\n", status);
167
/* load srtp_driver debug module */
168
status = crypto_kernel_load_debug_module(&mod_driver);
170
printf("error: load of srtp_driver debug module failed "
171
"with error code %d\n", status);
175
/* process input arguments */
177
q = getopt_s(argc, argv, "trcvld:");
185
do_rejection_test = 1;
197
status = crypto_kernel_set_debug_module(optarg_s, 1);
199
printf("error: set debug module (%s) failed\n", optarg_s);
208
if (!do_validation && !do_timing_test && !do_codec_timing
209
&& !do_list_mods && !do_rejection_test)
213
status = crypto_kernel_list_debug_modules();
215
printf("error: list of debug modules failed\n");
221
const srtp_policy_t **policy = policy_array;
222
srtp_policy_t *big_policy;
224
/* loop over policy array, testing srtp and srtcp for each policy */
225
while (*policy != NULL) {
226
printf("testing srtp_protect and srtp_unprotect\n");
227
if (srtp_test(*policy) == err_status_ok)
228
printf("passed\n\n");
233
printf("testing srtp_protect_rtcp and srtp_unprotect_rtcp\n");
234
if (srtcp_test(*policy) == err_status_ok)
235
printf("passed\n\n");
243
/* create a big policy list and run tests on it */
244
status = srtp_create_big_policy(&big_policy);
246
printf("unexpected failure with error code %d\n", status);
249
printf("testing srtp_protect and srtp_unprotect with big policy\n");
250
if (srtp_test(big_policy) == err_status_ok)
251
printf("passed\n\n");
257
/* run test on wildcard policy */
258
printf("testing srtp_protect and srtp_unprotect on "
259
"wildcard ssrc policy\n");
260
if (srtp_test(&wildcard_policy) == err_status_ok)
261
printf("passed\n\n");
268
* run validation test against the reference packets - note
269
* that this test only covers the default policy
271
printf("testing srtp_protect and srtp_unprotect against "
272
"reference packets\n");
273
if (srtp_validate() == err_status_ok)
274
printf("passed\n\n");
281
* test the function srtp_remove_stream()
283
printf("testing srtp_remove_stream()...");
284
if (srtp_test_remove_stream() == err_status_ok)
292
if (do_timing_test) {
293
const srtp_policy_t **policy = policy_array;
295
/* loop over policies, run timing test for each */
296
while (*policy != NULL) {
297
srtp_print_policy(*policy);
298
srtp_do_timing(*policy);
303
if (do_rejection_test) {
304
const srtp_policy_t **policy = policy_array;
306
/* loop over policies, run rejection timing test for each */
307
while (*policy != NULL) {
308
srtp_print_policy(*policy);
309
srtp_do_rejection_timing(*policy);
314
if (do_codec_timing) {
315
srtp_policy_t policy;
317
double mips = mips_estimate(1000000000, &ignore);
319
crypto_policy_set_rtp_default(&policy.rtp);
320
crypto_policy_set_rtcp_default(&policy.rtcp);
321
policy.ssrc.type = ssrc_specific;
322
policy.ssrc.value = 0xdecafbad;
323
policy.key = test_key;
326
printf("mips estimate: %e\n", mips);
328
printf("testing srtp processing time for voice codecs:\n");
329
printf("codec\t\tlength (octets)\t\tsrtp instructions/second\n");
330
printf("G.711\t\t%d\t\t\t%e\n", 80,
331
(double) mips * (80 * 8) /
332
srtp_bits_per_second(80, &policy) / .01 );
333
printf("G.711\t\t%d\t\t\t%e\n", 160,
334
(double) mips * (160 * 8) /
335
srtp_bits_per_second(160, &policy) / .02);
336
printf("G.726-32\t%d\t\t\t%e\n", 40,
337
(double) mips * (40 * 8) /
338
srtp_bits_per_second(40, &policy) / .01 );
339
printf("G.726-32\t%d\t\t\t%e\n", 80,
340
(double) mips * (80 * 8) /
341
srtp_bits_per_second(80, &policy) / .02);
342
printf("G.729\t\t%d\t\t\t%e\n", 10,
343
(double) mips * (10 * 8) /
344
srtp_bits_per_second(10, &policy) / .01 );
345
printf("G.729\t\t%d\t\t\t%e\n", 20,
346
(double) mips * (20 * 8) /
347
srtp_bits_per_second(20, &policy) / .02 );
348
printf("Wideband\t%d\t\t\t%e\n", 320,
349
(double) mips * (320 * 8) /
350
srtp_bits_per_second(320, &policy) / .01 );
351
printf("Wideband\t%d\t\t\t%e\n", 640,
352
(double) mips * (640 * 8) /
353
srtp_bits_per_second(640, &policy) / .02 );
362
* srtp_create_test_packet(len, ssrc) returns a pointer to a
363
* (malloced) example RTP packet whose data field has the length given
364
* by pkt_octet_len and the SSRC value ssrc. The total length of the
365
* packet is twelve octets longer, since the header is at the
366
* beginning. There is room at the end of the packet for a trailer,
367
* and the four octets following the packet are filled with 0xff
368
* values to enable testing for overwrites.
370
* note that the location of the test packet can (and should) be
371
* deallocated with the free() call once it is no longer needed.
375
srtp_create_test_packet(int pkt_octet_len, uint32_t ssrc) {
379
int bytes_in_hdr = 12;
381
/* allocate memory for test packet */
382
hdr = (srtp_hdr_t*) malloc(pkt_octet_len + bytes_in_hdr
383
+ SRTP_MAX_TRAILER_LEN + 4);
387
hdr->version = 2; /* RTP version two */
388
hdr->p = 0; /* no padding needed */
389
hdr->x = 0; /* no header extension */
390
hdr->cc = 0; /* no CSRCs */
391
hdr->m = 0; /* marker bit */
392
hdr->pt = 0xf; /* payload type */
393
hdr->seq = htons(0x1234); /* sequence number */
394
hdr->ts = htonl(0xdecafbad); /* timestamp */
395
hdr->ssrc = htonl(ssrc); /* synch. source */
397
buffer = (uint8_t *)hdr;
398
buffer += bytes_in_hdr;
400
/* set RTP data to 0xab */
401
for (i=0; i < pkt_octet_len; i++)
404
/* set post-data value to 0xffff to enable overrun checking */
405
for (i=0; i < SRTP_MAX_TRAILER_LEN+4; i++)
412
srtp_do_timing(const srtp_policy_t *policy) {
416
* note: the output of this function is formatted so that it
417
* can be used in gnuplot. '#' indicates a comment, and "\r\n"
418
* terminates a record
421
printf("# testing srtp throughput:\r\n");
422
printf("# mesg length (octets)\tthroughput (megabits per second)\r\n");
424
for (len=16; len <= 2048; len *= 2)
425
printf("%d\t\t\t%f\r\n", len,
426
srtp_bits_per_second(len, policy) / 1.0E6);
428
/* these extra linefeeds let gnuplot know that a dataset is done */
434
srtp_do_rejection_timing(const srtp_policy_t *policy) {
438
* note: the output of this function is formatted so that it
439
* can be used in gnuplot. '#' indicates a comment, and "\r\n"
440
* terminates a record
443
printf("# testing srtp rejection throughput:\r\n");
444
printf("# mesg length (octets)\trejections per second\r\n");
446
for (len=8; len <= 2048; len *= 2)
447
printf("%d\t\t\t%e\r\n", len, srtp_rejections_per_second(len, policy));
449
/* these extra linefeeds let gnuplot know that a dataset is done */
455
#define MAX_MSG_LEN 1024
458
srtp_bits_per_second(int msg_len_octets, const srtp_policy_t *policy) {
463
int num_trials = 100000;
469
* allocate and initialize an srtp session
471
status = srtp_create(&srtp, policy);
473
printf("error: srtp_create() failed with error code %d\n", status);
478
* if the ssrc is unspecified, use a predetermined one
480
if (policy->ssrc.type != ssrc_specific) {
483
ssrc = policy->ssrc.value;
487
* create a test packet
489
mesg = srtp_create_test_packet(msg_len_octets, ssrc);
491
return 0.0; /* indicate failure by returning zero */
494
for (i=0; i < num_trials; i++) {
496
len = msg_len_octets + 12; /* add in rtp header length */
498
/* srtp protect message */
499
status = srtp_protect(srtp, mesg, &len);
501
printf("error: srtp_protect() failed with error code %d\n", status);
505
/* increment message number */
506
mesg->seq = htons(ntohs(mesg->seq) + 1);
509
timer = clock() - timer;
513
return (double) (msg_len_octets) * 8 *
514
num_trials * CLOCKS_PER_SEC / timer;
518
srtp_rejections_per_second(int msg_len_octets, const srtp_policy_t *policy) {
524
int num_trials = 1000000;
525
uint32_t ssrc = policy->ssrc.value;
529
* allocate and initialize an srtp session
531
status = srtp_create(&srtp, policy);
533
printf("error: srtp_create() failed with error code %d\n", status);
537
mesg = srtp_create_test_packet(msg_len_octets, ssrc);
539
return 0.0; /* indicate failure by returning zero */
541
len = msg_len_octets;
542
srtp_protect(srtp, (srtp_hdr_t *)mesg, &len);
545
for (i=0; i < num_trials; i++) {
546
len = msg_len_octets;
547
srtp_unprotect(srtp, (srtp_hdr_t *)mesg, &len);
549
timer = clock() - timer;
553
return (double) num_trials * CLOCKS_PER_SEC / timer;
558
err_check(err_status_t s) {
559
if (s == err_status_ok)
562
fprintf(stderr, "error: unexpected srtp failure (code %d)\n", s);
567
srtp_test(const srtp_policy_t *policy) {
571
err_status_t status = err_status_ok;
572
srtp_hdr_t *hdr, *hdr2;
575
int msg_len_octets, msg_len_enc;
577
int tag_length = policy->rtp.auth_tag_len;
579
srtp_policy_t *rcvr_policy;
581
err_check(srtp_create(&srtp_sender, policy));
583
/* print out policy */
584
err_check(srtp_session_print_policy(srtp_sender));
587
* initialize data buffer, using the ssrc in the policy unless that
588
* value is a wildcard, in which case we'll just use an arbitrary
591
if (policy->ssrc.type != ssrc_specific)
594
ssrc = policy->ssrc.value;
596
hdr = srtp_create_test_packet(msg_len_octets, ssrc);
599
return err_status_alloc_fail;
600
hdr2 = srtp_create_test_packet(msg_len_octets, ssrc);
603
return err_status_alloc_fail;
606
/* set message length */
607
len = msg_len_octets;
609
debug_print(mod_driver, "before protection:\n%s",
610
srtp_packet_to_string(hdr, len));
612
#if PRINT_REFERENCE_PACKET
613
debug_print(mod_driver, "reference packet before protection:\n%s",
614
octet_string_hex_string((uint8_t *)hdr, len));
616
err_check(srtp_protect(srtp_sender, hdr, &len));
618
debug_print(mod_driver, "after protection:\n%s",
619
srtp_packet_to_string(hdr, len));
620
#if PRINT_REFERENCE_PACKET
621
debug_print(mod_driver, "after protection:\n%s",
622
octet_string_hex_string((uint8_t *)hdr, len));
625
/* save protected message and length */
626
memcpy(hdr_enc, hdr, len);
630
* check for overrun of the srtp_protect() function
632
* The packet is followed by a value of 0xfffff; if the value of the
633
* data following the packet is different, then we know that the
634
* protect function is overwriting the end of the packet.
636
pkt_end = (uint8_t *)hdr + sizeof(srtp_hdr_t)
637
+ msg_len_octets + tag_length;
638
for (i = 0; i < 4; i++)
639
if (pkt_end[i] != 0xff) {
640
fprintf(stdout, "overwrite in srtp_protect() function "
641
"(expected %x, found %x in trailing octet %d)\n",
642
0xff, ((uint8_t *)hdr)[i], i);
645
return err_status_algo_fail;
649
* if the policy includes confidentiality, check that ciphertext is
650
* different than plaintext
652
* Note that this check will give false negatives, with some small
653
* probability, especially if the packets are short. For that
654
* reason, we skip this check if the plaintext is less than four
657
if ((policy->rtp.sec_serv & sec_serv_conf) && (msg_len_octets >= 4)) {
658
printf("testing that ciphertext is distinct from plaintext...");
659
status = err_status_algo_fail;
660
for (i=12; i < msg_len_octets+12; i++)
661
if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) {
662
status = err_status_ok;
674
* if the policy uses a 'wildcard' ssrc, then we need to make a copy
675
* of the policy that changes the direction to inbound
677
* we always copy the policy into the rcvr_policy, since otherwise
678
* the compiler would fret about the constness of the policy
680
rcvr_policy = (srtp_policy_t*) malloc(sizeof(srtp_policy_t));
681
if (rcvr_policy == NULL)
682
return err_status_alloc_fail;
683
memcpy(rcvr_policy, policy, sizeof(srtp_policy_t));
684
if (policy->ssrc.type == ssrc_any_outbound) {
685
rcvr_policy->ssrc.type = ssrc_any_inbound;
688
err_check(srtp_create(&srtp_rcvr, rcvr_policy));
690
err_check(srtp_unprotect(srtp_rcvr, hdr, &len));
692
debug_print(mod_driver, "after unprotection:\n%s",
693
srtp_packet_to_string(hdr, len));
695
/* verify that the unprotected packet matches the origial one */
696
for (i=0; i < msg_len_octets; i++)
697
if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) {
698
fprintf(stdout, "mismatch at octet %d\n", i);
699
status = err_status_algo_fail;
708
* if the policy includes authentication, then test for false positives
710
if (policy->rtp.sec_serv & sec_serv_auth) {
711
char *data = ((char *)hdr) + 12;
713
printf("testing for false positives in replay check...");
715
/* set message length */
718
/* unprotect a second time - should fail with a replay error */
719
status = srtp_unprotect(srtp_rcvr, hdr_enc, &len);
720
if (status != err_status_replay_fail) {
721
printf("failed with error code %d\n", status);
729
printf("testing for false positives in auth check...");
731
/* increment sequence number in header */
734
/* set message length */
735
len = msg_len_octets;
737
/* apply protection */
738
err_check(srtp_protect(srtp_sender, hdr, &len));
740
/* flip bits in packet */
743
/* unprotect, and check for authentication failure */
744
status = srtp_unprotect(srtp_rcvr, hdr, &len);
745
if (status != err_status_auth_fail) {
756
err_check(srtp_dealloc(srtp_sender));
757
err_check(srtp_dealloc(srtp_rcvr));
761
return err_status_ok;
766
srtcp_test(const srtp_policy_t *policy) {
770
err_status_t status = err_status_ok;
771
srtp_hdr_t *hdr, *hdr2;
774
int msg_len_octets, msg_len_enc;
776
int tag_length = policy->rtp.auth_tag_len;
778
srtp_policy_t *rcvr_policy;
780
err_check(srtp_create(&srtcp_sender, policy));
782
/* print out policy */
783
err_check(srtp_session_print_policy(srtcp_sender));
786
* initialize data buffer, using the ssrc in the policy unless that
787
* value is a wildcard, in which case we'll just use an arbitrary
790
if (policy->ssrc.type != ssrc_specific)
793
ssrc = policy->ssrc.value;
795
hdr = srtp_create_test_packet(msg_len_octets, ssrc);
798
return err_status_alloc_fail;
799
hdr2 = srtp_create_test_packet(msg_len_octets, ssrc);
802
return err_status_alloc_fail;
805
/* set message length */
806
len = msg_len_octets;
808
debug_print(mod_driver, "before protection:\n%s",
809
srtp_packet_to_string(hdr, len));
811
#if PRINT_REFERENCE_PACKET
812
debug_print(mod_driver, "reference packet before protection:\n%s",
813
octet_string_hex_string((uint8_t *)hdr, len));
815
err_check(srtp_protect_rtcp(srtcp_sender, hdr, &len));
817
debug_print(mod_driver, "after protection:\n%s",
818
srtp_packet_to_string(hdr, len));
819
#if PRINT_REFERENCE_PACKET
820
debug_print(mod_driver, "after protection:\n%s",
821
octet_string_hex_string((uint8_t *)hdr, len));
824
/* save protected message and length */
825
memcpy(hdr_enc, hdr, len);
829
* check for overrun of the srtp_protect() function
831
* The packet is followed by a value of 0xfffff; if the value of the
832
* data following the packet is different, then we know that the
833
* protect function is overwriting the end of the packet.
835
pkt_end = (uint8_t *)hdr + sizeof(srtp_hdr_t)
836
+ msg_len_octets + tag_length;
837
for (i = 0; i < 4; i++)
838
if (pkt_end[i] != 0xff) {
839
fprintf(stdout, "overwrite in srtp_protect_rtcp() function "
840
"(expected %x, found %x in trailing octet %d)\n",
841
0xff, ((uint8_t *)hdr)[i], i);
844
return err_status_algo_fail;
848
* if the policy includes confidentiality, check that ciphertext is
849
* different than plaintext
851
* Note that this check will give false negatives, with some small
852
* probability, especially if the packets are short. For that
853
* reason, we skip this check if the plaintext is less than four
856
if ((policy->rtp.sec_serv & sec_serv_conf) && (msg_len_octets >= 4)) {
857
printf("testing that ciphertext is distinct from plaintext...");
858
status = err_status_algo_fail;
859
for (i=12; i < msg_len_octets+12; i++)
860
if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) {
861
status = err_status_ok;
873
* if the policy uses a 'wildcard' ssrc, then we need to make a copy
874
* of the policy that changes the direction to inbound
876
* we always copy the policy into the rcvr_policy, since otherwise
877
* the compiler would fret about the constness of the policy
879
rcvr_policy = (srtp_policy_t*) malloc(sizeof(srtp_policy_t));
880
if (rcvr_policy == NULL)
881
return err_status_alloc_fail;
882
memcpy(rcvr_policy, policy, sizeof(srtp_policy_t));
883
if (policy->ssrc.type == ssrc_any_outbound) {
884
rcvr_policy->ssrc.type = ssrc_any_inbound;
887
err_check(srtp_create(&srtcp_rcvr, rcvr_policy));
889
err_check(srtp_unprotect_rtcp(srtcp_rcvr, hdr, &len));
891
debug_print(mod_driver, "after unprotection:\n%s",
892
srtp_packet_to_string(hdr, len));
894
/* verify that the unprotected packet matches the origial one */
895
for (i=0; i < msg_len_octets; i++)
896
if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) {
897
fprintf(stdout, "mismatch at octet %d\n", i);
898
status = err_status_algo_fail;
907
* if the policy includes authentication, then test for false positives
909
if (policy->rtp.sec_serv & sec_serv_auth) {
910
char *data = ((char *)hdr) + 12;
912
printf("testing for false positives in replay check...");
914
/* set message length */
917
/* unprotect a second time - should fail with a replay error */
918
status = srtp_unprotect_rtcp(srtcp_rcvr, hdr_enc, &len);
919
if (status != err_status_replay_fail) {
920
printf("failed with error code %d\n", status);
928
printf("testing for false positives in auth check...");
930
/* increment sequence number in header */
933
/* set message length */
934
len = msg_len_octets;
936
/* apply protection */
937
err_check(srtp_protect_rtcp(srtcp_sender, hdr, &len));
939
/* flip bits in packet */
942
/* unprotect, and check for authentication failure */
943
status = srtp_unprotect_rtcp(srtcp_rcvr, hdr, &len);
944
if (status != err_status_auth_fail) {
955
err_check(srtp_dealloc(srtcp_sender));
956
err_check(srtp_dealloc(srtcp_rcvr));
960
return err_status_ok;
965
srtp_session_print_policy(srtp_t srtp) {
966
char *serv_descr[4] = {
970
"confidentiality and authentication"
972
char *direction[3] = {
977
srtp_stream_t stream;
979
/* sanity checking */
981
return err_status_fail;
983
/* if there's a template stream, print it out */
984
if (srtp->stream_template != NULL) {
985
stream = srtp->stream_template;
986
printf("# SSRC: any %s\r\n"
987
"# rtp cipher: %s\r\n"
989
"# rtp services: %s\r\n"
990
"# rtcp cipher: %s\r\n"
991
"# rtcp auth: %s\r\n"
992
"# rtcp services: %s\r\n",
993
direction[stream->direction],
994
stream->rtp_cipher->type->description,
995
stream->rtp_auth->type->description,
996
serv_descr[stream->rtp_services],
997
stream->rtcp_cipher->type->description,
998
stream->rtcp_auth->type->description,
999
serv_descr[stream->rtcp_services]);
1002
/* loop over streams in session, printing the policy of each */
1003
stream = srtp->stream_list;
1004
while (stream != NULL) {
1005
if (stream->rtp_services > sec_serv_conf_and_auth)
1006
return err_status_bad_param;
1008
printf("# SSRC: 0x%08x\r\n"
1009
"# rtp cipher: %s\r\n"
1010
"# rtp auth: %s\r\n"
1011
"# rtp services: %s\r\n"
1012
"# rtcp cipher: %s\r\n"
1013
"# rtcp auth: %s\r\n"
1014
"# rtcp services: %s\r\n",
1016
stream->rtp_cipher->type->description,
1017
stream->rtp_auth->type->description,
1018
serv_descr[stream->rtp_services],
1019
stream->rtcp_cipher->type->description,
1020
stream->rtcp_auth->type->description,
1021
serv_descr[stream->rtcp_services]);
1023
/* advance to next stream in the list */
1024
stream = stream->next;
1026
return err_status_ok;
1030
srtp_print_policy(const srtp_policy_t *policy) {
1031
err_status_t status;
1034
status = srtp_create(&session, policy);
1037
status = srtp_session_print_policy(session);
1040
status = srtp_dealloc(session);
1043
return err_status_ok;
1047
* srtp_print_packet(...) is for debugging only
1048
* it prints an RTP packet to the stdout
1050
* note that this function is *not* threadsafe
1057
char packet_string[MTU];
1060
srtp_packet_to_string(srtp_hdr_t *hdr, int pkt_octet_len) {
1061
int octets_in_rtp_header = 12;
1062
uint8_t *data = ((uint8_t *)hdr)+octets_in_rtp_header;
1063
int hex_len = pkt_octet_len-octets_in_rtp_header;
1065
/* sanity checking */
1066
if ((hdr == NULL) || (pkt_octet_len > MTU))
1069
/* write packet into string */
1070
sprintf(packet_string,
1071
"(s)rtp packet: {\n"
1082
"} (%d octets in total)\n",
1092
octet_string_hex_string(data, hex_len),
1095
return packet_string;
1099
* mips_estimate() is a simple function to estimate the number of
1100
* instructions per second that the host can perform. note that this
1101
* function can be grossly wrong; you may want to have a manual sanity
1102
* check of its output!
1104
* the 'ignore' pointer is there to convince the compiler to not just
1105
* optimize away the function
1109
mips_estimate(int num_trials, int *ignore) {
1115
for (i=0; i<num_trials; i++)
1119
/* printf("%d\n", sum); */
1122
return (double) num_trials * CLOCKS_PER_SEC / t;
1127
* srtp_validate() verifies the correctness of libsrtp by comparing
1128
* some computed packets against some pre-computed reference values.
1129
* These packets were made with the default SRTP policy.
1135
unsigned char test_key[30] = {
1136
0xe1, 0xf9, 0x7a, 0x0d, 0x3e, 0x01, 0x8b, 0xe0,
1137
0xd6, 0x4f, 0xa3, 0x2c, 0x06, 0xde, 0x41, 0x39,
1138
0x0e, 0xc6, 0x75, 0xad, 0x49, 0x8a, 0xfe, 0xeb,
1139
0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6
1141
uint8_t srtp_plaintext_ref[28] = {
1142
0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1143
0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
1144
0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1145
0xab, 0xab, 0xab, 0xab
1147
uint8_t srtp_plaintext[38] = {
1148
0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1149
0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
1150
0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1151
0xab, 0xab, 0xab, 0xab, 0x00, 0x00, 0x00, 0x00,
1152
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1154
uint8_t srtp_ciphertext[38] = {
1155
0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1156
0xca, 0xfe, 0xba, 0xbe, 0x4e, 0x55, 0xdc, 0x4c,
1157
0xe7, 0x99, 0x78, 0xd8, 0x8c, 0xa4, 0xd2, 0x15,
1158
0x94, 0x9d, 0x24, 0x02, 0xb7, 0x8d, 0x6a, 0xcc,
1159
0x99, 0xea, 0x17, 0x9b, 0x8d, 0xbb
1161
srtp_t srtp_snd, srtp_recv;
1162
err_status_t status;
1164
srtp_policy_t policy;
1167
* create a session with a single stream using the default srtp
1168
* policy and with the SSRC value 0xcafebabe
1170
crypto_policy_set_rtp_default(&policy.rtp);
1171
crypto_policy_set_rtcp_default(&policy.rtcp);
1172
policy.ssrc.type = ssrc_specific;
1173
policy.ssrc.value = 0xcafebabe;
1174
policy.key = test_key;
1177
status = srtp_create(&srtp_snd, &policy);
1182
* protect plaintext, then compare with ciphertext
1185
status = srtp_protect(srtp_snd, srtp_plaintext, &len);
1186
if (status || (len != 38))
1187
return err_status_fail;
1189
debug_print(mod_driver, "ciphertext:\n %s",
1190
octet_string_hex_string(srtp_plaintext, len));
1191
debug_print(mod_driver, "ciphertext reference:\n %s",
1192
octet_string_hex_string(srtp_ciphertext, len));
1194
if (octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len))
1195
return err_status_fail;
1198
* create a receiver session context comparable to the one created
1199
* above - we need to do this so that the replay checking doesn't
1202
status = srtp_create(&srtp_recv, &policy);
1207
* unprotect ciphertext, then compare with plaintext
1209
status = srtp_unprotect(srtp_recv, srtp_ciphertext, &len);
1210
if (status || (len != 28))
1213
if (octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len))
1214
return err_status_fail;
1216
return err_status_ok;
1221
srtp_create_big_policy(srtp_policy_t **list) {
1222
extern const srtp_policy_t *policy_array[];
1223
srtp_policy_t *p, *tmp;
1227
/* sanity checking */
1228
if ((list == NULL) || (policy_array[0] == NULL))
1229
return err_status_bad_param;
1232
* loop over policy list, mallocing a new list and copying values
1233
* into it (and incrementing the SSRC value as we go along)
1236
while (policy_array[i] != NULL) {
1237
p = (srtp_policy_t*) malloc(sizeof(srtp_policy_t));
1239
return err_status_bad_param;
1240
memcpy(p, policy_array[i], sizeof(srtp_policy_t));
1241
p->ssrc.type = ssrc_specific;
1242
p->ssrc.value = ssrc++;
1249
return err_status_ok;
1253
srtp_test_remove_stream() {
1254
err_status_t status;
1255
srtp_policy_t *policy_list;
1257
srtp_stream_t stream;
1259
* srtp_get_stream() is a libSRTP internal function that we declare
1260
* here so that we can use it to verify the correct operation of the
1263
extern srtp_stream_t srtp_get_stream(srtp_t srtp, uint32_t ssrc);
1266
status = srtp_create_big_policy(&policy_list);
1270
status = srtp_create(&session, policy_list);
1275
* check for false positives by trying to remove a stream that's not
1278
status = srtp_remove_stream(session, htonl(0xaaaaaaaa));
1279
if (status != err_status_no_ctx)
1280
return err_status_fail;
1283
* check for false negatives by removing stream 0x1, then
1284
* searching for streams 0x0 and 0x2
1286
status = srtp_remove_stream(session, htonl(0x1));
1287
if (status != err_status_ok)
1288
return err_status_fail;
1289
stream = srtp_get_stream(session, htonl(0x0));
1291
return err_status_fail;
1292
stream = srtp_get_stream(session, htonl(0x2));
1294
return err_status_fail;
1296
return err_status_ok;
1300
* srtp policy definitions - these definitions are used above
1303
unsigned char test_key[30] = {
1304
0xe1, 0xf9, 0x7a, 0x0d, 0x3e, 0x01, 0x8b, 0xe0,
1305
0xd6, 0x4f, 0xa3, 0x2c, 0x06, 0xde, 0x41, 0x39,
1306
0x0e, 0xc6, 0x75, 0xad, 0x49, 0x8a, 0xfe, 0xeb,
1307
0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6
1311
const srtp_policy_t default_policy = {
1312
{ ssrc_any_outbound, 0 }, /* SSRC */
1314
AES_128_ICM, /* cipher type */
1315
30, /* cipher key length in octets */
1316
HMAC_SHA1, /* authentication func type */
1317
16, /* auth key length in octets */
1318
10, /* auth tag length in octets */
1319
sec_serv_conf_and_auth /* security services flag */
1321
{ /* SRTCP policy */
1322
AES_128_ICM, /* cipher type */
1323
30, /* cipher key length in octets */
1324
HMAC_SHA1, /* authentication func type */
1325
16, /* auth key length in octets */
1326
10, /* auth tag length in octets */
1327
sec_serv_conf_and_auth /* security services flag */
1333
const srtp_policy_t aes_tmmh_policy = {
1334
{ ssrc_any_outbound, 0 }, /* SSRC */
1336
AES_128_ICM, /* cipher type */
1337
30, /* cipher key length in octets */
1338
UST_TMMHv2, /* authentication func type */
1339
94, /* auth key length in octets */
1340
4, /* auth tag length in octets */
1341
sec_serv_conf_and_auth /* security services flag */
1344
AES_128_ICM, /* cipher type */
1345
30, /* cipher key length in octets */
1346
UST_TMMHv2, /* authentication func type */
1347
94, /* auth key length in octets */
1348
4, /* auth tag length in octets */
1349
sec_serv_conf_and_auth /* security services flag */
1355
const srtp_policy_t tmmh_only_policy = {
1356
{ ssrc_any_outbound, 0 }, /* SSRC */
1358
AES_128_ICM, /* cipher type */
1359
30, /* cipher key length in octets */
1360
UST_TMMHv2, /* authentication func type */
1361
94, /* auth key length in octets */
1362
4, /* auth tag length in octets */
1363
sec_serv_auth /* security services flag */
1366
AES_128_ICM, /* cipher type */
1367
30, /* cipher key length in octets */
1368
UST_TMMHv2, /* authentication func type */
1369
94, /* auth key length in octets */
1370
4, /* auth tag length in octets */
1371
sec_serv_auth /* security services flag */
1377
const srtp_policy_t aes_only_policy = {
1378
{ ssrc_any_outbound, 0 }, /* SSRC */
1380
AES_128_ICM, /* cipher type */
1381
30, /* cipher key length in octets */
1382
NULL_AUTH, /* authentication func type */
1383
0, /* auth key length in octets */
1384
0, /* auth tag length in octets */
1385
sec_serv_conf /* security services flag */
1388
AES_128_ICM, /* cipher type */
1389
30, /* cipher key length in octets */
1390
NULL_AUTH, /* authentication func type */
1391
0, /* auth key length in octets */
1392
0, /* auth tag length in octets */
1393
sec_serv_conf /* security services flag */
1399
const srtp_policy_t hmac_only_policy = {
1400
{ ssrc_any_outbound, 0 }, /* SSRC */
1402
NULL_CIPHER, /* cipher type */
1403
0, /* cipher key length in octets */
1404
HMAC_SHA1, /* authentication func type */
1405
20, /* auth key length in octets */
1406
4, /* auth tag length in octets */
1407
sec_serv_auth /* security services flag */
1410
NULL_CIPHER, /* cipher type */
1411
0, /* cipher key length in octets */
1412
HMAC_SHA1, /* authentication func type */
1413
20, /* auth key length in octets */
1414
4, /* auth tag length in octets */
1415
sec_serv_auth /* security services flag */
1421
const srtp_policy_t null_policy = {
1422
{ ssrc_any_outbound, 0 }, /* SSRC */
1424
NULL_CIPHER, /* cipher type */
1425
0, /* cipher key length in octets */
1426
NULL_AUTH, /* authentication func type */
1427
0, /* auth key length in octets */
1428
0, /* auth tag length in octets */
1429
sec_serv_none /* security services flag */
1432
NULL_CIPHER, /* cipher type */
1433
0, /* cipher key length in octets */
1434
NULL_AUTH, /* authentication func type */
1435
0, /* auth key length in octets */
1436
0, /* auth tag length in octets */
1437
sec_serv_none /* security services flag */
1445
* an array of pointers to the policies listed above
1447
* This array is used to test various aspects of libSRTP for
1448
* different cryptographic policies. The order of the elements
1449
* matters - the timing test generates output that can be used
1450
* in a plot (see the gnuplot script file 'timing'). If you
1451
* add to this list, you should do it at the end.
1456
const srtp_policy_t *
1471
const srtp_policy_t wildcard_policy = {
1472
{ ssrc_any_outbound, 0 }, /* SSRC */
1474
AES_128_ICM, /* cipher type */
1475
30, /* cipher key length in octets */
1476
HMAC_SHA1, /* authentication func type */
1477
16, /* auth key length in octets */
1478
10, /* auth tag length in octets */
1479
sec_serv_conf_and_auth /* security services flag */
1481
{ /* SRTCP policy */
1482
AES_128_ICM, /* cipher type */
1483
30, /* cipher key length in octets */
1484
HMAC_SHA1, /* authentication func type */
1485
16, /* auth key length in octets */
1486
10, /* auth tag length in octets */
1487
sec_serv_conf_and_auth /* security services flag */