Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / libsrtp / srtp / test / srtp_driver.c
1 /*
2  * srtp_driver.c
3  * 
4  * a test driver for libSRTP
5  *
6  * David A. McGrew
7  * Cisco Systems, Inc.
8  */
9 /*
10  *      
11  * Copyright (c) 2001-2006, Cisco Systems, Inc.
12  * All rights reserved.
13  * 
14  * Redistribution and use in source and binary forms, with or without
15  * modification, are permitted provided that the following conditions
16  * are met:
17  * 
18  *   Redistributions of source code must retain the above copyright
19  *   notice, this list of conditions and the following disclaimer.
20  * 
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.
25  * 
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.
29  * 
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.
42  *
43  */
44
45
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()    */
51
52 #include "srtp_priv.h"
53
54 #ifdef HAVE_NETINET_IN_H
55 # include <netinet/in.h>
56 #elif defined HAVE_WINSOCK2_H
57 # include <winsock2.h>
58 #endif
59
60 #define PRINT_REFERENCE_PACKET 1
61
62 err_status_t
63 srtp_validate(void);
64
65 err_status_t
66 srtp_validate_aes_256(void);
67
68 err_status_t
69 srtp_create_big_policy(srtp_policy_t **list);
70
71 err_status_t
72 srtp_dealloc_big_policy(srtp_policy_t *list);
73
74 err_status_t
75 srtp_test_remove_stream(void);
76
77 double
78 srtp_bits_per_second(int msg_len_octets, const srtp_policy_t *policy);
79
80 double
81 srtp_rejections_per_second(int msg_len_octets, const srtp_policy_t *policy);
82
83 void
84 srtp_do_timing(const srtp_policy_t *policy);
85
86 void
87 srtp_do_rejection_timing(const srtp_policy_t *policy);
88
89 err_status_t
90 srtp_test(const srtp_policy_t *policy);
91
92 err_status_t
93 srtcp_test(const srtp_policy_t *policy);
94
95 err_status_t
96 srtp_session_print_policy(srtp_t srtp);
97
98 err_status_t
99 srtp_print_policy(const srtp_policy_t *policy); 
100
101 char *
102 srtp_packet_to_string(srtp_hdr_t *hdr, int packet_len);
103
104 double
105 mips_estimate(int num_trials, int *ignore);
106
107 extern uint8_t test_key[30];
108
109 void
110 usage(char *prog_name) {
111   printf("usage: %s [ -t ][ -c ][ -v ][-d <debug_module> ]* [ -l ]\n"
112          "  -t         run timing test\n"
113          "  -r         run rejection timing test\n"
114          "  -c         run codec timing test\n"
115          "  -v         run validation tests\n"
116          "  -d <mod>   turn on debugging module <mod>\n"
117          "  -l         list debugging modules\n", prog_name);
118   exit(1);
119 }
120
121 /*
122  * The policy_array is a null-terminated array of policy structs. it
123  * is declared at the end of this file
124  */
125
126 extern const srtp_policy_t *policy_array[];
127
128
129 /* the wildcard_policy is declared below; it has a wildcard ssrc */
130
131 extern const srtp_policy_t wildcard_policy;
132
133 /*
134  * mod_driver debug module - debugging module for this test driver
135  *
136  * we use the crypto_kernel debugging system in this driver, which 
137  * makes the interface uniform and increases portability
138  */ 
139
140 debug_module_t mod_driver = {
141   0,                  /* debugging is off by default */
142   "driver"            /* printable name for module   */
143 };
144
145 int
146 main (int argc, char *argv[]) {
147   int q;
148   unsigned do_timing_test    = 0;
149   unsigned do_rejection_test = 0;
150   unsigned do_codec_timing   = 0;
151   unsigned do_validation     = 0;
152   unsigned do_list_mods      = 0;
153   err_status_t status;
154
155   /* 
156    * verify that the compiler has interpreted the header data
157    * structure srtp_hdr_t correctly
158    */
159   if (sizeof(srtp_hdr_t) != 12) {
160      printf("error: srtp_hdr_t has incorrect size"
161             "(size is %ld bytes, expected 12)\n", 
162             (long)sizeof(srtp_hdr_t));
163     exit(1);
164   }
165
166   /* initialize srtp library */
167   status = srtp_init();
168   if (status) {
169     printf("error: srtp init failed with error code %d\n", status);
170     exit(1);
171   }
172
173   /*  load srtp_driver debug module */
174   status = crypto_kernel_load_debug_module(&mod_driver);
175     if (status) {
176     printf("error: load of srtp_driver debug module failed "
177            "with error code %d\n", status);
178     exit(1);   
179   }
180
181   /* process input arguments */
182   while (1) {
183     q = getopt_s(argc, argv, "trcvld:");
184     if (q == -1) 
185       break;
186     switch (q) {
187     case 't':
188       do_timing_test = 1;
189       break;
190     case 'r':
191       do_rejection_test = 1;
192       break;
193     case 'c':
194       do_codec_timing = 1;
195       break;
196     case 'v':
197       do_validation = 1;
198       break;
199     case 'l':
200       do_list_mods = 1;
201       break;
202     case 'd':
203       status = crypto_kernel_set_debug_module(optarg_s, 1);
204       if (status) {
205         printf("error: set debug module (%s) failed\n", optarg_s);
206         exit(1);
207       }  
208       break;
209     default:
210       usage(argv[0]);
211     }    
212   }
213
214   if (!do_validation && !do_timing_test && !do_codec_timing 
215       && !do_list_mods && !do_rejection_test)
216     usage(argv[0]);
217
218   if (do_list_mods) {
219     status = crypto_kernel_list_debug_modules();
220     if (status) {
221       printf("error: list of debug modules failed\n");
222       exit(1);
223     }
224   }
225   
226   if (do_validation) {
227     const srtp_policy_t **policy = policy_array;
228     srtp_policy_t *big_policy;
229
230     /* loop over policy array, testing srtp and srtcp for each policy */
231     while (*policy != NULL) {
232       printf("testing srtp_protect and srtp_unprotect\n");
233       if (srtp_test(*policy) == err_status_ok)
234         printf("passed\n\n");
235       else {
236         printf("failed\n");
237         exit(1);
238       }
239       printf("testing srtp_protect_rtcp and srtp_unprotect_rtcp\n");
240       if (srtcp_test(*policy) == err_status_ok)
241         printf("passed\n\n");
242       else {
243         printf("failed\n");
244         exit(1);
245       }
246       policy++;
247     }
248
249     /* create a big policy list and run tests on it */
250     status = srtp_create_big_policy(&big_policy);
251     if (status) {
252       printf("unexpected failure with error code %d\n", status);
253       exit(1);
254     }
255     printf("testing srtp_protect and srtp_unprotect with big policy\n");
256     if (srtp_test(big_policy) == err_status_ok)
257       printf("passed\n\n");
258     else {
259       printf("failed\n");
260       exit(1);
261     }
262     status = srtp_dealloc_big_policy(big_policy);
263     if (status) {
264       printf("unexpected failure with error code %d\n", status);
265       exit(1);
266     }
267
268     /* run test on wildcard policy */
269     printf("testing srtp_protect and srtp_unprotect on "
270            "wildcard ssrc policy\n");
271     if (srtp_test(&wildcard_policy) == err_status_ok)
272       printf("passed\n\n");
273     else {
274       printf("failed\n");
275       exit(1);
276     }   
277
278     /*
279      * run validation test against the reference packets - note 
280      * that this test only covers the default policy
281      */
282     printf("testing srtp_protect and srtp_unprotect against "
283            "reference packets\n");
284     if (srtp_validate() == err_status_ok) 
285       printf("passed\n\n");
286     else {
287       printf("failed\n");
288        exit(1); 
289     }
290
291     /*
292      * run validation test against the reference packets for
293      * AES-256
294      */
295     printf("testing srtp_protect and srtp_unprotect against "
296            "reference packets (AES-256)\n");
297     if (srtp_validate_aes_256() == err_status_ok) 
298       printf("passed\n\n");
299     else {
300       printf("failed\n");
301        exit(1); 
302     }
303
304     /*
305      * test the function srtp_remove_stream()
306      */
307     printf("testing srtp_remove_stream()...");
308     if (srtp_test_remove_stream() == err_status_ok)
309       printf("passed\n");
310     else {
311       printf("failed\n");
312       exit(1);
313     }
314   }
315   
316   if (do_timing_test) {
317     const srtp_policy_t **policy = policy_array;
318     
319     /* loop over policies, run timing test for each */
320     while (*policy != NULL) {
321       srtp_print_policy(*policy);
322       srtp_do_timing(*policy);
323       policy++;
324     }
325   }
326
327   if (do_rejection_test) {
328     const srtp_policy_t **policy = policy_array;
329     
330     /* loop over policies, run rejection timing test for each */
331     while (*policy != NULL) {
332       srtp_print_policy(*policy);
333       srtp_do_rejection_timing(*policy);
334       policy++;
335     }
336   }
337   
338   if (do_codec_timing) {
339     srtp_policy_t policy;
340     int ignore;
341     double mips_value = mips_estimate(1000000000, &ignore);
342
343     crypto_policy_set_rtp_default(&policy.rtp);
344     crypto_policy_set_rtcp_default(&policy.rtcp);
345     policy.ssrc.type  = ssrc_specific;
346     policy.ssrc.value = 0xdecafbad;
347     policy.key  = test_key;
348     policy.ekt = NULL;
349     policy.window_size = 128;
350     policy.allow_repeat_tx = 0;
351     policy.next = NULL;
352
353     printf("mips estimate: %e\n", mips_value);
354
355     printf("testing srtp processing time for voice codecs:\n");
356     printf("codec\t\tlength (octets)\t\tsrtp instructions/second\n");
357     printf("G.711\t\t%d\t\t\t%e\n", 80, 
358            (double) mips_value * (80 * 8) /
359            srtp_bits_per_second(80, &policy) / .01 );
360     printf("G.711\t\t%d\t\t\t%e\n", 160, 
361            (double) mips_value * (160 * 8) /
362            srtp_bits_per_second(160, &policy) / .02);
363     printf("G.726-32\t%d\t\t\t%e\n", 40, 
364            (double) mips_value * (40 * 8) /
365            srtp_bits_per_second(40, &policy) / .01 );
366     printf("G.726-32\t%d\t\t\t%e\n", 80, 
367            (double) mips_value * (80 * 8) /
368            srtp_bits_per_second(80, &policy) / .02);
369     printf("G.729\t\t%d\t\t\t%e\n", 10, 
370            (double) mips_value * (10 * 8) /
371            srtp_bits_per_second(10, &policy) / .01 );
372     printf("G.729\t\t%d\t\t\t%e\n", 20, 
373            (double) mips_value * (20 * 8) /
374            srtp_bits_per_second(20, &policy) / .02 );
375     printf("Wideband\t%d\t\t\t%e\n", 320, 
376            (double) mips_value * (320 * 8) /
377            srtp_bits_per_second(320, &policy) / .01 );
378     printf("Wideband\t%d\t\t\t%e\n", 640, 
379            (double) mips_value * (640 * 8) /
380            srtp_bits_per_second(640, &policy) / .02 );
381   }
382
383   status = srtp_shutdown();
384   if (status) {
385     printf("error: srtp shutdown failed with error code %d\n", status);
386     exit(1);
387   }
388
389   return 0;  
390 }
391
392
393
394 /*
395  * srtp_create_test_packet(len, ssrc) returns a pointer to a
396  * (malloced) example RTP packet whose data field has the length given
397  * by pkt_octet_len and the SSRC value ssrc.  The total length of the
398  * packet is twelve octets longer, since the header is at the
399  * beginning.  There is room at the end of the packet for a trailer,
400  * and the four octets following the packet are filled with 0xff
401  * values to enable testing for overwrites.
402  *
403  * note that the location of the test packet can (and should) be
404  * deallocated with the free() call once it is no longer needed.
405  */
406
407 srtp_hdr_t *
408 srtp_create_test_packet(int pkt_octet_len, uint32_t ssrc) {
409   int i;
410   uint8_t *buffer;
411   srtp_hdr_t *hdr;
412   int bytes_in_hdr = 12;
413
414   /* allocate memory for test packet */
415   hdr = (srtp_hdr_t*) malloc(pkt_octet_len + bytes_in_hdr
416                + SRTP_MAX_TRAILER_LEN + 4);
417   if (!hdr)
418     return NULL;
419   
420   hdr->version = 2;              /* RTP version two     */
421   hdr->p    = 0;                 /* no padding needed   */
422   hdr->x    = 0;                 /* no header extension */
423   hdr->cc   = 0;                 /* no CSRCs            */
424   hdr->m    = 0;                 /* marker bit          */
425   hdr->pt   = 0xf;               /* payload type        */
426   hdr->seq  = htons(0x1234);     /* sequence number     */
427   hdr->ts   = htonl(0xdecafbad); /* timestamp           */
428   hdr->ssrc = htonl(ssrc);       /* synch. source       */
429
430   buffer = (uint8_t *)hdr;
431   buffer += bytes_in_hdr;
432
433   /* set RTP data to 0xab */
434   for (i=0; i < pkt_octet_len; i++)
435     *buffer++ = 0xab;
436
437   /* set post-data value to 0xffff to enable overrun checking */
438   for (i=0; i < SRTP_MAX_TRAILER_LEN+4; i++)
439     *buffer++ = 0xff;
440
441   return hdr;
442 }
443
444 void
445 srtp_do_timing(const srtp_policy_t *policy) {
446   int len;
447
448   /*
449    * note: the output of this function is formatted so that it
450    * can be used in gnuplot.  '#' indicates a comment, and "\r\n"
451    * terminates a record
452    */
453   
454   printf("# testing srtp throughput:\r\n");
455   printf("# mesg length (octets)\tthroughput (megabits per second)\r\n");
456   
457   for (len=16; len <= 2048; len *= 2)
458     printf("%d\t\t\t%f\r\n", len, 
459            srtp_bits_per_second(len, policy) / 1.0E6);
460   
461   /* these extra linefeeds let gnuplot know that a dataset is done */
462   printf("\r\n\r\n");  
463
464 }
465
466 void
467 srtp_do_rejection_timing(const srtp_policy_t *policy) {
468   int len;
469
470   /*
471    * note: the output of this function is formatted so that it
472    * can be used in gnuplot.  '#' indicates a comment, and "\r\n"
473    * terminates a record
474    */
475   
476   printf("# testing srtp rejection throughput:\r\n");
477   printf("# mesg length (octets)\trejections per second\r\n");
478   
479   for (len=8; len <= 2048; len *= 2)
480     printf("%d\t\t\t%e\r\n", len, srtp_rejections_per_second(len, policy));
481   
482   /* these extra linefeeds let gnuplot know that a dataset is done */
483   printf("\r\n\r\n");  
484
485 }
486
487
488 #define MAX_MSG_LEN 1024
489
490 double
491 srtp_bits_per_second(int msg_len_octets, const srtp_policy_t *policy) {
492   srtp_t srtp;
493   srtp_hdr_t *mesg;  
494   int i;
495   clock_t timer;
496   int num_trials = 100000;
497   int len;
498   uint32_t ssrc;
499   err_status_t status;
500
501   /*
502    * allocate and initialize an srtp session
503    */
504   status = srtp_create(&srtp, policy);
505   if (status) {
506     printf("error: srtp_create() failed with error code %d\n", status);
507     exit(1);
508   }
509
510   /*
511    * if the ssrc is unspecified, use a predetermined one
512    */
513   if (policy->ssrc.type != ssrc_specific) {
514     ssrc = 0xdeadbeef;
515   } else {
516     ssrc = policy->ssrc.value;
517   }
518
519   /*
520    * create a test packet
521    */
522   mesg = srtp_create_test_packet(msg_len_octets, ssrc);
523   if (mesg == NULL)
524     return 0.0;   /* indicate failure by returning zero */
525   
526   timer = clock();
527   for (i=0; i < num_trials; i++) {
528     len = msg_len_octets + 12;  /* add in rtp header length */
529     
530     /* srtp protect message */
531     status = srtp_protect(srtp, mesg, &len);
532     if (status) {
533       printf("error: srtp_protect() failed with error code %d\n", status);
534       exit(1);
535     }
536
537     /* increment message number */
538     {
539       /* hack sequence to avoid problems with macros for htons/ntohs on some systems */
540       short new_seq = ntohs(mesg->seq) + 1;
541       mesg->seq = htons(new_seq);
542     }
543   }
544   timer = clock() - timer;
545
546   free(mesg);
547
548   status = srtp_dealloc(srtp);
549   if (status) {
550     printf("error: srtp_dealloc() failed with error code %d\n", status);
551     exit(1);
552   }
553   
554   return (double) (msg_len_octets) * 8 *
555                   num_trials * CLOCKS_PER_SEC / timer;   
556 }
557
558 double
559 srtp_rejections_per_second(int msg_len_octets, const srtp_policy_t *policy) {
560   srtp_ctx_t *srtp;
561   srtp_hdr_t *mesg; 
562   int i;
563   int len;
564   clock_t timer;
565   int num_trials = 1000000;
566   uint32_t ssrc = policy->ssrc.value;
567   err_status_t status;
568
569   /*
570    * allocate and initialize an srtp session
571    */
572   status = srtp_create(&srtp, policy);
573   if (status) {
574     printf("error: srtp_create() failed with error code %d\n", status);
575     exit(1);
576   } 
577
578   mesg = srtp_create_test_packet(msg_len_octets, ssrc);
579   if (mesg == NULL)
580     return 0.0;  /* indicate failure by returning zero */
581   
582   len = msg_len_octets;  
583   srtp_protect(srtp, (srtp_hdr_t *)mesg, &len);
584   
585   timer = clock();
586   for (i=0; i < num_trials; i++) {
587     len = msg_len_octets;
588     srtp_unprotect(srtp, (srtp_hdr_t *)mesg, &len);
589   }
590   timer = clock() - timer;
591
592   free(mesg);
593
594   status = srtp_dealloc(srtp);
595   if (status) {
596     printf("error: srtp_dealloc() failed with error code %d\n", status);
597     exit(1);
598   }
599
600   return (double) num_trials * CLOCKS_PER_SEC / timer;   
601 }
602
603
604 void
605 err_check(err_status_t s) {
606   if (s == err_status_ok) 
607     return;
608   else
609     fprintf(stderr, "error: unexpected srtp failure (code %d)\n", s);
610   exit (1);
611 }
612
613 err_status_t
614 srtp_test(const srtp_policy_t *policy) {
615   int i;
616   srtp_t srtp_sender;
617   srtp_t srtp_rcvr;
618   err_status_t status = err_status_ok;
619   srtp_hdr_t *hdr, *hdr2;
620   uint8_t hdr_enc[64];
621   uint8_t *pkt_end;
622   int msg_len_octets, msg_len_enc;
623   int len;
624   int tag_length = policy->rtp.auth_tag_len; 
625   uint32_t ssrc;
626   srtp_policy_t *rcvr_policy;
627
628   err_check(srtp_create(&srtp_sender, policy));
629
630   /* print out policy */
631   err_check(srtp_session_print_policy(srtp_sender)); 
632
633   /*
634    * initialize data buffer, using the ssrc in the policy unless that
635    * value is a wildcard, in which case we'll just use an arbitrary
636    * one
637    */
638   if (policy->ssrc.type != ssrc_specific)
639     ssrc = 0xdecafbad;
640   else
641     ssrc = policy->ssrc.value;
642   msg_len_octets = 28;
643   hdr = srtp_create_test_packet(msg_len_octets, ssrc);
644
645   if (hdr == NULL)
646     return err_status_alloc_fail;
647   hdr2 = srtp_create_test_packet(msg_len_octets, ssrc);
648   if (hdr2 == NULL) {
649     free(hdr);
650     return err_status_alloc_fail;
651   }
652
653   /* set message length */
654   len = msg_len_octets;
655
656   debug_print(mod_driver, "before protection:\n%s",           
657               srtp_packet_to_string(hdr, len));
658
659 #if PRINT_REFERENCE_PACKET
660   debug_print(mod_driver, "reference packet before protection:\n%s",          
661               octet_string_hex_string((uint8_t *)hdr, len));
662 #endif
663   err_check(srtp_protect(srtp_sender, hdr, &len));
664
665   debug_print(mod_driver, "after protection:\n%s",            
666               srtp_packet_to_string(hdr, len));
667 #if PRINT_REFERENCE_PACKET
668   debug_print(mod_driver, "after protection:\n%s",            
669               octet_string_hex_string((uint8_t *)hdr, len));
670 #endif
671
672   /* save protected message and length */
673   memcpy(hdr_enc, hdr, len);
674   msg_len_enc = len;
675
676   /* 
677    * check for overrun of the srtp_protect() function
678    *
679    * The packet is followed by a value of 0xfffff; if the value of the
680    * data following the packet is different, then we know that the
681    * protect function is overwriting the end of the packet.
682    */
683   pkt_end = (uint8_t *)hdr + sizeof(srtp_hdr_t) 
684     + msg_len_octets + tag_length;
685   for (i = 0; i < 4; i++)
686     if (pkt_end[i] != 0xff) {
687       fprintf(stdout, "overwrite in srtp_protect() function "
688               "(expected %x, found %x in trailing octet %d)\n",
689               0xff, ((uint8_t *)hdr)[i], i);
690       free(hdr);
691       free(hdr2);
692       return err_status_algo_fail;
693     }  
694
695   /*
696    * if the policy includes confidentiality, check that ciphertext is
697    * different than plaintext
698    * 
699    * Note that this check will give false negatives, with some small
700    * probability, especially if the packets are short.  For that
701    * reason, we skip this check if the plaintext is less than four
702    * octets long.
703    */
704   if ((policy->rtp.sec_serv & sec_serv_conf) && (msg_len_octets >= 4)) {
705     printf("testing that ciphertext is distinct from plaintext...");
706     status = err_status_algo_fail;
707     for (i=12; i < msg_len_octets+12; i++)
708       if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) {
709         status = err_status_ok;
710       }
711     if (status) {
712       printf("failed\n");
713       free(hdr);
714       free(hdr2);
715       return status;
716     }
717     printf("passed\n");
718   }
719   
720   /*
721    * if the policy uses a 'wildcard' ssrc, then we need to make a copy
722    * of the policy that changes the direction to inbound
723    *
724    * we always copy the policy into the rcvr_policy, since otherwise
725    * the compiler would fret about the constness of the policy
726    */
727   rcvr_policy = (srtp_policy_t*) malloc(sizeof(srtp_policy_t));
728   if (rcvr_policy == NULL) {
729     free(hdr);
730     free(hdr2);
731     return err_status_alloc_fail;
732   }
733   memcpy(rcvr_policy, policy, sizeof(srtp_policy_t));
734   if (policy->ssrc.type == ssrc_any_outbound) {
735     rcvr_policy->ssrc.type = ssrc_any_inbound;       
736   } 
737
738   err_check(srtp_create(&srtp_rcvr, rcvr_policy));
739    
740   err_check(srtp_unprotect(srtp_rcvr, hdr, &len));
741
742   debug_print(mod_driver, "after unprotection:\n%s",          
743               srtp_packet_to_string(hdr, len));
744
745   /* verify that the unprotected packet matches the origial one */
746   for (i=0; i < msg_len_octets; i++)
747     if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) {
748       fprintf(stdout, "mismatch at octet %d\n", i);
749       status = err_status_algo_fail;
750     }
751   if (status) {
752     free(hdr);
753     free(hdr2);
754     free(rcvr_policy);
755     return status;
756   }
757
758   /* 
759    * if the policy includes authentication, then test for false positives
760    */  
761   if (policy->rtp.sec_serv & sec_serv_auth) {
762     char *data = ((char *)hdr) + 12;
763     
764     printf("testing for false positives in replay check...");
765
766     /* set message length */
767     len = msg_len_enc;
768
769     /* unprotect a second time - should fail with a replay error */
770     status = srtp_unprotect(srtp_rcvr, hdr_enc, &len);
771     if (status != err_status_replay_fail) {
772       printf("failed with error code %d\n", status);
773       free(hdr); 
774       free(hdr2);
775       free(rcvr_policy);
776       return status;
777     } else {
778       printf("passed\n");
779     }
780
781     printf("testing for false positives in auth check...");
782
783     /* increment sequence number in header */
784     hdr->seq++; 
785
786     /* set message length */
787     len = msg_len_octets;
788
789     /* apply protection */
790     err_check(srtp_protect(srtp_sender, hdr, &len));
791     
792     /* flip bits in packet */
793     data[0] ^= 0xff;
794
795     /* unprotect, and check for authentication failure */
796     status = srtp_unprotect(srtp_rcvr, hdr, &len);
797     if (status != err_status_auth_fail) {
798       printf("failed\n");
799       free(hdr); 
800       free(hdr2);
801       free(rcvr_policy);
802       return status;
803     } else {
804       printf("passed\n");
805     }
806             
807   }
808
809   err_check(srtp_dealloc(srtp_sender));
810   err_check(srtp_dealloc(srtp_rcvr));
811
812   free(hdr);
813   free(hdr2);
814   free(rcvr_policy);
815   return err_status_ok;
816 }
817
818
819 err_status_t
820 srtcp_test(const srtp_policy_t *policy) {
821   int i;
822   srtp_t srtcp_sender;
823   srtp_t srtcp_rcvr;
824   err_status_t status = err_status_ok;
825   srtp_hdr_t *hdr, *hdr2;
826   uint8_t hdr_enc[64];
827   uint8_t *pkt_end;
828   int msg_len_octets, msg_len_enc;
829   int len;
830   int tag_length = policy->rtp.auth_tag_len; 
831   uint32_t ssrc;
832   srtp_policy_t *rcvr_policy;
833
834   err_check(srtp_create(&srtcp_sender, policy));
835
836   /* print out policy */
837   err_check(srtp_session_print_policy(srtcp_sender)); 
838
839   /*
840    * initialize data buffer, using the ssrc in the policy unless that
841    * value is a wildcard, in which case we'll just use an arbitrary
842    * one
843    */
844   if (policy->ssrc.type != ssrc_specific)
845     ssrc = 0xdecafbad;
846   else
847     ssrc = policy->ssrc.value;
848   msg_len_octets = 28;
849   hdr = srtp_create_test_packet(msg_len_octets, ssrc);
850
851   if (hdr == NULL)
852     return err_status_alloc_fail;
853   hdr2 = srtp_create_test_packet(msg_len_octets, ssrc);
854   if (hdr2 == NULL) {
855     free(hdr);
856     return err_status_alloc_fail;
857   }
858
859   /* set message length */
860   len = msg_len_octets;
861
862   debug_print(mod_driver, "before protection:\n%s",           
863               srtp_packet_to_string(hdr, len));
864
865 #if PRINT_REFERENCE_PACKET
866   debug_print(mod_driver, "reference packet before protection:\n%s",          
867               octet_string_hex_string((uint8_t *)hdr, len));
868 #endif
869   err_check(srtp_protect_rtcp(srtcp_sender, hdr, &len));
870
871   debug_print(mod_driver, "after protection:\n%s",            
872               srtp_packet_to_string(hdr, len));
873 #if PRINT_REFERENCE_PACKET
874   debug_print(mod_driver, "after protection:\n%s",            
875               octet_string_hex_string((uint8_t *)hdr, len));
876 #endif
877
878   /* save protected message and length */
879   memcpy(hdr_enc, hdr, len);
880   msg_len_enc = len;
881
882   /* 
883    * check for overrun of the srtp_protect() function
884    *
885    * The packet is followed by a value of 0xfffff; if the value of the
886    * data following the packet is different, then we know that the
887    * protect function is overwriting the end of the packet.
888    */
889   pkt_end = (uint8_t *)hdr + sizeof(srtp_hdr_t) 
890     + msg_len_octets + tag_length;
891   for (i = 0; i < 4; i++)
892     if (pkt_end[i] != 0xff) {
893       fprintf(stdout, "overwrite in srtp_protect_rtcp() function "
894               "(expected %x, found %x in trailing octet %d)\n",
895               0xff, ((uint8_t *)hdr)[i], i);
896       free(hdr);
897       free(hdr2);
898       return err_status_algo_fail;
899     }  
900
901   /*
902    * if the policy includes confidentiality, check that ciphertext is
903    * different than plaintext
904    * 
905    * Note that this check will give false negatives, with some small
906    * probability, especially if the packets are short.  For that
907    * reason, we skip this check if the plaintext is less than four
908    * octets long.
909    */
910   if ((policy->rtp.sec_serv & sec_serv_conf) && (msg_len_octets >= 4)) {
911     printf("testing that ciphertext is distinct from plaintext...");
912     status = err_status_algo_fail;
913     for (i=12; i < msg_len_octets+12; i++)
914       if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) {
915         status = err_status_ok;
916       }
917     if (status) {
918       printf("failed\n");
919       free(hdr);
920       free(hdr2);
921       return status;
922     }
923     printf("passed\n");
924   }
925   
926   /*
927    * if the policy uses a 'wildcard' ssrc, then we need to make a copy
928    * of the policy that changes the direction to inbound
929    *
930    * we always copy the policy into the rcvr_policy, since otherwise
931    * the compiler would fret about the constness of the policy
932    */
933   rcvr_policy = (srtp_policy_t*) malloc(sizeof(srtp_policy_t));
934   if (rcvr_policy == NULL)
935     return err_status_alloc_fail;
936   memcpy(rcvr_policy, policy, sizeof(srtp_policy_t));
937   if (policy->ssrc.type == ssrc_any_outbound) {
938     rcvr_policy->ssrc.type = ssrc_any_inbound;       
939   } 
940
941   err_check(srtp_create(&srtcp_rcvr, rcvr_policy));
942    
943   err_check(srtp_unprotect_rtcp(srtcp_rcvr, hdr, &len));
944
945   debug_print(mod_driver, "after unprotection:\n%s",          
946               srtp_packet_to_string(hdr, len));
947
948   /* verify that the unprotected packet matches the origial one */
949   for (i=0; i < msg_len_octets; i++)
950     if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) {
951       fprintf(stdout, "mismatch at octet %d\n", i);
952       status = err_status_algo_fail;
953     }
954   if (status) {
955     free(hdr);
956     free(hdr2);
957     free(rcvr_policy);
958     return status;
959   }
960
961   /* 
962    * if the policy includes authentication, then test for false positives
963    */  
964   if (policy->rtp.sec_serv & sec_serv_auth) {
965     char *data = ((char *)hdr) + 12;
966     
967     printf("testing for false positives in replay check...");
968
969     /* set message length */
970     len = msg_len_enc;
971
972     /* unprotect a second time - should fail with a replay error */
973     status = srtp_unprotect_rtcp(srtcp_rcvr, hdr_enc, &len);
974     if (status != err_status_replay_fail) {
975       printf("failed with error code %d\n", status);
976       free(hdr); 
977       free(hdr2);
978       free(rcvr_policy);
979       return status;
980     } else {
981       printf("passed\n");
982     }
983
984     printf("testing for false positives in auth check...");
985
986     /* increment sequence number in header */
987     hdr->seq++; 
988
989     /* set message length */
990     len = msg_len_octets;
991
992     /* apply protection */
993     err_check(srtp_protect_rtcp(srtcp_sender, hdr, &len));
994     
995     /* flip bits in packet */
996     data[0] ^= 0xff;
997
998     /* unprotect, and check for authentication failure */
999     status = srtp_unprotect_rtcp(srtcp_rcvr, hdr, &len);
1000     if (status != err_status_auth_fail) {
1001       printf("failed\n");
1002       free(hdr); 
1003       free(hdr2);
1004       free(rcvr_policy);
1005       return status;
1006     } else {
1007       printf("passed\n");
1008     }
1009             
1010   }
1011
1012   err_check(srtp_dealloc(srtcp_sender));
1013   err_check(srtp_dealloc(srtcp_rcvr));
1014
1015   free(hdr);
1016   free(hdr2);
1017   free(rcvr_policy);
1018   return err_status_ok;
1019 }
1020
1021
1022 err_status_t
1023 srtp_session_print_policy(srtp_t srtp) {
1024   char *serv_descr[4] = {
1025     "none",
1026     "confidentiality",
1027     "authentication",
1028     "confidentiality and authentication"
1029   };
1030   char *direction[3] = {
1031     "unknown",
1032     "outbound",
1033     "inbound"
1034   };
1035   srtp_stream_t stream;
1036
1037   /* sanity checking */
1038   if (srtp == NULL)
1039     return err_status_fail;
1040
1041   /* if there's a template stream, print it out */
1042   if (srtp->stream_template != NULL) {
1043     stream = srtp->stream_template;
1044     printf("# SSRC:          any %s\r\n"
1045            "# rtp cipher:    %s\r\n"
1046            "# rtp auth:      %s\r\n"
1047            "# rtp services:  %s\r\n" 
1048            "# rtcp cipher:   %s\r\n"
1049            "# rtcp auth:     %s\r\n"
1050            "# rtcp services: %s\r\n"
1051            "# window size:   %lu\r\n"
1052            "# tx rtx allowed:%s\r\n",
1053            direction[stream->direction],
1054            stream->rtp_cipher->type->description,
1055            stream->rtp_auth->type->description,
1056            serv_descr[stream->rtp_services],
1057            stream->rtcp_cipher->type->description,
1058            stream->rtcp_auth->type->description,
1059            serv_descr[stream->rtcp_services],
1060            rdbx_get_window_size(&stream->rtp_rdbx),
1061            stream->allow_repeat_tx ? "true" : "false");
1062   }
1063
1064   /* loop over streams in session, printing the policy of each */
1065   stream = srtp->stream_list;
1066   while (stream != NULL) {
1067     if (stream->rtp_services > sec_serv_conf_and_auth)
1068       return err_status_bad_param;
1069     
1070     printf("# SSRC:          0x%08x\r\n"
1071            "# rtp cipher:    %s\r\n"
1072            "# rtp auth:      %s\r\n"
1073            "# rtp services:  %s\r\n" 
1074            "# rtcp cipher:   %s\r\n"
1075            "# rtcp auth:     %s\r\n"
1076            "# rtcp services: %s\r\n"
1077            "# window size:   %lu\r\n"
1078            "# tx rtx allowed:%s\r\n",
1079            stream->ssrc,
1080            stream->rtp_cipher->type->description,
1081            stream->rtp_auth->type->description,
1082            serv_descr[stream->rtp_services],
1083            stream->rtcp_cipher->type->description,
1084            stream->rtcp_auth->type->description,
1085            serv_descr[stream->rtcp_services],
1086            rdbx_get_window_size(&stream->rtp_rdbx),
1087            stream->allow_repeat_tx ? "true" : "false");
1088
1089     /* advance to next stream in the list */
1090     stream = stream->next;
1091   } 
1092   return err_status_ok;
1093 }
1094
1095 err_status_t
1096 srtp_print_policy(const srtp_policy_t *policy) {
1097   err_status_t status;
1098   srtp_t session;
1099
1100   status = srtp_create(&session, policy);
1101   if (status)
1102     return status;
1103   status = srtp_session_print_policy(session);
1104   if (status)
1105     return status;
1106   status = srtp_dealloc(session);
1107   if (status)
1108     return status;
1109   return err_status_ok;
1110 }
1111
1112 /* 
1113  * srtp_print_packet(...) is for debugging only 
1114  * it prints an RTP packet to the stdout
1115  *
1116  * note that this function is *not* threadsafe
1117  */
1118
1119 #include <stdio.h>
1120
1121 #define MTU 2048
1122
1123 char packet_string[MTU];
1124
1125 char *
1126 srtp_packet_to_string(srtp_hdr_t *hdr, int pkt_octet_len) {
1127   int octets_in_rtp_header = 12;
1128   uint8_t *data = ((uint8_t *)hdr)+octets_in_rtp_header;
1129   int hex_len = pkt_octet_len-octets_in_rtp_header;
1130
1131   /* sanity checking */
1132   if ((hdr == NULL) || (pkt_octet_len > MTU))
1133     return NULL;
1134
1135   /* write packet into string */
1136   sprintf(packet_string, 
1137           "(s)rtp packet: {\n"
1138           "   version:\t%d\n" 
1139           "   p:\t\t%d\n"     
1140           "   x:\t\t%d\n"     
1141           "   cc:\t\t%d\n"    
1142           "   m:\t\t%d\n"     
1143           "   pt:\t\t%x\n"    
1144           "   seq:\t\t%x\n"   
1145           "   ts:\t\t%x\n"    
1146           "   ssrc:\t%x\n"    
1147           "   data:\t%s\n"    
1148           "} (%d octets in total)\n", 
1149           hdr->version,  
1150           hdr->p,              
1151           hdr->x,              
1152           hdr->cc,       
1153           hdr->m,              
1154           hdr->pt,       
1155           hdr->seq,      
1156           hdr->ts,       
1157           hdr->ssrc,      
1158           octet_string_hex_string(data, hex_len),
1159           pkt_octet_len);
1160
1161   return packet_string;
1162 }
1163
1164 /*
1165  * mips_estimate() is a simple function to estimate the number of
1166  * instructions per second that the host can perform.  note that this
1167  * function can be grossly wrong; you may want to have a manual sanity
1168  * check of its output!
1169  *
1170  * the 'ignore' pointer is there to convince the compiler to not just
1171  * optimize away the function
1172  */
1173
1174 double
1175 mips_estimate(int num_trials, int *ignore) {
1176   clock_t t;
1177   volatile int i, sum;
1178
1179   sum = 0;
1180   t = clock();
1181   for (i=0; i<num_trials; i++)
1182     sum += i;
1183   t = clock() - t;
1184
1185 /*   printf("%d\n", sum); */
1186   *ignore = sum;
1187
1188   return (double) num_trials * CLOCKS_PER_SEC / t;
1189 }
1190
1191
1192 /*
1193  * srtp_validate() verifies the correctness of libsrtp by comparing
1194  * some computed packets against some pre-computed reference values.
1195  * These packets were made with the default SRTP policy.
1196  */
1197
1198
1199 err_status_t
1200 srtp_validate() {
1201   uint8_t srtp_plaintext_ref[28] = {
1202     0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad, 
1203     0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
1204     0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 
1205     0xab, 0xab, 0xab, 0xab
1206   };
1207   uint8_t srtp_plaintext[38] = {
1208     0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad, 
1209     0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
1210     0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 
1211     0xab, 0xab, 0xab, 0xab, 0x00, 0x00, 0x00, 0x00, 
1212     0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1213   };
1214   uint8_t srtp_ciphertext[38] = {
1215     0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad, 
1216     0xca, 0xfe, 0xba, 0xbe, 0x4e, 0x55, 0xdc, 0x4c,
1217     0xe7, 0x99, 0x78, 0xd8, 0x8c, 0xa4, 0xd2, 0x15, 
1218     0x94, 0x9d, 0x24, 0x02, 0xb7, 0x8d, 0x6a, 0xcc,
1219     0x99, 0xea, 0x17, 0x9b, 0x8d, 0xbb
1220   };
1221   srtp_t srtp_snd, srtp_recv;
1222   err_status_t status;
1223   int len;
1224   srtp_policy_t policy;
1225   
1226   /*
1227    * create a session with a single stream using the default srtp
1228    * policy and with the SSRC value 0xcafebabe
1229    */
1230   crypto_policy_set_rtp_default(&policy.rtp);
1231   crypto_policy_set_rtcp_default(&policy.rtcp);
1232   policy.ssrc.type  = ssrc_specific;
1233   policy.ssrc.value = 0xcafebabe;
1234   policy.key  = test_key;
1235   policy.ekt = NULL;
1236   policy.window_size = 128;
1237   policy.allow_repeat_tx = 0;
1238   policy.next = NULL;
1239
1240   status = srtp_create(&srtp_snd, &policy);
1241   if (status)
1242     return status;
1243  
1244   /* 
1245    * protect plaintext, then compare with ciphertext 
1246    */
1247   len = 28;
1248   status = srtp_protect(srtp_snd, srtp_plaintext, &len);
1249   if (status || (len != 38))
1250     return err_status_fail;
1251
1252   debug_print(mod_driver, "ciphertext:\n  %s",        
1253               octet_string_hex_string(srtp_plaintext, len));
1254   debug_print(mod_driver, "ciphertext reference:\n  %s",              
1255               octet_string_hex_string(srtp_ciphertext, len));
1256
1257   if (octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len))
1258     return err_status_fail;
1259   
1260   /*
1261    * create a receiver session context comparable to the one created
1262    * above - we need to do this so that the replay checking doesn't
1263    * complain
1264    */
1265   status = srtp_create(&srtp_recv, &policy);
1266   if (status)
1267     return status;
1268
1269   /*
1270    * unprotect ciphertext, then compare with plaintext 
1271    */
1272   status = srtp_unprotect(srtp_recv, srtp_ciphertext, &len);
1273   if (status || (len != 28))
1274     return status;
1275   
1276   if (octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len))
1277     return err_status_fail;
1278
1279   status = srtp_dealloc(srtp_snd);
1280   if (status)
1281     return status;
1282
1283   status = srtp_dealloc(srtp_recv);
1284   if (status)
1285     return status;
1286
1287   return err_status_ok;
1288 }
1289
1290
1291 /*
1292  * srtp_validate_aes_256() verifies the correctness of libsrtp by comparing
1293  * some computed packets against some pre-computed reference values.
1294  * These packets were made with the AES-CM-256/HMAC-SHA-1-80 policy.
1295  */
1296
1297
1298 err_status_t
1299 srtp_validate_aes_256() {
1300   unsigned char aes_256_test_key[46] = {
1301     0xf0, 0xf0, 0x49, 0x14, 0xb5, 0x13, 0xf2, 0x76,
1302     0x3a, 0x1b, 0x1f, 0xa1, 0x30, 0xf1, 0x0e, 0x29,
1303     0x98, 0xf6, 0xf6, 0xe4, 0x3e, 0x43, 0x09, 0xd1,
1304     0xe6, 0x22, 0xa0, 0xe3, 0x32, 0xb9, 0xf1, 0xb6,
1305
1306     0x3b, 0x04, 0x80, 0x3d, 0xe5, 0x1e, 0xe7, 0xc9,
1307     0x64, 0x23, 0xab, 0x5b, 0x78, 0xd2
1308   };
1309   uint8_t srtp_plaintext_ref[28] = {
1310     0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad, 
1311     0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
1312     0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 
1313     0xab, 0xab, 0xab, 0xab
1314   };
1315   uint8_t srtp_plaintext[38] = {
1316     0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad, 
1317     0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
1318     0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 
1319     0xab, 0xab, 0xab, 0xab, 0x00, 0x00, 0x00, 0x00, 
1320     0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1321   };
1322   uint8_t srtp_ciphertext[38] = {
1323     0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad, 
1324     0xca, 0xfe, 0xba, 0xbe, 0xf1, 0xd9, 0xde, 0x17, 
1325     0xff, 0x25, 0x1f, 0xf1, 0xaa, 0x00, 0x77, 0x74, 
1326     0xb0, 0xb4, 0xb4, 0x0d, 0xa0, 0x8d, 0x9d, 0x9a, 
1327     0x5b, 0x3a, 0x55, 0xd8, 0x87, 0x3b
1328   };
1329   srtp_t srtp_snd, srtp_recv;
1330   err_status_t status;
1331   int len;
1332   srtp_policy_t policy;
1333   
1334   /*
1335    * create a session with a single stream using the default srtp
1336    * policy and with the SSRC value 0xcafebabe
1337    */
1338   crypto_policy_set_aes_cm_256_hmac_sha1_80(&policy.rtp);
1339   crypto_policy_set_aes_cm_256_hmac_sha1_80(&policy.rtcp);
1340   policy.ssrc.type  = ssrc_specific;
1341   policy.ssrc.value = 0xcafebabe;
1342   policy.key  = aes_256_test_key;
1343   policy.ekt = NULL;
1344   policy.window_size = 128;
1345   policy.allow_repeat_tx = 0;
1346   policy.next = NULL;
1347
1348   status = srtp_create(&srtp_snd, &policy);
1349   if (status)
1350     return status;
1351  
1352   /* 
1353    * protect plaintext, then compare with ciphertext 
1354    */
1355   len = 28;
1356   status = srtp_protect(srtp_snd, srtp_plaintext, &len);
1357   if (status || (len != 38))
1358     return err_status_fail;
1359
1360   debug_print(mod_driver, "ciphertext:\n  %s",        
1361               octet_string_hex_string(srtp_plaintext, len));
1362   debug_print(mod_driver, "ciphertext reference:\n  %s",              
1363               octet_string_hex_string(srtp_ciphertext, len));
1364
1365   if (octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len))
1366     return err_status_fail;
1367   
1368   /*
1369    * create a receiver session context comparable to the one created
1370    * above - we need to do this so that the replay checking doesn't
1371    * complain
1372    */
1373   status = srtp_create(&srtp_recv, &policy);
1374   if (status)
1375     return status;
1376
1377   /*
1378    * unprotect ciphertext, then compare with plaintext 
1379    */
1380   status = srtp_unprotect(srtp_recv, srtp_ciphertext, &len);
1381   if (status || (len != 28))
1382     return status;
1383   
1384   if (octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len))
1385     return err_status_fail;
1386
1387   status = srtp_dealloc(srtp_snd);
1388   if (status)
1389     return status;
1390
1391   status = srtp_dealloc(srtp_recv);
1392   if (status)
1393     return status;
1394
1395   return err_status_ok;
1396 }
1397
1398
1399 err_status_t
1400 srtp_create_big_policy(srtp_policy_t **list) {
1401   extern const srtp_policy_t *policy_array[];
1402   srtp_policy_t *p, *tmp;
1403   int i = 0;
1404   uint32_t ssrc = 0;
1405
1406   /* sanity checking */
1407   if ((list == NULL) || (policy_array[0] == NULL))
1408     return err_status_bad_param;
1409
1410   /* 
1411    * loop over policy list, mallocing a new list and copying values
1412    * into it (and incrementing the SSRC value as we go along)
1413    */
1414   tmp = NULL;
1415   while (policy_array[i] != NULL) {
1416     p  = (srtp_policy_t*) malloc(sizeof(srtp_policy_t));
1417     if (p == NULL)
1418       return err_status_bad_param;
1419     memcpy(p, policy_array[i], sizeof(srtp_policy_t));
1420     p->ssrc.type = ssrc_specific;
1421     p->ssrc.value = ssrc++;
1422     p->next = tmp;
1423     tmp = p;
1424     i++;
1425   }
1426   *list = p;
1427  
1428   return err_status_ok;
1429 }
1430
1431 err_status_t
1432 srtp_dealloc_big_policy(srtp_policy_t *list) {
1433   srtp_policy_t *p, *next;
1434
1435   for (p = list; p != NULL; p = next) {
1436     next = p->next;
1437     free(p);
1438   }
1439
1440   return err_status_ok;
1441 }
1442
1443
1444 err_status_t
1445 srtp_test_remove_stream() { 
1446   err_status_t status;
1447   srtp_policy_t *policy_list, policy;
1448   srtp_t session;
1449   srtp_stream_t stream;
1450   /* 
1451    * srtp_get_stream() is a libSRTP internal function that we declare
1452    * here so that we can use it to verify the correct operation of the
1453    * library
1454    */ 
1455   extern srtp_stream_t srtp_get_stream(srtp_t srtp, uint32_t ssrc);
1456   
1457
1458   status = srtp_create_big_policy(&policy_list);
1459   if (status)
1460     return status;
1461
1462   status = srtp_create(&session, policy_list);
1463   if (status)
1464     return status;
1465
1466   /*
1467    * check for false positives by trying to remove a stream that's not
1468    * in the session
1469    */
1470   status = srtp_remove_stream(session, htonl(0xaaaaaaaa));
1471   if (status != err_status_no_ctx)
1472     return err_status_fail;
1473   
1474   /* 
1475    * check for false negatives by removing stream 0x1, then
1476    * searching for streams 0x0 and 0x2
1477    */
1478   status = srtp_remove_stream(session, htonl(0x1));
1479   if (status != err_status_ok)
1480     return err_status_fail;
1481   stream = srtp_get_stream(session, htonl(0x0));
1482   if (stream == NULL)
1483     return err_status_fail;
1484   stream = srtp_get_stream(session, htonl(0x2));
1485   if (stream == NULL)
1486     return err_status_fail;  
1487
1488   status = srtp_dealloc(session);
1489   if (status != err_status_ok)
1490     return status;
1491
1492   status = srtp_dealloc_big_policy(policy_list);
1493   if (status != err_status_ok)
1494     return status;
1495
1496   /* Now test adding and removing a single stream */
1497   crypto_policy_set_rtp_default(&policy.rtp);
1498   crypto_policy_set_rtcp_default(&policy.rtcp);
1499   policy.ssrc.type  = ssrc_specific;
1500   policy.ssrc.value = 0xcafebabe;
1501   policy.key  = test_key;
1502   policy.ekt = NULL;
1503   policy.window_size = 128;
1504   policy.allow_repeat_tx = 0;
1505   policy.next = NULL;
1506
1507   status = srtp_create(&session, NULL);
1508   if (status != err_status_ok)
1509     return status;
1510   
1511   status = srtp_add_stream(session, &policy);
1512   if (status != err_status_ok)
1513     return status;
1514
1515   status = srtp_remove_stream(session, htonl(0xcafebabe));
1516   if (status != err_status_ok)
1517     return status;
1518
1519   status = srtp_dealloc(session);
1520   if (status != err_status_ok)
1521     return status;
1522
1523   return err_status_ok;  
1524 }
1525
1526 /*
1527  * srtp policy definitions - these definitions are used above
1528  */
1529
1530 unsigned char test_key[30] = {
1531     0xe1, 0xf9, 0x7a, 0x0d, 0x3e, 0x01, 0x8b, 0xe0,
1532     0xd6, 0x4f, 0xa3, 0x2c, 0x06, 0xde, 0x41, 0x39,
1533     0x0e, 0xc6, 0x75, 0xad, 0x49, 0x8a, 0xfe, 0xeb,
1534     0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6
1535 };
1536
1537
1538 const srtp_policy_t default_policy = {
1539   { ssrc_any_outbound, 0 },  /* SSRC                           */
1540   {                      /* SRTP policy                    */                  
1541     AES_128_ICM,            /* cipher type                 */
1542     30,                     /* cipher key length in octets */
1543     HMAC_SHA1,              /* authentication func type    */
1544     16,                     /* auth key length in octets   */
1545     10,                     /* auth tag length in octets   */
1546     sec_serv_conf_and_auth  /* security services flag      */
1547   },
1548   {                      /* SRTCP policy                   */
1549     AES_128_ICM,            /* cipher type                 */
1550     30,                     /* cipher key length in octets */
1551     HMAC_SHA1,              /* authentication func type    */
1552     16,                     /* auth key length in octets   */
1553     10,                     /* auth tag length in octets   */
1554     sec_serv_conf_and_auth  /* security services flag      */
1555   },
1556   test_key,
1557   NULL,        /* indicates that EKT is not in use */
1558   128,         /* replay window size */
1559   0,           /* retransmission not allowed */
1560   NULL
1561 };
1562
1563 const srtp_policy_t aes_tmmh_policy = {
1564   { ssrc_any_outbound, 0 },     /* SSRC                        */
1565   { 
1566     AES_128_ICM,            /* cipher type                 */
1567     30,                     /* cipher key length in octets */
1568     UST_TMMHv2,             /* authentication func type    */
1569     94,                     /* auth key length in octets   */
1570     4,                      /* auth tag length in octets   */
1571     sec_serv_conf_and_auth  /* security services flag      */
1572   },
1573   { 
1574     AES_128_ICM,            /* cipher type                 */
1575     30,                     /* cipher key length in octets */
1576     UST_TMMHv2,             /* authentication func type    */
1577     94,                     /* auth key length in octets   */
1578     4,                      /* auth tag length in octets   */
1579     sec_serv_conf_and_auth  /* security services flag      */
1580   },
1581   test_key,
1582   NULL,        /* indicates that EKT is not in use */
1583   128,         /* replay window size */
1584   0,           /* retransmission not allowed */
1585   NULL
1586 };
1587
1588 const srtp_policy_t tmmh_only_policy = {
1589   { ssrc_any_outbound, 0 },     /* SSRC                        */
1590   {
1591     AES_128_ICM,            /* cipher type                 */
1592     30,                     /* cipher key length in octets */
1593     UST_TMMHv2,             /* authentication func type    */
1594     94,                     /* auth key length in octets   */
1595     4,                      /* auth tag length in octets   */
1596     sec_serv_auth           /* security services flag      */
1597   },
1598   {
1599     AES_128_ICM,            /* cipher type                 */
1600     30,                     /* cipher key length in octets */
1601     UST_TMMHv2,             /* authentication func type    */
1602     94,                     /* auth key length in octets   */
1603     4,                      /* auth tag length in octets   */
1604     sec_serv_auth           /* security services flag      */
1605   },
1606   test_key,
1607   NULL,        /* indicates that EKT is not in use */
1608   128,         /* replay window size */
1609   0,           /* retransmission not allowed */
1610   NULL
1611 };
1612
1613 const srtp_policy_t aes_only_policy = {
1614   { ssrc_any_outbound, 0 },     /* SSRC                        */ 
1615   {
1616     AES_128_ICM,            /* cipher type                 */
1617     30,                     /* cipher key length in octets */
1618     NULL_AUTH,              /* authentication func type    */
1619     0,                      /* auth key length in octets   */
1620     0,                      /* auth tag length in octets   */
1621     sec_serv_conf           /* security services flag      */
1622   },
1623   {
1624     AES_128_ICM,            /* cipher type                 */
1625     30,                     /* cipher key length in octets */
1626     NULL_AUTH,              /* authentication func type    */
1627     0,                      /* auth key length in octets   */
1628     0,                      /* auth tag length in octets   */
1629     sec_serv_conf           /* security services flag      */
1630   },
1631   test_key,
1632   NULL,        /* indicates that EKT is not in use */
1633   128,         /* replay window size */
1634   0,           /* retransmission not allowed */
1635   NULL
1636 };
1637
1638 const srtp_policy_t hmac_only_policy = {
1639   { ssrc_any_outbound, 0 },     /* SSRC                        */
1640   {
1641     NULL_CIPHER,            /* cipher type                 */
1642     0,                      /* cipher key length in octets */
1643     HMAC_SHA1,              /* authentication func type    */
1644     20,                     /* auth key length in octets   */
1645     4,                      /* auth tag length in octets   */
1646     sec_serv_auth           /* security services flag      */
1647   },  
1648   {
1649     NULL_CIPHER,            /* cipher type                 */
1650     0,                      /* cipher key length in octets */
1651     HMAC_SHA1,              /* authentication func type    */
1652     20,                     /* auth key length in octets   */
1653     4,                      /* auth tag length in octets   */
1654     sec_serv_auth           /* security services flag      */
1655   },
1656   test_key,
1657   NULL,        /* indicates that EKT is not in use */
1658   128,         /* replay window size */
1659   0,           /* retransmission not allowed */
1660   NULL
1661 };
1662
1663 const srtp_policy_t null_policy = {
1664   { ssrc_any_outbound, 0 },     /* SSRC                        */ 
1665   {
1666     NULL_CIPHER,            /* cipher type                 */
1667     0,                      /* cipher key length in octets */
1668     NULL_AUTH,              /* authentication func type    */
1669     0,                      /* auth key length in octets   */
1670     0,                      /* auth tag length in octets   */
1671     sec_serv_none           /* security services flag      */  
1672   },
1673   {
1674     NULL_CIPHER,            /* cipher type                 */
1675     0,                      /* cipher key length in octets */
1676     NULL_AUTH,              /* authentication func type    */
1677     0,                      /* auth key length in octets   */
1678     0,                      /* auth tag length in octets   */
1679     sec_serv_none           /* security services flag      */  
1680   },
1681   test_key,
1682   NULL,        /* indicates that EKT is not in use */
1683   128,         /* replay window size */
1684   0,           /* retransmission not allowed */
1685   NULL
1686 };
1687
1688 unsigned char test_256_key[46] = {
1689         0xf0, 0xf0, 0x49, 0x14, 0xb5, 0x13, 0xf2, 0x76,
1690         0x3a, 0x1b, 0x1f, 0xa1, 0x30, 0xf1, 0x0e, 0x29,
1691         0x98, 0xf6, 0xf6, 0xe4, 0x3e, 0x43, 0x09, 0xd1,
1692         0xe6, 0x22, 0xa0, 0xe3, 0x32, 0xb9, 0xf1, 0xb6,
1693
1694         0x3b, 0x04, 0x80, 0x3d, 0xe5, 0x1e, 0xe7, 0xc9,
1695         0x64, 0x23, 0xab, 0x5b, 0x78, 0xd2
1696 };
1697
1698 const srtp_policy_t aes_256_hmac_policy = {
1699   { ssrc_any_outbound, 0 },  /* SSRC                           */
1700   {                      /* SRTP policy                    */                  
1701     AES_ICM,                /* cipher type                 */
1702     46,                     /* cipher key length in octets */
1703     HMAC_SHA1,              /* authentication func type    */
1704     20,                     /* auth key length in octets   */
1705     10,                     /* auth tag length in octets   */
1706     sec_serv_conf_and_auth  /* security services flag      */
1707   },
1708   {                      /* SRTCP policy                   */
1709     AES_ICM,                /* cipher type                 */
1710     46,                     /* cipher key length in octets */
1711     HMAC_SHA1,              /* authentication func type    */
1712     20,                     /* auth key length in octets   */
1713     10,                     /* auth tag length in octets   */
1714     sec_serv_conf_and_auth  /* security services flag      */
1715   },
1716   test_256_key,
1717   NULL,        /* indicates that EKT is not in use */
1718   128,         /* replay window size */
1719   0,           /* retransmission not allowed */
1720   NULL
1721 };
1722
1723 uint8_t ekt_test_key[16] = {
1724   0x77, 0x26, 0x9d, 0xac, 0x16, 0xa3, 0x28, 0xca, 
1725   0x8e, 0xc9, 0x68, 0x4b, 0xcc, 0xc4, 0xd2, 0x1b
1726 };
1727
1728 #include "ekt.h"
1729
1730 ekt_policy_ctx_t ekt_test_policy = {
1731   0xa5a5,                   /* SPI */
1732   EKT_CIPHER_AES_128_ECB,
1733   ekt_test_key,
1734   NULL
1735 };
1736
1737 const srtp_policy_t hmac_only_with_ekt_policy = {
1738   { ssrc_any_outbound, 0 },     /* SSRC                        */
1739   {
1740     NULL_CIPHER,            /* cipher type                 */
1741     0,                      /* cipher key length in octets */
1742     HMAC_SHA1,              /* authentication func type    */
1743     20,                     /* auth key length in octets   */
1744     4,                      /* auth tag length in octets   */
1745     sec_serv_auth           /* security services flag      */
1746   },  
1747   {
1748     NULL_CIPHER,            /* cipher type                 */
1749     0,                      /* cipher key length in octets */
1750     HMAC_SHA1,              /* authentication func type    */
1751     20,                     /* auth key length in octets   */
1752     4,                      /* auth tag length in octets   */
1753     sec_serv_auth           /* security services flag      */
1754   },
1755   test_key,
1756   &ekt_test_policy,        /* indicates that EKT is not in use */
1757   128,                     /* replay window size */
1758   0,                       /* retransmission not allowed */
1759   NULL
1760 };
1761
1762
1763 /*
1764  * an array of pointers to the policies listed above
1765  *
1766  * This array is used to test various aspects of libSRTP for
1767  * different cryptographic policies.  The order of the elements
1768  * matters - the timing test generates output that can be used
1769  * in a plot (see the gnuplot script file 'timing').  If you 
1770  * add to this list, you should do it at the end.
1771  */
1772
1773 #define USE_TMMH 0
1774
1775 const srtp_policy_t *
1776 policy_array[] = {
1777   &hmac_only_policy,
1778 #if USE_TMMH
1779   &tmmh_only_policy,
1780 #endif
1781   &aes_only_policy,
1782 #if USE_TMMH
1783   &aes_tmmh_policy,
1784 #endif
1785   &default_policy,
1786   &null_policy,
1787   &aes_256_hmac_policy,
1788   &hmac_only_with_ekt_policy,
1789   NULL
1790 };
1791
1792 const srtp_policy_t wildcard_policy = {
1793   { ssrc_any_outbound, 0 }, /* SSRC                        */
1794   {                      /* SRTP policy                    */                  
1795     AES_128_ICM,            /* cipher type                 */
1796     30,                     /* cipher key length in octets */
1797     HMAC_SHA1,              /* authentication func type    */
1798     16,                     /* auth key length in octets   */
1799     10,                     /* auth tag length in octets   */
1800     sec_serv_conf_and_auth  /* security services flag      */
1801   },
1802   {                      /* SRTCP policy                   */
1803     AES_128_ICM,            /* cipher type                 */
1804     30,                     /* cipher key length in octets */
1805     HMAC_SHA1,              /* authentication func type    */
1806     16,                     /* auth key length in octets   */
1807     10,                     /* auth tag length in octets   */
1808     sec_serv_conf_and_auth  /* security services flag      */
1809   },
1810   test_key,
1811   NULL,
1812   128,                   /* replay window size */
1813   0,                     /* retransmission not allowed */
1814   NULL
1815 };