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
62err_status_t
63srtp_validate(void);
64
65err_status_t
66srtp_validate_aes_256(void);
67
68err_status_t
69srtp_create_big_policy(srtp_policy_t **list);
70
71err_status_t
72srtp_dealloc_big_policy(srtp_policy_t *list);
73
74err_status_t
75srtp_test_remove_stream(void);
76
77double
78srtp_bits_per_second(int msg_len_octets, const srtp_policy_t *policy);
79
80double
81srtp_rejections_per_second(int msg_len_octets, const srtp_policy_t *policy);
82
83void
84srtp_do_timing(const srtp_policy_t *policy);
85
86void
87srtp_do_rejection_timing(const srtp_policy_t *policy);
88
89err_status_t
90srtp_test(const srtp_policy_t *policy);
91
92err_status_t
93srtcp_test(const srtp_policy_t *policy);
94
95err_status_t
96srtp_session_print_policy(srtp_t srtp);
97
98err_status_t
99srtp_print_policy(const srtp_policy_t *policy);
100
101char *
102srtp_packet_to_string(srtp_hdr_t *hdr, int packet_len);
103
104double
105mips_estimate(int num_trials, int *ignore);
106
107extern uint8_t test_key[30];
108
109void
110usage(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
126extern const srtp_policy_t *policy_array[];
127
128
129/* the wildcard_policy is declared below; it has a wildcard ssrc */
130
131extern 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
140debug_module_t mod_driver = {
141  0,                  /* debugging is off by default */
142  "driver"            /* printable name for module   */
143};
144
145int
146main (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 = 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);
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 * (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 * (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 * (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 * (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 * (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 * (20 * 8) /
374	   srtp_bits_per_second(20, &policy) / .02 );
375    printf("Wideband\t%d\t\t\t%e\n", 320,
376           (double) mips * (320 * 8) /
377	   srtp_bits_per_second(320, &policy) / .01 );
378    printf("Wideband\t%d\t\t\t%e\n", 640,
379           (double) mips * (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
407srtp_hdr_t *
408srtp_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
444void
445srtp_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
466void
467srtp_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
490double
491srtp_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
558double
559srtp_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
604void
605err_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
613err_status_t
614srtp_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
819err_status_t
820srtcp_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
1022err_status_t
1023srtp_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
1095err_status_t
1096srtp_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
1123char packet_string[MTU];
1124
1125char *
1126srtp_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
1174double
1175mips_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
1199err_status_t
1200srtp_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
1298err_status_t
1299srtp_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
1399err_status_t
1400srtp_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
1431err_status_t
1432srtp_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
1444err_status_t
1445srtp_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
1530unsigned 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
1538const 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
1563const 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
1588const 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
1613const 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
1638const 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
1663const 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
1688unsigned 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
1698const 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
1723uint8_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
1730ekt_policy_ctx_t ekt_test_policy = {
1731  0xa5a5,                   /* SPI */
1732  EKT_CIPHER_AES_128_ECB,
1733  ekt_test_key,
1734  NULL
1735};
1736
1737const 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
1775const srtp_policy_t *
1776policy_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
1792const 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};
1816