blob: e6fdc9366a81c4fef11820435a5c0664530f6ed3 [file] [log] [blame]
Cullen Jennings235513a2005-09-21 22:51:36 +00001/*
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-2005, 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 <unistd.h> /* for getopt() */
51
52#include "srtp.h"
53
Marcus Sundberg1cbca882005-10-02 20:50:06 +000054#ifdef HAVE_NETINET_IN_H
55# include <netinet/in.h>
56#elif defined HAVE_WINSOCK2_H
57# include <winsock2.h>
58#endif
59
Cullen Jennings235513a2005-09-21 22:51:36 +000060#define PRINT_REFERENCE_PACKET 1
61
62err_status_t
Marcus Sundberga3f95fe2005-09-29 12:48:41 +000063srtp_validate(void);
Cullen Jennings235513a2005-09-21 22:51:36 +000064
65err_status_t
66srtp_create_big_policy(srtp_policy_t **list);
67
68err_status_t
Marcus Sundberga3f95fe2005-09-29 12:48:41 +000069srtp_test_remove_stream(void);
Cullen Jennings235513a2005-09-21 22:51:36 +000070
71double
72srtp_bits_per_second(int msg_len_octets, const srtp_policy_t *policy);
73
74double
75srtp_rejections_per_second(int msg_len_octets, const srtp_policy_t *policy);
76
77void
78srtp_do_timing(const srtp_policy_t *policy);
79
80void
81srtp_do_rejection_timing(const srtp_policy_t *policy);
82
83err_status_t
Marcus Sundberga3f95fe2005-09-29 12:48:41 +000084srtp_test(const srtp_policy_t *policy);
Cullen Jennings235513a2005-09-21 22:51:36 +000085
86err_status_t
David McGrew9c70f292006-05-03 19:38:38 +000087srtcp_test(const srtp_policy_t *policy);
88
89err_status_t
Cullen Jennings235513a2005-09-21 22:51:36 +000090srtp_session_print_policy(srtp_t srtp);
91
92err_status_t
93srtp_print_policy(const srtp_policy_t *policy);
94
95char *
96srtp_packet_to_string(srtp_hdr_t *hdr, int packet_len);
97
98double
99mips_estimate(int num_trials, int *ignore);
100
Marcus Sundberg410faaa2005-09-29 12:36:43 +0000101extern uint8_t test_key[30];
Cullen Jennings235513a2005-09-21 22:51:36 +0000102
103void
104usage(char *prog_name) {
105 printf("usage: %s [ -t ][ -c ][ -v ][-d <debug_module> ]* [ -l ]\n"
106 " -t run timing test\n"
107 " -r run rejection timing test\n"
108 " -c run codec timing test\n"
109 " -v run validation tests\n"
110 " -d <mod> turn on debugging module <mod>\n"
111 " -l list debugging modules\n", prog_name);
112 exit(1);
113}
114
115/*
116 * The policy_array is a null-terminated array of policy structs. it
117 * is declared at the end of this file
118 */
119
120extern const srtp_policy_t *policy_array[];
121
122
123/* the wildcard_policy is declared below; it has a wildcard ssrc */
124
125extern const srtp_policy_t wildcard_policy;
126
127/*
128 * mod_driver debug module - debugging module for this test driver
129 *
130 * we use the crypto_kernel debugging system in this driver, which
131 * makes the interface uniform and increases portability
132 */
133
134debug_module_t mod_driver = {
135 0, /* debugging is off by default */
136 "driver" /* printable name for module */
137};
138
139int
140main (int argc, char *argv[]) {
141 char q;
142 unsigned do_timing_test = 0;
143 unsigned do_rejection_test = 0;
144 unsigned do_codec_timing = 0;
145 unsigned do_validation = 0;
146 unsigned do_list_mods = 0;
147 err_status_t status;
148
149 /*
150 * verify that the compiler has interpreted the header data
151 * structure srtp_hdr_t correctly
152 */
153 if (sizeof(srtp_hdr_t) != 12) {
154 printf("error: srtp_hdr_t has incorrect size\n");
155 exit(1);
156 }
157
158 /* initialize srtp library */
159 status = srtp_init();
160 if (status) {
161 printf("error: srtp init failed with error code %d\n", status);
162 exit(1);
163 }
164
165 /* load srtp_driver debug module */
166 status = crypto_kernel_load_debug_module(&mod_driver);
167 if (status) {
168 printf("error: load of srtp_driver debug module failed "
169 "with error code %d\n", status);
170 exit(1);
171 }
172
173 /* process input arguments */
174 while (1) {
175 q = getopt(argc, argv, "trcvld:");
176 if (q == -1)
177 break;
178 switch (q) {
179 case 't':
180 do_timing_test = 1;
181 break;
182 case 'r':
183 do_rejection_test = 1;
184 break;
185 case 'c':
186 do_codec_timing = 1;
187 break;
188 case 'v':
189 do_validation = 1;
190 break;
191 case 'l':
192 do_list_mods = 1;
193 break;
194 case 'd':
195 status = crypto_kernel_set_debug_module(optarg, 1);
196 if (status) {
197 printf("error: set debug module (%s) failed\n", optarg);
198 exit(1);
199 }
200 break;
201 default:
202 usage(argv[0]);
203 }
204 }
205
206 if (!do_validation && !do_timing_test && !do_codec_timing
207 && !do_list_mods && !do_rejection_test)
208 usage(argv[0]);
209
210 if (do_list_mods) {
211 status = crypto_kernel_list_debug_modules();
212 if (status) {
213 printf("error: list of debug modules failed\n");
214 exit(1);
215 }
216 }
217
218 if (do_validation) {
219 const srtp_policy_t **policy = policy_array;
220 srtp_policy_t *big_policy;
221
David McGrew9c70f292006-05-03 19:38:38 +0000222 /* loop over policy array, testing srtp and srtcp for each policy */
Cullen Jennings235513a2005-09-21 22:51:36 +0000223 while (*policy != NULL) {
224 printf("testing srtp_protect and srtp_unprotect\n");
225 if (srtp_test(*policy) == err_status_ok)
226 printf("passed\n\n");
227 else {
228 printf("failed\n");
229 exit(1);
230 }
David McGrew9c70f292006-05-03 19:38:38 +0000231 printf("testing srtp_protect_rtcp and srtp_unprotect_rtcp\n");
232 if (srtcp_test(*policy) == err_status_ok)
233 printf("passed\n\n");
234 else {
235 printf("failed\n");
236 exit(1);
237 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000238 policy++;
239 }
240
241 /* create a big policy list and run tests on it */
242 status = srtp_create_big_policy(&big_policy);
243 if (status) {
244 printf("unexpected failure with error code %d\n", status);
245 exit(1);
246 }
247 printf("testing srtp_protect and srtp_unprotect with big policy\n");
248 if (srtp_test(big_policy) == err_status_ok)
249 printf("passed\n\n");
250 else {
251 printf("failed\n");
252 exit(1);
253 }
254
255 /* run test on wildcard policy */
256 printf("testing srtp_protect and srtp_unprotect on "
257 "wildcard ssrc policy\n");
258 if (srtp_test(&wildcard_policy) == err_status_ok)
259 printf("passed\n\n");
260 else {
261 printf("failed\n");
262 exit(1);
263 }
264
265 /*
266 * run validation test against the reference packets - note
267 * that this test only covers the default policy
268 */
269 printf("testing srtp_protect and srtp_unprotect against "
270 "reference packets\n");
271 if (srtp_validate() == err_status_ok)
272 printf("passed\n\n");
273 else {
274 printf("failed\n");
275 exit(1);
276 }
277
278 /*
279 * test the function srtp_remove_stream()
280 */
281 printf("testing srtp_remove_stream()...");
282 if (srtp_test_remove_stream() == err_status_ok)
283 printf("passed\n");
284 else {
285 printf("failed\n");
286 exit(1);
287 }
288 }
289
290 if (do_timing_test) {
291 const srtp_policy_t **policy = policy_array;
292
293 /* loop over policies, run timing test for each */
294 while (*policy != NULL) {
295 srtp_print_policy(*policy);
296 srtp_do_timing(*policy);
297 policy++;
298 }
299 }
300
301 if (do_rejection_test) {
302 const srtp_policy_t **policy = policy_array;
303
304 /* loop over policies, run rejection timing test for each */
305 while (*policy != NULL) {
306 srtp_print_policy(*policy);
307 srtp_do_rejection_timing(*policy);
308 policy++;
309 }
310 }
311
312 if (do_codec_timing) {
313 srtp_policy_t policy;
314 int ignore;
315 double mips = mips_estimate(1000000000, &ignore);
316
317 crypto_policy_set_rtp_default(&policy.rtp);
318 crypto_policy_set_rtcp_default(&policy.rtcp);
319 policy.ssrc.type = ssrc_specific;
320 policy.ssrc.value = 0xdecafbad;
321 policy.key = test_key;
322 policy.next = NULL;
323
324 printf("mips estimate: %e\n", mips);
325
326 printf("testing srtp processing time for voice codecs:\n");
327 printf("codec\t\tlength (octets)\t\tsrtp instructions/second\n");
328 printf("G.711\t\t%d\t\t\t%e\n", 80,
329 (double) mips * (80 * 8) /
330 srtp_bits_per_second(80, &policy) / .01 );
331 printf("G.711\t\t%d\t\t\t%e\n", 160,
332 (double) mips * (160 * 8) /
333 srtp_bits_per_second(160, &policy) / .02);
334 printf("G.726-32\t%d\t\t\t%e\n", 40,
335 (double) mips * (40 * 8) /
336 srtp_bits_per_second(40, &policy) / .01 );
337 printf("G.726-32\t%d\t\t\t%e\n", 80,
338 (double) mips * (80 * 8) /
339 srtp_bits_per_second(80, &policy) / .02);
340 printf("G.729\t\t%d\t\t\t%e\n", 10,
341 (double) mips * (10 * 8) /
342 srtp_bits_per_second(10, &policy) / .01 );
343 printf("G.729\t\t%d\t\t\t%e\n", 20,
344 (double) mips * (20 * 8) /
345 srtp_bits_per_second(20, &policy) / .02 );
346 }
347
348 return 0;
349}
350
351
352
353/*
354 * srtp_create_test_packet(len, ssrc) returns a pointer to a
355 * (malloced) example RTP packet whose data field has the length given
356 * by pkt_octet_len and the SSRC value ssrc. The total length of the
357 * packet is twelve octets longer, since the header is at the
358 * beginning. There is room at the end of the packet for a trailer,
359 * and the four octets following the packet are filled with 0xff
360 * values to enable testing for overwrites.
361 *
362 * note that the location of the test packet can (and should) be
363 * deallocated with the free() call once it is no longer needed.
364 */
365
366srtp_hdr_t *
367srtp_create_test_packet(int pkt_octet_len, uint32_t ssrc) {
368 int i;
Marcus Sundberg410faaa2005-09-29 12:36:43 +0000369 uint8_t *buffer;
Cullen Jennings235513a2005-09-21 22:51:36 +0000370 srtp_hdr_t *hdr;
371 int bytes_in_hdr = 12;
372
373 /* allocate memory for test packet */
374 hdr = malloc(pkt_octet_len + bytes_in_hdr
375 + SRTP_MAX_TRAILER_LEN + 4);
376 if (!hdr)
377 return NULL;
378
379 hdr->version = 2; /* RTP version two */
380 hdr->p = 0; /* no padding needed */
381 hdr->x = 0; /* no header extension */
382 hdr->cc = 0; /* no CSRCs */
383 hdr->m = 0; /* marker bit */
384 hdr->pt = 0xf; /* payload type */
385 hdr->seq = htons(0x1234); /* sequence number */
386 hdr->ts = htonl(0xdecafbad); /* timestamp */
387 hdr->ssrc = htonl(ssrc); /* synch. source */
388
Marcus Sundberg410faaa2005-09-29 12:36:43 +0000389 buffer = (uint8_t *)hdr;
Cullen Jennings235513a2005-09-21 22:51:36 +0000390 buffer += bytes_in_hdr;
391
392 /* set RTP data to 0xab */
393 for (i=0; i < pkt_octet_len; i++)
394 *buffer++ = 0xab;
395
396 /* set post-data value to 0xffff to enable overrun checking */
397 for (i=0; i < SRTP_MAX_TRAILER_LEN+4; i++)
398 *buffer++ = 0xff;
399
400 return hdr;
401}
402
403void
404srtp_do_timing(const srtp_policy_t *policy) {
405 int len;
406
407 /*
408 * note: the output of this function is formatted so that it
409 * can be used in gnuplot. '#' indicates a comment, and "\r\n"
410 * terminates a record
411 */
412
413 printf("# testing srtp throughput:\r\n");
414 printf("# mesg length (octets)\tthroughput (megabits per second)\r\n");
415
416 for (len=16; len <= 2048; len *= 2)
417 printf("%d\t\t\t%f\r\n", len,
418 srtp_bits_per_second(len, policy) / 1.0E6);
419
420 /* these extra linefeeds let gnuplot know that a dataset is done */
421 printf("\r\n\r\n");
422
423}
424
425void
426srtp_do_rejection_timing(const srtp_policy_t *policy) {
427 int len;
428
429 /*
430 * note: the output of this function is formatted so that it
431 * can be used in gnuplot. '#' indicates a comment, and "\r\n"
432 * terminates a record
433 */
434
435 printf("# testing srtp rejection throughput:\r\n");
436 printf("# mesg length (octets)\trejections per second\r\n");
437
438 for (len=8; len <= 2048; len *= 2)
439 printf("%d\t\t\t%e\r\n", len, srtp_rejections_per_second(len, policy));
440
441 /* these extra linefeeds let gnuplot know that a dataset is done */
442 printf("\r\n\r\n");
443
444}
445
446
447#define MAX_MSG_LEN 1024
448
449double
450srtp_bits_per_second(int msg_len_octets, const srtp_policy_t *policy) {
451 srtp_t srtp;
452 srtp_hdr_t *mesg;
453 int i;
454 clock_t timer;
455 int num_trials = 100000;
456 int len;
457 uint32_t ssrc;
458 err_status_t status;
459
460 /*
461 * allocate and initialize an srtp session
462 */
463 status = srtp_create(&srtp, policy);
464 if (status) {
465 printf("error: srtp_create() failed with error code %d\n", status);
466 exit(1);
467 }
468
469 /*
470 * if the ssrc is unspecified, use a predetermined one
471 */
472 if (policy->ssrc.type != ssrc_specific) {
473 ssrc = 0xdeadbeef;
474 } else {
475 ssrc = policy->ssrc.value;
476 }
477
478 /*
479 * create a test packet
480 */
481 mesg = srtp_create_test_packet(msg_len_octets, ssrc);
482 if (mesg == NULL)
483 return 0.0; /* indicate failure by returning zero */
484
485 timer = clock();
486 for (i=0; i < num_trials; i++) {
487 err_status_t status;
David McGrewd2f8de42006-02-03 19:43:59 +0000488 len = msg_len_octets + 12; /* add in rtp header length */
Cullen Jennings235513a2005-09-21 22:51:36 +0000489
490 /* srtp protect message */
491 status = srtp_protect(srtp, mesg, &len);
492 if (status) {
493 printf("error: srtp_protect() failed with error code %d\n", status);
494 exit(1);
495 }
496
497 /* increment message number */
498 mesg->seq = htons(ntohs(mesg->seq) + 1);
499
500 }
501 timer = clock() - timer;
502
503 free(mesg);
504
505 return (double) (msg_len_octets) * 8 *
506 num_trials * CLOCKS_PER_SEC / timer;
507}
508
509double
510srtp_rejections_per_second(int msg_len_octets, const srtp_policy_t *policy) {
511 srtp_ctx_t *srtp;
512 srtp_hdr_t *mesg;
513 int i;
514 int len;
515 clock_t timer;
516 int num_trials = 1000000;
517 uint32_t ssrc = policy->ssrc.value;
518 err_status_t status;
519
520 /*
521 * allocate and initialize an srtp session
522 */
523 status = srtp_create(&srtp, policy);
524 if (status) {
525 printf("error: srtp_create() failed with error code %d\n", status);
526 exit(1);
527 }
528
529 mesg = srtp_create_test_packet(msg_len_octets, ssrc);
530 if (mesg == NULL)
531 return 0.0; /* indicate failure by returning zero */
532
533 len = msg_len_octets;
534 srtp_protect(srtp, (srtp_hdr_t *)mesg, &len);
535
536 timer = clock();
537 for (i=0; i < num_trials; i++) {
538 len = msg_len_octets;
539 srtp_unprotect(srtp, (srtp_hdr_t *)mesg, &len);
540 }
541 timer = clock() - timer;
542
543 free(mesg);
544
545 return (double) num_trials * CLOCKS_PER_SEC / timer;
546}
547
548
549void
550err_check(err_status_t s) {
551 if (s == err_status_ok)
552 return;
553 else
554 fprintf(stderr, "error: unexpected srtp failure (code %d)\n", s);
555 exit (1);
556}
557
558err_status_t
559srtp_test(const srtp_policy_t *policy) {
560 int i;
561 srtp_t srtp_sender;
562 srtp_t srtp_rcvr;
563 err_status_t status = err_status_ok;
564 srtp_hdr_t *hdr, *hdr2;
Marcus Sundberg5c40da82005-10-08 18:15:00 +0000565 uint8_t hdr_enc[64];
Marcus Sundberg410faaa2005-09-29 12:36:43 +0000566 uint8_t *pkt_end;
Marcus Sundberg5c40da82005-10-08 18:15:00 +0000567 int msg_len_octets, msg_len_enc;
Cullen Jennings235513a2005-09-21 22:51:36 +0000568 int len;
569 int tag_length = policy->rtp.auth_tag_len;
570 uint32_t ssrc;
571 srtp_policy_t *rcvr_policy;
572
573 err_check(srtp_create(&srtp_sender, policy));
574
575 /* print out policy */
576 err_check(srtp_session_print_policy(srtp_sender));
577
578 /*
579 * initialize data buffer, using the ssrc in the policy unless that
580 * value is a wildcard, in which case we'll just use an arbitrary
581 * one
582 */
583 if (policy->ssrc.type != ssrc_specific)
584 ssrc = 0xdecafbad;
585 else
586 ssrc = policy->ssrc.value;
587 msg_len_octets = 28;
588 hdr = srtp_create_test_packet(msg_len_octets, ssrc);
589
590 if (hdr == NULL)
591 return err_status_alloc_fail;
592 hdr2 = srtp_create_test_packet(msg_len_octets, ssrc);
593 if (hdr2 == NULL) {
594 free(hdr);
595 return err_status_alloc_fail;
596 }
597
598 /* set message length */
599 len = msg_len_octets;
600
601 debug_print(mod_driver, "before protection:\n%s",
602 srtp_packet_to_string(hdr, len));
603
604#if PRINT_REFERENCE_PACKET
605 debug_print(mod_driver, "reference packet before protection:\n%s",
Marcus Sundberg410faaa2005-09-29 12:36:43 +0000606 octet_string_hex_string((uint8_t *)hdr, len));
Cullen Jennings235513a2005-09-21 22:51:36 +0000607#endif
608 err_check(srtp_protect(srtp_sender, hdr, &len));
609
610 debug_print(mod_driver, "after protection:\n%s",
611 srtp_packet_to_string(hdr, len));
612#if PRINT_REFERENCE_PACKET
613 debug_print(mod_driver, "after protection:\n%s",
Marcus Sundberg410faaa2005-09-29 12:36:43 +0000614 octet_string_hex_string((uint8_t *)hdr, len));
Cullen Jennings235513a2005-09-21 22:51:36 +0000615#endif
616
Marcus Sundberg5c40da82005-10-08 18:15:00 +0000617 /* save protected message and length */
618 memcpy(hdr_enc, hdr, len);
619 msg_len_enc = len;
620
Cullen Jennings235513a2005-09-21 22:51:36 +0000621 /*
622 * check for overrun of the srtp_protect() function
623 *
624 * The packet is followed by a value of 0xfffff; if the value of the
625 * data following the packet is different, then we know that the
626 * protect function is overwriting the end of the packet.
627 */
Marcus Sundberg410faaa2005-09-29 12:36:43 +0000628 pkt_end = (uint8_t *)hdr + sizeof(srtp_hdr_t)
Cullen Jennings235513a2005-09-21 22:51:36 +0000629 + msg_len_octets + tag_length;
630 for (i = 0; i < 4; i++)
631 if (pkt_end[i] != 0xff) {
632 fprintf(stdout, "overwrite in srtp_protect() function "
633 "(expected %x, found %x in trailing octet %d)\n",
Marcus Sundberg410faaa2005-09-29 12:36:43 +0000634 0xff, ((uint8_t *)hdr)[i], i);
Cullen Jennings235513a2005-09-21 22:51:36 +0000635 free(hdr);
636 free(hdr2);
637 return err_status_algo_fail;
638 }
639
640 /*
641 * if the policy includes confidentiality, check that ciphertext is
642 * different than plaintext
643 *
644 * Note that this check will give false negatives, with some small
645 * probability, especially if the packets are short. For that
646 * reason, we skip this check if the plaintext is less than four
647 * octets long.
648 */
649 if ((policy->rtp.sec_serv & sec_serv_conf) && (msg_len_octets >= 4)) {
650 printf("testing that ciphertext is distinct from plaintext...");
651 status = err_status_algo_fail;
652 for (i=12; i < msg_len_octets+12; i++)
Marcus Sundberg410faaa2005-09-29 12:36:43 +0000653 if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) {
Cullen Jennings235513a2005-09-21 22:51:36 +0000654 status = err_status_ok;
655 }
656 if (status) {
657 printf("failed\n");
658 free(hdr);
659 free(hdr2);
660 return status;
661 }
662 printf("passed\n");
663 }
664
665 /*
666 * if the policy uses a 'wildcard' ssrc, then we need to make a copy
667 * of the policy that changes the direction to inbound
668 *
669 * we always copy the policy into the rcvr_policy, since otherwise
670 * the compiler would fret about the constness of the policy
671 */
672 rcvr_policy = malloc(sizeof(srtp_policy_t));
673 if (rcvr_policy == NULL)
674 return err_status_alloc_fail;
675 memcpy(rcvr_policy, policy, sizeof(srtp_policy_t));
676 if (policy->ssrc.type == ssrc_any_outbound) {
677 rcvr_policy->ssrc.type = ssrc_any_inbound;
678 }
679
680 err_check(srtp_create(&srtp_rcvr, rcvr_policy));
681
682 err_check(srtp_unprotect(srtp_rcvr, hdr, &len));
683
684 debug_print(mod_driver, "after unprotection:\n%s",
685 srtp_packet_to_string(hdr, len));
686
687 /* verify that the unprotected packet matches the origial one */
688 for (i=0; i < msg_len_octets; i++)
Marcus Sundberg410faaa2005-09-29 12:36:43 +0000689 if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) {
Cullen Jennings235513a2005-09-21 22:51:36 +0000690 fprintf(stdout, "mismatch at octet %d\n", i);
691 status = err_status_algo_fail;
692 }
693 if (status) {
694 free(hdr);
695 free(hdr2);
696 return status;
697 }
698
699 /*
700 * if the policy includes authentication, then test for false positives
701 */
702 if (policy->rtp.sec_serv & sec_serv_auth) {
703 char *data = ((char *)hdr) + 12;
704
705 printf("testing for false positives in replay check...");
706
Marcus Sundberg5c40da82005-10-08 18:15:00 +0000707 /* set message length */
708 len = msg_len_enc;
709
Cullen Jennings235513a2005-09-21 22:51:36 +0000710 /* unprotect a second time - should fail with a replay error */
Marcus Sundberg5c40da82005-10-08 18:15:00 +0000711 status = srtp_unprotect(srtp_rcvr, hdr_enc, &len);
Cullen Jennings235513a2005-09-21 22:51:36 +0000712 if (status != err_status_replay_fail) {
713 printf("failed with error code %d\n", status);
714 free(hdr);
715 free(hdr2);
716 return status;
717 } else {
718 printf("passed\n");
719 }
720
721 printf("testing for false positives in auth check...");
722
723 /* increment sequence number in header */
724 hdr->seq++;
725
Marcus Sundberg5c40da82005-10-08 18:15:00 +0000726 /* set message length */
727 len = msg_len_octets;
728
Cullen Jennings235513a2005-09-21 22:51:36 +0000729 /* apply protection */
730 err_check(srtp_protect(srtp_sender, hdr, &len));
731
732 /* flip bits in packet */
733 data[0] ^= 0xff;
734
735 /* unprotect, and check for authentication failure */
736 status = srtp_unprotect(srtp_rcvr, hdr, &len);
737 if (status != err_status_auth_fail) {
738 printf("failed\n");
739 free(hdr);
740 free(hdr2);
741 return status;
742 } else {
743 printf("passed\n");
744 }
745
746 }
747
748 err_check(srtp_dealloc(srtp_sender));
749 err_check(srtp_dealloc(srtp_rcvr));
750
751 free(hdr);
752 free(hdr2);
753 return err_status_ok;
754}
755
756
757err_status_t
David McGrew9c70f292006-05-03 19:38:38 +0000758srtcp_test(const srtp_policy_t *policy) {
759 int i;
760 srtp_t srtcp_sender;
761 srtp_t srtcp_rcvr;
762 err_status_t status = err_status_ok;
763 srtp_hdr_t *hdr, *hdr2;
764 uint8_t hdr_enc[64];
765 uint8_t *pkt_end;
766 int msg_len_octets, msg_len_enc;
767 int len;
768 int tag_length = policy->rtp.auth_tag_len;
769 uint32_t ssrc;
770 srtp_policy_t *rcvr_policy;
771
772 err_check(srtp_create(&srtcp_sender, policy));
773
774 /* print out policy */
775 err_check(srtp_session_print_policy(srtcp_sender));
776
777 /*
778 * initialize data buffer, using the ssrc in the policy unless that
779 * value is a wildcard, in which case we'll just use an arbitrary
780 * one
781 */
782 if (policy->ssrc.type != ssrc_specific)
783 ssrc = 0xdecafbad;
784 else
785 ssrc = policy->ssrc.value;
786 msg_len_octets = 28;
787 hdr = srtp_create_test_packet(msg_len_octets, ssrc);
788
789 if (hdr == NULL)
790 return err_status_alloc_fail;
791 hdr2 = srtp_create_test_packet(msg_len_octets, ssrc);
792 if (hdr2 == NULL) {
793 free(hdr);
794 return err_status_alloc_fail;
795 }
796
797 /* set message length */
798 len = msg_len_octets;
799
800 debug_print(mod_driver, "before protection:\n%s",
801 srtp_packet_to_string(hdr, len));
802
803#if PRINT_REFERENCE_PACKET
804 debug_print(mod_driver, "reference packet before protection:\n%s",
805 octet_string_hex_string((uint8_t *)hdr, len));
806#endif
807 err_check(srtp_protect_rtcp(srtcp_sender, hdr, &len));
808
809 debug_print(mod_driver, "after protection:\n%s",
810 srtp_packet_to_string(hdr, len));
811#if PRINT_REFERENCE_PACKET
812 debug_print(mod_driver, "after protection:\n%s",
813 octet_string_hex_string((uint8_t *)hdr, len));
814#endif
815
816 /* save protected message and length */
817 memcpy(hdr_enc, hdr, len);
818 msg_len_enc = len;
819
820 /*
821 * check for overrun of the srtp_protect() function
822 *
823 * The packet is followed by a value of 0xfffff; if the value of the
824 * data following the packet is different, then we know that the
825 * protect function is overwriting the end of the packet.
826 */
827 pkt_end = (uint8_t *)hdr + sizeof(srtp_hdr_t)
828 + msg_len_octets + tag_length;
829 for (i = 0; i < 4; i++)
830 if (pkt_end[i] != 0xff) {
831 fprintf(stdout, "overwrite in srtp_protect_rtcp() function "
832 "(expected %x, found %x in trailing octet %d)\n",
833 0xff, ((uint8_t *)hdr)[i], i);
834 free(hdr);
835 free(hdr2);
836 return err_status_algo_fail;
837 }
838
839 /*
840 * if the policy includes confidentiality, check that ciphertext is
841 * different than plaintext
842 *
843 * Note that this check will give false negatives, with some small
844 * probability, especially if the packets are short. For that
845 * reason, we skip this check if the plaintext is less than four
846 * octets long.
847 */
848 if ((policy->rtp.sec_serv & sec_serv_conf) && (msg_len_octets >= 4)) {
849 printf("testing that ciphertext is distinct from plaintext...");
850 status = err_status_algo_fail;
851 for (i=12; i < msg_len_octets+12; i++)
852 if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) {
853 status = err_status_ok;
854 }
855 if (status) {
856 printf("failed\n");
857 free(hdr);
858 free(hdr2);
859 return status;
860 }
861 printf("passed\n");
862 }
863
864 /*
865 * if the policy uses a 'wildcard' ssrc, then we need to make a copy
866 * of the policy that changes the direction to inbound
867 *
868 * we always copy the policy into the rcvr_policy, since otherwise
869 * the compiler would fret about the constness of the policy
870 */
871 rcvr_policy = malloc(sizeof(srtp_policy_t));
872 if (rcvr_policy == NULL)
873 return err_status_alloc_fail;
874 memcpy(rcvr_policy, policy, sizeof(srtp_policy_t));
875 if (policy->ssrc.type == ssrc_any_outbound) {
876 rcvr_policy->ssrc.type = ssrc_any_inbound;
877 }
878
879 err_check(srtp_create(&srtcp_rcvr, rcvr_policy));
880
881 err_check(srtp_unprotect_rtcp(srtcp_rcvr, hdr, &len));
882
883 debug_print(mod_driver, "after unprotection:\n%s",
884 srtp_packet_to_string(hdr, len));
885
886 /* verify that the unprotected packet matches the origial one */
887 for (i=0; i < msg_len_octets; i++)
888 if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) {
889 fprintf(stdout, "mismatch at octet %d\n", i);
890 status = err_status_algo_fail;
891 }
892 if (status) {
893 free(hdr);
894 free(hdr2);
895 return status;
896 }
897
898 /*
899 * if the policy includes authentication, then test for false positives
900 */
901 if (policy->rtp.sec_serv & sec_serv_auth) {
902 char *data = ((char *)hdr) + 12;
903
904 printf("testing for false positives in replay check...");
905
906 /* set message length */
907 len = msg_len_enc;
908
909 /* unprotect a second time - should fail with a replay error */
910 status = srtp_unprotect_rtcp(srtcp_rcvr, hdr_enc, &len);
911 if (status != err_status_replay_fail) {
912 printf("failed with error code %d\n", status);
913 free(hdr);
914 free(hdr2);
915 return status;
916 } else {
917 printf("passed\n");
918 }
919
920 printf("testing for false positives in auth check...");
921
922 /* increment sequence number in header */
923 hdr->seq++;
924
925 /* set message length */
926 len = msg_len_octets;
927
928 /* apply protection */
929 err_check(srtp_protect_rtcp(srtcp_sender, hdr, &len));
930
931 /* flip bits in packet */
932 data[0] ^= 0xff;
933
934 /* unprotect, and check for authentication failure */
935 status = srtp_unprotect_rtcp(srtcp_rcvr, hdr, &len);
936 if (status != err_status_auth_fail) {
937 printf("failed\n");
938 free(hdr);
939 free(hdr2);
940 return status;
941 } else {
942 printf("passed\n");
943 }
944
945 }
946
947 err_check(srtp_dealloc(srtcp_sender));
948 err_check(srtp_dealloc(srtcp_rcvr));
949
950 free(hdr);
951 free(hdr2);
952 return err_status_ok;
953}
954
955
956err_status_t
Cullen Jennings235513a2005-09-21 22:51:36 +0000957srtp_session_print_policy(srtp_t srtp) {
958 char *serv_descr[4] = {
959 "none",
960 "confidentiality",
961 "authentication",
962 "confidentiality and authentication"
963 };
964 char *direction[3] = {
965 "unknown",
966 "outbound",
967 "inbound"
968 };
969 srtp_stream_t stream;
970
971 /* sanity checking */
972 if (srtp == NULL)
973 return err_status_fail;
974
975 /* if there's a template stream, print it out */
976 if (srtp->stream_template != NULL) {
977 stream = srtp->stream_template;
978 printf("# SSRC: any %s\r\n"
979 "# rtp cipher: %s\r\n"
980 "# rtp auth: %s\r\n"
981 "# rtp services: %s\r\n"
982 "# rtcp cipher: %s\r\n"
983 "# rtcp auth: %s\r\n"
984 "# rtcp services: %s\r\n",
985 direction[stream->direction],
986 stream->rtp_cipher->type->description,
987 stream->rtp_auth->type->description,
988 serv_descr[stream->rtp_services],
989 stream->rtcp_cipher->type->description,
990 stream->rtcp_auth->type->description,
991 serv_descr[stream->rtcp_services]);
992 }
993
994 /* loop over streams in session, printing the policy of each */
995 stream = srtp->stream_list;
996 while (stream != NULL) {
997 if (stream->rtp_services > sec_serv_conf_and_auth)
998 return err_status_bad_param;
999
1000 printf("# SSRC: 0x%08x\r\n"
1001 "# rtp cipher: %s\r\n"
1002 "# rtp auth: %s\r\n"
1003 "# rtp services: %s\r\n"
1004 "# rtcp cipher: %s\r\n"
1005 "# rtcp auth: %s\r\n"
1006 "# rtcp services: %s\r\n",
1007 stream->ssrc,
1008 stream->rtp_cipher->type->description,
1009 stream->rtp_auth->type->description,
1010 serv_descr[stream->rtp_services],
1011 stream->rtcp_cipher->type->description,
1012 stream->rtcp_auth->type->description,
1013 serv_descr[stream->rtcp_services]);
1014
1015 /* advance to next stream in the list */
1016 stream = stream->next;
1017 }
1018 return err_status_ok;
1019}
1020
1021err_status_t
1022srtp_print_policy(const srtp_policy_t *policy) {
1023 err_status_t status;
1024 srtp_t session;
1025
1026 status = srtp_create(&session, policy);
1027 if (status)
1028 return status;
1029 status = srtp_session_print_policy(session);
1030 if (status)
1031 return status;
1032 status = srtp_dealloc(session);
1033 if (status)
1034 return status;
1035 return err_status_ok;
1036}
1037
1038/*
1039 * srtp_print_packet(...) is for debugging only
1040 * it prints an RTP packet to the stdout
1041 *
1042 * note that this function is *not* threadsafe
1043 */
1044
1045#include <stdio.h>
1046
1047#define MTU 2048
1048
1049char packet_string[MTU];
1050
1051char *
1052srtp_packet_to_string(srtp_hdr_t *hdr, int pkt_octet_len) {
1053 int octets_in_rtp_header = 12;
Marcus Sundberg410faaa2005-09-29 12:36:43 +00001054 uint8_t *data = ((uint8_t *)hdr)+octets_in_rtp_header;
Cullen Jennings235513a2005-09-21 22:51:36 +00001055 int hex_len = pkt_octet_len-octets_in_rtp_header;
1056
1057 /* sanity checking */
1058 if ((hdr == NULL) || (pkt_octet_len > MTU))
1059 return NULL;
1060
1061 /* write packet into string */
1062 sprintf(packet_string,
1063 "(s)rtp packet: {\n"
1064 " version:\t%d\n"
1065 " p:\t\t%d\n"
1066 " x:\t\t%d\n"
1067 " cc:\t\t%d\n"
1068 " m:\t\t%d\n"
1069 " pt:\t\t%x\n"
1070 " seq:\t\t%x\n"
1071 " ts:\t\t%x\n"
1072 " ssrc:\t%x\n"
1073 " data:\t%s\n"
1074 "} (%d octets in total)\n",
1075 hdr->version,
1076 hdr->p,
1077 hdr->x,
1078 hdr->cc,
1079 hdr->m,
1080 hdr->pt,
1081 hdr->seq,
1082 hdr->ts,
1083 hdr->ssrc,
1084 octet_string_hex_string(data, hex_len),
1085 pkt_octet_len);
1086
1087 return packet_string;
1088}
1089
1090/*
1091 * mips_estimate() is a simple function to estimate the number of
1092 * instructions per second that the host can perform. note that this
1093 * function can be grossly wrong; you may want to have a manual sanity
1094 * check of its output!
1095 *
1096 * the 'ignore' pointer is there to convince the compiler to not just
1097 * optimize away the function
1098 */
1099
1100double
1101mips_estimate(int num_trials, int *ignore) {
1102 clock_t t;
1103 int i, sum;
1104
1105 sum = 0;
1106 t = clock();
1107 for (i=0; i<num_trials; i++)
1108 sum += i;
1109 t = clock() - t;
1110
1111/* printf("%d\n", sum); */
1112 *ignore = sum;
1113
1114 return (double) num_trials * CLOCKS_PER_SEC / t;
1115}
1116
1117
1118/*
1119 * srtp_validate() verifies the correctness of libsrtp by comparing
1120 * some computed packets against some pre-computed reference values.
1121 * These packets were made with the default SRTP policy.
1122 */
1123
1124
1125err_status_t
1126srtp_validate() {
1127 unsigned char test_key[30] = {
1128 0xe1, 0xf9, 0x7a, 0x0d, 0x3e, 0x01, 0x8b, 0xe0,
1129 0xd6, 0x4f, 0xa3, 0x2c, 0x06, 0xde, 0x41, 0x39,
1130 0x0e, 0xc6, 0x75, 0xad, 0x49, 0x8a, 0xfe, 0xeb,
1131 0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6
1132 };
Marcus Sundberg410faaa2005-09-29 12:36:43 +00001133 uint8_t srtp_plaintext_ref[28] = {
Cullen Jennings235513a2005-09-21 22:51:36 +00001134 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1135 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
1136 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1137 0xab, 0xab, 0xab, 0xab
1138 };
Marcus Sundberg410faaa2005-09-29 12:36:43 +00001139 uint8_t srtp_plaintext[38] = {
Cullen Jennings235513a2005-09-21 22:51:36 +00001140 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1141 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
1142 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1143 0xab, 0xab, 0xab, 0xab, 0x00, 0x00, 0x00, 0x00,
1144 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1145 };
Marcus Sundberg410faaa2005-09-29 12:36:43 +00001146 uint8_t srtp_ciphertext[38] = {
Cullen Jennings235513a2005-09-21 22:51:36 +00001147 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1148 0xca, 0xfe, 0xba, 0xbe, 0x4e, 0x55, 0xdc, 0x4c,
1149 0xe7, 0x99, 0x78, 0xd8, 0x8c, 0xa4, 0xd2, 0x15,
1150 0x94, 0x9d, 0x24, 0x02, 0xb7, 0x8d, 0x6a, 0xcc,
1151 0x99, 0xea, 0x17, 0x9b, 0x8d, 0xbb
1152 };
1153 srtp_t srtp_snd, srtp_recv;
1154 err_status_t status;
1155 int len;
1156 srtp_policy_t policy;
1157
1158 /*
1159 * create a session with a single stream using the default srtp
1160 * policy and with the SSRC value 0xcafebabe
1161 */
1162 crypto_policy_set_rtp_default(&policy.rtp);
1163 crypto_policy_set_rtcp_default(&policy.rtcp);
1164 policy.ssrc.type = ssrc_specific;
1165 policy.ssrc.value = 0xcafebabe;
1166 policy.key = test_key;
1167 policy.next = NULL;
1168
1169 status = srtp_create(&srtp_snd, &policy);
1170 if (status)
1171 return status;
1172
1173 /*
1174 * protect plaintext, then compare with ciphertext
1175 */
1176 len = 28;
1177 status = srtp_protect(srtp_snd, srtp_plaintext, &len);
1178 if (status || (len != 38))
1179 return err_status_fail;
1180
1181 debug_print(mod_driver, "ciphertext:\n %s",
1182 octet_string_hex_string(srtp_plaintext, len));
1183 debug_print(mod_driver, "ciphertext reference:\n %s",
1184 octet_string_hex_string(srtp_ciphertext, len));
1185
1186 if (octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len))
1187 return err_status_fail;
1188
1189 /*
1190 * create a receiver session context comparable to the one created
1191 * above - we need to do this so that the replay checking doesn't
1192 * complain
1193 */
1194 status = srtp_create(&srtp_recv, &policy);
1195 if (status)
1196 return status;
1197
1198 /*
1199 * unprotect ciphertext, then compare with plaintext
1200 */
1201 status = srtp_unprotect(srtp_recv, srtp_ciphertext, &len);
1202 if (status || (len != 28))
1203 return status;
1204
1205 if (octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len))
1206 return err_status_fail;
1207
1208 return err_status_ok;
1209}
1210
1211
1212err_status_t
1213srtp_create_big_policy(srtp_policy_t **list) {
1214 extern const srtp_policy_t *policy_array[];
1215 srtp_policy_t *p, *tmp;
1216 int i = 0;
1217 uint32_t ssrc = 0;
1218
1219 /* sanity checking */
1220 if ((list == NULL) || (policy_array[0] == NULL))
1221 return err_status_bad_param;
1222
1223 /*
1224 * loop over policy list, mallocing a new list and copying values
1225 * into it (and incrementing the SSRC value as we go along)
1226 */
1227 tmp = NULL;
1228 while (policy_array[i] != NULL) {
1229 p = malloc(sizeof(srtp_policy_t));
1230 if (p == NULL)
1231 return err_status_bad_param;
1232 memcpy(p, policy_array[i], sizeof(srtp_policy_t));
1233 p->ssrc.type = ssrc_specific;
1234 p->ssrc.value = ssrc++;
1235 p->next = tmp;
1236 tmp = p;
1237 i++;
1238 }
1239 *list = p;
1240
1241 return err_status_ok;
1242}
1243
1244err_status_t
1245srtp_test_remove_stream() {
1246 err_status_t status;
1247 srtp_policy_t *policy_list;
1248 srtp_t session;
1249 srtp_stream_t stream;
1250 /*
1251 * srtp_get_stream() is a libSRTP internal function that we declare
1252 * here so that we can use it to verify the correct operation of the
1253 * library
1254 */
1255 extern srtp_stream_t srtp_get_stream(srtp_t srtp, uint32_t ssrc);
1256
1257
1258 status = srtp_create_big_policy(&policy_list);
1259 if (status)
1260 return status;
1261
1262 status = srtp_create(&session, policy_list);
1263 if (status)
1264 return status;
1265
1266 /*
1267 * check for false positives by trying to remove a stream that's not
1268 * in the session
1269 */
1270 status = srtp_remove_stream(session, htonl(0xaaaaaaaa));
1271 if (status != err_status_no_ctx)
1272 return err_status_fail;
1273
1274 /*
1275 * check for false negatives by removing stream 0x1, then
1276 * searching for streams 0x0 and 0x2
1277 */
1278 status = srtp_remove_stream(session, htonl(0x1));
1279 if (status != err_status_ok)
1280 return err_status_fail;
1281 stream = srtp_get_stream(session, htonl(0x0));
1282 if (stream == NULL)
1283 return err_status_fail;
1284 stream = srtp_get_stream(session, htonl(0x2));
1285 if (stream == NULL)
1286 return err_status_fail;
1287
1288 return err_status_ok;
1289}
1290
1291/*
1292 * srtp policy definitions - these definitions are used above
1293 */
1294
1295unsigned char test_key[30] = {
1296 0xe1, 0xf9, 0x7a, 0x0d, 0x3e, 0x01, 0x8b, 0xe0,
1297 0xd6, 0x4f, 0xa3, 0x2c, 0x06, 0xde, 0x41, 0x39,
1298 0x0e, 0xc6, 0x75, 0xad, 0x49, 0x8a, 0xfe, 0xeb,
1299 0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6
1300};
1301
1302
1303const srtp_policy_t default_policy = {
1304 { ssrc_any_outbound, 0 }, /* SSRC */
1305 { /* SRTP policy */
1306 AES_128_ICM, /* cipher type */
1307 30, /* cipher key length in octets */
1308 HMAC_SHA1, /* authentication func type */
1309 16, /* auth key length in octets */
1310 10, /* auth tag length in octets */
1311 sec_serv_conf_and_auth /* security services flag */
1312 },
1313 { /* SRTCP policy */
1314 AES_128_ICM, /* cipher type */
1315 30, /* cipher key length in octets */
1316 HMAC_SHA1, /* authentication func type */
1317 16, /* auth key length in octets */
1318 10, /* auth tag length in octets */
1319 sec_serv_conf_and_auth /* security services flag */
1320 },
1321 test_key,
1322 NULL
1323};
1324
1325const srtp_policy_t aes_tmmh_policy = {
1326 { ssrc_any_outbound, 0 }, /* SSRC */
1327 {
1328 AES_128_ICM, /* cipher type */
1329 30, /* cipher key length in octets */
1330 UST_TMMHv2, /* authentication func type */
1331 94, /* auth key length in octets */
1332 4, /* auth tag length in octets */
1333 sec_serv_conf_and_auth /* security services flag */
1334 },
1335 {
1336 AES_128_ICM, /* cipher type */
1337 30, /* cipher key length in octets */
1338 UST_TMMHv2, /* authentication func type */
1339 94, /* auth key length in octets */
1340 4, /* auth tag length in octets */
1341 sec_serv_conf_and_auth /* security services flag */
1342 },
1343 test_key,
1344 NULL
1345};
1346
1347const srtp_policy_t tmmh_only_policy = {
1348 { ssrc_any_outbound, 0 }, /* SSRC */
1349 {
1350 AES_128_ICM, /* cipher type */
1351 30, /* cipher key length in octets */
1352 UST_TMMHv2, /* authentication func type */
1353 94, /* auth key length in octets */
1354 4, /* auth tag length in octets */
1355 sec_serv_auth /* security services flag */
1356 },
1357 {
1358 AES_128_ICM, /* cipher type */
1359 30, /* cipher key length in octets */
1360 UST_TMMHv2, /* authentication func type */
1361 94, /* auth key length in octets */
1362 4, /* auth tag length in octets */
1363 sec_serv_auth /* security services flag */
1364 },
1365 test_key,
1366 NULL
1367};
1368
1369const srtp_policy_t aes_only_policy = {
1370 { ssrc_any_outbound, 0 }, /* SSRC */
1371 {
1372 AES_128_ICM, /* cipher type */
1373 30, /* cipher key length in octets */
1374 NULL_AUTH, /* authentication func type */
1375 0, /* auth key length in octets */
1376 0, /* auth tag length in octets */
1377 sec_serv_conf /* security services flag */
1378 },
1379 {
1380 AES_128_ICM, /* cipher type */
1381 30, /* cipher key length in octets */
1382 NULL_AUTH, /* authentication func type */
1383 0, /* auth key length in octets */
1384 0, /* auth tag length in octets */
1385 sec_serv_conf /* security services flag */
1386 },
1387 test_key,
1388 NULL
1389};
1390
1391const srtp_policy_t hmac_only_policy = {
1392 { ssrc_any_outbound, 0 }, /* SSRC */
1393 {
1394 NULL_CIPHER, /* cipher type */
1395 0, /* cipher key length in octets */
1396 HMAC_SHA1, /* authentication func type */
1397 20, /* auth key length in octets */
1398 4, /* auth tag length in octets */
1399 sec_serv_auth /* security services flag */
1400 },
1401 {
1402 NULL_CIPHER, /* cipher type */
1403 0, /* cipher key length in octets */
1404 HMAC_SHA1, /* authentication func type */
1405 20, /* auth key length in octets */
1406 4, /* auth tag length in octets */
1407 sec_serv_auth /* security services flag */
1408 },
1409 test_key,
1410 NULL
1411};
1412
1413const srtp_policy_t null_policy = {
1414 { ssrc_any_outbound, 0 }, /* SSRC */
1415 {
1416 NULL_CIPHER, /* cipher type */
1417 0, /* cipher key length in octets */
1418 NULL_AUTH, /* authentication func type */
1419 0, /* auth key length in octets */
1420 0, /* auth tag length in octets */
1421 sec_serv_none /* security services flag */
1422 },
1423 {
1424 NULL_CIPHER, /* cipher type */
1425 0, /* cipher key length in octets */
1426 NULL_AUTH, /* authentication func type */
1427 0, /* auth key length in octets */
1428 0, /* auth tag length in octets */
1429 sec_serv_none /* security services flag */
1430 },
1431 test_key,
1432 NULL
1433};
1434
1435
1436/*
1437 * an array of pointers to the policies listed above
1438 *
1439 * This array is used to test various aspects of libSRTP for
1440 * different cryptographic policies. The order of the elements
1441 * matters - the timing test generates output that can be used
1442 * in a plot (see the gnuplot script file 'timing'). If you
1443 * add to this list, you should do it at the end.
1444 */
1445
1446#define USE_TMMH 0
1447
1448const srtp_policy_t *
1449policy_array[] = {
1450 &hmac_only_policy,
1451#if USE_TMMH
1452 &tmmh_only_policy,
1453#endif
1454 &aes_only_policy,
1455#if USE_TMMH
1456 &aes_tmmh_policy,
1457#endif
1458 &default_policy,
1459 &null_policy,
1460 NULL
1461};
1462
1463const srtp_policy_t wildcard_policy = {
1464 { ssrc_any_outbound, 0 }, /* SSRC */
1465 { /* SRTP policy */
1466 AES_128_ICM, /* cipher type */
1467 30, /* cipher key length in octets */
1468 HMAC_SHA1, /* authentication func type */
1469 16, /* auth key length in octets */
1470 10, /* auth tag length in octets */
1471 sec_serv_conf_and_auth /* security services flag */
1472 },
1473 { /* SRTCP policy */
1474 AES_128_ICM, /* cipher type */
1475 30, /* cipher key length in octets */
1476 HMAC_SHA1, /* authentication func type */
1477 16, /* auth key length in octets */
1478 10, /* auth tag length in octets */
1479 sec_serv_conf_and_auth /* security services flag */
1480 },
1481 test_key,
1482 NULL
1483};