blob: eb98914ec65ddf1c0008473d766be813513de44c [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[]) {
Jonathan Lennoxb4842bf2010-05-15 03:55:24 +0000141 int q;
Cullen Jennings235513a2005-09-21 22:51:36 +0000142 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",
Jonathan Lennoxf3132b92010-05-14 22:54:10 +0000156 (long)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
Jonathan Lennoxdfb30842010-05-15 04:52:01 +0000356 status = srtp_shutdown();
357 if (status) {
358 printf("error: srtp shutdown failed with error code %d\n", status);
359 exit(1);
360 }
361
Cullen Jennings235513a2005-09-21 22:51:36 +0000362 return 0;
363}
364
365
366
367/*
368 * srtp_create_test_packet(len, ssrc) returns a pointer to a
369 * (malloced) example RTP packet whose data field has the length given
370 * by pkt_octet_len and the SSRC value ssrc. The total length of the
371 * packet is twelve octets longer, since the header is at the
372 * beginning. There is room at the end of the packet for a trailer,
373 * and the four octets following the packet are filled with 0xff
374 * values to enable testing for overwrites.
375 *
376 * note that the location of the test packet can (and should) be
377 * deallocated with the free() call once it is no longer needed.
378 */
379
380srtp_hdr_t *
381srtp_create_test_packet(int pkt_octet_len, uint32_t ssrc) {
382 int i;
Marcus Sundberg410faaa2005-09-29 12:36:43 +0000383 uint8_t *buffer;
Cullen Jennings235513a2005-09-21 22:51:36 +0000384 srtp_hdr_t *hdr;
385 int bytes_in_hdr = 12;
386
387 /* allocate memory for test packet */
Derek MacDonald17127da2006-07-12 22:22:08 +0000388 hdr = (srtp_hdr_t*) malloc(pkt_octet_len + bytes_in_hdr
Cullen Jennings235513a2005-09-21 22:51:36 +0000389 + SRTP_MAX_TRAILER_LEN + 4);
390 if (!hdr)
391 return NULL;
392
393 hdr->version = 2; /* RTP version two */
394 hdr->p = 0; /* no padding needed */
395 hdr->x = 0; /* no header extension */
396 hdr->cc = 0; /* no CSRCs */
397 hdr->m = 0; /* marker bit */
398 hdr->pt = 0xf; /* payload type */
399 hdr->seq = htons(0x1234); /* sequence number */
400 hdr->ts = htonl(0xdecafbad); /* timestamp */
401 hdr->ssrc = htonl(ssrc); /* synch. source */
402
Marcus Sundberg410faaa2005-09-29 12:36:43 +0000403 buffer = (uint8_t *)hdr;
Cullen Jennings235513a2005-09-21 22:51:36 +0000404 buffer += bytes_in_hdr;
405
406 /* set RTP data to 0xab */
407 for (i=0; i < pkt_octet_len; i++)
408 *buffer++ = 0xab;
409
410 /* set post-data value to 0xffff to enable overrun checking */
411 for (i=0; i < SRTP_MAX_TRAILER_LEN+4; i++)
412 *buffer++ = 0xff;
413
414 return hdr;
415}
416
417void
418srtp_do_timing(const srtp_policy_t *policy) {
419 int len;
420
421 /*
422 * note: the output of this function is formatted so that it
423 * can be used in gnuplot. '#' indicates a comment, and "\r\n"
424 * terminates a record
425 */
426
427 printf("# testing srtp throughput:\r\n");
428 printf("# mesg length (octets)\tthroughput (megabits per second)\r\n");
429
430 for (len=16; len <= 2048; len *= 2)
431 printf("%d\t\t\t%f\r\n", len,
432 srtp_bits_per_second(len, policy) / 1.0E6);
433
434 /* these extra linefeeds let gnuplot know that a dataset is done */
435 printf("\r\n\r\n");
436
437}
438
439void
440srtp_do_rejection_timing(const srtp_policy_t *policy) {
441 int len;
442
443 /*
444 * note: the output of this function is formatted so that it
445 * can be used in gnuplot. '#' indicates a comment, and "\r\n"
446 * terminates a record
447 */
448
449 printf("# testing srtp rejection throughput:\r\n");
450 printf("# mesg length (octets)\trejections per second\r\n");
451
452 for (len=8; len <= 2048; len *= 2)
453 printf("%d\t\t\t%e\r\n", len, srtp_rejections_per_second(len, policy));
454
455 /* these extra linefeeds let gnuplot know that a dataset is done */
456 printf("\r\n\r\n");
457
458}
459
460
461#define MAX_MSG_LEN 1024
462
463double
464srtp_bits_per_second(int msg_len_octets, const srtp_policy_t *policy) {
465 srtp_t srtp;
466 srtp_hdr_t *mesg;
467 int i;
468 clock_t timer;
469 int num_trials = 100000;
470 int len;
471 uint32_t ssrc;
472 err_status_t status;
473
474 /*
475 * allocate and initialize an srtp session
476 */
477 status = srtp_create(&srtp, policy);
478 if (status) {
479 printf("error: srtp_create() failed with error code %d\n", status);
480 exit(1);
481 }
482
483 /*
484 * if the ssrc is unspecified, use a predetermined one
485 */
486 if (policy->ssrc.type != ssrc_specific) {
487 ssrc = 0xdeadbeef;
488 } else {
489 ssrc = policy->ssrc.value;
490 }
491
492 /*
493 * create a test packet
494 */
495 mesg = srtp_create_test_packet(msg_len_octets, ssrc);
496 if (mesg == NULL)
497 return 0.0; /* indicate failure by returning zero */
498
499 timer = clock();
500 for (i=0; i < num_trials; i++) {
501 err_status_t status;
David McGrewd2f8de42006-02-03 19:43:59 +0000502 len = msg_len_octets + 12; /* add in rtp header length */
Cullen Jennings235513a2005-09-21 22:51:36 +0000503
504 /* srtp protect message */
505 status = srtp_protect(srtp, mesg, &len);
506 if (status) {
507 printf("error: srtp_protect() failed with error code %d\n", status);
508 exit(1);
509 }
510
511 /* increment message number */
512 mesg->seq = htons(ntohs(mesg->seq) + 1);
513
514 }
515 timer = clock() - timer;
516
517 free(mesg);
518
519 return (double) (msg_len_octets) * 8 *
520 num_trials * CLOCKS_PER_SEC / timer;
521}
522
523double
524srtp_rejections_per_second(int msg_len_octets, const srtp_policy_t *policy) {
525 srtp_ctx_t *srtp;
526 srtp_hdr_t *mesg;
527 int i;
528 int len;
529 clock_t timer;
530 int num_trials = 1000000;
531 uint32_t ssrc = policy->ssrc.value;
532 err_status_t status;
533
534 /*
535 * allocate and initialize an srtp session
536 */
537 status = srtp_create(&srtp, policy);
538 if (status) {
539 printf("error: srtp_create() failed with error code %d\n", status);
540 exit(1);
541 }
542
543 mesg = srtp_create_test_packet(msg_len_octets, ssrc);
544 if (mesg == NULL)
545 return 0.0; /* indicate failure by returning zero */
546
547 len = msg_len_octets;
548 srtp_protect(srtp, (srtp_hdr_t *)mesg, &len);
549
550 timer = clock();
551 for (i=0; i < num_trials; i++) {
552 len = msg_len_octets;
553 srtp_unprotect(srtp, (srtp_hdr_t *)mesg, &len);
554 }
555 timer = clock() - timer;
556
557 free(mesg);
558
559 return (double) num_trials * CLOCKS_PER_SEC / timer;
560}
561
562
563void
564err_check(err_status_t s) {
565 if (s == err_status_ok)
566 return;
567 else
568 fprintf(stderr, "error: unexpected srtp failure (code %d)\n", s);
569 exit (1);
570}
571
572err_status_t
573srtp_test(const srtp_policy_t *policy) {
574 int i;
575 srtp_t srtp_sender;
576 srtp_t srtp_rcvr;
577 err_status_t status = err_status_ok;
578 srtp_hdr_t *hdr, *hdr2;
Marcus Sundberg5c40da82005-10-08 18:15:00 +0000579 uint8_t hdr_enc[64];
Marcus Sundberg410faaa2005-09-29 12:36:43 +0000580 uint8_t *pkt_end;
Marcus Sundberg5c40da82005-10-08 18:15:00 +0000581 int msg_len_octets, msg_len_enc;
Cullen Jennings235513a2005-09-21 22:51:36 +0000582 int len;
583 int tag_length = policy->rtp.auth_tag_len;
584 uint32_t ssrc;
585 srtp_policy_t *rcvr_policy;
586
587 err_check(srtp_create(&srtp_sender, policy));
588
589 /* print out policy */
590 err_check(srtp_session_print_policy(srtp_sender));
591
592 /*
593 * initialize data buffer, using the ssrc in the policy unless that
594 * value is a wildcard, in which case we'll just use an arbitrary
595 * one
596 */
597 if (policy->ssrc.type != ssrc_specific)
598 ssrc = 0xdecafbad;
599 else
600 ssrc = policy->ssrc.value;
601 msg_len_octets = 28;
602 hdr = srtp_create_test_packet(msg_len_octets, ssrc);
603
604 if (hdr == NULL)
605 return err_status_alloc_fail;
606 hdr2 = srtp_create_test_packet(msg_len_octets, ssrc);
607 if (hdr2 == NULL) {
608 free(hdr);
609 return err_status_alloc_fail;
610 }
611
612 /* set message length */
613 len = msg_len_octets;
614
615 debug_print(mod_driver, "before protection:\n%s",
616 srtp_packet_to_string(hdr, len));
617
618#if PRINT_REFERENCE_PACKET
619 debug_print(mod_driver, "reference packet before protection:\n%s",
Marcus Sundberg410faaa2005-09-29 12:36:43 +0000620 octet_string_hex_string((uint8_t *)hdr, len));
Cullen Jennings235513a2005-09-21 22:51:36 +0000621#endif
622 err_check(srtp_protect(srtp_sender, hdr, &len));
623
624 debug_print(mod_driver, "after protection:\n%s",
625 srtp_packet_to_string(hdr, len));
626#if PRINT_REFERENCE_PACKET
627 debug_print(mod_driver, "after protection:\n%s",
Marcus Sundberg410faaa2005-09-29 12:36:43 +0000628 octet_string_hex_string((uint8_t *)hdr, len));
Cullen Jennings235513a2005-09-21 22:51:36 +0000629#endif
630
Marcus Sundberg5c40da82005-10-08 18:15:00 +0000631 /* save protected message and length */
632 memcpy(hdr_enc, hdr, len);
633 msg_len_enc = len;
634
Cullen Jennings235513a2005-09-21 22:51:36 +0000635 /*
636 * check for overrun of the srtp_protect() function
637 *
638 * The packet is followed by a value of 0xfffff; if the value of the
639 * data following the packet is different, then we know that the
640 * protect function is overwriting the end of the packet.
641 */
Marcus Sundberg410faaa2005-09-29 12:36:43 +0000642 pkt_end = (uint8_t *)hdr + sizeof(srtp_hdr_t)
Cullen Jennings235513a2005-09-21 22:51:36 +0000643 + msg_len_octets + tag_length;
644 for (i = 0; i < 4; i++)
645 if (pkt_end[i] != 0xff) {
646 fprintf(stdout, "overwrite in srtp_protect() function "
647 "(expected %x, found %x in trailing octet %d)\n",
Marcus Sundberg410faaa2005-09-29 12:36:43 +0000648 0xff, ((uint8_t *)hdr)[i], i);
Cullen Jennings235513a2005-09-21 22:51:36 +0000649 free(hdr);
650 free(hdr2);
651 return err_status_algo_fail;
652 }
653
654 /*
655 * if the policy includes confidentiality, check that ciphertext is
656 * different than plaintext
657 *
658 * Note that this check will give false negatives, with some small
659 * probability, especially if the packets are short. For that
660 * reason, we skip this check if the plaintext is less than four
661 * octets long.
662 */
663 if ((policy->rtp.sec_serv & sec_serv_conf) && (msg_len_octets >= 4)) {
664 printf("testing that ciphertext is distinct from plaintext...");
665 status = err_status_algo_fail;
666 for (i=12; i < msg_len_octets+12; i++)
Marcus Sundberg410faaa2005-09-29 12:36:43 +0000667 if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) {
Cullen Jennings235513a2005-09-21 22:51:36 +0000668 status = err_status_ok;
669 }
670 if (status) {
671 printf("failed\n");
672 free(hdr);
673 free(hdr2);
674 return status;
675 }
676 printf("passed\n");
677 }
678
679 /*
680 * if the policy uses a 'wildcard' ssrc, then we need to make a copy
681 * of the policy that changes the direction to inbound
682 *
683 * we always copy the policy into the rcvr_policy, since otherwise
684 * the compiler would fret about the constness of the policy
685 */
Derek MacDonald17127da2006-07-12 22:22:08 +0000686 rcvr_policy = (srtp_policy_t*) malloc(sizeof(srtp_policy_t));
Cullen Jennings235513a2005-09-21 22:51:36 +0000687 if (rcvr_policy == NULL)
688 return err_status_alloc_fail;
689 memcpy(rcvr_policy, policy, sizeof(srtp_policy_t));
690 if (policy->ssrc.type == ssrc_any_outbound) {
691 rcvr_policy->ssrc.type = ssrc_any_inbound;
692 }
693
694 err_check(srtp_create(&srtp_rcvr, rcvr_policy));
695
696 err_check(srtp_unprotect(srtp_rcvr, hdr, &len));
697
698 debug_print(mod_driver, "after unprotection:\n%s",
699 srtp_packet_to_string(hdr, len));
700
701 /* verify that the unprotected packet matches the origial one */
702 for (i=0; i < msg_len_octets; i++)
Marcus Sundberg410faaa2005-09-29 12:36:43 +0000703 if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) {
Cullen Jennings235513a2005-09-21 22:51:36 +0000704 fprintf(stdout, "mismatch at octet %d\n", i);
705 status = err_status_algo_fail;
706 }
707 if (status) {
708 free(hdr);
709 free(hdr2);
710 return status;
711 }
712
713 /*
714 * if the policy includes authentication, then test for false positives
715 */
716 if (policy->rtp.sec_serv & sec_serv_auth) {
717 char *data = ((char *)hdr) + 12;
718
719 printf("testing for false positives in replay check...");
720
Marcus Sundberg5c40da82005-10-08 18:15:00 +0000721 /* set message length */
722 len = msg_len_enc;
723
Cullen Jennings235513a2005-09-21 22:51:36 +0000724 /* unprotect a second time - should fail with a replay error */
Marcus Sundberg5c40da82005-10-08 18:15:00 +0000725 status = srtp_unprotect(srtp_rcvr, hdr_enc, &len);
Cullen Jennings235513a2005-09-21 22:51:36 +0000726 if (status != err_status_replay_fail) {
727 printf("failed with error code %d\n", status);
728 free(hdr);
729 free(hdr2);
730 return status;
731 } else {
732 printf("passed\n");
733 }
734
735 printf("testing for false positives in auth check...");
736
737 /* increment sequence number in header */
738 hdr->seq++;
739
Marcus Sundberg5c40da82005-10-08 18:15:00 +0000740 /* set message length */
741 len = msg_len_octets;
742
Cullen Jennings235513a2005-09-21 22:51:36 +0000743 /* apply protection */
744 err_check(srtp_protect(srtp_sender, hdr, &len));
745
746 /* flip bits in packet */
747 data[0] ^= 0xff;
748
749 /* unprotect, and check for authentication failure */
750 status = srtp_unprotect(srtp_rcvr, hdr, &len);
751 if (status != err_status_auth_fail) {
752 printf("failed\n");
753 free(hdr);
754 free(hdr2);
755 return status;
756 } else {
757 printf("passed\n");
758 }
759
760 }
761
762 err_check(srtp_dealloc(srtp_sender));
763 err_check(srtp_dealloc(srtp_rcvr));
764
765 free(hdr);
766 free(hdr2);
767 return err_status_ok;
768}
769
770
771err_status_t
David McGrew9c70f292006-05-03 19:38:38 +0000772srtcp_test(const srtp_policy_t *policy) {
773 int i;
774 srtp_t srtcp_sender;
775 srtp_t srtcp_rcvr;
776 err_status_t status = err_status_ok;
777 srtp_hdr_t *hdr, *hdr2;
778 uint8_t hdr_enc[64];
779 uint8_t *pkt_end;
780 int msg_len_octets, msg_len_enc;
781 int len;
782 int tag_length = policy->rtp.auth_tag_len;
783 uint32_t ssrc;
784 srtp_policy_t *rcvr_policy;
785
786 err_check(srtp_create(&srtcp_sender, policy));
787
788 /* print out policy */
789 err_check(srtp_session_print_policy(srtcp_sender));
790
791 /*
792 * initialize data buffer, using the ssrc in the policy unless that
793 * value is a wildcard, in which case we'll just use an arbitrary
794 * one
795 */
796 if (policy->ssrc.type != ssrc_specific)
797 ssrc = 0xdecafbad;
798 else
799 ssrc = policy->ssrc.value;
800 msg_len_octets = 28;
801 hdr = srtp_create_test_packet(msg_len_octets, ssrc);
802
803 if (hdr == NULL)
804 return err_status_alloc_fail;
805 hdr2 = srtp_create_test_packet(msg_len_octets, ssrc);
806 if (hdr2 == NULL) {
807 free(hdr);
808 return err_status_alloc_fail;
809 }
810
811 /* set message length */
812 len = msg_len_octets;
813
814 debug_print(mod_driver, "before protection:\n%s",
815 srtp_packet_to_string(hdr, len));
816
817#if PRINT_REFERENCE_PACKET
818 debug_print(mod_driver, "reference packet before protection:\n%s",
819 octet_string_hex_string((uint8_t *)hdr, len));
820#endif
821 err_check(srtp_protect_rtcp(srtcp_sender, hdr, &len));
822
823 debug_print(mod_driver, "after protection:\n%s",
824 srtp_packet_to_string(hdr, len));
825#if PRINT_REFERENCE_PACKET
826 debug_print(mod_driver, "after protection:\n%s",
827 octet_string_hex_string((uint8_t *)hdr, len));
828#endif
829
830 /* save protected message and length */
831 memcpy(hdr_enc, hdr, len);
832 msg_len_enc = len;
833
834 /*
835 * check for overrun of the srtp_protect() function
836 *
837 * The packet is followed by a value of 0xfffff; if the value of the
838 * data following the packet is different, then we know that the
839 * protect function is overwriting the end of the packet.
840 */
841 pkt_end = (uint8_t *)hdr + sizeof(srtp_hdr_t)
842 + msg_len_octets + tag_length;
843 for (i = 0; i < 4; i++)
844 if (pkt_end[i] != 0xff) {
845 fprintf(stdout, "overwrite in srtp_protect_rtcp() function "
846 "(expected %x, found %x in trailing octet %d)\n",
847 0xff, ((uint8_t *)hdr)[i], i);
848 free(hdr);
849 free(hdr2);
850 return err_status_algo_fail;
851 }
852
853 /*
854 * if the policy includes confidentiality, check that ciphertext is
855 * different than plaintext
856 *
857 * Note that this check will give false negatives, with some small
858 * probability, especially if the packets are short. For that
859 * reason, we skip this check if the plaintext is less than four
860 * octets long.
861 */
862 if ((policy->rtp.sec_serv & sec_serv_conf) && (msg_len_octets >= 4)) {
863 printf("testing that ciphertext is distinct from plaintext...");
864 status = err_status_algo_fail;
865 for (i=12; i < msg_len_octets+12; i++)
866 if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) {
867 status = err_status_ok;
868 }
869 if (status) {
870 printf("failed\n");
871 free(hdr);
872 free(hdr2);
873 return status;
874 }
875 printf("passed\n");
876 }
877
878 /*
879 * if the policy uses a 'wildcard' ssrc, then we need to make a copy
880 * of the policy that changes the direction to inbound
881 *
882 * we always copy the policy into the rcvr_policy, since otherwise
883 * the compiler would fret about the constness of the policy
884 */
Derek MacDonald17127da2006-07-12 22:22:08 +0000885 rcvr_policy = (srtp_policy_t*) malloc(sizeof(srtp_policy_t));
David McGrew9c70f292006-05-03 19:38:38 +0000886 if (rcvr_policy == NULL)
887 return err_status_alloc_fail;
888 memcpy(rcvr_policy, policy, sizeof(srtp_policy_t));
889 if (policy->ssrc.type == ssrc_any_outbound) {
890 rcvr_policy->ssrc.type = ssrc_any_inbound;
891 }
892
893 err_check(srtp_create(&srtcp_rcvr, rcvr_policy));
894
895 err_check(srtp_unprotect_rtcp(srtcp_rcvr, hdr, &len));
896
897 debug_print(mod_driver, "after unprotection:\n%s",
898 srtp_packet_to_string(hdr, len));
899
900 /* verify that the unprotected packet matches the origial one */
901 for (i=0; i < msg_len_octets; i++)
902 if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) {
903 fprintf(stdout, "mismatch at octet %d\n", i);
904 status = err_status_algo_fail;
905 }
906 if (status) {
907 free(hdr);
908 free(hdr2);
909 return status;
910 }
911
912 /*
913 * if the policy includes authentication, then test for false positives
914 */
915 if (policy->rtp.sec_serv & sec_serv_auth) {
916 char *data = ((char *)hdr) + 12;
917
918 printf("testing for false positives in replay check...");
919
920 /* set message length */
921 len = msg_len_enc;
922
923 /* unprotect a second time - should fail with a replay error */
924 status = srtp_unprotect_rtcp(srtcp_rcvr, hdr_enc, &len);
925 if (status != err_status_replay_fail) {
926 printf("failed with error code %d\n", status);
927 free(hdr);
928 free(hdr2);
929 return status;
930 } else {
931 printf("passed\n");
932 }
933
934 printf("testing for false positives in auth check...");
935
936 /* increment sequence number in header */
937 hdr->seq++;
938
939 /* set message length */
940 len = msg_len_octets;
941
942 /* apply protection */
943 err_check(srtp_protect_rtcp(srtcp_sender, hdr, &len));
944
945 /* flip bits in packet */
946 data[0] ^= 0xff;
947
948 /* unprotect, and check for authentication failure */
949 status = srtp_unprotect_rtcp(srtcp_rcvr, hdr, &len);
950 if (status != err_status_auth_fail) {
951 printf("failed\n");
952 free(hdr);
953 free(hdr2);
954 return status;
955 } else {
956 printf("passed\n");
957 }
958
959 }
960
961 err_check(srtp_dealloc(srtcp_sender));
962 err_check(srtp_dealloc(srtcp_rcvr));
963
964 free(hdr);
965 free(hdr2);
966 return err_status_ok;
967}
968
969
970err_status_t
Cullen Jennings235513a2005-09-21 22:51:36 +0000971srtp_session_print_policy(srtp_t srtp) {
972 char *serv_descr[4] = {
973 "none",
974 "confidentiality",
975 "authentication",
976 "confidentiality and authentication"
977 };
978 char *direction[3] = {
979 "unknown",
980 "outbound",
981 "inbound"
982 };
983 srtp_stream_t stream;
984
985 /* sanity checking */
986 if (srtp == NULL)
987 return err_status_fail;
988
989 /* if there's a template stream, print it out */
990 if (srtp->stream_template != NULL) {
991 stream = srtp->stream_template;
992 printf("# SSRC: any %s\r\n"
993 "# rtp cipher: %s\r\n"
994 "# rtp auth: %s\r\n"
995 "# rtp services: %s\r\n"
996 "# rtcp cipher: %s\r\n"
997 "# rtcp auth: %s\r\n"
998 "# rtcp services: %s\r\n",
999 direction[stream->direction],
1000 stream->rtp_cipher->type->description,
1001 stream->rtp_auth->type->description,
1002 serv_descr[stream->rtp_services],
1003 stream->rtcp_cipher->type->description,
1004 stream->rtcp_auth->type->description,
1005 serv_descr[stream->rtcp_services]);
1006 }
1007
1008 /* loop over streams in session, printing the policy of each */
1009 stream = srtp->stream_list;
1010 while (stream != NULL) {
1011 if (stream->rtp_services > sec_serv_conf_and_auth)
1012 return err_status_bad_param;
1013
1014 printf("# SSRC: 0x%08x\r\n"
1015 "# rtp cipher: %s\r\n"
1016 "# rtp auth: %s\r\n"
1017 "# rtp services: %s\r\n"
1018 "# rtcp cipher: %s\r\n"
1019 "# rtcp auth: %s\r\n"
1020 "# rtcp services: %s\r\n",
1021 stream->ssrc,
1022 stream->rtp_cipher->type->description,
1023 stream->rtp_auth->type->description,
1024 serv_descr[stream->rtp_services],
1025 stream->rtcp_cipher->type->description,
1026 stream->rtcp_auth->type->description,
1027 serv_descr[stream->rtcp_services]);
1028
1029 /* advance to next stream in the list */
1030 stream = stream->next;
1031 }
1032 return err_status_ok;
1033}
1034
1035err_status_t
1036srtp_print_policy(const srtp_policy_t *policy) {
1037 err_status_t status;
1038 srtp_t session;
1039
1040 status = srtp_create(&session, policy);
1041 if (status)
1042 return status;
1043 status = srtp_session_print_policy(session);
1044 if (status)
1045 return status;
1046 status = srtp_dealloc(session);
1047 if (status)
1048 return status;
1049 return err_status_ok;
1050}
1051
1052/*
1053 * srtp_print_packet(...) is for debugging only
1054 * it prints an RTP packet to the stdout
1055 *
1056 * note that this function is *not* threadsafe
1057 */
1058
1059#include <stdio.h>
1060
1061#define MTU 2048
1062
1063char packet_string[MTU];
1064
1065char *
1066srtp_packet_to_string(srtp_hdr_t *hdr, int pkt_octet_len) {
1067 int octets_in_rtp_header = 12;
Marcus Sundberg410faaa2005-09-29 12:36:43 +00001068 uint8_t *data = ((uint8_t *)hdr)+octets_in_rtp_header;
Cullen Jennings235513a2005-09-21 22:51:36 +00001069 int hex_len = pkt_octet_len-octets_in_rtp_header;
1070
1071 /* sanity checking */
1072 if ((hdr == NULL) || (pkt_octet_len > MTU))
1073 return NULL;
1074
1075 /* write packet into string */
1076 sprintf(packet_string,
1077 "(s)rtp packet: {\n"
1078 " version:\t%d\n"
1079 " p:\t\t%d\n"
1080 " x:\t\t%d\n"
1081 " cc:\t\t%d\n"
1082 " m:\t\t%d\n"
1083 " pt:\t\t%x\n"
1084 " seq:\t\t%x\n"
1085 " ts:\t\t%x\n"
1086 " ssrc:\t%x\n"
1087 " data:\t%s\n"
1088 "} (%d octets in total)\n",
1089 hdr->version,
1090 hdr->p,
1091 hdr->x,
1092 hdr->cc,
1093 hdr->m,
1094 hdr->pt,
1095 hdr->seq,
1096 hdr->ts,
1097 hdr->ssrc,
1098 octet_string_hex_string(data, hex_len),
1099 pkt_octet_len);
1100
1101 return packet_string;
1102}
1103
1104/*
1105 * mips_estimate() is a simple function to estimate the number of
1106 * instructions per second that the host can perform. note that this
1107 * function can be grossly wrong; you may want to have a manual sanity
1108 * check of its output!
1109 *
1110 * the 'ignore' pointer is there to convince the compiler to not just
1111 * optimize away the function
1112 */
1113
1114double
1115mips_estimate(int num_trials, int *ignore) {
1116 clock_t t;
1117 int i, sum;
1118
1119 sum = 0;
1120 t = clock();
1121 for (i=0; i<num_trials; i++)
1122 sum += i;
1123 t = clock() - t;
1124
1125/* printf("%d\n", sum); */
1126 *ignore = sum;
1127
1128 return (double) num_trials * CLOCKS_PER_SEC / t;
1129}
1130
1131
1132/*
1133 * srtp_validate() verifies the correctness of libsrtp by comparing
1134 * some computed packets against some pre-computed reference values.
1135 * These packets were made with the default SRTP policy.
1136 */
1137
1138
1139err_status_t
1140srtp_validate() {
1141 unsigned char test_key[30] = {
1142 0xe1, 0xf9, 0x7a, 0x0d, 0x3e, 0x01, 0x8b, 0xe0,
1143 0xd6, 0x4f, 0xa3, 0x2c, 0x06, 0xde, 0x41, 0x39,
1144 0x0e, 0xc6, 0x75, 0xad, 0x49, 0x8a, 0xfe, 0xeb,
1145 0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6
1146 };
Marcus Sundberg410faaa2005-09-29 12:36:43 +00001147 uint8_t srtp_plaintext_ref[28] = {
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
1152 };
Marcus Sundberg410faaa2005-09-29 12:36:43 +00001153 uint8_t srtp_plaintext[38] = {
Cullen Jennings235513a2005-09-21 22:51:36 +00001154 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1155 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
1156 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1157 0xab, 0xab, 0xab, 0xab, 0x00, 0x00, 0x00, 0x00,
1158 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1159 };
Marcus Sundberg410faaa2005-09-29 12:36:43 +00001160 uint8_t srtp_ciphertext[38] = {
Cullen Jennings235513a2005-09-21 22:51:36 +00001161 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1162 0xca, 0xfe, 0xba, 0xbe, 0x4e, 0x55, 0xdc, 0x4c,
1163 0xe7, 0x99, 0x78, 0xd8, 0x8c, 0xa4, 0xd2, 0x15,
1164 0x94, 0x9d, 0x24, 0x02, 0xb7, 0x8d, 0x6a, 0xcc,
1165 0x99, 0xea, 0x17, 0x9b, 0x8d, 0xbb
1166 };
1167 srtp_t srtp_snd, srtp_recv;
1168 err_status_t status;
1169 int len;
1170 srtp_policy_t policy;
1171
1172 /*
1173 * create a session with a single stream using the default srtp
1174 * policy and with the SSRC value 0xcafebabe
1175 */
1176 crypto_policy_set_rtp_default(&policy.rtp);
1177 crypto_policy_set_rtcp_default(&policy.rtcp);
1178 policy.ssrc.type = ssrc_specific;
1179 policy.ssrc.value = 0xcafebabe;
1180 policy.key = test_key;
1181 policy.next = NULL;
1182
1183 status = srtp_create(&srtp_snd, &policy);
1184 if (status)
1185 return status;
1186
1187 /*
1188 * protect plaintext, then compare with ciphertext
1189 */
1190 len = 28;
1191 status = srtp_protect(srtp_snd, srtp_plaintext, &len);
1192 if (status || (len != 38))
1193 return err_status_fail;
1194
1195 debug_print(mod_driver, "ciphertext:\n %s",
1196 octet_string_hex_string(srtp_plaintext, len));
1197 debug_print(mod_driver, "ciphertext reference:\n %s",
1198 octet_string_hex_string(srtp_ciphertext, len));
1199
1200 if (octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len))
1201 return err_status_fail;
1202
1203 /*
1204 * create a receiver session context comparable to the one created
1205 * above - we need to do this so that the replay checking doesn't
1206 * complain
1207 */
1208 status = srtp_create(&srtp_recv, &policy);
1209 if (status)
1210 return status;
1211
1212 /*
1213 * unprotect ciphertext, then compare with plaintext
1214 */
1215 status = srtp_unprotect(srtp_recv, srtp_ciphertext, &len);
1216 if (status || (len != 28))
1217 return status;
1218
1219 if (octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len))
1220 return err_status_fail;
1221
1222 return err_status_ok;
1223}
1224
1225
1226err_status_t
1227srtp_create_big_policy(srtp_policy_t **list) {
1228 extern const srtp_policy_t *policy_array[];
1229 srtp_policy_t *p, *tmp;
1230 int i = 0;
1231 uint32_t ssrc = 0;
1232
1233 /* sanity checking */
1234 if ((list == NULL) || (policy_array[0] == NULL))
1235 return err_status_bad_param;
1236
1237 /*
1238 * loop over policy list, mallocing a new list and copying values
1239 * into it (and incrementing the SSRC value as we go along)
1240 */
1241 tmp = NULL;
1242 while (policy_array[i] != NULL) {
Derek MacDonald17127da2006-07-12 22:22:08 +00001243 p = (srtp_policy_t*) malloc(sizeof(srtp_policy_t));
Cullen Jennings235513a2005-09-21 22:51:36 +00001244 if (p == NULL)
1245 return err_status_bad_param;
1246 memcpy(p, policy_array[i], sizeof(srtp_policy_t));
1247 p->ssrc.type = ssrc_specific;
1248 p->ssrc.value = ssrc++;
1249 p->next = tmp;
1250 tmp = p;
1251 i++;
1252 }
1253 *list = p;
1254
1255 return err_status_ok;
1256}
1257
1258err_status_t
1259srtp_test_remove_stream() {
1260 err_status_t status;
1261 srtp_policy_t *policy_list;
1262 srtp_t session;
1263 srtp_stream_t stream;
1264 /*
1265 * srtp_get_stream() is a libSRTP internal function that we declare
1266 * here so that we can use it to verify the correct operation of the
1267 * library
1268 */
1269 extern srtp_stream_t srtp_get_stream(srtp_t srtp, uint32_t ssrc);
1270
1271
1272 status = srtp_create_big_policy(&policy_list);
1273 if (status)
1274 return status;
1275
1276 status = srtp_create(&session, policy_list);
1277 if (status)
1278 return status;
1279
1280 /*
1281 * check for false positives by trying to remove a stream that's not
1282 * in the session
1283 */
1284 status = srtp_remove_stream(session, htonl(0xaaaaaaaa));
1285 if (status != err_status_no_ctx)
1286 return err_status_fail;
1287
1288 /*
1289 * check for false negatives by removing stream 0x1, then
1290 * searching for streams 0x0 and 0x2
1291 */
1292 status = srtp_remove_stream(session, htonl(0x1));
1293 if (status != err_status_ok)
1294 return err_status_fail;
1295 stream = srtp_get_stream(session, htonl(0x0));
1296 if (stream == NULL)
1297 return err_status_fail;
1298 stream = srtp_get_stream(session, htonl(0x2));
1299 if (stream == NULL)
1300 return err_status_fail;
1301
1302 return err_status_ok;
1303}
1304
1305/*
1306 * srtp policy definitions - these definitions are used above
1307 */
1308
1309unsigned char test_key[30] = {
1310 0xe1, 0xf9, 0x7a, 0x0d, 0x3e, 0x01, 0x8b, 0xe0,
1311 0xd6, 0x4f, 0xa3, 0x2c, 0x06, 0xde, 0x41, 0x39,
1312 0x0e, 0xc6, 0x75, 0xad, 0x49, 0x8a, 0xfe, 0xeb,
1313 0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6
1314};
1315
1316
1317const srtp_policy_t default_policy = {
1318 { ssrc_any_outbound, 0 }, /* SSRC */
1319 { /* SRTP policy */
1320 AES_128_ICM, /* cipher type */
1321 30, /* cipher key length in octets */
1322 HMAC_SHA1, /* authentication func type */
1323 16, /* auth key length in octets */
1324 10, /* auth tag length in octets */
1325 sec_serv_conf_and_auth /* security services flag */
1326 },
1327 { /* SRTCP policy */
1328 AES_128_ICM, /* cipher type */
1329 30, /* cipher key length in octets */
1330 HMAC_SHA1, /* authentication func type */
1331 16, /* auth key length in octets */
1332 10, /* auth tag length in octets */
1333 sec_serv_conf_and_auth /* security services flag */
1334 },
1335 test_key,
David McGrew79870d62007-06-15 18:17:39 +00001336 NULL, /* indicates that EKT is not in use */
Cullen Jennings235513a2005-09-21 22:51:36 +00001337 NULL
1338};
1339
1340const srtp_policy_t aes_tmmh_policy = {
1341 { ssrc_any_outbound, 0 }, /* SSRC */
1342 {
1343 AES_128_ICM, /* cipher type */
1344 30, /* cipher key length in octets */
1345 UST_TMMHv2, /* authentication func type */
1346 94, /* auth key length in octets */
1347 4, /* auth tag length in octets */
1348 sec_serv_conf_and_auth /* security services flag */
1349 },
1350 {
1351 AES_128_ICM, /* cipher type */
1352 30, /* cipher key length in octets */
1353 UST_TMMHv2, /* authentication func type */
1354 94, /* auth key length in octets */
1355 4, /* auth tag length in octets */
1356 sec_serv_conf_and_auth /* security services flag */
1357 },
1358 test_key,
David McGrew79870d62007-06-15 18:17:39 +00001359 NULL, /* indicates that EKT is not in use */
Cullen Jennings235513a2005-09-21 22:51:36 +00001360 NULL
1361};
1362
1363const srtp_policy_t tmmh_only_policy = {
1364 { ssrc_any_outbound, 0 }, /* SSRC */
1365 {
1366 AES_128_ICM, /* cipher type */
1367 30, /* cipher key length in octets */
1368 UST_TMMHv2, /* authentication func type */
1369 94, /* auth key length in octets */
1370 4, /* auth tag length in octets */
1371 sec_serv_auth /* security services flag */
1372 },
1373 {
1374 AES_128_ICM, /* cipher type */
1375 30, /* cipher key length in octets */
1376 UST_TMMHv2, /* authentication func type */
1377 94, /* auth key length in octets */
1378 4, /* auth tag length in octets */
1379 sec_serv_auth /* security services flag */
1380 },
1381 test_key,
David McGrew79870d62007-06-15 18:17:39 +00001382 NULL, /* indicates that EKT is not in use */
Cullen Jennings235513a2005-09-21 22:51:36 +00001383 NULL
1384};
1385
1386const srtp_policy_t aes_only_policy = {
1387 { ssrc_any_outbound, 0 }, /* SSRC */
1388 {
1389 AES_128_ICM, /* cipher type */
1390 30, /* cipher key length in octets */
1391 NULL_AUTH, /* authentication func type */
1392 0, /* auth key length in octets */
1393 0, /* auth tag length in octets */
1394 sec_serv_conf /* security services flag */
1395 },
1396 {
1397 AES_128_ICM, /* cipher type */
1398 30, /* cipher key length in octets */
1399 NULL_AUTH, /* authentication func type */
1400 0, /* auth key length in octets */
1401 0, /* auth tag length in octets */
1402 sec_serv_conf /* security services flag */
1403 },
1404 test_key,
David McGrew79870d62007-06-15 18:17:39 +00001405 NULL, /* indicates that EKT is not in use */
Cullen Jennings235513a2005-09-21 22:51:36 +00001406 NULL
1407};
1408
1409const srtp_policy_t hmac_only_policy = {
1410 { ssrc_any_outbound, 0 }, /* SSRC */
1411 {
1412 NULL_CIPHER, /* cipher type */
1413 0, /* cipher key length in octets */
1414 HMAC_SHA1, /* authentication func type */
1415 20, /* auth key length in octets */
1416 4, /* auth tag length in octets */
1417 sec_serv_auth /* security services flag */
1418 },
1419 {
1420 NULL_CIPHER, /* cipher type */
1421 0, /* cipher key length in octets */
1422 HMAC_SHA1, /* authentication func type */
1423 20, /* auth key length in octets */
1424 4, /* auth tag length in octets */
1425 sec_serv_auth /* security services flag */
1426 },
1427 test_key,
David McGrew79870d62007-06-15 18:17:39 +00001428 NULL, /* indicates that EKT is not in use */
Cullen Jennings235513a2005-09-21 22:51:36 +00001429 NULL
1430};
1431
1432const srtp_policy_t null_policy = {
1433 { ssrc_any_outbound, 0 }, /* SSRC */
1434 {
1435 NULL_CIPHER, /* cipher type */
1436 0, /* cipher key length in octets */
1437 NULL_AUTH, /* authentication func type */
1438 0, /* auth key length in octets */
1439 0, /* auth tag length in octets */
1440 sec_serv_none /* security services flag */
1441 },
1442 {
1443 NULL_CIPHER, /* cipher type */
1444 0, /* cipher key length in octets */
1445 NULL_AUTH, /* authentication func type */
1446 0, /* auth key length in octets */
1447 0, /* auth tag length in octets */
1448 sec_serv_none /* security services flag */
1449 },
1450 test_key,
David McGrew79870d62007-06-15 18:17:39 +00001451 NULL, /* indicates that EKT is not in use */
1452 NULL
1453};
1454
1455uint8_t ekt_test_key[16] = {
1456 0x77, 0x26, 0x9d, 0xac, 0x16, 0xa3, 0x28, 0xca,
1457 0x8e, 0xc9, 0x68, 0x4b, 0xcc, 0xc4, 0xd2, 0x1b
1458};
1459
1460#include "ekt.h"
1461
1462ekt_policy_ctx_t ekt_test_policy = {
1463 0xa5a5, /* SPI */
1464 EKT_CIPHER_AES_128_ECB,
1465 ekt_test_key,
1466 NULL
1467};
1468
1469const srtp_policy_t hmac_only_with_ekt_policy = {
1470 { ssrc_any_outbound, 0 }, /* SSRC */
1471 {
1472 NULL_CIPHER, /* cipher type */
1473 0, /* cipher key length in octets */
1474 HMAC_SHA1, /* authentication func type */
1475 20, /* auth key length in octets */
1476 4, /* auth tag length in octets */
1477 sec_serv_auth /* security services flag */
1478 },
1479 {
1480 NULL_CIPHER, /* cipher type */
1481 0, /* cipher key length in octets */
1482 HMAC_SHA1, /* authentication func type */
1483 20, /* auth key length in octets */
1484 4, /* auth tag length in octets */
1485 sec_serv_auth /* security services flag */
1486 },
1487 test_key,
1488 &ekt_test_policy, /* indicates that EKT is not in use */
Cullen Jennings235513a2005-09-21 22:51:36 +00001489 NULL
1490};
1491
1492
1493/*
1494 * an array of pointers to the policies listed above
1495 *
1496 * This array is used to test various aspects of libSRTP for
1497 * different cryptographic policies. The order of the elements
1498 * matters - the timing test generates output that can be used
1499 * in a plot (see the gnuplot script file 'timing'). If you
1500 * add to this list, you should do it at the end.
1501 */
1502
1503#define USE_TMMH 0
1504
1505const srtp_policy_t *
1506policy_array[] = {
1507 &hmac_only_policy,
1508#if USE_TMMH
1509 &tmmh_only_policy,
1510#endif
1511 &aes_only_policy,
1512#if USE_TMMH
1513 &aes_tmmh_policy,
1514#endif
1515 &default_policy,
1516 &null_policy,
David McGrew79870d62007-06-15 18:17:39 +00001517 &hmac_only_with_ekt_policy,
Cullen Jennings235513a2005-09-21 22:51:36 +00001518 NULL
1519};
1520
1521const srtp_policy_t wildcard_policy = {
1522 { ssrc_any_outbound, 0 }, /* SSRC */
1523 { /* SRTP policy */
1524 AES_128_ICM, /* cipher type */
1525 30, /* cipher key length in octets */
1526 HMAC_SHA1, /* authentication func type */
1527 16, /* auth key length in octets */
1528 10, /* auth tag length in octets */
1529 sec_serv_conf_and_auth /* security services flag */
1530 },
1531 { /* SRTCP policy */
1532 AES_128_ICM, /* cipher type */
1533 30, /* cipher key length in octets */
1534 HMAC_SHA1, /* authentication func type */
1535 16, /* auth key length in octets */
1536 10, /* auth tag length in octets */
1537 sec_serv_conf_and_auth /* security services flag */
1538 },
1539 test_key,
Jonathan Lennox28bd7c12010-05-15 00:23:19 +00001540 NULL,
Cullen Jennings235513a2005-09-21 22:51:36 +00001541 NULL
1542};