blob: ce80ee0a7516b316d0961536ec2c744fe3cf27dc [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
jfigus857009c2014-11-05 11:17:43 -050062srtp_err_status_t
Marcus Sundberga3f95fe2005-09-29 12:48:41 +000063srtp_validate(void);
Cullen Jennings235513a2005-09-21 22:51:36 +000064
jfigus857009c2014-11-05 11:17:43 -050065srtp_err_status_t
Jonathan Lennox5df951a2010-05-20 20:55:54 +000066srtp_validate_aes_256(void);
67
jfigus857009c2014-11-05 11:17:43 -050068srtp_err_status_t
Cullen Jennings235513a2005-09-21 22:51:36 +000069srtp_create_big_policy(srtp_policy_t **list);
70
jfigus857009c2014-11-05 11:17:43 -050071srtp_err_status_t
Jonathan Lennox80c4c832010-05-17 19:30:28 +000072srtp_dealloc_big_policy(srtp_policy_t *list);
73
jfigus857009c2014-11-05 11:17:43 -050074srtp_err_status_t
Marcus Sundberga3f95fe2005-09-29 12:48:41 +000075srtp_test_remove_stream(void);
Cullen Jennings235513a2005-09-21 22:51:36 +000076
77double
78srtp_bits_per_second(int msg_len_octets, const srtp_policy_t *policy);
79
80double
81srtp_rejections_per_second(int msg_len_octets, const srtp_policy_t *policy);
82
83void
84srtp_do_timing(const srtp_policy_t *policy);
85
86void
87srtp_do_rejection_timing(const srtp_policy_t *policy);
88
jfigus857009c2014-11-05 11:17:43 -050089srtp_err_status_t
Marcus Sundberga3f95fe2005-09-29 12:48:41 +000090srtp_test(const srtp_policy_t *policy);
Cullen Jennings235513a2005-09-21 22:51:36 +000091
jfigus857009c2014-11-05 11:17:43 -050092srtp_err_status_t
David McGrew9c70f292006-05-03 19:38:38 +000093srtcp_test(const srtp_policy_t *policy);
94
jfigus857009c2014-11-05 11:17:43 -050095srtp_err_status_t
Cullen Jennings235513a2005-09-21 22:51:36 +000096srtp_session_print_policy(srtp_t srtp);
97
jfigus857009c2014-11-05 11:17:43 -050098srtp_err_status_t
Cullen Jennings235513a2005-09-21 22:51:36 +000099srtp_print_policy(const srtp_policy_t *policy);
100
101char *
102srtp_packet_to_string(srtp_hdr_t *hdr, int packet_len);
103
104double
105mips_estimate(int num_trials, int *ignore);
106
jfigus8c36da22013-10-01 16:41:19 -0400107extern uint8_t test_key[46];
Cullen Jennings235513a2005-09-21 22:51:36 +0000108
109void
110usage(char *prog_name) {
111 printf("usage: %s [ -t ][ -c ][ -v ][-d <debug_module> ]* [ -l ]\n"
112 " -t run timing test\n"
113 " -r run rejection timing test\n"
114 " -c run codec timing test\n"
115 " -v run validation tests\n"
116 " -d <mod> turn on debugging module <mod>\n"
117 " -l list debugging modules\n", prog_name);
118 exit(1);
119}
120
121/*
122 * The policy_array is a null-terminated array of policy structs. it
123 * is declared at the end of this file
124 */
125
126extern const srtp_policy_t *policy_array[];
127
128
129/* the wildcard_policy is declared below; it has a wildcard ssrc */
130
131extern const srtp_policy_t wildcard_policy;
132
133/*
134 * mod_driver debug module - debugging module for this test driver
135 *
136 * we use the crypto_kernel debugging system in this driver, which
137 * makes the interface uniform and increases portability
138 */
139
140debug_module_t mod_driver = {
141 0, /* debugging is off by default */
142 "driver" /* printable name for module */
143};
144
145int
146main (int argc, char *argv[]) {
Jonathan Lennoxb4842bf2010-05-15 03:55:24 +0000147 int q;
Cullen Jennings235513a2005-09-21 22:51:36 +0000148 unsigned do_timing_test = 0;
149 unsigned do_rejection_test = 0;
150 unsigned do_codec_timing = 0;
151 unsigned do_validation = 0;
152 unsigned do_list_mods = 0;
jfigus857009c2014-11-05 11:17:43 -0500153 srtp_err_status_t status;
Cullen Jennings235513a2005-09-21 22:51:36 +0000154
155 /*
156 * verify that the compiler has interpreted the header data
157 * structure srtp_hdr_t correctly
158 */
159 if (sizeof(srtp_hdr_t) != 12) {
David McGrew1a2ab2c2006-07-12 22:48:44 +0000160 printf("error: srtp_hdr_t has incorrect size"
161 "(size is %ld bytes, expected 12)\n",
Jonathan Lennoxf3132b92010-05-14 22:54:10 +0000162 (long)sizeof(srtp_hdr_t));
Cullen Jennings235513a2005-09-21 22:51:36 +0000163 exit(1);
164 }
165
166 /* initialize srtp library */
167 status = srtp_init();
168 if (status) {
169 printf("error: srtp init failed with error code %d\n", status);
170 exit(1);
171 }
172
173 /* load srtp_driver debug module */
174 status = crypto_kernel_load_debug_module(&mod_driver);
175 if (status) {
176 printf("error: load of srtp_driver debug module failed "
177 "with error code %d\n", status);
178 exit(1);
179 }
180
181 /* process input arguments */
182 while (1) {
David McGrew79bd3012006-07-17 20:41:21 +0000183 q = getopt_s(argc, argv, "trcvld:");
Cullen Jennings235513a2005-09-21 22:51:36 +0000184 if (q == -1)
185 break;
186 switch (q) {
187 case 't':
188 do_timing_test = 1;
189 break;
190 case 'r':
191 do_rejection_test = 1;
192 break;
193 case 'c':
194 do_codec_timing = 1;
195 break;
196 case 'v':
197 do_validation = 1;
198 break;
199 case 'l':
200 do_list_mods = 1;
201 break;
202 case 'd':
David McGrew79bd3012006-07-17 20:41:21 +0000203 status = crypto_kernel_set_debug_module(optarg_s, 1);
Cullen Jennings235513a2005-09-21 22:51:36 +0000204 if (status) {
David McGrew79bd3012006-07-17 20:41:21 +0000205 printf("error: set debug module (%s) failed\n", optarg_s);
Cullen Jennings235513a2005-09-21 22:51:36 +0000206 exit(1);
207 }
208 break;
209 default:
210 usage(argv[0]);
211 }
212 }
213
214 if (!do_validation && !do_timing_test && !do_codec_timing
215 && !do_list_mods && !do_rejection_test)
216 usage(argv[0]);
217
218 if (do_list_mods) {
219 status = crypto_kernel_list_debug_modules();
220 if (status) {
221 printf("error: list of debug modules failed\n");
222 exit(1);
223 }
224 }
225
226 if (do_validation) {
227 const srtp_policy_t **policy = policy_array;
228 srtp_policy_t *big_policy;
229
David McGrew9c70f292006-05-03 19:38:38 +0000230 /* loop over policy array, testing srtp and srtcp for each policy */
Cullen Jennings235513a2005-09-21 22:51:36 +0000231 while (*policy != NULL) {
232 printf("testing srtp_protect and srtp_unprotect\n");
jfigus857009c2014-11-05 11:17:43 -0500233 if (srtp_test(*policy) == srtp_err_status_ok)
Cullen Jennings235513a2005-09-21 22:51:36 +0000234 printf("passed\n\n");
235 else {
236 printf("failed\n");
237 exit(1);
238 }
David McGrew9c70f292006-05-03 19:38:38 +0000239 printf("testing srtp_protect_rtcp and srtp_unprotect_rtcp\n");
jfigus857009c2014-11-05 11:17:43 -0500240 if (srtcp_test(*policy) == srtp_err_status_ok)
David McGrew9c70f292006-05-03 19:38:38 +0000241 printf("passed\n\n");
242 else {
243 printf("failed\n");
244 exit(1);
245 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000246 policy++;
247 }
248
249 /* create a big policy list and run tests on it */
250 status = srtp_create_big_policy(&big_policy);
251 if (status) {
252 printf("unexpected failure with error code %d\n", status);
253 exit(1);
254 }
255 printf("testing srtp_protect and srtp_unprotect with big policy\n");
jfigus857009c2014-11-05 11:17:43 -0500256 if (srtp_test(big_policy) == srtp_err_status_ok)
Cullen Jennings235513a2005-09-21 22:51:36 +0000257 printf("passed\n\n");
258 else {
259 printf("failed\n");
260 exit(1);
261 }
Jonathan Lennox80c4c832010-05-17 19:30:28 +0000262 status = srtp_dealloc_big_policy(big_policy);
263 if (status) {
264 printf("unexpected failure with error code %d\n", status);
265 exit(1);
266 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000267
268 /* run test on wildcard policy */
269 printf("testing srtp_protect and srtp_unprotect on "
270 "wildcard ssrc policy\n");
jfigus857009c2014-11-05 11:17:43 -0500271 if (srtp_test(&wildcard_policy) == srtp_err_status_ok)
Cullen Jennings235513a2005-09-21 22:51:36 +0000272 printf("passed\n\n");
273 else {
274 printf("failed\n");
275 exit(1);
276 }
277
278 /*
279 * run validation test against the reference packets - note
280 * that this test only covers the default policy
281 */
282 printf("testing srtp_protect and srtp_unprotect against "
283 "reference packets\n");
jfigus857009c2014-11-05 11:17:43 -0500284 if (srtp_validate() == srtp_err_status_ok)
Cullen Jennings235513a2005-09-21 22:51:36 +0000285 printf("passed\n\n");
286 else {
287 printf("failed\n");
288 exit(1);
289 }
290
jfigusa14b5a02013-03-29 12:24:12 -0400291//FIXME: need to get this working with the OpenSSL AES module
292#ifndef OPENSSL
Cullen Jennings235513a2005-09-21 22:51:36 +0000293 /*
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000294 * run validation test against the reference packets for
295 * AES-256
296 */
297 printf("testing srtp_protect and srtp_unprotect against "
298 "reference packets (AES-256)\n");
jfigus857009c2014-11-05 11:17:43 -0500299 if (srtp_validate_aes_256() == srtp_err_status_ok)
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000300 printf("passed\n\n");
301 else {
302 printf("failed\n");
303 exit(1);
304 }
jfigusa14b5a02013-03-29 12:24:12 -0400305#endif
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000306
307 /*
Cullen Jennings235513a2005-09-21 22:51:36 +0000308 * test the function srtp_remove_stream()
309 */
310 printf("testing srtp_remove_stream()...");
jfigus857009c2014-11-05 11:17:43 -0500311 if (srtp_test_remove_stream() == srtp_err_status_ok)
Cullen Jennings235513a2005-09-21 22:51:36 +0000312 printf("passed\n");
313 else {
314 printf("failed\n");
315 exit(1);
316 }
317 }
318
319 if (do_timing_test) {
320 const srtp_policy_t **policy = policy_array;
321
322 /* loop over policies, run timing test for each */
323 while (*policy != NULL) {
324 srtp_print_policy(*policy);
325 srtp_do_timing(*policy);
326 policy++;
327 }
328 }
329
330 if (do_rejection_test) {
331 const srtp_policy_t **policy = policy_array;
332
333 /* loop over policies, run rejection timing test for each */
334 while (*policy != NULL) {
335 srtp_print_policy(*policy);
336 srtp_do_rejection_timing(*policy);
337 policy++;
338 }
339 }
340
341 if (do_codec_timing) {
342 srtp_policy_t policy;
343 int ignore;
344 double mips = mips_estimate(1000000000, &ignore);
345
jfigus857009c2014-11-05 11:17:43 -0500346 srtp_crypto_policy_set_rtp_default(&policy.rtp);
347 srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
Cullen Jennings235513a2005-09-21 22:51:36 +0000348 policy.ssrc.type = ssrc_specific;
349 policy.ssrc.value = 0xdecafbad;
350 policy.key = test_key;
Jonathan Lennoxa1242f82010-05-17 21:46:04 +0000351 policy.ekt = NULL;
352 policy.window_size = 128;
Jonathan Lennoxdcee5c62010-05-17 22:08:40 +0000353 policy.allow_repeat_tx = 0;
Cullen Jennings235513a2005-09-21 22:51:36 +0000354 policy.next = NULL;
355
356 printf("mips estimate: %e\n", mips);
357
358 printf("testing srtp processing time for voice codecs:\n");
359 printf("codec\t\tlength (octets)\t\tsrtp instructions/second\n");
360 printf("G.711\t\t%d\t\t\t%e\n", 80,
361 (double) mips * (80 * 8) /
362 srtp_bits_per_second(80, &policy) / .01 );
363 printf("G.711\t\t%d\t\t\t%e\n", 160,
364 (double) mips * (160 * 8) /
365 srtp_bits_per_second(160, &policy) / .02);
366 printf("G.726-32\t%d\t\t\t%e\n", 40,
367 (double) mips * (40 * 8) /
368 srtp_bits_per_second(40, &policy) / .01 );
369 printf("G.726-32\t%d\t\t\t%e\n", 80,
370 (double) mips * (80 * 8) /
371 srtp_bits_per_second(80, &policy) / .02);
372 printf("G.729\t\t%d\t\t\t%e\n", 10,
373 (double) mips * (10 * 8) /
374 srtp_bits_per_second(10, &policy) / .01 );
375 printf("G.729\t\t%d\t\t\t%e\n", 20,
376 (double) mips * (20 * 8) /
377 srtp_bits_per_second(20, &policy) / .02 );
David McGrew93451082006-09-18 13:41:35 +0000378 printf("Wideband\t%d\t\t\t%e\n", 320,
379 (double) mips * (320 * 8) /
380 srtp_bits_per_second(320, &policy) / .01 );
381 printf("Wideband\t%d\t\t\t%e\n", 640,
382 (double) mips * (640 * 8) /
383 srtp_bits_per_second(640, &policy) / .02 );
Cullen Jennings235513a2005-09-21 22:51:36 +0000384 }
385
Jonathan Lennoxdfb30842010-05-15 04:52:01 +0000386 status = srtp_shutdown();
387 if (status) {
388 printf("error: srtp shutdown failed with error code %d\n", status);
389 exit(1);
390 }
391
Cullen Jennings235513a2005-09-21 22:51:36 +0000392 return 0;
393}
394
395
396
397/*
398 * srtp_create_test_packet(len, ssrc) returns a pointer to a
399 * (malloced) example RTP packet whose data field has the length given
400 * by pkt_octet_len and the SSRC value ssrc. The total length of the
401 * packet is twelve octets longer, since the header is at the
402 * beginning. There is room at the end of the packet for a trailer,
403 * and the four octets following the packet are filled with 0xff
404 * values to enable testing for overwrites.
405 *
406 * note that the location of the test packet can (and should) be
407 * deallocated with the free() call once it is no longer needed.
408 */
409
410srtp_hdr_t *
411srtp_create_test_packet(int pkt_octet_len, uint32_t ssrc) {
412 int i;
Marcus Sundberg410faaa2005-09-29 12:36:43 +0000413 uint8_t *buffer;
Cullen Jennings235513a2005-09-21 22:51:36 +0000414 srtp_hdr_t *hdr;
415 int bytes_in_hdr = 12;
416
417 /* allocate memory for test packet */
Derek MacDonald17127da2006-07-12 22:22:08 +0000418 hdr = (srtp_hdr_t*) malloc(pkt_octet_len + bytes_in_hdr
Cullen Jennings235513a2005-09-21 22:51:36 +0000419 + SRTP_MAX_TRAILER_LEN + 4);
420 if (!hdr)
421 return NULL;
422
423 hdr->version = 2; /* RTP version two */
424 hdr->p = 0; /* no padding needed */
425 hdr->x = 0; /* no header extension */
426 hdr->cc = 0; /* no CSRCs */
427 hdr->m = 0; /* marker bit */
428 hdr->pt = 0xf; /* payload type */
429 hdr->seq = htons(0x1234); /* sequence number */
430 hdr->ts = htonl(0xdecafbad); /* timestamp */
431 hdr->ssrc = htonl(ssrc); /* synch. source */
432
Marcus Sundberg410faaa2005-09-29 12:36:43 +0000433 buffer = (uint8_t *)hdr;
Cullen Jennings235513a2005-09-21 22:51:36 +0000434 buffer += bytes_in_hdr;
435
436 /* set RTP data to 0xab */
437 for (i=0; i < pkt_octet_len; i++)
438 *buffer++ = 0xab;
439
440 /* set post-data value to 0xffff to enable overrun checking */
441 for (i=0; i < SRTP_MAX_TRAILER_LEN+4; i++)
442 *buffer++ = 0xff;
443
444 return hdr;
445}
446
447void
448srtp_do_timing(const srtp_policy_t *policy) {
449 int len;
450
451 /*
452 * note: the output of this function is formatted so that it
453 * can be used in gnuplot. '#' indicates a comment, and "\r\n"
454 * terminates a record
455 */
456
457 printf("# testing srtp throughput:\r\n");
458 printf("# mesg length (octets)\tthroughput (megabits per second)\r\n");
459
460 for (len=16; len <= 2048; len *= 2)
461 printf("%d\t\t\t%f\r\n", len,
462 srtp_bits_per_second(len, policy) / 1.0E6);
463
464 /* these extra linefeeds let gnuplot know that a dataset is done */
465 printf("\r\n\r\n");
466
467}
468
469void
470srtp_do_rejection_timing(const srtp_policy_t *policy) {
471 int len;
472
473 /*
474 * note: the output of this function is formatted so that it
475 * can be used in gnuplot. '#' indicates a comment, and "\r\n"
476 * terminates a record
477 */
478
479 printf("# testing srtp rejection throughput:\r\n");
480 printf("# mesg length (octets)\trejections per second\r\n");
481
482 for (len=8; len <= 2048; len *= 2)
483 printf("%d\t\t\t%e\r\n", len, srtp_rejections_per_second(len, policy));
484
485 /* these extra linefeeds let gnuplot know that a dataset is done */
486 printf("\r\n\r\n");
487
488}
489
490
491#define MAX_MSG_LEN 1024
492
493double
494srtp_bits_per_second(int msg_len_octets, const srtp_policy_t *policy) {
495 srtp_t srtp;
496 srtp_hdr_t *mesg;
497 int i;
498 clock_t timer;
499 int num_trials = 100000;
500 int len;
501 uint32_t ssrc;
jfigus857009c2014-11-05 11:17:43 -0500502 srtp_err_status_t status;
Cullen Jennings235513a2005-09-21 22:51:36 +0000503
504 /*
505 * allocate and initialize an srtp session
506 */
507 status = srtp_create(&srtp, policy);
508 if (status) {
509 printf("error: srtp_create() failed with error code %d\n", status);
510 exit(1);
511 }
512
513 /*
514 * if the ssrc is unspecified, use a predetermined one
515 */
516 if (policy->ssrc.type != ssrc_specific) {
517 ssrc = 0xdeadbeef;
518 } else {
519 ssrc = policy->ssrc.value;
520 }
521
522 /*
523 * create a test packet
524 */
525 mesg = srtp_create_test_packet(msg_len_octets, ssrc);
526 if (mesg == NULL)
527 return 0.0; /* indicate failure by returning zero */
528
529 timer = clock();
530 for (i=0; i < num_trials; i++) {
David McGrewd2f8de42006-02-03 19:43:59 +0000531 len = msg_len_octets + 12; /* add in rtp header length */
Cullen Jennings235513a2005-09-21 22:51:36 +0000532
533 /* srtp protect message */
534 status = srtp_protect(srtp, mesg, &len);
535 if (status) {
536 printf("error: srtp_protect() failed with error code %d\n", status);
537 exit(1);
538 }
539
540 /* increment message number */
Jonathan Lennox75b36872010-05-21 00:30:21 +0000541 {
542 /* hack sequence to avoid problems with macros for htons/ntohs on some systems */
543 short new_seq = ntohs(mesg->seq) + 1;
544 mesg->seq = htons(new_seq);
545 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000546 }
547 timer = clock() - timer;
548
549 free(mesg);
Jonathan Lennox80c4c832010-05-17 19:30:28 +0000550
551 status = srtp_dealloc(srtp);
552 if (status) {
553 printf("error: srtp_dealloc() failed with error code %d\n", status);
554 exit(1);
555 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000556
557 return (double) (msg_len_octets) * 8 *
558 num_trials * CLOCKS_PER_SEC / timer;
559}
560
561double
562srtp_rejections_per_second(int msg_len_octets, const srtp_policy_t *policy) {
563 srtp_ctx_t *srtp;
564 srtp_hdr_t *mesg;
565 int i;
566 int len;
567 clock_t timer;
568 int num_trials = 1000000;
569 uint32_t ssrc = policy->ssrc.value;
jfigus857009c2014-11-05 11:17:43 -0500570 srtp_err_status_t status;
Cullen Jennings235513a2005-09-21 22:51:36 +0000571
572 /*
573 * allocate and initialize an srtp session
574 */
575 status = srtp_create(&srtp, policy);
576 if (status) {
577 printf("error: srtp_create() failed with error code %d\n", status);
578 exit(1);
579 }
580
581 mesg = srtp_create_test_packet(msg_len_octets, ssrc);
582 if (mesg == NULL)
583 return 0.0; /* indicate failure by returning zero */
584
585 len = msg_len_octets;
586 srtp_protect(srtp, (srtp_hdr_t *)mesg, &len);
587
588 timer = clock();
589 for (i=0; i < num_trials; i++) {
590 len = msg_len_octets;
591 srtp_unprotect(srtp, (srtp_hdr_t *)mesg, &len);
592 }
593 timer = clock() - timer;
594
595 free(mesg);
Jonathan Lennox80c4c832010-05-17 19:30:28 +0000596
597 status = srtp_dealloc(srtp);
598 if (status) {
599 printf("error: srtp_dealloc() failed with error code %d\n", status);
600 exit(1);
601 }
602
Cullen Jennings235513a2005-09-21 22:51:36 +0000603 return (double) num_trials * CLOCKS_PER_SEC / timer;
604}
605
606
607void
jfigus857009c2014-11-05 11:17:43 -0500608err_check(srtp_err_status_t s) {
609 if (s == srtp_err_status_ok)
Cullen Jennings235513a2005-09-21 22:51:36 +0000610 return;
611 else
612 fprintf(stderr, "error: unexpected srtp failure (code %d)\n", s);
613 exit (1);
614}
615
jfigus857009c2014-11-05 11:17:43 -0500616srtp_err_status_t
Cullen Jennings235513a2005-09-21 22:51:36 +0000617srtp_test(const srtp_policy_t *policy) {
618 int i;
619 srtp_t srtp_sender;
620 srtp_t srtp_rcvr;
jfigus857009c2014-11-05 11:17:43 -0500621 srtp_err_status_t status = srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +0000622 srtp_hdr_t *hdr, *hdr2;
Marcus Sundberg5c40da82005-10-08 18:15:00 +0000623 uint8_t hdr_enc[64];
Marcus Sundberg410faaa2005-09-29 12:36:43 +0000624 uint8_t *pkt_end;
Marcus Sundberg5c40da82005-10-08 18:15:00 +0000625 int msg_len_octets, msg_len_enc;
Cullen Jennings235513a2005-09-21 22:51:36 +0000626 int len;
627 int tag_length = policy->rtp.auth_tag_len;
628 uint32_t ssrc;
629 srtp_policy_t *rcvr_policy;
630
631 err_check(srtp_create(&srtp_sender, policy));
632
633 /* print out policy */
634 err_check(srtp_session_print_policy(srtp_sender));
635
636 /*
637 * initialize data buffer, using the ssrc in the policy unless that
638 * value is a wildcard, in which case we'll just use an arbitrary
639 * one
640 */
641 if (policy->ssrc.type != ssrc_specific)
642 ssrc = 0xdecafbad;
643 else
644 ssrc = policy->ssrc.value;
645 msg_len_octets = 28;
646 hdr = srtp_create_test_packet(msg_len_octets, ssrc);
647
648 if (hdr == NULL)
jfigus857009c2014-11-05 11:17:43 -0500649 return srtp_err_status_alloc_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +0000650 hdr2 = srtp_create_test_packet(msg_len_octets, ssrc);
651 if (hdr2 == NULL) {
652 free(hdr);
jfigus857009c2014-11-05 11:17:43 -0500653 return srtp_err_status_alloc_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +0000654 }
655
656 /* set message length */
657 len = msg_len_octets;
658
659 debug_print(mod_driver, "before protection:\n%s",
660 srtp_packet_to_string(hdr, len));
661
662#if PRINT_REFERENCE_PACKET
663 debug_print(mod_driver, "reference packet before protection:\n%s",
Marcus Sundberg410faaa2005-09-29 12:36:43 +0000664 octet_string_hex_string((uint8_t *)hdr, len));
Cullen Jennings235513a2005-09-21 22:51:36 +0000665#endif
666 err_check(srtp_protect(srtp_sender, hdr, &len));
667
668 debug_print(mod_driver, "after protection:\n%s",
669 srtp_packet_to_string(hdr, len));
670#if PRINT_REFERENCE_PACKET
671 debug_print(mod_driver, "after protection:\n%s",
Marcus Sundberg410faaa2005-09-29 12:36:43 +0000672 octet_string_hex_string((uint8_t *)hdr, len));
Cullen Jennings235513a2005-09-21 22:51:36 +0000673#endif
674
Marcus Sundberg5c40da82005-10-08 18:15:00 +0000675 /* save protected message and length */
676 memcpy(hdr_enc, hdr, len);
677 msg_len_enc = len;
678
Cullen Jennings235513a2005-09-21 22:51:36 +0000679 /*
680 * check for overrun of the srtp_protect() function
681 *
682 * The packet is followed by a value of 0xfffff; if the value of the
683 * data following the packet is different, then we know that the
684 * protect function is overwriting the end of the packet.
685 */
Marcus Sundberg410faaa2005-09-29 12:36:43 +0000686 pkt_end = (uint8_t *)hdr + sizeof(srtp_hdr_t)
Cullen Jennings235513a2005-09-21 22:51:36 +0000687 + msg_len_octets + tag_length;
688 for (i = 0; i < 4; i++)
689 if (pkt_end[i] != 0xff) {
690 fprintf(stdout, "overwrite in srtp_protect() function "
691 "(expected %x, found %x in trailing octet %d)\n",
Marcus Sundberg410faaa2005-09-29 12:36:43 +0000692 0xff, ((uint8_t *)hdr)[i], i);
Cullen Jennings235513a2005-09-21 22:51:36 +0000693 free(hdr);
694 free(hdr2);
jfigus857009c2014-11-05 11:17:43 -0500695 return srtp_err_status_algo_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +0000696 }
697
698 /*
699 * if the policy includes confidentiality, check that ciphertext is
700 * different than plaintext
701 *
702 * Note that this check will give false negatives, with some small
703 * probability, especially if the packets are short. For that
704 * reason, we skip this check if the plaintext is less than four
705 * octets long.
706 */
707 if ((policy->rtp.sec_serv & sec_serv_conf) && (msg_len_octets >= 4)) {
708 printf("testing that ciphertext is distinct from plaintext...");
jfigus857009c2014-11-05 11:17:43 -0500709 status = srtp_err_status_algo_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +0000710 for (i=12; i < msg_len_octets+12; i++)
Marcus Sundberg410faaa2005-09-29 12:36:43 +0000711 if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) {
jfigus857009c2014-11-05 11:17:43 -0500712 status = srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +0000713 }
714 if (status) {
715 printf("failed\n");
716 free(hdr);
717 free(hdr2);
718 return status;
719 }
720 printf("passed\n");
721 }
722
723 /*
724 * if the policy uses a 'wildcard' ssrc, then we need to make a copy
725 * of the policy that changes the direction to inbound
726 *
727 * we always copy the policy into the rcvr_policy, since otherwise
728 * the compiler would fret about the constness of the policy
729 */
Derek MacDonald17127da2006-07-12 22:22:08 +0000730 rcvr_policy = (srtp_policy_t*) malloc(sizeof(srtp_policy_t));
Jonathan Lennox80c4c832010-05-17 19:30:28 +0000731 if (rcvr_policy == NULL) {
732 free(hdr);
733 free(hdr2);
jfigus857009c2014-11-05 11:17:43 -0500734 return srtp_err_status_alloc_fail;
Jonathan Lennox80c4c832010-05-17 19:30:28 +0000735 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000736 memcpy(rcvr_policy, policy, sizeof(srtp_policy_t));
737 if (policy->ssrc.type == ssrc_any_outbound) {
738 rcvr_policy->ssrc.type = ssrc_any_inbound;
739 }
740
741 err_check(srtp_create(&srtp_rcvr, rcvr_policy));
742
743 err_check(srtp_unprotect(srtp_rcvr, hdr, &len));
744
745 debug_print(mod_driver, "after unprotection:\n%s",
746 srtp_packet_to_string(hdr, len));
747
748 /* verify that the unprotected packet matches the origial one */
749 for (i=0; i < msg_len_octets; i++)
Marcus Sundberg410faaa2005-09-29 12:36:43 +0000750 if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) {
Cullen Jennings235513a2005-09-21 22:51:36 +0000751 fprintf(stdout, "mismatch at octet %d\n", i);
jfigus857009c2014-11-05 11:17:43 -0500752 status = srtp_err_status_algo_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +0000753 }
754 if (status) {
755 free(hdr);
756 free(hdr2);
Jonathan Lennox80c4c832010-05-17 19:30:28 +0000757 free(rcvr_policy);
Cullen Jennings235513a2005-09-21 22:51:36 +0000758 return status;
759 }
760
761 /*
762 * if the policy includes authentication, then test for false positives
763 */
764 if (policy->rtp.sec_serv & sec_serv_auth) {
765 char *data = ((char *)hdr) + 12;
766
767 printf("testing for false positives in replay check...");
768
Marcus Sundberg5c40da82005-10-08 18:15:00 +0000769 /* set message length */
770 len = msg_len_enc;
771
Cullen Jennings235513a2005-09-21 22:51:36 +0000772 /* unprotect a second time - should fail with a replay error */
Marcus Sundberg5c40da82005-10-08 18:15:00 +0000773 status = srtp_unprotect(srtp_rcvr, hdr_enc, &len);
jfigus857009c2014-11-05 11:17:43 -0500774 if (status != srtp_err_status_replay_fail) {
Cullen Jennings235513a2005-09-21 22:51:36 +0000775 printf("failed with error code %d\n", status);
776 free(hdr);
777 free(hdr2);
Jonathan Lennox80c4c832010-05-17 19:30:28 +0000778 free(rcvr_policy);
Cullen Jennings235513a2005-09-21 22:51:36 +0000779 return status;
780 } else {
781 printf("passed\n");
782 }
783
784 printf("testing for false positives in auth check...");
785
786 /* increment sequence number in header */
787 hdr->seq++;
788
Marcus Sundberg5c40da82005-10-08 18:15:00 +0000789 /* set message length */
790 len = msg_len_octets;
791
Cullen Jennings235513a2005-09-21 22:51:36 +0000792 /* apply protection */
793 err_check(srtp_protect(srtp_sender, hdr, &len));
794
795 /* flip bits in packet */
796 data[0] ^= 0xff;
797
798 /* unprotect, and check for authentication failure */
799 status = srtp_unprotect(srtp_rcvr, hdr, &len);
jfigus857009c2014-11-05 11:17:43 -0500800 if (status != srtp_err_status_auth_fail) {
Cullen Jennings235513a2005-09-21 22:51:36 +0000801 printf("failed\n");
802 free(hdr);
803 free(hdr2);
Jonathan Lennox80c4c832010-05-17 19:30:28 +0000804 free(rcvr_policy);
Cullen Jennings235513a2005-09-21 22:51:36 +0000805 return status;
806 } else {
807 printf("passed\n");
808 }
809
810 }
811
812 err_check(srtp_dealloc(srtp_sender));
813 err_check(srtp_dealloc(srtp_rcvr));
814
815 free(hdr);
816 free(hdr2);
Jonathan Lennox80c4c832010-05-17 19:30:28 +0000817 free(rcvr_policy);
jfigus857009c2014-11-05 11:17:43 -0500818 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +0000819}
820
821
jfigus857009c2014-11-05 11:17:43 -0500822srtp_err_status_t
David McGrew9c70f292006-05-03 19:38:38 +0000823srtcp_test(const srtp_policy_t *policy) {
824 int i;
825 srtp_t srtcp_sender;
826 srtp_t srtcp_rcvr;
jfigus857009c2014-11-05 11:17:43 -0500827 srtp_err_status_t status = srtp_err_status_ok;
David McGrew9c70f292006-05-03 19:38:38 +0000828 srtp_hdr_t *hdr, *hdr2;
829 uint8_t hdr_enc[64];
830 uint8_t *pkt_end;
831 int msg_len_octets, msg_len_enc;
832 int len;
833 int tag_length = policy->rtp.auth_tag_len;
834 uint32_t ssrc;
835 srtp_policy_t *rcvr_policy;
836
837 err_check(srtp_create(&srtcp_sender, policy));
838
839 /* print out policy */
840 err_check(srtp_session_print_policy(srtcp_sender));
841
842 /*
843 * initialize data buffer, using the ssrc in the policy unless that
844 * value is a wildcard, in which case we'll just use an arbitrary
845 * one
846 */
847 if (policy->ssrc.type != ssrc_specific)
848 ssrc = 0xdecafbad;
849 else
850 ssrc = policy->ssrc.value;
851 msg_len_octets = 28;
852 hdr = srtp_create_test_packet(msg_len_octets, ssrc);
853
854 if (hdr == NULL)
jfigus857009c2014-11-05 11:17:43 -0500855 return srtp_err_status_alloc_fail;
David McGrew9c70f292006-05-03 19:38:38 +0000856 hdr2 = srtp_create_test_packet(msg_len_octets, ssrc);
857 if (hdr2 == NULL) {
858 free(hdr);
jfigus857009c2014-11-05 11:17:43 -0500859 return srtp_err_status_alloc_fail;
David McGrew9c70f292006-05-03 19:38:38 +0000860 }
861
862 /* set message length */
863 len = msg_len_octets;
864
865 debug_print(mod_driver, "before protection:\n%s",
866 srtp_packet_to_string(hdr, len));
867
868#if PRINT_REFERENCE_PACKET
869 debug_print(mod_driver, "reference packet before protection:\n%s",
870 octet_string_hex_string((uint8_t *)hdr, len));
871#endif
872 err_check(srtp_protect_rtcp(srtcp_sender, hdr, &len));
873
874 debug_print(mod_driver, "after protection:\n%s",
875 srtp_packet_to_string(hdr, len));
876#if PRINT_REFERENCE_PACKET
877 debug_print(mod_driver, "after protection:\n%s",
878 octet_string_hex_string((uint8_t *)hdr, len));
879#endif
880
881 /* save protected message and length */
882 memcpy(hdr_enc, hdr, len);
883 msg_len_enc = len;
884
885 /*
886 * check for overrun of the srtp_protect() function
887 *
888 * The packet is followed by a value of 0xfffff; if the value of the
889 * data following the packet is different, then we know that the
890 * protect function is overwriting the end of the packet.
891 */
892 pkt_end = (uint8_t *)hdr + sizeof(srtp_hdr_t)
893 + msg_len_octets + tag_length;
894 for (i = 0; i < 4; i++)
895 if (pkt_end[i] != 0xff) {
896 fprintf(stdout, "overwrite in srtp_protect_rtcp() function "
897 "(expected %x, found %x in trailing octet %d)\n",
898 0xff, ((uint8_t *)hdr)[i], i);
899 free(hdr);
900 free(hdr2);
jfigus857009c2014-11-05 11:17:43 -0500901 return srtp_err_status_algo_fail;
David McGrew9c70f292006-05-03 19:38:38 +0000902 }
903
904 /*
905 * if the policy includes confidentiality, check that ciphertext is
906 * different than plaintext
907 *
908 * Note that this check will give false negatives, with some small
909 * probability, especially if the packets are short. For that
910 * reason, we skip this check if the plaintext is less than four
911 * octets long.
912 */
913 if ((policy->rtp.sec_serv & sec_serv_conf) && (msg_len_octets >= 4)) {
914 printf("testing that ciphertext is distinct from plaintext...");
jfigus857009c2014-11-05 11:17:43 -0500915 status = srtp_err_status_algo_fail;
David McGrew9c70f292006-05-03 19:38:38 +0000916 for (i=12; i < msg_len_octets+12; i++)
917 if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) {
jfigus857009c2014-11-05 11:17:43 -0500918 status = srtp_err_status_ok;
David McGrew9c70f292006-05-03 19:38:38 +0000919 }
920 if (status) {
921 printf("failed\n");
922 free(hdr);
923 free(hdr2);
924 return status;
925 }
926 printf("passed\n");
927 }
928
929 /*
930 * if the policy uses a 'wildcard' ssrc, then we need to make a copy
931 * of the policy that changes the direction to inbound
932 *
933 * we always copy the policy into the rcvr_policy, since otherwise
934 * the compiler would fret about the constness of the policy
935 */
Derek MacDonald17127da2006-07-12 22:22:08 +0000936 rcvr_policy = (srtp_policy_t*) malloc(sizeof(srtp_policy_t));
David McGrew9c70f292006-05-03 19:38:38 +0000937 if (rcvr_policy == NULL)
jfigus857009c2014-11-05 11:17:43 -0500938 return srtp_err_status_alloc_fail;
David McGrew9c70f292006-05-03 19:38:38 +0000939 memcpy(rcvr_policy, policy, sizeof(srtp_policy_t));
940 if (policy->ssrc.type == ssrc_any_outbound) {
941 rcvr_policy->ssrc.type = ssrc_any_inbound;
942 }
943
944 err_check(srtp_create(&srtcp_rcvr, rcvr_policy));
945
946 err_check(srtp_unprotect_rtcp(srtcp_rcvr, hdr, &len));
947
948 debug_print(mod_driver, "after unprotection:\n%s",
949 srtp_packet_to_string(hdr, len));
950
951 /* verify that the unprotected packet matches the origial one */
952 for (i=0; i < msg_len_octets; i++)
953 if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) {
954 fprintf(stdout, "mismatch at octet %d\n", i);
jfigus857009c2014-11-05 11:17:43 -0500955 status = srtp_err_status_algo_fail;
David McGrew9c70f292006-05-03 19:38:38 +0000956 }
957 if (status) {
958 free(hdr);
959 free(hdr2);
Jonathan Lennox80c4c832010-05-17 19:30:28 +0000960 free(rcvr_policy);
David McGrew9c70f292006-05-03 19:38:38 +0000961 return status;
962 }
963
964 /*
965 * if the policy includes authentication, then test for false positives
966 */
967 if (policy->rtp.sec_serv & sec_serv_auth) {
968 char *data = ((char *)hdr) + 12;
969
970 printf("testing for false positives in replay check...");
971
972 /* set message length */
973 len = msg_len_enc;
974
975 /* unprotect a second time - should fail with a replay error */
976 status = srtp_unprotect_rtcp(srtcp_rcvr, hdr_enc, &len);
jfigus857009c2014-11-05 11:17:43 -0500977 if (status != srtp_err_status_replay_fail) {
David McGrew9c70f292006-05-03 19:38:38 +0000978 printf("failed with error code %d\n", status);
979 free(hdr);
980 free(hdr2);
Jonathan Lennox80c4c832010-05-17 19:30:28 +0000981 free(rcvr_policy);
David McGrew9c70f292006-05-03 19:38:38 +0000982 return status;
983 } else {
984 printf("passed\n");
985 }
986
987 printf("testing for false positives in auth check...");
988
989 /* increment sequence number in header */
990 hdr->seq++;
991
992 /* set message length */
993 len = msg_len_octets;
994
995 /* apply protection */
996 err_check(srtp_protect_rtcp(srtcp_sender, hdr, &len));
997
998 /* flip bits in packet */
999 data[0] ^= 0xff;
1000
1001 /* unprotect, and check for authentication failure */
1002 status = srtp_unprotect_rtcp(srtcp_rcvr, hdr, &len);
jfigus857009c2014-11-05 11:17:43 -05001003 if (status != srtp_err_status_auth_fail) {
David McGrew9c70f292006-05-03 19:38:38 +00001004 printf("failed\n");
1005 free(hdr);
1006 free(hdr2);
Jonathan Lennox80c4c832010-05-17 19:30:28 +00001007 free(rcvr_policy);
David McGrew9c70f292006-05-03 19:38:38 +00001008 return status;
1009 } else {
1010 printf("passed\n");
1011 }
1012
1013 }
1014
1015 err_check(srtp_dealloc(srtcp_sender));
1016 err_check(srtp_dealloc(srtcp_rcvr));
1017
1018 free(hdr);
1019 free(hdr2);
Jonathan Lennox80c4c832010-05-17 19:30:28 +00001020 free(rcvr_policy);
jfigus857009c2014-11-05 11:17:43 -05001021 return srtp_err_status_ok;
David McGrew9c70f292006-05-03 19:38:38 +00001022}
1023
1024
jfigus857009c2014-11-05 11:17:43 -05001025srtp_err_status_t
Cullen Jennings235513a2005-09-21 22:51:36 +00001026srtp_session_print_policy(srtp_t srtp) {
1027 char *serv_descr[4] = {
1028 "none",
1029 "confidentiality",
1030 "authentication",
1031 "confidentiality and authentication"
1032 };
1033 char *direction[3] = {
1034 "unknown",
1035 "outbound",
1036 "inbound"
1037 };
1038 srtp_stream_t stream;
1039
1040 /* sanity checking */
1041 if (srtp == NULL)
jfigus857009c2014-11-05 11:17:43 -05001042 return srtp_err_status_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +00001043
1044 /* if there's a template stream, print it out */
1045 if (srtp->stream_template != NULL) {
1046 stream = srtp->stream_template;
1047 printf("# SSRC: any %s\r\n"
1048 "# rtp cipher: %s\r\n"
1049 "# rtp auth: %s\r\n"
1050 "# rtp services: %s\r\n"
1051 "# rtcp cipher: %s\r\n"
1052 "# rtcp auth: %s\r\n"
Jonathan Lennoxa1242f82010-05-17 21:46:04 +00001053 "# rtcp services: %s\r\n"
Jonathan Lennoxdcee5c62010-05-17 22:08:40 +00001054 "# window size: %lu\r\n"
1055 "# tx rtx allowed:%s\r\n",
Cullen Jennings235513a2005-09-21 22:51:36 +00001056 direction[stream->direction],
1057 stream->rtp_cipher->type->description,
1058 stream->rtp_auth->type->description,
1059 serv_descr[stream->rtp_services],
1060 stream->rtcp_cipher->type->description,
1061 stream->rtcp_auth->type->description,
Jonathan Lennoxa1242f82010-05-17 21:46:04 +00001062 serv_descr[stream->rtcp_services],
Jonathan Lennoxdcee5c62010-05-17 22:08:40 +00001063 rdbx_get_window_size(&stream->rtp_rdbx),
1064 stream->allow_repeat_tx ? "true" : "false");
Cullen Jennings235513a2005-09-21 22:51:36 +00001065 }
1066
1067 /* loop over streams in session, printing the policy of each */
1068 stream = srtp->stream_list;
1069 while (stream != NULL) {
1070 if (stream->rtp_services > sec_serv_conf_and_auth)
jfigus857009c2014-11-05 11:17:43 -05001071 return srtp_err_status_bad_param;
Cullen Jennings235513a2005-09-21 22:51:36 +00001072
1073 printf("# SSRC: 0x%08x\r\n"
1074 "# rtp cipher: %s\r\n"
1075 "# rtp auth: %s\r\n"
1076 "# rtp services: %s\r\n"
1077 "# rtcp cipher: %s\r\n"
1078 "# rtcp auth: %s\r\n"
Jonathan Lennoxa1242f82010-05-17 21:46:04 +00001079 "# rtcp services: %s\r\n"
Jonathan Lennoxdcee5c62010-05-17 22:08:40 +00001080 "# window size: %lu\r\n"
1081 "# tx rtx allowed:%s\r\n",
Cullen Jennings235513a2005-09-21 22:51:36 +00001082 stream->ssrc,
1083 stream->rtp_cipher->type->description,
1084 stream->rtp_auth->type->description,
1085 serv_descr[stream->rtp_services],
1086 stream->rtcp_cipher->type->description,
1087 stream->rtcp_auth->type->description,
Jonathan Lennoxa1242f82010-05-17 21:46:04 +00001088 serv_descr[stream->rtcp_services],
Jonathan Lennoxdcee5c62010-05-17 22:08:40 +00001089 rdbx_get_window_size(&stream->rtp_rdbx),
1090 stream->allow_repeat_tx ? "true" : "false");
Cullen Jennings235513a2005-09-21 22:51:36 +00001091
1092 /* advance to next stream in the list */
1093 stream = stream->next;
1094 }
jfigus857009c2014-11-05 11:17:43 -05001095 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +00001096}
1097
jfigus857009c2014-11-05 11:17:43 -05001098srtp_err_status_t
Cullen Jennings235513a2005-09-21 22:51:36 +00001099srtp_print_policy(const srtp_policy_t *policy) {
jfigus857009c2014-11-05 11:17:43 -05001100 srtp_err_status_t status;
Cullen Jennings235513a2005-09-21 22:51:36 +00001101 srtp_t session;
1102
1103 status = srtp_create(&session, policy);
1104 if (status)
1105 return status;
1106 status = srtp_session_print_policy(session);
1107 if (status)
1108 return status;
1109 status = srtp_dealloc(session);
1110 if (status)
1111 return status;
jfigus857009c2014-11-05 11:17:43 -05001112 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +00001113}
1114
1115/*
1116 * srtp_print_packet(...) is for debugging only
1117 * it prints an RTP packet to the stdout
1118 *
1119 * note that this function is *not* threadsafe
1120 */
1121
1122#include <stdio.h>
1123
1124#define MTU 2048
1125
1126char packet_string[MTU];
1127
1128char *
1129srtp_packet_to_string(srtp_hdr_t *hdr, int pkt_octet_len) {
1130 int octets_in_rtp_header = 12;
Marcus Sundberg410faaa2005-09-29 12:36:43 +00001131 uint8_t *data = ((uint8_t *)hdr)+octets_in_rtp_header;
Cullen Jennings235513a2005-09-21 22:51:36 +00001132 int hex_len = pkt_octet_len-octets_in_rtp_header;
1133
1134 /* sanity checking */
1135 if ((hdr == NULL) || (pkt_octet_len > MTU))
1136 return NULL;
1137
1138 /* write packet into string */
1139 sprintf(packet_string,
1140 "(s)rtp packet: {\n"
1141 " version:\t%d\n"
1142 " p:\t\t%d\n"
1143 " x:\t\t%d\n"
1144 " cc:\t\t%d\n"
1145 " m:\t\t%d\n"
1146 " pt:\t\t%x\n"
1147 " seq:\t\t%x\n"
1148 " ts:\t\t%x\n"
1149 " ssrc:\t%x\n"
1150 " data:\t%s\n"
1151 "} (%d octets in total)\n",
1152 hdr->version,
1153 hdr->p,
1154 hdr->x,
1155 hdr->cc,
1156 hdr->m,
1157 hdr->pt,
1158 hdr->seq,
1159 hdr->ts,
1160 hdr->ssrc,
1161 octet_string_hex_string(data, hex_len),
1162 pkt_octet_len);
1163
1164 return packet_string;
1165}
1166
1167/*
1168 * mips_estimate() is a simple function to estimate the number of
1169 * instructions per second that the host can perform. note that this
1170 * function can be grossly wrong; you may want to have a manual sanity
1171 * check of its output!
1172 *
1173 * the 'ignore' pointer is there to convince the compiler to not just
1174 * optimize away the function
1175 */
1176
1177double
1178mips_estimate(int num_trials, int *ignore) {
1179 clock_t t;
Jonathan Lennox33554932010-05-15 04:53:10 +00001180 volatile int i, sum;
Cullen Jennings235513a2005-09-21 22:51:36 +00001181
1182 sum = 0;
1183 t = clock();
1184 for (i=0; i<num_trials; i++)
1185 sum += i;
1186 t = clock() - t;
1187
1188/* printf("%d\n", sum); */
1189 *ignore = sum;
1190
1191 return (double) num_trials * CLOCKS_PER_SEC / t;
1192}
1193
1194
1195/*
1196 * srtp_validate() verifies the correctness of libsrtp by comparing
1197 * some computed packets against some pre-computed reference values.
1198 * These packets were made with the default SRTP policy.
1199 */
1200
1201
jfigus857009c2014-11-05 11:17:43 -05001202srtp_err_status_t
Cullen Jennings235513a2005-09-21 22:51:36 +00001203srtp_validate() {
Marcus Sundberg410faaa2005-09-29 12:36:43 +00001204 uint8_t srtp_plaintext_ref[28] = {
Cullen Jennings235513a2005-09-21 22:51:36 +00001205 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1206 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
1207 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1208 0xab, 0xab, 0xab, 0xab
1209 };
Marcus Sundberg410faaa2005-09-29 12:36:43 +00001210 uint8_t srtp_plaintext[38] = {
Cullen Jennings235513a2005-09-21 22:51:36 +00001211 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1212 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
1213 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1214 0xab, 0xab, 0xab, 0xab, 0x00, 0x00, 0x00, 0x00,
1215 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1216 };
Marcus Sundberg410faaa2005-09-29 12:36:43 +00001217 uint8_t srtp_ciphertext[38] = {
Cullen Jennings235513a2005-09-21 22:51:36 +00001218 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1219 0xca, 0xfe, 0xba, 0xbe, 0x4e, 0x55, 0xdc, 0x4c,
1220 0xe7, 0x99, 0x78, 0xd8, 0x8c, 0xa4, 0xd2, 0x15,
1221 0x94, 0x9d, 0x24, 0x02, 0xb7, 0x8d, 0x6a, 0xcc,
1222 0x99, 0xea, 0x17, 0x9b, 0x8d, 0xbb
1223 };
1224 srtp_t srtp_snd, srtp_recv;
jfigus857009c2014-11-05 11:17:43 -05001225 srtp_err_status_t status;
Cullen Jennings235513a2005-09-21 22:51:36 +00001226 int len;
1227 srtp_policy_t policy;
1228
1229 /*
1230 * create a session with a single stream using the default srtp
1231 * policy and with the SSRC value 0xcafebabe
1232 */
jfigus857009c2014-11-05 11:17:43 -05001233 srtp_crypto_policy_set_rtp_default(&policy.rtp);
1234 srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
Cullen Jennings235513a2005-09-21 22:51:36 +00001235 policy.ssrc.type = ssrc_specific;
1236 policy.ssrc.value = 0xcafebabe;
1237 policy.key = test_key;
Jonathan Lennoxa1242f82010-05-17 21:46:04 +00001238 policy.ekt = NULL;
1239 policy.window_size = 128;
Jonathan Lennoxdcee5c62010-05-17 22:08:40 +00001240 policy.allow_repeat_tx = 0;
Cullen Jennings235513a2005-09-21 22:51:36 +00001241 policy.next = NULL;
1242
1243 status = srtp_create(&srtp_snd, &policy);
1244 if (status)
1245 return status;
1246
1247 /*
1248 * protect plaintext, then compare with ciphertext
1249 */
1250 len = 28;
1251 status = srtp_protect(srtp_snd, srtp_plaintext, &len);
1252 if (status || (len != 38))
jfigus857009c2014-11-05 11:17:43 -05001253 return srtp_err_status_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +00001254
1255 debug_print(mod_driver, "ciphertext:\n %s",
1256 octet_string_hex_string(srtp_plaintext, len));
1257 debug_print(mod_driver, "ciphertext reference:\n %s",
1258 octet_string_hex_string(srtp_ciphertext, len));
1259
1260 if (octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len))
jfigus857009c2014-11-05 11:17:43 -05001261 return srtp_err_status_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +00001262
1263 /*
1264 * create a receiver session context comparable to the one created
1265 * above - we need to do this so that the replay checking doesn't
1266 * complain
1267 */
1268 status = srtp_create(&srtp_recv, &policy);
1269 if (status)
1270 return status;
1271
1272 /*
1273 * unprotect ciphertext, then compare with plaintext
1274 */
1275 status = srtp_unprotect(srtp_recv, srtp_ciphertext, &len);
1276 if (status || (len != 28))
1277 return status;
1278
1279 if (octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len))
jfigus857009c2014-11-05 11:17:43 -05001280 return srtp_err_status_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +00001281
Jonathan Lennox80c4c832010-05-17 19:30:28 +00001282 status = srtp_dealloc(srtp_snd);
1283 if (status)
1284 return status;
1285
1286 status = srtp_dealloc(srtp_recv);
1287 if (status)
1288 return status;
1289
jfigus857009c2014-11-05 11:17:43 -05001290 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +00001291}
1292
1293
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001294/*
1295 * srtp_validate_aes_256() verifies the correctness of libsrtp by comparing
1296 * some computed packets against some pre-computed reference values.
1297 * These packets were made with the AES-CM-256/HMAC-SHA-1-80 policy.
1298 */
1299
1300
jfigus857009c2014-11-05 11:17:43 -05001301srtp_err_status_t
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001302srtp_validate_aes_256() {
Jonathan Lennox75b36872010-05-21 00:30:21 +00001303 unsigned char aes_256_test_key[46] = {
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001304 0xf0, 0xf0, 0x49, 0x14, 0xb5, 0x13, 0xf2, 0x76,
1305 0x3a, 0x1b, 0x1f, 0xa1, 0x30, 0xf1, 0x0e, 0x29,
1306 0x98, 0xf6, 0xf6, 0xe4, 0x3e, 0x43, 0x09, 0xd1,
1307 0xe6, 0x22, 0xa0, 0xe3, 0x32, 0xb9, 0xf1, 0xb6,
1308
1309 0x3b, 0x04, 0x80, 0x3d, 0xe5, 0x1e, 0xe7, 0xc9,
1310 0x64, 0x23, 0xab, 0x5b, 0x78, 0xd2
1311 };
1312 uint8_t srtp_plaintext_ref[28] = {
1313 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1314 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
1315 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1316 0xab, 0xab, 0xab, 0xab
1317 };
1318 uint8_t srtp_plaintext[38] = {
1319 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1320 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
1321 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1322 0xab, 0xab, 0xab, 0xab, 0x00, 0x00, 0x00, 0x00,
1323 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1324 };
1325 uint8_t srtp_ciphertext[38] = {
1326 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1327 0xca, 0xfe, 0xba, 0xbe, 0xf1, 0xd9, 0xde, 0x17,
1328 0xff, 0x25, 0x1f, 0xf1, 0xaa, 0x00, 0x77, 0x74,
1329 0xb0, 0xb4, 0xb4, 0x0d, 0xa0, 0x8d, 0x9d, 0x9a,
1330 0x5b, 0x3a, 0x55, 0xd8, 0x87, 0x3b
1331 };
1332 srtp_t srtp_snd, srtp_recv;
jfigus857009c2014-11-05 11:17:43 -05001333 srtp_err_status_t status;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001334 int len;
1335 srtp_policy_t policy;
1336
1337 /*
1338 * create a session with a single stream using the default srtp
1339 * policy and with the SSRC value 0xcafebabe
1340 */
jfigus857009c2014-11-05 11:17:43 -05001341 srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(&policy.rtp);
1342 srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(&policy.rtcp);
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001343 policy.ssrc.type = ssrc_specific;
1344 policy.ssrc.value = 0xcafebabe;
Jonathan Lennox75b36872010-05-21 00:30:21 +00001345 policy.key = aes_256_test_key;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001346 policy.ekt = NULL;
1347 policy.window_size = 128;
1348 policy.allow_repeat_tx = 0;
1349 policy.next = NULL;
1350
1351 status = srtp_create(&srtp_snd, &policy);
1352 if (status)
1353 return status;
1354
1355 /*
1356 * protect plaintext, then compare with ciphertext
1357 */
1358 len = 28;
1359 status = srtp_protect(srtp_snd, srtp_plaintext, &len);
1360 if (status || (len != 38))
jfigus857009c2014-11-05 11:17:43 -05001361 return srtp_err_status_fail;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001362
1363 debug_print(mod_driver, "ciphertext:\n %s",
1364 octet_string_hex_string(srtp_plaintext, len));
1365 debug_print(mod_driver, "ciphertext reference:\n %s",
1366 octet_string_hex_string(srtp_ciphertext, len));
1367
1368 if (octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len))
jfigus857009c2014-11-05 11:17:43 -05001369 return srtp_err_status_fail;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001370
1371 /*
1372 * create a receiver session context comparable to the one created
1373 * above - we need to do this so that the replay checking doesn't
1374 * complain
1375 */
1376 status = srtp_create(&srtp_recv, &policy);
1377 if (status)
1378 return status;
1379
1380 /*
1381 * unprotect ciphertext, then compare with plaintext
1382 */
1383 status = srtp_unprotect(srtp_recv, srtp_ciphertext, &len);
1384 if (status || (len != 28))
1385 return status;
1386
1387 if (octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len))
jfigus857009c2014-11-05 11:17:43 -05001388 return srtp_err_status_fail;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001389
1390 status = srtp_dealloc(srtp_snd);
1391 if (status)
1392 return status;
1393
1394 status = srtp_dealloc(srtp_recv);
1395 if (status)
1396 return status;
1397
jfigus857009c2014-11-05 11:17:43 -05001398 return srtp_err_status_ok;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001399}
1400
1401
jfigus857009c2014-11-05 11:17:43 -05001402srtp_err_status_t
Cullen Jennings235513a2005-09-21 22:51:36 +00001403srtp_create_big_policy(srtp_policy_t **list) {
1404 extern const srtp_policy_t *policy_array[];
1405 srtp_policy_t *p, *tmp;
1406 int i = 0;
1407 uint32_t ssrc = 0;
1408
1409 /* sanity checking */
1410 if ((list == NULL) || (policy_array[0] == NULL))
jfigus857009c2014-11-05 11:17:43 -05001411 return srtp_err_status_bad_param;
Cullen Jennings235513a2005-09-21 22:51:36 +00001412
1413 /*
1414 * loop over policy list, mallocing a new list and copying values
1415 * into it (and incrementing the SSRC value as we go along)
1416 */
1417 tmp = NULL;
1418 while (policy_array[i] != NULL) {
Derek MacDonald17127da2006-07-12 22:22:08 +00001419 p = (srtp_policy_t*) malloc(sizeof(srtp_policy_t));
Cullen Jennings235513a2005-09-21 22:51:36 +00001420 if (p == NULL)
jfigus857009c2014-11-05 11:17:43 -05001421 return srtp_err_status_bad_param;
Cullen Jennings235513a2005-09-21 22:51:36 +00001422 memcpy(p, policy_array[i], sizeof(srtp_policy_t));
1423 p->ssrc.type = ssrc_specific;
1424 p->ssrc.value = ssrc++;
1425 p->next = tmp;
1426 tmp = p;
1427 i++;
1428 }
1429 *list = p;
1430
jfigus857009c2014-11-05 11:17:43 -05001431 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +00001432}
1433
jfigus857009c2014-11-05 11:17:43 -05001434srtp_err_status_t
Jonathan Lennox80c4c832010-05-17 19:30:28 +00001435srtp_dealloc_big_policy(srtp_policy_t *list) {
1436 srtp_policy_t *p, *next;
1437
1438 for (p = list; p != NULL; p = next) {
1439 next = p->next;
1440 free(p);
1441 }
1442
jfigus857009c2014-11-05 11:17:43 -05001443 return srtp_err_status_ok;
Jonathan Lennox80c4c832010-05-17 19:30:28 +00001444}
1445
1446
jfigus857009c2014-11-05 11:17:43 -05001447srtp_err_status_t
Cullen Jennings235513a2005-09-21 22:51:36 +00001448srtp_test_remove_stream() {
jfigus857009c2014-11-05 11:17:43 -05001449 srtp_err_status_t status;
Jonathan Lennoxad741b22010-05-27 19:23:05 +00001450 srtp_policy_t *policy_list, policy;
Cullen Jennings235513a2005-09-21 22:51:36 +00001451 srtp_t session;
1452 srtp_stream_t stream;
1453 /*
1454 * srtp_get_stream() is a libSRTP internal function that we declare
1455 * here so that we can use it to verify the correct operation of the
1456 * library
1457 */
1458 extern srtp_stream_t srtp_get_stream(srtp_t srtp, uint32_t ssrc);
1459
1460
1461 status = srtp_create_big_policy(&policy_list);
1462 if (status)
1463 return status;
1464
1465 status = srtp_create(&session, policy_list);
1466 if (status)
1467 return status;
1468
1469 /*
1470 * check for false positives by trying to remove a stream that's not
1471 * in the session
1472 */
1473 status = srtp_remove_stream(session, htonl(0xaaaaaaaa));
jfigus857009c2014-11-05 11:17:43 -05001474 if (status != srtp_err_status_no_ctx)
1475 return srtp_err_status_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +00001476
1477 /*
1478 * check for false negatives by removing stream 0x1, then
1479 * searching for streams 0x0 and 0x2
1480 */
1481 status = srtp_remove_stream(session, htonl(0x1));
jfigus857009c2014-11-05 11:17:43 -05001482 if (status != srtp_err_status_ok)
1483 return srtp_err_status_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +00001484 stream = srtp_get_stream(session, htonl(0x0));
1485 if (stream == NULL)
jfigus857009c2014-11-05 11:17:43 -05001486 return srtp_err_status_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +00001487 stream = srtp_get_stream(session, htonl(0x2));
1488 if (stream == NULL)
jfigus857009c2014-11-05 11:17:43 -05001489 return srtp_err_status_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +00001490
Jonathan Lennox80c4c832010-05-17 19:30:28 +00001491 status = srtp_dealloc(session);
jfigus857009c2014-11-05 11:17:43 -05001492 if (status != srtp_err_status_ok)
Jonathan Lennox80c4c832010-05-17 19:30:28 +00001493 return status;
1494
1495 status = srtp_dealloc_big_policy(policy_list);
jfigus857009c2014-11-05 11:17:43 -05001496 if (status != srtp_err_status_ok)
Jonathan Lennox80c4c832010-05-17 19:30:28 +00001497 return status;
1498
Jonathan Lennoxad741b22010-05-27 19:23:05 +00001499 /* Now test adding and removing a single stream */
jfigus857009c2014-11-05 11:17:43 -05001500 srtp_crypto_policy_set_rtp_default(&policy.rtp);
1501 srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
Jonathan Lennoxad741b22010-05-27 19:23:05 +00001502 policy.ssrc.type = ssrc_specific;
1503 policy.ssrc.value = 0xcafebabe;
1504 policy.key = test_key;
1505 policy.ekt = NULL;
1506 policy.window_size = 128;
1507 policy.allow_repeat_tx = 0;
1508 policy.next = NULL;
1509
1510 status = srtp_create(&session, NULL);
jfigus857009c2014-11-05 11:17:43 -05001511 if (status != srtp_err_status_ok)
Jonathan Lennoxad741b22010-05-27 19:23:05 +00001512 return status;
1513
1514 status = srtp_add_stream(session, &policy);
jfigus857009c2014-11-05 11:17:43 -05001515 if (status != srtp_err_status_ok)
Jonathan Lennoxad741b22010-05-27 19:23:05 +00001516 return status;
1517
1518 status = srtp_remove_stream(session, htonl(0xcafebabe));
jfigus857009c2014-11-05 11:17:43 -05001519 if (status != srtp_err_status_ok)
Jonathan Lennoxad741b22010-05-27 19:23:05 +00001520 return status;
1521
1522 status = srtp_dealloc(session);
jfigus857009c2014-11-05 11:17:43 -05001523 if (status != srtp_err_status_ok)
Jonathan Lennoxad741b22010-05-27 19:23:05 +00001524 return status;
1525
jfigus857009c2014-11-05 11:17:43 -05001526 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +00001527}
1528
1529/*
1530 * srtp policy definitions - these definitions are used above
1531 */
1532
jfigus8c36da22013-10-01 16:41:19 -04001533unsigned char test_key[46] = {
Cullen Jennings235513a2005-09-21 22:51:36 +00001534 0xe1, 0xf9, 0x7a, 0x0d, 0x3e, 0x01, 0x8b, 0xe0,
1535 0xd6, 0x4f, 0xa3, 0x2c, 0x06, 0xde, 0x41, 0x39,
1536 0x0e, 0xc6, 0x75, 0xad, 0x49, 0x8a, 0xfe, 0xeb,
jfigus8c36da22013-10-01 16:41:19 -04001537 0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6, 0xc1, 0x73,
1538 0xc3, 0x17, 0xf2, 0xda, 0xbe, 0x35, 0x77, 0x93,
Cullen Jennings235513a2005-09-21 22:51:36 +00001539 0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6
1540};
1541
1542
1543const srtp_policy_t default_policy = {
1544 { ssrc_any_outbound, 0 }, /* SSRC */
1545 { /* SRTP policy */
1546 AES_128_ICM, /* cipher type */
1547 30, /* cipher key length in octets */
1548 HMAC_SHA1, /* authentication func type */
1549 16, /* auth key length in octets */
1550 10, /* auth tag length in octets */
1551 sec_serv_conf_and_auth /* security services flag */
1552 },
1553 { /* SRTCP policy */
1554 AES_128_ICM, /* cipher type */
1555 30, /* cipher key length in octets */
1556 HMAC_SHA1, /* authentication func type */
1557 16, /* auth key length in octets */
1558 10, /* auth tag length in octets */
1559 sec_serv_conf_and_auth /* security services flag */
1560 },
1561 test_key,
David McGrew79870d62007-06-15 18:17:39 +00001562 NULL, /* indicates that EKT is not in use */
Jonathan Lennoxa1242f82010-05-17 21:46:04 +00001563 128, /* replay window size */
Jonathan Lennoxdcee5c62010-05-17 22:08:40 +00001564 0, /* retransmission not allowed */
Cullen Jennings235513a2005-09-21 22:51:36 +00001565 NULL
1566};
1567
1568const srtp_policy_t aes_tmmh_policy = {
1569 { ssrc_any_outbound, 0 }, /* SSRC */
1570 {
1571 AES_128_ICM, /* cipher type */
1572 30, /* cipher key length in octets */
1573 UST_TMMHv2, /* authentication func type */
1574 94, /* auth key length in octets */
1575 4, /* auth tag length in octets */
1576 sec_serv_conf_and_auth /* security services flag */
1577 },
1578 {
1579 AES_128_ICM, /* cipher type */
1580 30, /* cipher key length in octets */
1581 UST_TMMHv2, /* authentication func type */
1582 94, /* auth key length in octets */
1583 4, /* auth tag length in octets */
1584 sec_serv_conf_and_auth /* security services flag */
1585 },
1586 test_key,
David McGrew79870d62007-06-15 18:17:39 +00001587 NULL, /* indicates that EKT is not in use */
Jonathan Lennoxa1242f82010-05-17 21:46:04 +00001588 128, /* replay window size */
Jonathan Lennoxdcee5c62010-05-17 22:08:40 +00001589 0, /* retransmission not allowed */
Cullen Jennings235513a2005-09-21 22:51:36 +00001590 NULL
1591};
1592
1593const srtp_policy_t tmmh_only_policy = {
1594 { ssrc_any_outbound, 0 }, /* SSRC */
1595 {
1596 AES_128_ICM, /* cipher type */
1597 30, /* cipher key length in octets */
1598 UST_TMMHv2, /* authentication func type */
1599 94, /* auth key length in octets */
1600 4, /* auth tag length in octets */
1601 sec_serv_auth /* security services flag */
1602 },
1603 {
1604 AES_128_ICM, /* cipher type */
1605 30, /* cipher key length in octets */
1606 UST_TMMHv2, /* authentication func type */
1607 94, /* auth key length in octets */
1608 4, /* auth tag length in octets */
1609 sec_serv_auth /* security services flag */
1610 },
1611 test_key,
David McGrew79870d62007-06-15 18:17:39 +00001612 NULL, /* indicates that EKT is not in use */
Jonathan Lennoxa1242f82010-05-17 21:46:04 +00001613 128, /* replay window size */
Jonathan Lennoxdcee5c62010-05-17 22:08:40 +00001614 0, /* retransmission not allowed */
Cullen Jennings235513a2005-09-21 22:51:36 +00001615 NULL
1616};
1617
1618const srtp_policy_t aes_only_policy = {
1619 { ssrc_any_outbound, 0 }, /* SSRC */
1620 {
1621 AES_128_ICM, /* cipher type */
1622 30, /* cipher key length in octets */
1623 NULL_AUTH, /* authentication func type */
1624 0, /* auth key length in octets */
1625 0, /* auth tag length in octets */
1626 sec_serv_conf /* security services flag */
1627 },
1628 {
1629 AES_128_ICM, /* cipher type */
1630 30, /* cipher key length in octets */
1631 NULL_AUTH, /* authentication func type */
1632 0, /* auth key length in octets */
1633 0, /* auth tag length in octets */
1634 sec_serv_conf /* security services flag */
1635 },
1636 test_key,
David McGrew79870d62007-06-15 18:17:39 +00001637 NULL, /* indicates that EKT is not in use */
Jonathan Lennoxa1242f82010-05-17 21:46:04 +00001638 128, /* replay window size */
Jonathan Lennoxdcee5c62010-05-17 22:08:40 +00001639 0, /* retransmission not allowed */
Cullen Jennings235513a2005-09-21 22:51:36 +00001640 NULL
1641};
1642
1643const srtp_policy_t hmac_only_policy = {
1644 { ssrc_any_outbound, 0 }, /* SSRC */
1645 {
1646 NULL_CIPHER, /* cipher type */
1647 0, /* cipher key length in octets */
1648 HMAC_SHA1, /* authentication func type */
1649 20, /* auth key length in octets */
1650 4, /* auth tag length in octets */
1651 sec_serv_auth /* security services flag */
1652 },
1653 {
1654 NULL_CIPHER, /* cipher type */
1655 0, /* cipher key length in octets */
1656 HMAC_SHA1, /* authentication func type */
1657 20, /* auth key length in octets */
1658 4, /* auth tag length in octets */
1659 sec_serv_auth /* security services flag */
1660 },
1661 test_key,
David McGrew79870d62007-06-15 18:17:39 +00001662 NULL, /* indicates that EKT is not in use */
Jonathan Lennoxa1242f82010-05-17 21:46:04 +00001663 128, /* replay window size */
Jonathan Lennoxdcee5c62010-05-17 22:08:40 +00001664 0, /* retransmission not allowed */
Cullen Jennings235513a2005-09-21 22:51:36 +00001665 NULL
1666};
1667
jfigus8c36da22013-10-01 16:41:19 -04001668#ifdef OPENSSL
1669const srtp_policy_t aes128_gcm_8_policy = {
1670 { ssrc_any_outbound, 0 }, /* SSRC */
1671 { /* SRTP policy */
1672 AES_128_GCM, /* cipher type */
jfigus857009c2014-11-05 11:17:43 -05001673 SRTP_AES_128_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
jfigus8c36da22013-10-01 16:41:19 -04001674 NULL_AUTH, /* authentication func type */
1675 0, /* auth key length in octets */
1676 8, /* auth tag length in octets */
1677 sec_serv_conf_and_auth /* security services flag */
1678 },
1679 { /* SRTCP policy */
1680 AES_128_GCM, /* cipher type */
jfigus857009c2014-11-05 11:17:43 -05001681 SRTP_AES_128_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
jfigus8c36da22013-10-01 16:41:19 -04001682 NULL_AUTH, /* authentication func type */
1683 0, /* auth key length in octets */
1684 8, /* auth tag length in octets */
1685 sec_serv_conf_and_auth /* security services flag */
1686 },
1687 test_key,
1688 NULL, /* indicates that EKT is not in use */
1689 128, /* replay window size */
1690 0, /* retransmission not allowed */
1691 NULL
1692};
1693
1694const srtp_policy_t aes128_gcm_8_cauth_policy = {
1695 { ssrc_any_outbound, 0 }, /* SSRC */
1696 { /* SRTP policy */
1697 AES_128_GCM, /* cipher type */
jfigus857009c2014-11-05 11:17:43 -05001698 SRTP_AES_128_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
jfigus8c36da22013-10-01 16:41:19 -04001699 NULL_AUTH, /* authentication func type */
1700 0, /* auth key length in octets */
1701 8, /* auth tag length in octets */
1702 sec_serv_conf_and_auth /* security services flag */
1703 },
1704 { /* SRTCP policy */
1705 AES_128_GCM, /* cipher type */
jfigus857009c2014-11-05 11:17:43 -05001706 SRTP_AES_128_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
jfigus8c36da22013-10-01 16:41:19 -04001707 NULL_AUTH, /* authentication func type */
1708 0, /* auth key length in octets */
1709 8, /* auth tag length in octets */
1710 sec_serv_auth /* security services flag */
1711 },
1712 test_key,
1713 NULL, /* indicates that EKT is not in use */
1714 128, /* replay window size */
1715 0, /* retransmission not allowed */
1716 NULL
1717};
1718
1719const srtp_policy_t aes256_gcm_8_policy = {
1720 { ssrc_any_outbound, 0 }, /* SSRC */
1721 { /* SRTP policy */
1722 AES_256_GCM, /* cipher type */
jfigus857009c2014-11-05 11:17:43 -05001723 SRTP_AES_256_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
jfigus8c36da22013-10-01 16:41:19 -04001724 NULL_AUTH, /* authentication func type */
1725 0, /* auth key length in octets */
1726 8, /* auth tag length in octets */
1727 sec_serv_conf_and_auth /* security services flag */
1728 },
1729 { /* SRTCP policy */
1730 AES_256_GCM, /* cipher type */
jfigus857009c2014-11-05 11:17:43 -05001731 SRTP_AES_256_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
jfigus8c36da22013-10-01 16:41:19 -04001732 NULL_AUTH, /* authentication func type */
1733 0, /* auth key length in octets */
1734 8, /* auth tag length in octets */
1735 sec_serv_conf_and_auth /* security services flag */
1736 },
1737 test_key,
1738 NULL, /* indicates that EKT is not in use */
1739 128, /* replay window size */
1740 0, /* retransmission not allowed */
1741 NULL
1742};
1743
1744const srtp_policy_t aes256_gcm_8_cauth_policy = {
1745 { ssrc_any_outbound, 0 }, /* SSRC */
1746 { /* SRTP policy */
1747 AES_256_GCM, /* cipher type */
jfigus857009c2014-11-05 11:17:43 -05001748 SRTP_AES_256_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
jfigus8c36da22013-10-01 16:41:19 -04001749 NULL_AUTH, /* authentication func type */
1750 0, /* auth key length in octets */
1751 8, /* auth tag length in octets */
1752 sec_serv_conf_and_auth /* security services flag */
1753 },
1754 { /* SRTCP policy */
1755 AES_256_GCM, /* cipher type */
jfigus857009c2014-11-05 11:17:43 -05001756 SRTP_AES_256_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
jfigus8c36da22013-10-01 16:41:19 -04001757 NULL_AUTH, /* authentication func type */
1758 0, /* auth key length in octets */
1759 8, /* auth tag length in octets */
1760 sec_serv_auth /* security services flag */
1761 },
1762 test_key,
1763 NULL, /* indicates that EKT is not in use */
1764 128, /* replay window size */
1765 0, /* retransmission not allowed */
1766 NULL
1767};
1768#endif
1769
Cullen Jennings235513a2005-09-21 22:51:36 +00001770const srtp_policy_t null_policy = {
1771 { ssrc_any_outbound, 0 }, /* SSRC */
1772 {
1773 NULL_CIPHER, /* cipher type */
1774 0, /* cipher key length in octets */
1775 NULL_AUTH, /* authentication func type */
1776 0, /* auth key length in octets */
1777 0, /* auth tag length in octets */
1778 sec_serv_none /* security services flag */
1779 },
1780 {
1781 NULL_CIPHER, /* cipher type */
1782 0, /* cipher key length in octets */
1783 NULL_AUTH, /* authentication func type */
1784 0, /* auth key length in octets */
1785 0, /* auth tag length in octets */
1786 sec_serv_none /* security services flag */
1787 },
1788 test_key,
David McGrew79870d62007-06-15 18:17:39 +00001789 NULL, /* indicates that EKT is not in use */
Jonathan Lennoxa1242f82010-05-17 21:46:04 +00001790 128, /* replay window size */
Jonathan Lennoxdcee5c62010-05-17 22:08:40 +00001791 0, /* retransmission not allowed */
David McGrew79870d62007-06-15 18:17:39 +00001792 NULL
1793};
1794
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001795unsigned char test_256_key[46] = {
1796 0xf0, 0xf0, 0x49, 0x14, 0xb5, 0x13, 0xf2, 0x76,
1797 0x3a, 0x1b, 0x1f, 0xa1, 0x30, 0xf1, 0x0e, 0x29,
1798 0x98, 0xf6, 0xf6, 0xe4, 0x3e, 0x43, 0x09, 0xd1,
1799 0xe6, 0x22, 0xa0, 0xe3, 0x32, 0xb9, 0xf1, 0xb6,
1800
1801 0x3b, 0x04, 0x80, 0x3d, 0xe5, 0x1e, 0xe7, 0xc9,
1802 0x64, 0x23, 0xab, 0x5b, 0x78, 0xd2
1803};
1804
1805const srtp_policy_t aes_256_hmac_policy = {
1806 { ssrc_any_outbound, 0 }, /* SSRC */
1807 { /* SRTP policy */
1808 AES_ICM, /* cipher type */
1809 46, /* cipher key length in octets */
1810 HMAC_SHA1, /* authentication func type */
1811 20, /* auth key length in octets */
1812 10, /* auth tag length in octets */
1813 sec_serv_conf_and_auth /* security services flag */
1814 },
1815 { /* SRTCP policy */
1816 AES_ICM, /* cipher type */
1817 46, /* cipher key length in octets */
1818 HMAC_SHA1, /* authentication func type */
1819 20, /* auth key length in octets */
1820 10, /* auth tag length in octets */
1821 sec_serv_conf_and_auth /* security services flag */
1822 },
1823 test_256_key,
1824 NULL, /* indicates that EKT is not in use */
1825 128, /* replay window size */
1826 0, /* retransmission not allowed */
1827 NULL
1828};
1829
David McGrew79870d62007-06-15 18:17:39 +00001830uint8_t ekt_test_key[16] = {
1831 0x77, 0x26, 0x9d, 0xac, 0x16, 0xa3, 0x28, 0xca,
1832 0x8e, 0xc9, 0x68, 0x4b, 0xcc, 0xc4, 0xd2, 0x1b
1833};
1834
1835#include "ekt.h"
1836
jfigusc5887e72014-11-06 09:46:18 -05001837srtp_ekt_policy_ctx_t ekt_test_policy = {
David McGrew79870d62007-06-15 18:17:39 +00001838 0xa5a5, /* SPI */
jfigusc5887e72014-11-06 09:46:18 -05001839 SRTP_EKT_CIPHER_AES_128_ECB,
David McGrew79870d62007-06-15 18:17:39 +00001840 ekt_test_key,
1841 NULL
1842};
1843
1844const srtp_policy_t hmac_only_with_ekt_policy = {
1845 { ssrc_any_outbound, 0 }, /* SSRC */
1846 {
1847 NULL_CIPHER, /* cipher type */
1848 0, /* cipher key length in octets */
1849 HMAC_SHA1, /* authentication func type */
1850 20, /* auth key length in octets */
1851 4, /* auth tag length in octets */
1852 sec_serv_auth /* security services flag */
1853 },
1854 {
1855 NULL_CIPHER, /* cipher type */
1856 0, /* cipher key length in octets */
1857 HMAC_SHA1, /* authentication func type */
1858 20, /* auth key length in octets */
1859 4, /* auth tag length in octets */
1860 sec_serv_auth /* security services flag */
1861 },
1862 test_key,
1863 &ekt_test_policy, /* indicates that EKT is not in use */
Jonathan Lennoxa1242f82010-05-17 21:46:04 +00001864 128, /* replay window size */
Jonathan Lennoxdcee5c62010-05-17 22:08:40 +00001865 0, /* retransmission not allowed */
Cullen Jennings235513a2005-09-21 22:51:36 +00001866 NULL
1867};
1868
1869
1870/*
1871 * an array of pointers to the policies listed above
1872 *
1873 * This array is used to test various aspects of libSRTP for
1874 * different cryptographic policies. The order of the elements
1875 * matters - the timing test generates output that can be used
1876 * in a plot (see the gnuplot script file 'timing'). If you
1877 * add to this list, you should do it at the end.
1878 */
1879
1880#define USE_TMMH 0
1881
1882const srtp_policy_t *
1883policy_array[] = {
1884 &hmac_only_policy,
1885#if USE_TMMH
1886 &tmmh_only_policy,
1887#endif
1888 &aes_only_policy,
1889#if USE_TMMH
1890 &aes_tmmh_policy,
1891#endif
1892 &default_policy,
jfigus8c36da22013-10-01 16:41:19 -04001893#ifdef OPENSSL
1894 &aes128_gcm_8_policy,
1895 &aes128_gcm_8_cauth_policy,
1896 &aes256_gcm_8_policy,
1897 &aes256_gcm_8_cauth_policy,
1898#endif
Cullen Jennings235513a2005-09-21 22:51:36 +00001899 &null_policy,
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001900 &aes_256_hmac_policy,
David McGrew79870d62007-06-15 18:17:39 +00001901 &hmac_only_with_ekt_policy,
Cullen Jennings235513a2005-09-21 22:51:36 +00001902 NULL
1903};
1904
1905const srtp_policy_t wildcard_policy = {
1906 { ssrc_any_outbound, 0 }, /* SSRC */
1907 { /* SRTP policy */
1908 AES_128_ICM, /* cipher type */
1909 30, /* cipher key length in octets */
1910 HMAC_SHA1, /* authentication func type */
1911 16, /* auth key length in octets */
1912 10, /* auth tag length in octets */
1913 sec_serv_conf_and_auth /* security services flag */
1914 },
1915 { /* SRTCP policy */
1916 AES_128_ICM, /* cipher type */
1917 30, /* cipher key length in octets */
1918 HMAC_SHA1, /* authentication func type */
1919 16, /* auth key length in octets */
1920 10, /* auth tag length in octets */
1921 sec_serv_conf_and_auth /* security services flag */
1922 },
1923 test_key,
Jonathan Lennox28bd7c12010-05-15 00:23:19 +00001924 NULL,
Jonathan Lennoxa1242f82010-05-17 21:46:04 +00001925 128, /* replay window size */
Jonathan Lennoxdcee5c62010-05-17 22:08:40 +00001926 0, /* retransmission not allowed */
Cullen Jennings235513a2005-09-21 22:51:36 +00001927 NULL
1928};