blob: d16cacd9c0c1509583e69dca5fd79c65dc865890 [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() */
jfigus46d6b472014-11-14 16:42:01 -050051#include "util.h"
Cullen Jennings235513a2005-09-21 22:51:36 +000052
David McGrew3c45e0c2006-07-12 00:50:56 +000053#include "srtp_priv.h"
Cullen Jennings235513a2005-09-21 22:51:36 +000054
Marcus Sundberg1cbca882005-10-02 20:50:06 +000055#ifdef HAVE_NETINET_IN_H
56# include <netinet/in.h>
57#elif defined HAVE_WINSOCK2_H
58# include <winsock2.h>
59#endif
60
Cullen Jennings235513a2005-09-21 22:51:36 +000061#define PRINT_REFERENCE_PACKET 1
62
jfigus857009c2014-11-05 11:17:43 -050063srtp_err_status_t
Marcus Sundberga3f95fe2005-09-29 12:48:41 +000064srtp_validate(void);
Cullen Jennings235513a2005-09-21 22:51:36 +000065
jfigus857009c2014-11-05 11:17:43 -050066srtp_err_status_t
Jonathan Lennox5df951a2010-05-20 20:55:54 +000067srtp_validate_aes_256(void);
68
jfigus857009c2014-11-05 11:17:43 -050069srtp_err_status_t
Cullen Jennings235513a2005-09-21 22:51:36 +000070srtp_create_big_policy(srtp_policy_t **list);
71
jfigus857009c2014-11-05 11:17:43 -050072srtp_err_status_t
Jonathan Lennox80c4c832010-05-17 19:30:28 +000073srtp_dealloc_big_policy(srtp_policy_t *list);
74
jfigus857009c2014-11-05 11:17:43 -050075srtp_err_status_t
Marcus Sundberga3f95fe2005-09-29 12:48:41 +000076srtp_test_remove_stream(void);
Cullen Jennings235513a2005-09-21 22:51:36 +000077
78double
79srtp_bits_per_second(int msg_len_octets, const srtp_policy_t *policy);
80
81double
82srtp_rejections_per_second(int msg_len_octets, const srtp_policy_t *policy);
83
84void
85srtp_do_timing(const srtp_policy_t *policy);
86
87void
88srtp_do_rejection_timing(const srtp_policy_t *policy);
89
jfigus857009c2014-11-05 11:17:43 -050090srtp_err_status_t
Marcus Sundberga3f95fe2005-09-29 12:48:41 +000091srtp_test(const srtp_policy_t *policy);
Cullen Jennings235513a2005-09-21 22:51:36 +000092
jfigus857009c2014-11-05 11:17:43 -050093srtp_err_status_t
David McGrew9c70f292006-05-03 19:38:38 +000094srtcp_test(const srtp_policy_t *policy);
95
jfigus857009c2014-11-05 11:17:43 -050096srtp_err_status_t
Cullen Jennings235513a2005-09-21 22:51:36 +000097srtp_session_print_policy(srtp_t srtp);
98
jfigus857009c2014-11-05 11:17:43 -050099srtp_err_status_t
Cullen Jennings235513a2005-09-21 22:51:36 +0000100srtp_print_policy(const srtp_policy_t *policy);
101
102char *
103srtp_packet_to_string(srtp_hdr_t *hdr, int packet_len);
104
105double
106mips_estimate(int num_trials, int *ignore);
107
jfigus8c36da22013-10-01 16:41:19 -0400108extern uint8_t test_key[46];
Cullen Jennings235513a2005-09-21 22:51:36 +0000109
110void
111usage(char *prog_name) {
112 printf("usage: %s [ -t ][ -c ][ -v ][-d <debug_module> ]* [ -l ]\n"
113 " -t run timing test\n"
114 " -r run rejection timing test\n"
115 " -c run codec timing test\n"
116 " -v run validation tests\n"
117 " -d <mod> turn on debugging module <mod>\n"
118 " -l list debugging modules\n", prog_name);
119 exit(1);
120}
121
122/*
123 * The policy_array is a null-terminated array of policy structs. it
124 * is declared at the end of this file
125 */
126
127extern const srtp_policy_t *policy_array[];
128
129
130/* the wildcard_policy is declared below; it has a wildcard ssrc */
131
132extern const srtp_policy_t wildcard_policy;
133
134/*
135 * mod_driver debug module - debugging module for this test driver
136 *
137 * we use the crypto_kernel debugging system in this driver, which
138 * makes the interface uniform and increases portability
139 */
140
141debug_module_t mod_driver = {
142 0, /* debugging is off by default */
143 "driver" /* printable name for module */
144};
145
146int
147main (int argc, char *argv[]) {
Jonathan Lennoxb4842bf2010-05-15 03:55:24 +0000148 int q;
Cullen Jennings235513a2005-09-21 22:51:36 +0000149 unsigned do_timing_test = 0;
150 unsigned do_rejection_test = 0;
151 unsigned do_codec_timing = 0;
152 unsigned do_validation = 0;
153 unsigned do_list_mods = 0;
jfigus857009c2014-11-05 11:17:43 -0500154 srtp_err_status_t status;
Cullen Jennings235513a2005-09-21 22:51:36 +0000155
156 /*
157 * verify that the compiler has interpreted the header data
158 * structure srtp_hdr_t correctly
159 */
160 if (sizeof(srtp_hdr_t) != 12) {
David McGrew1a2ab2c2006-07-12 22:48:44 +0000161 printf("error: srtp_hdr_t has incorrect size"
162 "(size is %ld bytes, expected 12)\n",
Jonathan Lennoxf3132b92010-05-14 22:54:10 +0000163 (long)sizeof(srtp_hdr_t));
Cullen Jennings235513a2005-09-21 22:51:36 +0000164 exit(1);
165 }
166
167 /* initialize srtp library */
168 status = srtp_init();
169 if (status) {
170 printf("error: srtp init failed with error code %d\n", status);
171 exit(1);
172 }
173
174 /* load srtp_driver debug module */
175 status = crypto_kernel_load_debug_module(&mod_driver);
176 if (status) {
177 printf("error: load of srtp_driver debug module failed "
178 "with error code %d\n", status);
179 exit(1);
180 }
181
182 /* process input arguments */
183 while (1) {
David McGrew79bd3012006-07-17 20:41:21 +0000184 q = getopt_s(argc, argv, "trcvld:");
Cullen Jennings235513a2005-09-21 22:51:36 +0000185 if (q == -1)
186 break;
187 switch (q) {
188 case 't':
189 do_timing_test = 1;
190 break;
191 case 'r':
192 do_rejection_test = 1;
193 break;
194 case 'c':
195 do_codec_timing = 1;
196 break;
197 case 'v':
198 do_validation = 1;
199 break;
200 case 'l':
201 do_list_mods = 1;
202 break;
203 case 'd':
David McGrew79bd3012006-07-17 20:41:21 +0000204 status = crypto_kernel_set_debug_module(optarg_s, 1);
Cullen Jennings235513a2005-09-21 22:51:36 +0000205 if (status) {
David McGrew79bd3012006-07-17 20:41:21 +0000206 printf("error: set debug module (%s) failed\n", optarg_s);
Cullen Jennings235513a2005-09-21 22:51:36 +0000207 exit(1);
208 }
209 break;
210 default:
211 usage(argv[0]);
212 }
213 }
214
215 if (!do_validation && !do_timing_test && !do_codec_timing
216 && !do_list_mods && !do_rejection_test)
217 usage(argv[0]);
218
219 if (do_list_mods) {
220 status = crypto_kernel_list_debug_modules();
221 if (status) {
222 printf("error: list of debug modules failed\n");
223 exit(1);
224 }
225 }
226
227 if (do_validation) {
228 const srtp_policy_t **policy = policy_array;
229 srtp_policy_t *big_policy;
230
David McGrew9c70f292006-05-03 19:38:38 +0000231 /* loop over policy array, testing srtp and srtcp for each policy */
Cullen Jennings235513a2005-09-21 22:51:36 +0000232 while (*policy != NULL) {
233 printf("testing srtp_protect and srtp_unprotect\n");
jfigus857009c2014-11-05 11:17:43 -0500234 if (srtp_test(*policy) == srtp_err_status_ok)
Cullen Jennings235513a2005-09-21 22:51:36 +0000235 printf("passed\n\n");
236 else {
237 printf("failed\n");
238 exit(1);
239 }
David McGrew9c70f292006-05-03 19:38:38 +0000240 printf("testing srtp_protect_rtcp and srtp_unprotect_rtcp\n");
jfigus857009c2014-11-05 11:17:43 -0500241 if (srtcp_test(*policy) == srtp_err_status_ok)
David McGrew9c70f292006-05-03 19:38:38 +0000242 printf("passed\n\n");
243 else {
244 printf("failed\n");
245 exit(1);
246 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000247 policy++;
248 }
249
250 /* create a big policy list and run tests on it */
251 status = srtp_create_big_policy(&big_policy);
252 if (status) {
253 printf("unexpected failure with error code %d\n", status);
254 exit(1);
255 }
256 printf("testing srtp_protect and srtp_unprotect with big policy\n");
jfigus857009c2014-11-05 11:17:43 -0500257 if (srtp_test(big_policy) == srtp_err_status_ok)
Cullen Jennings235513a2005-09-21 22:51:36 +0000258 printf("passed\n\n");
259 else {
260 printf("failed\n");
261 exit(1);
262 }
Jonathan Lennox80c4c832010-05-17 19:30:28 +0000263 status = srtp_dealloc_big_policy(big_policy);
264 if (status) {
265 printf("unexpected failure with error code %d\n", status);
266 exit(1);
267 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000268
269 /* run test on wildcard policy */
270 printf("testing srtp_protect and srtp_unprotect on "
271 "wildcard ssrc policy\n");
jfigus857009c2014-11-05 11:17:43 -0500272 if (srtp_test(&wildcard_policy) == srtp_err_status_ok)
Cullen Jennings235513a2005-09-21 22:51:36 +0000273 printf("passed\n\n");
274 else {
275 printf("failed\n");
276 exit(1);
277 }
278
279 /*
280 * run validation test against the reference packets - note
281 * that this test only covers the default policy
282 */
283 printf("testing srtp_protect and srtp_unprotect against "
284 "reference packets\n");
jfigus857009c2014-11-05 11:17:43 -0500285 if (srtp_validate() == srtp_err_status_ok)
Cullen Jennings235513a2005-09-21 22:51:36 +0000286 printf("passed\n\n");
287 else {
288 printf("failed\n");
289 exit(1);
290 }
291
jfigusa14b5a02013-03-29 12:24:12 -0400292//FIXME: need to get this working with the OpenSSL AES module
293#ifndef OPENSSL
Cullen Jennings235513a2005-09-21 22:51:36 +0000294 /*
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000295 * run validation test against the reference packets for
296 * AES-256
297 */
298 printf("testing srtp_protect and srtp_unprotect against "
299 "reference packets (AES-256)\n");
jfigus857009c2014-11-05 11:17:43 -0500300 if (srtp_validate_aes_256() == srtp_err_status_ok)
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000301 printf("passed\n\n");
302 else {
303 printf("failed\n");
304 exit(1);
305 }
jfigusa14b5a02013-03-29 12:24:12 -0400306#endif
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000307
308 /*
Cullen Jennings235513a2005-09-21 22:51:36 +0000309 * test the function srtp_remove_stream()
310 */
311 printf("testing srtp_remove_stream()...");
jfigus857009c2014-11-05 11:17:43 -0500312 if (srtp_test_remove_stream() == srtp_err_status_ok)
Cullen Jennings235513a2005-09-21 22:51:36 +0000313 printf("passed\n");
314 else {
315 printf("failed\n");
316 exit(1);
317 }
318 }
319
320 if (do_timing_test) {
321 const srtp_policy_t **policy = policy_array;
322
323 /* loop over policies, run timing test for each */
324 while (*policy != NULL) {
325 srtp_print_policy(*policy);
326 srtp_do_timing(*policy);
327 policy++;
328 }
329 }
330
331 if (do_rejection_test) {
332 const srtp_policy_t **policy = policy_array;
333
334 /* loop over policies, run rejection timing test for each */
335 while (*policy != NULL) {
336 srtp_print_policy(*policy);
337 srtp_do_rejection_timing(*policy);
338 policy++;
339 }
340 }
341
342 if (do_codec_timing) {
343 srtp_policy_t policy;
344 int ignore;
345 double mips = mips_estimate(1000000000, &ignore);
346
jfigus857009c2014-11-05 11:17:43 -0500347 srtp_crypto_policy_set_rtp_default(&policy.rtp);
348 srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
Cullen Jennings235513a2005-09-21 22:51:36 +0000349 policy.ssrc.type = ssrc_specific;
350 policy.ssrc.value = 0xdecafbad;
351 policy.key = test_key;
Jonathan Lennoxa1242f82010-05-17 21:46:04 +0000352 policy.ekt = NULL;
353 policy.window_size = 128;
Jonathan Lennoxdcee5c62010-05-17 22:08:40 +0000354 policy.allow_repeat_tx = 0;
Cullen Jennings235513a2005-09-21 22:51:36 +0000355 policy.next = NULL;
356
357 printf("mips estimate: %e\n", mips);
358
359 printf("testing srtp processing time for voice codecs:\n");
360 printf("codec\t\tlength (octets)\t\tsrtp instructions/second\n");
361 printf("G.711\t\t%d\t\t\t%e\n", 80,
362 (double) mips * (80 * 8) /
363 srtp_bits_per_second(80, &policy) / .01 );
364 printf("G.711\t\t%d\t\t\t%e\n", 160,
365 (double) mips * (160 * 8) /
366 srtp_bits_per_second(160, &policy) / .02);
367 printf("G.726-32\t%d\t\t\t%e\n", 40,
368 (double) mips * (40 * 8) /
369 srtp_bits_per_second(40, &policy) / .01 );
370 printf("G.726-32\t%d\t\t\t%e\n", 80,
371 (double) mips * (80 * 8) /
372 srtp_bits_per_second(80, &policy) / .02);
373 printf("G.729\t\t%d\t\t\t%e\n", 10,
374 (double) mips * (10 * 8) /
375 srtp_bits_per_second(10, &policy) / .01 );
376 printf("G.729\t\t%d\t\t\t%e\n", 20,
377 (double) mips * (20 * 8) /
378 srtp_bits_per_second(20, &policy) / .02 );
David McGrew93451082006-09-18 13:41:35 +0000379 printf("Wideband\t%d\t\t\t%e\n", 320,
380 (double) mips * (320 * 8) /
381 srtp_bits_per_second(320, &policy) / .01 );
382 printf("Wideband\t%d\t\t\t%e\n", 640,
383 (double) mips * (640 * 8) /
384 srtp_bits_per_second(640, &policy) / .02 );
Cullen Jennings235513a2005-09-21 22:51:36 +0000385 }
386
Jonathan Lennoxdfb30842010-05-15 04:52:01 +0000387 status = srtp_shutdown();
388 if (status) {
389 printf("error: srtp shutdown failed with error code %d\n", status);
390 exit(1);
391 }
392
Cullen Jennings235513a2005-09-21 22:51:36 +0000393 return 0;
394}
395
396
397
398/*
399 * srtp_create_test_packet(len, ssrc) returns a pointer to a
400 * (malloced) example RTP packet whose data field has the length given
401 * by pkt_octet_len and the SSRC value ssrc. The total length of the
402 * packet is twelve octets longer, since the header is at the
403 * beginning. There is room at the end of the packet for a trailer,
404 * and the four octets following the packet are filled with 0xff
405 * values to enable testing for overwrites.
406 *
407 * note that the location of the test packet can (and should) be
408 * deallocated with the free() call once it is no longer needed.
409 */
410
411srtp_hdr_t *
412srtp_create_test_packet(int pkt_octet_len, uint32_t ssrc) {
413 int i;
Marcus Sundberg410faaa2005-09-29 12:36:43 +0000414 uint8_t *buffer;
Cullen Jennings235513a2005-09-21 22:51:36 +0000415 srtp_hdr_t *hdr;
416 int bytes_in_hdr = 12;
417
418 /* allocate memory for test packet */
Derek MacDonald17127da2006-07-12 22:22:08 +0000419 hdr = (srtp_hdr_t*) malloc(pkt_octet_len + bytes_in_hdr
Cullen Jennings235513a2005-09-21 22:51:36 +0000420 + SRTP_MAX_TRAILER_LEN + 4);
421 if (!hdr)
422 return NULL;
423
424 hdr->version = 2; /* RTP version two */
425 hdr->p = 0; /* no padding needed */
426 hdr->x = 0; /* no header extension */
427 hdr->cc = 0; /* no CSRCs */
428 hdr->m = 0; /* marker bit */
429 hdr->pt = 0xf; /* payload type */
430 hdr->seq = htons(0x1234); /* sequence number */
431 hdr->ts = htonl(0xdecafbad); /* timestamp */
432 hdr->ssrc = htonl(ssrc); /* synch. source */
433
Marcus Sundberg410faaa2005-09-29 12:36:43 +0000434 buffer = (uint8_t *)hdr;
Cullen Jennings235513a2005-09-21 22:51:36 +0000435 buffer += bytes_in_hdr;
436
437 /* set RTP data to 0xab */
438 for (i=0; i < pkt_octet_len; i++)
439 *buffer++ = 0xab;
440
441 /* set post-data value to 0xffff to enable overrun checking */
442 for (i=0; i < SRTP_MAX_TRAILER_LEN+4; i++)
443 *buffer++ = 0xff;
444
445 return hdr;
446}
447
448void
449srtp_do_timing(const srtp_policy_t *policy) {
450 int len;
451
452 /*
453 * note: the output of this function is formatted so that it
454 * can be used in gnuplot. '#' indicates a comment, and "\r\n"
455 * terminates a record
456 */
457
458 printf("# testing srtp throughput:\r\n");
459 printf("# mesg length (octets)\tthroughput (megabits per second)\r\n");
460
461 for (len=16; len <= 2048; len *= 2)
462 printf("%d\t\t\t%f\r\n", len,
463 srtp_bits_per_second(len, policy) / 1.0E6);
464
465 /* these extra linefeeds let gnuplot know that a dataset is done */
466 printf("\r\n\r\n");
467
468}
469
470void
471srtp_do_rejection_timing(const srtp_policy_t *policy) {
472 int len;
473
474 /*
475 * note: the output of this function is formatted so that it
476 * can be used in gnuplot. '#' indicates a comment, and "\r\n"
477 * terminates a record
478 */
479
480 printf("# testing srtp rejection throughput:\r\n");
481 printf("# mesg length (octets)\trejections per second\r\n");
482
483 for (len=8; len <= 2048; len *= 2)
484 printf("%d\t\t\t%e\r\n", len, srtp_rejections_per_second(len, policy));
485
486 /* these extra linefeeds let gnuplot know that a dataset is done */
487 printf("\r\n\r\n");
488
489}
490
491
492#define MAX_MSG_LEN 1024
493
494double
495srtp_bits_per_second(int msg_len_octets, const srtp_policy_t *policy) {
496 srtp_t srtp;
497 srtp_hdr_t *mesg;
498 int i;
499 clock_t timer;
500 int num_trials = 100000;
501 int len;
502 uint32_t ssrc;
jfigus857009c2014-11-05 11:17:43 -0500503 srtp_err_status_t status;
Cullen Jennings235513a2005-09-21 22:51:36 +0000504
505 /*
506 * allocate and initialize an srtp session
507 */
508 status = srtp_create(&srtp, policy);
509 if (status) {
510 printf("error: srtp_create() failed with error code %d\n", status);
511 exit(1);
512 }
513
514 /*
515 * if the ssrc is unspecified, use a predetermined one
516 */
517 if (policy->ssrc.type != ssrc_specific) {
518 ssrc = 0xdeadbeef;
519 } else {
520 ssrc = policy->ssrc.value;
521 }
522
523 /*
524 * create a test packet
525 */
526 mesg = srtp_create_test_packet(msg_len_octets, ssrc);
527 if (mesg == NULL)
528 return 0.0; /* indicate failure by returning zero */
529
530 timer = clock();
531 for (i=0; i < num_trials; i++) {
David McGrewd2f8de42006-02-03 19:43:59 +0000532 len = msg_len_octets + 12; /* add in rtp header length */
Cullen Jennings235513a2005-09-21 22:51:36 +0000533
534 /* srtp protect message */
535 status = srtp_protect(srtp, mesg, &len);
536 if (status) {
537 printf("error: srtp_protect() failed with error code %d\n", status);
538 exit(1);
539 }
540
541 /* increment message number */
Jonathan Lennox75b36872010-05-21 00:30:21 +0000542 {
543 /* hack sequence to avoid problems with macros for htons/ntohs on some systems */
544 short new_seq = ntohs(mesg->seq) + 1;
545 mesg->seq = htons(new_seq);
546 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000547 }
548 timer = clock() - timer;
549
550 free(mesg);
Jonathan Lennox80c4c832010-05-17 19:30:28 +0000551
552 status = srtp_dealloc(srtp);
553 if (status) {
554 printf("error: srtp_dealloc() failed with error code %d\n", status);
555 exit(1);
556 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000557
558 return (double) (msg_len_octets) * 8 *
559 num_trials * CLOCKS_PER_SEC / timer;
560}
561
562double
563srtp_rejections_per_second(int msg_len_octets, const srtp_policy_t *policy) {
564 srtp_ctx_t *srtp;
565 srtp_hdr_t *mesg;
566 int i;
567 int len;
568 clock_t timer;
569 int num_trials = 1000000;
570 uint32_t ssrc = policy->ssrc.value;
jfigus857009c2014-11-05 11:17:43 -0500571 srtp_err_status_t status;
Cullen Jennings235513a2005-09-21 22:51:36 +0000572
573 /*
574 * allocate and initialize an srtp session
575 */
576 status = srtp_create(&srtp, policy);
577 if (status) {
578 printf("error: srtp_create() failed with error code %d\n", status);
579 exit(1);
580 }
581
582 mesg = srtp_create_test_packet(msg_len_octets, ssrc);
583 if (mesg == NULL)
584 return 0.0; /* indicate failure by returning zero */
585
586 len = msg_len_octets;
587 srtp_protect(srtp, (srtp_hdr_t *)mesg, &len);
588
589 timer = clock();
590 for (i=0; i < num_trials; i++) {
591 len = msg_len_octets;
592 srtp_unprotect(srtp, (srtp_hdr_t *)mesg, &len);
593 }
594 timer = clock() - timer;
595
596 free(mesg);
Jonathan Lennox80c4c832010-05-17 19:30:28 +0000597
598 status = srtp_dealloc(srtp);
599 if (status) {
600 printf("error: srtp_dealloc() failed with error code %d\n", status);
601 exit(1);
602 }
603
Cullen Jennings235513a2005-09-21 22:51:36 +0000604 return (double) num_trials * CLOCKS_PER_SEC / timer;
605}
606
607
608void
jfigus857009c2014-11-05 11:17:43 -0500609err_check(srtp_err_status_t s) {
610 if (s == srtp_err_status_ok)
Cullen Jennings235513a2005-09-21 22:51:36 +0000611 return;
612 else
613 fprintf(stderr, "error: unexpected srtp failure (code %d)\n", s);
614 exit (1);
615}
616
jfigus857009c2014-11-05 11:17:43 -0500617srtp_err_status_t
Cullen Jennings235513a2005-09-21 22:51:36 +0000618srtp_test(const srtp_policy_t *policy) {
619 int i;
620 srtp_t srtp_sender;
621 srtp_t srtp_rcvr;
jfigus857009c2014-11-05 11:17:43 -0500622 srtp_err_status_t status = srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +0000623 srtp_hdr_t *hdr, *hdr2;
Marcus Sundberg5c40da82005-10-08 18:15:00 +0000624 uint8_t hdr_enc[64];
Marcus Sundberg410faaa2005-09-29 12:36:43 +0000625 uint8_t *pkt_end;
Marcus Sundberg5c40da82005-10-08 18:15:00 +0000626 int msg_len_octets, msg_len_enc;
Cullen Jennings235513a2005-09-21 22:51:36 +0000627 int len;
628 int tag_length = policy->rtp.auth_tag_len;
629 uint32_t ssrc;
630 srtp_policy_t *rcvr_policy;
631
632 err_check(srtp_create(&srtp_sender, policy));
633
634 /* print out policy */
635 err_check(srtp_session_print_policy(srtp_sender));
636
637 /*
638 * initialize data buffer, using the ssrc in the policy unless that
639 * value is a wildcard, in which case we'll just use an arbitrary
640 * one
641 */
642 if (policy->ssrc.type != ssrc_specific)
643 ssrc = 0xdecafbad;
644 else
645 ssrc = policy->ssrc.value;
646 msg_len_octets = 28;
647 hdr = srtp_create_test_packet(msg_len_octets, ssrc);
648
649 if (hdr == NULL)
jfigus857009c2014-11-05 11:17:43 -0500650 return srtp_err_status_alloc_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +0000651 hdr2 = srtp_create_test_packet(msg_len_octets, ssrc);
652 if (hdr2 == NULL) {
653 free(hdr);
jfigus857009c2014-11-05 11:17:43 -0500654 return srtp_err_status_alloc_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +0000655 }
656
657 /* set message length */
658 len = msg_len_octets;
659
660 debug_print(mod_driver, "before protection:\n%s",
661 srtp_packet_to_string(hdr, len));
662
663#if PRINT_REFERENCE_PACKET
664 debug_print(mod_driver, "reference packet before protection:\n%s",
Marcus Sundberg410faaa2005-09-29 12:36:43 +0000665 octet_string_hex_string((uint8_t *)hdr, len));
Cullen Jennings235513a2005-09-21 22:51:36 +0000666#endif
667 err_check(srtp_protect(srtp_sender, hdr, &len));
668
669 debug_print(mod_driver, "after protection:\n%s",
670 srtp_packet_to_string(hdr, len));
671#if PRINT_REFERENCE_PACKET
672 debug_print(mod_driver, "after protection:\n%s",
Marcus Sundberg410faaa2005-09-29 12:36:43 +0000673 octet_string_hex_string((uint8_t *)hdr, len));
Cullen Jennings235513a2005-09-21 22:51:36 +0000674#endif
675
Marcus Sundberg5c40da82005-10-08 18:15:00 +0000676 /* save protected message and length */
677 memcpy(hdr_enc, hdr, len);
678 msg_len_enc = len;
679
Cullen Jennings235513a2005-09-21 22:51:36 +0000680 /*
681 * check for overrun of the srtp_protect() function
682 *
683 * The packet is followed by a value of 0xfffff; if the value of the
684 * data following the packet is different, then we know that the
685 * protect function is overwriting the end of the packet.
686 */
Marcus Sundberg410faaa2005-09-29 12:36:43 +0000687 pkt_end = (uint8_t *)hdr + sizeof(srtp_hdr_t)
Cullen Jennings235513a2005-09-21 22:51:36 +0000688 + msg_len_octets + tag_length;
689 for (i = 0; i < 4; i++)
690 if (pkt_end[i] != 0xff) {
691 fprintf(stdout, "overwrite in srtp_protect() function "
692 "(expected %x, found %x in trailing octet %d)\n",
Marcus Sundberg410faaa2005-09-29 12:36:43 +0000693 0xff, ((uint8_t *)hdr)[i], i);
Cullen Jennings235513a2005-09-21 22:51:36 +0000694 free(hdr);
695 free(hdr2);
jfigus857009c2014-11-05 11:17:43 -0500696 return srtp_err_status_algo_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +0000697 }
698
699 /*
700 * if the policy includes confidentiality, check that ciphertext is
701 * different than plaintext
702 *
703 * Note that this check will give false negatives, with some small
704 * probability, especially if the packets are short. For that
705 * reason, we skip this check if the plaintext is less than four
706 * octets long.
707 */
708 if ((policy->rtp.sec_serv & sec_serv_conf) && (msg_len_octets >= 4)) {
709 printf("testing that ciphertext is distinct from plaintext...");
jfigus857009c2014-11-05 11:17:43 -0500710 status = srtp_err_status_algo_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +0000711 for (i=12; i < msg_len_octets+12; i++)
Marcus Sundberg410faaa2005-09-29 12:36:43 +0000712 if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) {
jfigus857009c2014-11-05 11:17:43 -0500713 status = srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +0000714 }
715 if (status) {
716 printf("failed\n");
717 free(hdr);
718 free(hdr2);
719 return status;
720 }
721 printf("passed\n");
722 }
723
724 /*
725 * if the policy uses a 'wildcard' ssrc, then we need to make a copy
726 * of the policy that changes the direction to inbound
727 *
728 * we always copy the policy into the rcvr_policy, since otherwise
729 * the compiler would fret about the constness of the policy
730 */
Derek MacDonald17127da2006-07-12 22:22:08 +0000731 rcvr_policy = (srtp_policy_t*) malloc(sizeof(srtp_policy_t));
Jonathan Lennox80c4c832010-05-17 19:30:28 +0000732 if (rcvr_policy == NULL) {
733 free(hdr);
734 free(hdr2);
jfigus857009c2014-11-05 11:17:43 -0500735 return srtp_err_status_alloc_fail;
Jonathan Lennox80c4c832010-05-17 19:30:28 +0000736 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000737 memcpy(rcvr_policy, policy, sizeof(srtp_policy_t));
738 if (policy->ssrc.type == ssrc_any_outbound) {
739 rcvr_policy->ssrc.type = ssrc_any_inbound;
740 }
741
742 err_check(srtp_create(&srtp_rcvr, rcvr_policy));
743
744 err_check(srtp_unprotect(srtp_rcvr, hdr, &len));
745
746 debug_print(mod_driver, "after unprotection:\n%s",
747 srtp_packet_to_string(hdr, len));
748
749 /* verify that the unprotected packet matches the origial one */
750 for (i=0; i < msg_len_octets; i++)
Marcus Sundberg410faaa2005-09-29 12:36:43 +0000751 if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) {
Cullen Jennings235513a2005-09-21 22:51:36 +0000752 fprintf(stdout, "mismatch at octet %d\n", i);
jfigus857009c2014-11-05 11:17:43 -0500753 status = srtp_err_status_algo_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +0000754 }
755 if (status) {
756 free(hdr);
757 free(hdr2);
Jonathan Lennox80c4c832010-05-17 19:30:28 +0000758 free(rcvr_policy);
Cullen Jennings235513a2005-09-21 22:51:36 +0000759 return status;
760 }
761
762 /*
763 * if the policy includes authentication, then test for false positives
764 */
765 if (policy->rtp.sec_serv & sec_serv_auth) {
766 char *data = ((char *)hdr) + 12;
767
768 printf("testing for false positives in replay check...");
769
Marcus Sundberg5c40da82005-10-08 18:15:00 +0000770 /* set message length */
771 len = msg_len_enc;
772
Cullen Jennings235513a2005-09-21 22:51:36 +0000773 /* unprotect a second time - should fail with a replay error */
Marcus Sundberg5c40da82005-10-08 18:15:00 +0000774 status = srtp_unprotect(srtp_rcvr, hdr_enc, &len);
jfigus857009c2014-11-05 11:17:43 -0500775 if (status != srtp_err_status_replay_fail) {
Cullen Jennings235513a2005-09-21 22:51:36 +0000776 printf("failed with error code %d\n", status);
777 free(hdr);
778 free(hdr2);
Jonathan Lennox80c4c832010-05-17 19:30:28 +0000779 free(rcvr_policy);
Cullen Jennings235513a2005-09-21 22:51:36 +0000780 return status;
781 } else {
782 printf("passed\n");
783 }
784
785 printf("testing for false positives in auth check...");
786
787 /* increment sequence number in header */
788 hdr->seq++;
789
Marcus Sundberg5c40da82005-10-08 18:15:00 +0000790 /* set message length */
791 len = msg_len_octets;
792
Cullen Jennings235513a2005-09-21 22:51:36 +0000793 /* apply protection */
794 err_check(srtp_protect(srtp_sender, hdr, &len));
795
796 /* flip bits in packet */
797 data[0] ^= 0xff;
798
799 /* unprotect, and check for authentication failure */
800 status = srtp_unprotect(srtp_rcvr, hdr, &len);
jfigus857009c2014-11-05 11:17:43 -0500801 if (status != srtp_err_status_auth_fail) {
Cullen Jennings235513a2005-09-21 22:51:36 +0000802 printf("failed\n");
803 free(hdr);
804 free(hdr2);
Jonathan Lennox80c4c832010-05-17 19:30:28 +0000805 free(rcvr_policy);
Cullen Jennings235513a2005-09-21 22:51:36 +0000806 return status;
807 } else {
808 printf("passed\n");
809 }
810
811 }
812
813 err_check(srtp_dealloc(srtp_sender));
814 err_check(srtp_dealloc(srtp_rcvr));
815
816 free(hdr);
817 free(hdr2);
Jonathan Lennox80c4c832010-05-17 19:30:28 +0000818 free(rcvr_policy);
jfigus857009c2014-11-05 11:17:43 -0500819 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +0000820}
821
822
jfigus857009c2014-11-05 11:17:43 -0500823srtp_err_status_t
David McGrew9c70f292006-05-03 19:38:38 +0000824srtcp_test(const srtp_policy_t *policy) {
825 int i;
826 srtp_t srtcp_sender;
827 srtp_t srtcp_rcvr;
jfigus857009c2014-11-05 11:17:43 -0500828 srtp_err_status_t status = srtp_err_status_ok;
David McGrew9c70f292006-05-03 19:38:38 +0000829 srtp_hdr_t *hdr, *hdr2;
830 uint8_t hdr_enc[64];
831 uint8_t *pkt_end;
832 int msg_len_octets, msg_len_enc;
833 int len;
834 int tag_length = policy->rtp.auth_tag_len;
835 uint32_t ssrc;
836 srtp_policy_t *rcvr_policy;
837
838 err_check(srtp_create(&srtcp_sender, policy));
839
840 /* print out policy */
841 err_check(srtp_session_print_policy(srtcp_sender));
842
843 /*
844 * initialize data buffer, using the ssrc in the policy unless that
845 * value is a wildcard, in which case we'll just use an arbitrary
846 * one
847 */
848 if (policy->ssrc.type != ssrc_specific)
849 ssrc = 0xdecafbad;
850 else
851 ssrc = policy->ssrc.value;
852 msg_len_octets = 28;
853 hdr = srtp_create_test_packet(msg_len_octets, ssrc);
854
855 if (hdr == NULL)
jfigus857009c2014-11-05 11:17:43 -0500856 return srtp_err_status_alloc_fail;
David McGrew9c70f292006-05-03 19:38:38 +0000857 hdr2 = srtp_create_test_packet(msg_len_octets, ssrc);
858 if (hdr2 == NULL) {
859 free(hdr);
jfigus857009c2014-11-05 11:17:43 -0500860 return srtp_err_status_alloc_fail;
David McGrew9c70f292006-05-03 19:38:38 +0000861 }
862
863 /* set message length */
864 len = msg_len_octets;
865
866 debug_print(mod_driver, "before protection:\n%s",
867 srtp_packet_to_string(hdr, len));
868
869#if PRINT_REFERENCE_PACKET
870 debug_print(mod_driver, "reference packet before protection:\n%s",
871 octet_string_hex_string((uint8_t *)hdr, len));
872#endif
873 err_check(srtp_protect_rtcp(srtcp_sender, hdr, &len));
874
875 debug_print(mod_driver, "after protection:\n%s",
876 srtp_packet_to_string(hdr, len));
877#if PRINT_REFERENCE_PACKET
878 debug_print(mod_driver, "after protection:\n%s",
879 octet_string_hex_string((uint8_t *)hdr, len));
880#endif
881
882 /* save protected message and length */
883 memcpy(hdr_enc, hdr, len);
884 msg_len_enc = len;
885
886 /*
887 * check for overrun of the srtp_protect() function
888 *
889 * The packet is followed by a value of 0xfffff; if the value of the
890 * data following the packet is different, then we know that the
891 * protect function is overwriting the end of the packet.
892 */
893 pkt_end = (uint8_t *)hdr + sizeof(srtp_hdr_t)
894 + msg_len_octets + tag_length;
895 for (i = 0; i < 4; i++)
896 if (pkt_end[i] != 0xff) {
897 fprintf(stdout, "overwrite in srtp_protect_rtcp() function "
898 "(expected %x, found %x in trailing octet %d)\n",
899 0xff, ((uint8_t *)hdr)[i], i);
900 free(hdr);
901 free(hdr2);
jfigus857009c2014-11-05 11:17:43 -0500902 return srtp_err_status_algo_fail;
David McGrew9c70f292006-05-03 19:38:38 +0000903 }
904
905 /*
906 * if the policy includes confidentiality, check that ciphertext is
907 * different than plaintext
908 *
909 * Note that this check will give false negatives, with some small
910 * probability, especially if the packets are short. For that
911 * reason, we skip this check if the plaintext is less than four
912 * octets long.
913 */
914 if ((policy->rtp.sec_serv & sec_serv_conf) && (msg_len_octets >= 4)) {
915 printf("testing that ciphertext is distinct from plaintext...");
jfigus857009c2014-11-05 11:17:43 -0500916 status = srtp_err_status_algo_fail;
David McGrew9c70f292006-05-03 19:38:38 +0000917 for (i=12; i < msg_len_octets+12; i++)
918 if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) {
jfigus857009c2014-11-05 11:17:43 -0500919 status = srtp_err_status_ok;
David McGrew9c70f292006-05-03 19:38:38 +0000920 }
921 if (status) {
922 printf("failed\n");
923 free(hdr);
924 free(hdr2);
925 return status;
926 }
927 printf("passed\n");
928 }
929
930 /*
931 * if the policy uses a 'wildcard' ssrc, then we need to make a copy
932 * of the policy that changes the direction to inbound
933 *
934 * we always copy the policy into the rcvr_policy, since otherwise
935 * the compiler would fret about the constness of the policy
936 */
Derek MacDonald17127da2006-07-12 22:22:08 +0000937 rcvr_policy = (srtp_policy_t*) malloc(sizeof(srtp_policy_t));
David McGrew9c70f292006-05-03 19:38:38 +0000938 if (rcvr_policy == NULL)
jfigus857009c2014-11-05 11:17:43 -0500939 return srtp_err_status_alloc_fail;
David McGrew9c70f292006-05-03 19:38:38 +0000940 memcpy(rcvr_policy, policy, sizeof(srtp_policy_t));
941 if (policy->ssrc.type == ssrc_any_outbound) {
942 rcvr_policy->ssrc.type = ssrc_any_inbound;
943 }
944
945 err_check(srtp_create(&srtcp_rcvr, rcvr_policy));
946
947 err_check(srtp_unprotect_rtcp(srtcp_rcvr, hdr, &len));
948
949 debug_print(mod_driver, "after unprotection:\n%s",
950 srtp_packet_to_string(hdr, len));
951
952 /* verify that the unprotected packet matches the origial one */
953 for (i=0; i < msg_len_octets; i++)
954 if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) {
955 fprintf(stdout, "mismatch at octet %d\n", i);
jfigus857009c2014-11-05 11:17:43 -0500956 status = srtp_err_status_algo_fail;
David McGrew9c70f292006-05-03 19:38:38 +0000957 }
958 if (status) {
959 free(hdr);
960 free(hdr2);
Jonathan Lennox80c4c832010-05-17 19:30:28 +0000961 free(rcvr_policy);
David McGrew9c70f292006-05-03 19:38:38 +0000962 return status;
963 }
964
965 /*
966 * if the policy includes authentication, then test for false positives
967 */
968 if (policy->rtp.sec_serv & sec_serv_auth) {
969 char *data = ((char *)hdr) + 12;
970
971 printf("testing for false positives in replay check...");
972
973 /* set message length */
974 len = msg_len_enc;
975
976 /* unprotect a second time - should fail with a replay error */
977 status = srtp_unprotect_rtcp(srtcp_rcvr, hdr_enc, &len);
jfigus857009c2014-11-05 11:17:43 -0500978 if (status != srtp_err_status_replay_fail) {
David McGrew9c70f292006-05-03 19:38:38 +0000979 printf("failed with error code %d\n", status);
980 free(hdr);
981 free(hdr2);
Jonathan Lennox80c4c832010-05-17 19:30:28 +0000982 free(rcvr_policy);
David McGrew9c70f292006-05-03 19:38:38 +0000983 return status;
984 } else {
985 printf("passed\n");
986 }
987
988 printf("testing for false positives in auth check...");
989
990 /* increment sequence number in header */
991 hdr->seq++;
992
993 /* set message length */
994 len = msg_len_octets;
995
996 /* apply protection */
997 err_check(srtp_protect_rtcp(srtcp_sender, hdr, &len));
998
999 /* flip bits in packet */
1000 data[0] ^= 0xff;
1001
1002 /* unprotect, and check for authentication failure */
1003 status = srtp_unprotect_rtcp(srtcp_rcvr, hdr, &len);
jfigus857009c2014-11-05 11:17:43 -05001004 if (status != srtp_err_status_auth_fail) {
David McGrew9c70f292006-05-03 19:38:38 +00001005 printf("failed\n");
1006 free(hdr);
1007 free(hdr2);
Jonathan Lennox80c4c832010-05-17 19:30:28 +00001008 free(rcvr_policy);
David McGrew9c70f292006-05-03 19:38:38 +00001009 return status;
1010 } else {
1011 printf("passed\n");
1012 }
1013
1014 }
1015
1016 err_check(srtp_dealloc(srtcp_sender));
1017 err_check(srtp_dealloc(srtcp_rcvr));
1018
1019 free(hdr);
1020 free(hdr2);
Jonathan Lennox80c4c832010-05-17 19:30:28 +00001021 free(rcvr_policy);
jfigus857009c2014-11-05 11:17:43 -05001022 return srtp_err_status_ok;
David McGrew9c70f292006-05-03 19:38:38 +00001023}
1024
1025
jfigus857009c2014-11-05 11:17:43 -05001026srtp_err_status_t
Cullen Jennings235513a2005-09-21 22:51:36 +00001027srtp_session_print_policy(srtp_t srtp) {
1028 char *serv_descr[4] = {
1029 "none",
1030 "confidentiality",
1031 "authentication",
1032 "confidentiality and authentication"
1033 };
1034 char *direction[3] = {
1035 "unknown",
1036 "outbound",
1037 "inbound"
1038 };
1039 srtp_stream_t stream;
1040
1041 /* sanity checking */
1042 if (srtp == NULL)
jfigus857009c2014-11-05 11:17:43 -05001043 return srtp_err_status_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +00001044
1045 /* if there's a template stream, print it out */
1046 if (srtp->stream_template != NULL) {
1047 stream = srtp->stream_template;
1048 printf("# SSRC: any %s\r\n"
1049 "# rtp cipher: %s\r\n"
1050 "# rtp auth: %s\r\n"
1051 "# rtp services: %s\r\n"
1052 "# rtcp cipher: %s\r\n"
1053 "# rtcp auth: %s\r\n"
Jonathan Lennoxa1242f82010-05-17 21:46:04 +00001054 "# rtcp services: %s\r\n"
Jonathan Lennoxdcee5c62010-05-17 22:08:40 +00001055 "# window size: %lu\r\n"
1056 "# tx rtx allowed:%s\r\n",
Cullen Jennings235513a2005-09-21 22:51:36 +00001057 direction[stream->direction],
1058 stream->rtp_cipher->type->description,
1059 stream->rtp_auth->type->description,
1060 serv_descr[stream->rtp_services],
1061 stream->rtcp_cipher->type->description,
1062 stream->rtcp_auth->type->description,
Jonathan Lennoxa1242f82010-05-17 21:46:04 +00001063 serv_descr[stream->rtcp_services],
Jonathan Lennoxdcee5c62010-05-17 22:08:40 +00001064 rdbx_get_window_size(&stream->rtp_rdbx),
1065 stream->allow_repeat_tx ? "true" : "false");
Cullen Jennings235513a2005-09-21 22:51:36 +00001066 }
1067
1068 /* loop over streams in session, printing the policy of each */
1069 stream = srtp->stream_list;
1070 while (stream != NULL) {
1071 if (stream->rtp_services > sec_serv_conf_and_auth)
jfigus857009c2014-11-05 11:17:43 -05001072 return srtp_err_status_bad_param;
Cullen Jennings235513a2005-09-21 22:51:36 +00001073
1074 printf("# SSRC: 0x%08x\r\n"
1075 "# rtp cipher: %s\r\n"
1076 "# rtp auth: %s\r\n"
1077 "# rtp services: %s\r\n"
1078 "# rtcp cipher: %s\r\n"
1079 "# rtcp auth: %s\r\n"
Jonathan Lennoxa1242f82010-05-17 21:46:04 +00001080 "# rtcp services: %s\r\n"
Jonathan Lennoxdcee5c62010-05-17 22:08:40 +00001081 "# window size: %lu\r\n"
1082 "# tx rtx allowed:%s\r\n",
Cullen Jennings235513a2005-09-21 22:51:36 +00001083 stream->ssrc,
1084 stream->rtp_cipher->type->description,
1085 stream->rtp_auth->type->description,
1086 serv_descr[stream->rtp_services],
1087 stream->rtcp_cipher->type->description,
1088 stream->rtcp_auth->type->description,
Jonathan Lennoxa1242f82010-05-17 21:46:04 +00001089 serv_descr[stream->rtcp_services],
Jonathan Lennoxdcee5c62010-05-17 22:08:40 +00001090 rdbx_get_window_size(&stream->rtp_rdbx),
1091 stream->allow_repeat_tx ? "true" : "false");
Cullen Jennings235513a2005-09-21 22:51:36 +00001092
1093 /* advance to next stream in the list */
1094 stream = stream->next;
1095 }
jfigus857009c2014-11-05 11:17:43 -05001096 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +00001097}
1098
jfigus857009c2014-11-05 11:17:43 -05001099srtp_err_status_t
Cullen Jennings235513a2005-09-21 22:51:36 +00001100srtp_print_policy(const srtp_policy_t *policy) {
jfigus857009c2014-11-05 11:17:43 -05001101 srtp_err_status_t status;
Cullen Jennings235513a2005-09-21 22:51:36 +00001102 srtp_t session;
1103
1104 status = srtp_create(&session, policy);
1105 if (status)
1106 return status;
1107 status = srtp_session_print_policy(session);
1108 if (status)
1109 return status;
1110 status = srtp_dealloc(session);
1111 if (status)
1112 return status;
jfigus857009c2014-11-05 11:17:43 -05001113 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +00001114}
1115
1116/*
1117 * srtp_print_packet(...) is for debugging only
1118 * it prints an RTP packet to the stdout
1119 *
1120 * note that this function is *not* threadsafe
1121 */
1122
1123#include <stdio.h>
1124
1125#define MTU 2048
1126
1127char packet_string[MTU];
1128
1129char *
1130srtp_packet_to_string(srtp_hdr_t *hdr, int pkt_octet_len) {
1131 int octets_in_rtp_header = 12;
Marcus Sundberg410faaa2005-09-29 12:36:43 +00001132 uint8_t *data = ((uint8_t *)hdr)+octets_in_rtp_header;
Cullen Jennings235513a2005-09-21 22:51:36 +00001133 int hex_len = pkt_octet_len-octets_in_rtp_header;
1134
1135 /* sanity checking */
1136 if ((hdr == NULL) || (pkt_octet_len > MTU))
1137 return NULL;
1138
1139 /* write packet into string */
1140 sprintf(packet_string,
1141 "(s)rtp packet: {\n"
1142 " version:\t%d\n"
1143 " p:\t\t%d\n"
1144 " x:\t\t%d\n"
1145 " cc:\t\t%d\n"
1146 " m:\t\t%d\n"
1147 " pt:\t\t%x\n"
1148 " seq:\t\t%x\n"
1149 " ts:\t\t%x\n"
1150 " ssrc:\t%x\n"
1151 " data:\t%s\n"
1152 "} (%d octets in total)\n",
1153 hdr->version,
1154 hdr->p,
1155 hdr->x,
1156 hdr->cc,
1157 hdr->m,
1158 hdr->pt,
1159 hdr->seq,
1160 hdr->ts,
1161 hdr->ssrc,
1162 octet_string_hex_string(data, hex_len),
1163 pkt_octet_len);
1164
1165 return packet_string;
1166}
1167
1168/*
1169 * mips_estimate() is a simple function to estimate the number of
1170 * instructions per second that the host can perform. note that this
1171 * function can be grossly wrong; you may want to have a manual sanity
1172 * check of its output!
1173 *
1174 * the 'ignore' pointer is there to convince the compiler to not just
1175 * optimize away the function
1176 */
1177
1178double
1179mips_estimate(int num_trials, int *ignore) {
1180 clock_t t;
Jonathan Lennox33554932010-05-15 04:53:10 +00001181 volatile int i, sum;
Cullen Jennings235513a2005-09-21 22:51:36 +00001182
1183 sum = 0;
1184 t = clock();
1185 for (i=0; i<num_trials; i++)
1186 sum += i;
1187 t = clock() - t;
1188
1189/* printf("%d\n", sum); */
1190 *ignore = sum;
1191
1192 return (double) num_trials * CLOCKS_PER_SEC / t;
1193}
1194
1195
1196/*
1197 * srtp_validate() verifies the correctness of libsrtp by comparing
1198 * some computed packets against some pre-computed reference values.
1199 * These packets were made with the default SRTP policy.
1200 */
1201
1202
jfigus857009c2014-11-05 11:17:43 -05001203srtp_err_status_t
Cullen Jennings235513a2005-09-21 22:51:36 +00001204srtp_validate() {
Marcus Sundberg410faaa2005-09-29 12:36:43 +00001205 uint8_t srtp_plaintext_ref[28] = {
Cullen Jennings235513a2005-09-21 22:51:36 +00001206 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1207 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
1208 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1209 0xab, 0xab, 0xab, 0xab
1210 };
Marcus Sundberg410faaa2005-09-29 12:36:43 +00001211 uint8_t srtp_plaintext[38] = {
Cullen Jennings235513a2005-09-21 22:51:36 +00001212 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1213 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
1214 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1215 0xab, 0xab, 0xab, 0xab, 0x00, 0x00, 0x00, 0x00,
1216 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1217 };
Marcus Sundberg410faaa2005-09-29 12:36:43 +00001218 uint8_t srtp_ciphertext[38] = {
Cullen Jennings235513a2005-09-21 22:51:36 +00001219 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1220 0xca, 0xfe, 0xba, 0xbe, 0x4e, 0x55, 0xdc, 0x4c,
1221 0xe7, 0x99, 0x78, 0xd8, 0x8c, 0xa4, 0xd2, 0x15,
1222 0x94, 0x9d, 0x24, 0x02, 0xb7, 0x8d, 0x6a, 0xcc,
1223 0x99, 0xea, 0x17, 0x9b, 0x8d, 0xbb
1224 };
1225 srtp_t srtp_snd, srtp_recv;
jfigus857009c2014-11-05 11:17:43 -05001226 srtp_err_status_t status;
Cullen Jennings235513a2005-09-21 22:51:36 +00001227 int len;
1228 srtp_policy_t policy;
1229
1230 /*
1231 * create a session with a single stream using the default srtp
1232 * policy and with the SSRC value 0xcafebabe
1233 */
jfigus857009c2014-11-05 11:17:43 -05001234 srtp_crypto_policy_set_rtp_default(&policy.rtp);
1235 srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
Cullen Jennings235513a2005-09-21 22:51:36 +00001236 policy.ssrc.type = ssrc_specific;
1237 policy.ssrc.value = 0xcafebabe;
1238 policy.key = test_key;
Jonathan Lennoxa1242f82010-05-17 21:46:04 +00001239 policy.ekt = NULL;
1240 policy.window_size = 128;
Jonathan Lennoxdcee5c62010-05-17 22:08:40 +00001241 policy.allow_repeat_tx = 0;
Cullen Jennings235513a2005-09-21 22:51:36 +00001242 policy.next = NULL;
1243
1244 status = srtp_create(&srtp_snd, &policy);
1245 if (status)
1246 return status;
1247
1248 /*
1249 * protect plaintext, then compare with ciphertext
1250 */
1251 len = 28;
1252 status = srtp_protect(srtp_snd, srtp_plaintext, &len);
1253 if (status || (len != 38))
jfigus857009c2014-11-05 11:17:43 -05001254 return srtp_err_status_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +00001255
1256 debug_print(mod_driver, "ciphertext:\n %s",
1257 octet_string_hex_string(srtp_plaintext, len));
1258 debug_print(mod_driver, "ciphertext reference:\n %s",
1259 octet_string_hex_string(srtp_ciphertext, len));
1260
1261 if (octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len))
jfigus857009c2014-11-05 11:17:43 -05001262 return srtp_err_status_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +00001263
1264 /*
1265 * create a receiver session context comparable to the one created
1266 * above - we need to do this so that the replay checking doesn't
1267 * complain
1268 */
1269 status = srtp_create(&srtp_recv, &policy);
1270 if (status)
1271 return status;
1272
1273 /*
1274 * unprotect ciphertext, then compare with plaintext
1275 */
1276 status = srtp_unprotect(srtp_recv, srtp_ciphertext, &len);
1277 if (status || (len != 28))
1278 return status;
1279
1280 if (octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len))
jfigus857009c2014-11-05 11:17:43 -05001281 return srtp_err_status_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +00001282
Jonathan Lennox80c4c832010-05-17 19:30:28 +00001283 status = srtp_dealloc(srtp_snd);
1284 if (status)
1285 return status;
1286
1287 status = srtp_dealloc(srtp_recv);
1288 if (status)
1289 return status;
1290
jfigus857009c2014-11-05 11:17:43 -05001291 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +00001292}
1293
1294
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001295/*
1296 * srtp_validate_aes_256() verifies the correctness of libsrtp by comparing
1297 * some computed packets against some pre-computed reference values.
1298 * These packets were made with the AES-CM-256/HMAC-SHA-1-80 policy.
1299 */
1300
1301
jfigus857009c2014-11-05 11:17:43 -05001302srtp_err_status_t
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001303srtp_validate_aes_256() {
Jonathan Lennox75b36872010-05-21 00:30:21 +00001304 unsigned char aes_256_test_key[46] = {
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001305 0xf0, 0xf0, 0x49, 0x14, 0xb5, 0x13, 0xf2, 0x76,
1306 0x3a, 0x1b, 0x1f, 0xa1, 0x30, 0xf1, 0x0e, 0x29,
1307 0x98, 0xf6, 0xf6, 0xe4, 0x3e, 0x43, 0x09, 0xd1,
1308 0xe6, 0x22, 0xa0, 0xe3, 0x32, 0xb9, 0xf1, 0xb6,
1309
1310 0x3b, 0x04, 0x80, 0x3d, 0xe5, 0x1e, 0xe7, 0xc9,
1311 0x64, 0x23, 0xab, 0x5b, 0x78, 0xd2
1312 };
1313 uint8_t srtp_plaintext_ref[28] = {
1314 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1315 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
1316 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1317 0xab, 0xab, 0xab, 0xab
1318 };
1319 uint8_t srtp_plaintext[38] = {
1320 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1321 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
1322 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1323 0xab, 0xab, 0xab, 0xab, 0x00, 0x00, 0x00, 0x00,
1324 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1325 };
1326 uint8_t srtp_ciphertext[38] = {
1327 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1328 0xca, 0xfe, 0xba, 0xbe, 0xf1, 0xd9, 0xde, 0x17,
1329 0xff, 0x25, 0x1f, 0xf1, 0xaa, 0x00, 0x77, 0x74,
1330 0xb0, 0xb4, 0xb4, 0x0d, 0xa0, 0x8d, 0x9d, 0x9a,
1331 0x5b, 0x3a, 0x55, 0xd8, 0x87, 0x3b
1332 };
1333 srtp_t srtp_snd, srtp_recv;
jfigus857009c2014-11-05 11:17:43 -05001334 srtp_err_status_t status;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001335 int len;
1336 srtp_policy_t policy;
1337
1338 /*
1339 * create a session with a single stream using the default srtp
1340 * policy and with the SSRC value 0xcafebabe
1341 */
jfigus857009c2014-11-05 11:17:43 -05001342 srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(&policy.rtp);
1343 srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(&policy.rtcp);
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001344 policy.ssrc.type = ssrc_specific;
1345 policy.ssrc.value = 0xcafebabe;
Jonathan Lennox75b36872010-05-21 00:30:21 +00001346 policy.key = aes_256_test_key;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001347 policy.ekt = NULL;
1348 policy.window_size = 128;
1349 policy.allow_repeat_tx = 0;
1350 policy.next = NULL;
1351
1352 status = srtp_create(&srtp_snd, &policy);
1353 if (status)
1354 return status;
1355
1356 /*
1357 * protect plaintext, then compare with ciphertext
1358 */
1359 len = 28;
1360 status = srtp_protect(srtp_snd, srtp_plaintext, &len);
1361 if (status || (len != 38))
jfigus857009c2014-11-05 11:17:43 -05001362 return srtp_err_status_fail;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001363
1364 debug_print(mod_driver, "ciphertext:\n %s",
1365 octet_string_hex_string(srtp_plaintext, len));
1366 debug_print(mod_driver, "ciphertext reference:\n %s",
1367 octet_string_hex_string(srtp_ciphertext, len));
1368
1369 if (octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len))
jfigus857009c2014-11-05 11:17:43 -05001370 return srtp_err_status_fail;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001371
1372 /*
1373 * create a receiver session context comparable to the one created
1374 * above - we need to do this so that the replay checking doesn't
1375 * complain
1376 */
1377 status = srtp_create(&srtp_recv, &policy);
1378 if (status)
1379 return status;
1380
1381 /*
1382 * unprotect ciphertext, then compare with plaintext
1383 */
1384 status = srtp_unprotect(srtp_recv, srtp_ciphertext, &len);
1385 if (status || (len != 28))
1386 return status;
1387
1388 if (octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len))
jfigus857009c2014-11-05 11:17:43 -05001389 return srtp_err_status_fail;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001390
1391 status = srtp_dealloc(srtp_snd);
1392 if (status)
1393 return status;
1394
1395 status = srtp_dealloc(srtp_recv);
1396 if (status)
1397 return status;
1398
jfigus857009c2014-11-05 11:17:43 -05001399 return srtp_err_status_ok;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001400}
1401
1402
jfigus857009c2014-11-05 11:17:43 -05001403srtp_err_status_t
Cullen Jennings235513a2005-09-21 22:51:36 +00001404srtp_create_big_policy(srtp_policy_t **list) {
1405 extern const srtp_policy_t *policy_array[];
1406 srtp_policy_t *p, *tmp;
1407 int i = 0;
1408 uint32_t ssrc = 0;
1409
1410 /* sanity checking */
1411 if ((list == NULL) || (policy_array[0] == NULL))
jfigus857009c2014-11-05 11:17:43 -05001412 return srtp_err_status_bad_param;
Cullen Jennings235513a2005-09-21 22:51:36 +00001413
1414 /*
1415 * loop over policy list, mallocing a new list and copying values
1416 * into it (and incrementing the SSRC value as we go along)
1417 */
1418 tmp = NULL;
1419 while (policy_array[i] != NULL) {
Derek MacDonald17127da2006-07-12 22:22:08 +00001420 p = (srtp_policy_t*) malloc(sizeof(srtp_policy_t));
Cullen Jennings235513a2005-09-21 22:51:36 +00001421 if (p == NULL)
jfigus857009c2014-11-05 11:17:43 -05001422 return srtp_err_status_bad_param;
Cullen Jennings235513a2005-09-21 22:51:36 +00001423 memcpy(p, policy_array[i], sizeof(srtp_policy_t));
1424 p->ssrc.type = ssrc_specific;
1425 p->ssrc.value = ssrc++;
1426 p->next = tmp;
1427 tmp = p;
1428 i++;
1429 }
1430 *list = p;
1431
jfigus857009c2014-11-05 11:17:43 -05001432 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +00001433}
1434
jfigus857009c2014-11-05 11:17:43 -05001435srtp_err_status_t
Jonathan Lennox80c4c832010-05-17 19:30:28 +00001436srtp_dealloc_big_policy(srtp_policy_t *list) {
1437 srtp_policy_t *p, *next;
1438
1439 for (p = list; p != NULL; p = next) {
1440 next = p->next;
1441 free(p);
1442 }
1443
jfigus857009c2014-11-05 11:17:43 -05001444 return srtp_err_status_ok;
Jonathan Lennox80c4c832010-05-17 19:30:28 +00001445}
1446
1447
jfigus857009c2014-11-05 11:17:43 -05001448srtp_err_status_t
Cullen Jennings235513a2005-09-21 22:51:36 +00001449srtp_test_remove_stream() {
jfigus857009c2014-11-05 11:17:43 -05001450 srtp_err_status_t status;
Jonathan Lennoxad741b22010-05-27 19:23:05 +00001451 srtp_policy_t *policy_list, policy;
Cullen Jennings235513a2005-09-21 22:51:36 +00001452 srtp_t session;
1453 srtp_stream_t stream;
1454 /*
1455 * srtp_get_stream() is a libSRTP internal function that we declare
1456 * here so that we can use it to verify the correct operation of the
1457 * library
1458 */
1459 extern srtp_stream_t srtp_get_stream(srtp_t srtp, uint32_t ssrc);
1460
1461
1462 status = srtp_create_big_policy(&policy_list);
1463 if (status)
1464 return status;
1465
1466 status = srtp_create(&session, policy_list);
1467 if (status)
1468 return status;
1469
1470 /*
1471 * check for false positives by trying to remove a stream that's not
1472 * in the session
1473 */
1474 status = srtp_remove_stream(session, htonl(0xaaaaaaaa));
jfigus857009c2014-11-05 11:17:43 -05001475 if (status != srtp_err_status_no_ctx)
1476 return srtp_err_status_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +00001477
1478 /*
1479 * check for false negatives by removing stream 0x1, then
1480 * searching for streams 0x0 and 0x2
1481 */
1482 status = srtp_remove_stream(session, htonl(0x1));
jfigus857009c2014-11-05 11:17:43 -05001483 if (status != srtp_err_status_ok)
1484 return srtp_err_status_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +00001485 stream = srtp_get_stream(session, htonl(0x0));
1486 if (stream == NULL)
jfigus857009c2014-11-05 11:17:43 -05001487 return srtp_err_status_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +00001488 stream = srtp_get_stream(session, htonl(0x2));
1489 if (stream == NULL)
jfigus857009c2014-11-05 11:17:43 -05001490 return srtp_err_status_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +00001491
Jonathan Lennox80c4c832010-05-17 19:30:28 +00001492 status = srtp_dealloc(session);
jfigus857009c2014-11-05 11:17:43 -05001493 if (status != srtp_err_status_ok)
Jonathan Lennox80c4c832010-05-17 19:30:28 +00001494 return status;
1495
1496 status = srtp_dealloc_big_policy(policy_list);
jfigus857009c2014-11-05 11:17:43 -05001497 if (status != srtp_err_status_ok)
Jonathan Lennox80c4c832010-05-17 19:30:28 +00001498 return status;
1499
Jonathan Lennoxad741b22010-05-27 19:23:05 +00001500 /* Now test adding and removing a single stream */
jfigus857009c2014-11-05 11:17:43 -05001501 srtp_crypto_policy_set_rtp_default(&policy.rtp);
1502 srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
Jonathan Lennoxad741b22010-05-27 19:23:05 +00001503 policy.ssrc.type = ssrc_specific;
1504 policy.ssrc.value = 0xcafebabe;
1505 policy.key = test_key;
1506 policy.ekt = NULL;
1507 policy.window_size = 128;
1508 policy.allow_repeat_tx = 0;
1509 policy.next = NULL;
1510
1511 status = srtp_create(&session, NULL);
jfigus857009c2014-11-05 11:17:43 -05001512 if (status != srtp_err_status_ok)
Jonathan Lennoxad741b22010-05-27 19:23:05 +00001513 return status;
1514
1515 status = srtp_add_stream(session, &policy);
jfigus857009c2014-11-05 11:17:43 -05001516 if (status != srtp_err_status_ok)
Jonathan Lennoxad741b22010-05-27 19:23:05 +00001517 return status;
1518
1519 status = srtp_remove_stream(session, htonl(0xcafebabe));
jfigus857009c2014-11-05 11:17:43 -05001520 if (status != srtp_err_status_ok)
Jonathan Lennoxad741b22010-05-27 19:23:05 +00001521 return status;
1522
1523 status = srtp_dealloc(session);
jfigus857009c2014-11-05 11:17:43 -05001524 if (status != srtp_err_status_ok)
Jonathan Lennoxad741b22010-05-27 19:23:05 +00001525 return status;
1526
jfigus857009c2014-11-05 11:17:43 -05001527 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +00001528}
1529
1530/*
1531 * srtp policy definitions - these definitions are used above
1532 */
1533
jfigus8c36da22013-10-01 16:41:19 -04001534unsigned char test_key[46] = {
Cullen Jennings235513a2005-09-21 22:51:36 +00001535 0xe1, 0xf9, 0x7a, 0x0d, 0x3e, 0x01, 0x8b, 0xe0,
1536 0xd6, 0x4f, 0xa3, 0x2c, 0x06, 0xde, 0x41, 0x39,
1537 0x0e, 0xc6, 0x75, 0xad, 0x49, 0x8a, 0xfe, 0xeb,
jfigus8c36da22013-10-01 16:41:19 -04001538 0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6, 0xc1, 0x73,
1539 0xc3, 0x17, 0xf2, 0xda, 0xbe, 0x35, 0x77, 0x93,
Cullen Jennings235513a2005-09-21 22:51:36 +00001540 0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6
1541};
1542
1543
1544const srtp_policy_t default_policy = {
1545 { ssrc_any_outbound, 0 }, /* SSRC */
1546 { /* SRTP policy */
1547 AES_128_ICM, /* cipher type */
1548 30, /* cipher key length in octets */
1549 HMAC_SHA1, /* authentication func type */
1550 16, /* auth key length in octets */
1551 10, /* auth tag length in octets */
1552 sec_serv_conf_and_auth /* security services flag */
1553 },
1554 { /* SRTCP policy */
1555 AES_128_ICM, /* cipher type */
1556 30, /* cipher key length in octets */
1557 HMAC_SHA1, /* authentication func type */
1558 16, /* auth key length in octets */
1559 10, /* auth tag length in octets */
1560 sec_serv_conf_and_auth /* security services flag */
1561 },
1562 test_key,
David McGrew79870d62007-06-15 18:17:39 +00001563 NULL, /* indicates that EKT is not in use */
Jonathan Lennoxa1242f82010-05-17 21:46:04 +00001564 128, /* replay window size */
Jonathan Lennoxdcee5c62010-05-17 22:08:40 +00001565 0, /* retransmission not allowed */
Cullen Jennings235513a2005-09-21 22:51:36 +00001566 NULL
1567};
1568
1569const srtp_policy_t aes_tmmh_policy = {
1570 { ssrc_any_outbound, 0 }, /* SSRC */
1571 {
1572 AES_128_ICM, /* cipher type */
1573 30, /* cipher key length in octets */
1574 UST_TMMHv2, /* authentication func type */
1575 94, /* auth key length in octets */
1576 4, /* auth tag length in octets */
1577 sec_serv_conf_and_auth /* security services flag */
1578 },
1579 {
1580 AES_128_ICM, /* cipher type */
1581 30, /* cipher key length in octets */
1582 UST_TMMHv2, /* authentication func type */
1583 94, /* auth key length in octets */
1584 4, /* auth tag length in octets */
1585 sec_serv_conf_and_auth /* security services flag */
1586 },
1587 test_key,
David McGrew79870d62007-06-15 18:17:39 +00001588 NULL, /* indicates that EKT is not in use */
Jonathan Lennoxa1242f82010-05-17 21:46:04 +00001589 128, /* replay window size */
Jonathan Lennoxdcee5c62010-05-17 22:08:40 +00001590 0, /* retransmission not allowed */
Cullen Jennings235513a2005-09-21 22:51:36 +00001591 NULL
1592};
1593
1594const srtp_policy_t tmmh_only_policy = {
1595 { ssrc_any_outbound, 0 }, /* SSRC */
1596 {
1597 AES_128_ICM, /* cipher type */
1598 30, /* cipher key length in octets */
1599 UST_TMMHv2, /* authentication func type */
1600 94, /* auth key length in octets */
1601 4, /* auth tag length in octets */
1602 sec_serv_auth /* security services flag */
1603 },
1604 {
1605 AES_128_ICM, /* cipher type */
1606 30, /* cipher key length in octets */
1607 UST_TMMHv2, /* authentication func type */
1608 94, /* auth key length in octets */
1609 4, /* auth tag length in octets */
1610 sec_serv_auth /* security services flag */
1611 },
1612 test_key,
David McGrew79870d62007-06-15 18:17:39 +00001613 NULL, /* indicates that EKT is not in use */
Jonathan Lennoxa1242f82010-05-17 21:46:04 +00001614 128, /* replay window size */
Jonathan Lennoxdcee5c62010-05-17 22:08:40 +00001615 0, /* retransmission not allowed */
Cullen Jennings235513a2005-09-21 22:51:36 +00001616 NULL
1617};
1618
1619const srtp_policy_t aes_only_policy = {
1620 { ssrc_any_outbound, 0 }, /* SSRC */
1621 {
1622 AES_128_ICM, /* cipher type */
1623 30, /* cipher key length in octets */
1624 NULL_AUTH, /* authentication func type */
1625 0, /* auth key length in octets */
1626 0, /* auth tag length in octets */
1627 sec_serv_conf /* security services flag */
1628 },
1629 {
1630 AES_128_ICM, /* cipher type */
1631 30, /* cipher key length in octets */
1632 NULL_AUTH, /* authentication func type */
1633 0, /* auth key length in octets */
1634 0, /* auth tag length in octets */
1635 sec_serv_conf /* security services flag */
1636 },
1637 test_key,
David McGrew79870d62007-06-15 18:17:39 +00001638 NULL, /* indicates that EKT is not in use */
Jonathan Lennoxa1242f82010-05-17 21:46:04 +00001639 128, /* replay window size */
Jonathan Lennoxdcee5c62010-05-17 22:08:40 +00001640 0, /* retransmission not allowed */
Cullen Jennings235513a2005-09-21 22:51:36 +00001641 NULL
1642};
1643
1644const srtp_policy_t hmac_only_policy = {
1645 { ssrc_any_outbound, 0 }, /* SSRC */
1646 {
1647 NULL_CIPHER, /* cipher type */
1648 0, /* cipher key length in octets */
1649 HMAC_SHA1, /* authentication func type */
1650 20, /* auth key length in octets */
1651 4, /* auth tag length in octets */
1652 sec_serv_auth /* security services flag */
1653 },
1654 {
1655 NULL_CIPHER, /* cipher type */
1656 0, /* cipher key length in octets */
1657 HMAC_SHA1, /* authentication func type */
1658 20, /* auth key length in octets */
1659 4, /* auth tag length in octets */
1660 sec_serv_auth /* security services flag */
1661 },
1662 test_key,
David McGrew79870d62007-06-15 18:17:39 +00001663 NULL, /* indicates that EKT is not in use */
Jonathan Lennoxa1242f82010-05-17 21:46:04 +00001664 128, /* replay window size */
Jonathan Lennoxdcee5c62010-05-17 22:08:40 +00001665 0, /* retransmission not allowed */
Cullen Jennings235513a2005-09-21 22:51:36 +00001666 NULL
1667};
1668
jfigus8c36da22013-10-01 16:41:19 -04001669#ifdef OPENSSL
1670const srtp_policy_t aes128_gcm_8_policy = {
1671 { ssrc_any_outbound, 0 }, /* SSRC */
1672 { /* SRTP policy */
1673 AES_128_GCM, /* cipher type */
jfigus857009c2014-11-05 11:17:43 -05001674 SRTP_AES_128_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
jfigus8c36da22013-10-01 16:41:19 -04001675 NULL_AUTH, /* authentication func type */
1676 0, /* auth key length in octets */
1677 8, /* auth tag length in octets */
1678 sec_serv_conf_and_auth /* security services flag */
1679 },
1680 { /* SRTCP policy */
1681 AES_128_GCM, /* cipher type */
jfigus857009c2014-11-05 11:17:43 -05001682 SRTP_AES_128_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
jfigus8c36da22013-10-01 16:41:19 -04001683 NULL_AUTH, /* authentication func type */
1684 0, /* auth key length in octets */
1685 8, /* auth tag length in octets */
1686 sec_serv_conf_and_auth /* security services flag */
1687 },
1688 test_key,
1689 NULL, /* indicates that EKT is not in use */
1690 128, /* replay window size */
1691 0, /* retransmission not allowed */
1692 NULL
1693};
1694
1695const srtp_policy_t aes128_gcm_8_cauth_policy = {
1696 { ssrc_any_outbound, 0 }, /* SSRC */
1697 { /* SRTP policy */
1698 AES_128_GCM, /* cipher type */
jfigus857009c2014-11-05 11:17:43 -05001699 SRTP_AES_128_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
jfigus8c36da22013-10-01 16:41:19 -04001700 NULL_AUTH, /* authentication func type */
1701 0, /* auth key length in octets */
1702 8, /* auth tag length in octets */
1703 sec_serv_conf_and_auth /* security services flag */
1704 },
1705 { /* SRTCP policy */
1706 AES_128_GCM, /* cipher type */
jfigus857009c2014-11-05 11:17:43 -05001707 SRTP_AES_128_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
jfigus8c36da22013-10-01 16:41:19 -04001708 NULL_AUTH, /* authentication func type */
1709 0, /* auth key length in octets */
1710 8, /* auth tag length in octets */
1711 sec_serv_auth /* security services flag */
1712 },
1713 test_key,
1714 NULL, /* indicates that EKT is not in use */
1715 128, /* replay window size */
1716 0, /* retransmission not allowed */
1717 NULL
1718};
1719
1720const srtp_policy_t aes256_gcm_8_policy = {
1721 { ssrc_any_outbound, 0 }, /* SSRC */
1722 { /* SRTP policy */
1723 AES_256_GCM, /* cipher type */
jfigus857009c2014-11-05 11:17:43 -05001724 SRTP_AES_256_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
jfigus8c36da22013-10-01 16:41:19 -04001725 NULL_AUTH, /* authentication func type */
1726 0, /* auth key length in octets */
1727 8, /* auth tag length in octets */
1728 sec_serv_conf_and_auth /* security services flag */
1729 },
1730 { /* SRTCP policy */
1731 AES_256_GCM, /* cipher type */
jfigus857009c2014-11-05 11:17:43 -05001732 SRTP_AES_256_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
jfigus8c36da22013-10-01 16:41:19 -04001733 NULL_AUTH, /* authentication func type */
1734 0, /* auth key length in octets */
1735 8, /* auth tag length in octets */
1736 sec_serv_conf_and_auth /* security services flag */
1737 },
1738 test_key,
1739 NULL, /* indicates that EKT is not in use */
1740 128, /* replay window size */
1741 0, /* retransmission not allowed */
1742 NULL
1743};
1744
1745const srtp_policy_t aes256_gcm_8_cauth_policy = {
1746 { ssrc_any_outbound, 0 }, /* SSRC */
1747 { /* SRTP policy */
1748 AES_256_GCM, /* cipher type */
jfigus857009c2014-11-05 11:17:43 -05001749 SRTP_AES_256_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
jfigus8c36da22013-10-01 16:41:19 -04001750 NULL_AUTH, /* authentication func type */
1751 0, /* auth key length in octets */
1752 8, /* auth tag length in octets */
1753 sec_serv_conf_and_auth /* security services flag */
1754 },
1755 { /* SRTCP policy */
1756 AES_256_GCM, /* cipher type */
jfigus857009c2014-11-05 11:17:43 -05001757 SRTP_AES_256_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
jfigus8c36da22013-10-01 16:41:19 -04001758 NULL_AUTH, /* authentication func type */
1759 0, /* auth key length in octets */
1760 8, /* auth tag length in octets */
1761 sec_serv_auth /* security services flag */
1762 },
1763 test_key,
1764 NULL, /* indicates that EKT is not in use */
1765 128, /* replay window size */
1766 0, /* retransmission not allowed */
1767 NULL
1768};
1769#endif
1770
Cullen Jennings235513a2005-09-21 22:51:36 +00001771const srtp_policy_t null_policy = {
1772 { ssrc_any_outbound, 0 }, /* SSRC */
1773 {
1774 NULL_CIPHER, /* cipher type */
1775 0, /* cipher key length in octets */
1776 NULL_AUTH, /* authentication func type */
1777 0, /* auth key length in octets */
1778 0, /* auth tag length in octets */
1779 sec_serv_none /* security services flag */
1780 },
1781 {
1782 NULL_CIPHER, /* cipher type */
1783 0, /* cipher key length in octets */
1784 NULL_AUTH, /* authentication func type */
1785 0, /* auth key length in octets */
1786 0, /* auth tag length in octets */
1787 sec_serv_none /* security services flag */
1788 },
1789 test_key,
David McGrew79870d62007-06-15 18:17:39 +00001790 NULL, /* indicates that EKT is not in use */
Jonathan Lennoxa1242f82010-05-17 21:46:04 +00001791 128, /* replay window size */
Jonathan Lennoxdcee5c62010-05-17 22:08:40 +00001792 0, /* retransmission not allowed */
David McGrew79870d62007-06-15 18:17:39 +00001793 NULL
1794};
1795
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001796unsigned char test_256_key[46] = {
1797 0xf0, 0xf0, 0x49, 0x14, 0xb5, 0x13, 0xf2, 0x76,
1798 0x3a, 0x1b, 0x1f, 0xa1, 0x30, 0xf1, 0x0e, 0x29,
1799 0x98, 0xf6, 0xf6, 0xe4, 0x3e, 0x43, 0x09, 0xd1,
1800 0xe6, 0x22, 0xa0, 0xe3, 0x32, 0xb9, 0xf1, 0xb6,
1801
1802 0x3b, 0x04, 0x80, 0x3d, 0xe5, 0x1e, 0xe7, 0xc9,
1803 0x64, 0x23, 0xab, 0x5b, 0x78, 0xd2
1804};
1805
1806const srtp_policy_t aes_256_hmac_policy = {
1807 { ssrc_any_outbound, 0 }, /* SSRC */
1808 { /* SRTP policy */
1809 AES_ICM, /* cipher type */
1810 46, /* cipher key length in octets */
1811 HMAC_SHA1, /* authentication func type */
1812 20, /* auth key length in octets */
1813 10, /* auth tag length in octets */
1814 sec_serv_conf_and_auth /* security services flag */
1815 },
1816 { /* SRTCP policy */
1817 AES_ICM, /* cipher type */
1818 46, /* cipher key length in octets */
1819 HMAC_SHA1, /* authentication func type */
1820 20, /* auth key length in octets */
1821 10, /* auth tag length in octets */
1822 sec_serv_conf_and_auth /* security services flag */
1823 },
1824 test_256_key,
1825 NULL, /* indicates that EKT is not in use */
1826 128, /* replay window size */
1827 0, /* retransmission not allowed */
1828 NULL
1829};
1830
David McGrew79870d62007-06-15 18:17:39 +00001831uint8_t ekt_test_key[16] = {
1832 0x77, 0x26, 0x9d, 0xac, 0x16, 0xa3, 0x28, 0xca,
1833 0x8e, 0xc9, 0x68, 0x4b, 0xcc, 0xc4, 0xd2, 0x1b
1834};
1835
1836#include "ekt.h"
1837
jfigusc5887e72014-11-06 09:46:18 -05001838srtp_ekt_policy_ctx_t ekt_test_policy = {
David McGrew79870d62007-06-15 18:17:39 +00001839 0xa5a5, /* SPI */
jfigusc5887e72014-11-06 09:46:18 -05001840 SRTP_EKT_CIPHER_AES_128_ECB,
David McGrew79870d62007-06-15 18:17:39 +00001841 ekt_test_key,
1842 NULL
1843};
1844
1845const srtp_policy_t hmac_only_with_ekt_policy = {
1846 { ssrc_any_outbound, 0 }, /* SSRC */
1847 {
1848 NULL_CIPHER, /* cipher type */
1849 0, /* cipher key length in octets */
1850 HMAC_SHA1, /* authentication func type */
1851 20, /* auth key length in octets */
1852 4, /* auth tag length in octets */
1853 sec_serv_auth /* security services flag */
1854 },
1855 {
1856 NULL_CIPHER, /* cipher type */
1857 0, /* cipher key length in octets */
1858 HMAC_SHA1, /* authentication func type */
1859 20, /* auth key length in octets */
1860 4, /* auth tag length in octets */
1861 sec_serv_auth /* security services flag */
1862 },
1863 test_key,
1864 &ekt_test_policy, /* indicates that EKT is not in use */
Jonathan Lennoxa1242f82010-05-17 21:46:04 +00001865 128, /* replay window size */
Jonathan Lennoxdcee5c62010-05-17 22:08:40 +00001866 0, /* retransmission not allowed */
Cullen Jennings235513a2005-09-21 22:51:36 +00001867 NULL
1868};
1869
1870
1871/*
1872 * an array of pointers to the policies listed above
1873 *
1874 * This array is used to test various aspects of libSRTP for
1875 * different cryptographic policies. The order of the elements
1876 * matters - the timing test generates output that can be used
1877 * in a plot (see the gnuplot script file 'timing'). If you
1878 * add to this list, you should do it at the end.
1879 */
1880
1881#define USE_TMMH 0
1882
1883const srtp_policy_t *
1884policy_array[] = {
1885 &hmac_only_policy,
1886#if USE_TMMH
1887 &tmmh_only_policy,
1888#endif
1889 &aes_only_policy,
1890#if USE_TMMH
1891 &aes_tmmh_policy,
1892#endif
1893 &default_policy,
jfigus8c36da22013-10-01 16:41:19 -04001894#ifdef OPENSSL
1895 &aes128_gcm_8_policy,
1896 &aes128_gcm_8_cauth_policy,
1897 &aes256_gcm_8_policy,
1898 &aes256_gcm_8_cauth_policy,
1899#endif
Cullen Jennings235513a2005-09-21 22:51:36 +00001900 &null_policy,
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001901 &aes_256_hmac_policy,
David McGrew79870d62007-06-15 18:17:39 +00001902 &hmac_only_with_ekt_policy,
Cullen Jennings235513a2005-09-21 22:51:36 +00001903 NULL
1904};
1905
1906const srtp_policy_t wildcard_policy = {
1907 { ssrc_any_outbound, 0 }, /* SSRC */
1908 { /* SRTP policy */
1909 AES_128_ICM, /* cipher type */
1910 30, /* cipher key length in octets */
1911 HMAC_SHA1, /* authentication func type */
1912 16, /* auth key length in octets */
1913 10, /* auth tag length in octets */
1914 sec_serv_conf_and_auth /* security services flag */
1915 },
1916 { /* SRTCP policy */
1917 AES_128_ICM, /* cipher type */
1918 30, /* cipher key length in octets */
1919 HMAC_SHA1, /* authentication func type */
1920 16, /* auth key length in octets */
1921 10, /* auth tag length in octets */
1922 sec_serv_conf_and_auth /* security services flag */
1923 },
1924 test_key,
Jonathan Lennox28bd7c12010-05-15 00:23:19 +00001925 NULL,
Jonathan Lennoxa1242f82010-05-17 21:46:04 +00001926 128, /* replay window size */
Jonathan Lennoxdcee5c62010-05-17 22:08:40 +00001927 0, /* retransmission not allowed */
Cullen Jennings235513a2005-09-21 22:51:36 +00001928 NULL
1929};