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