blob: 186e8c24b2b066d18134cfa160b79cdd92bab60d [file] [log] [blame]
Cullen Jennings235513a2005-09-21 22:51:36 +00001/*
2 * srtp_driver.c
jfigus67b9c732014-11-20 10:17:21 -05003 *
Cullen Jennings235513a2005-09-21 22:51:36 +00004 * a test driver for libSRTP
5 *
6 * David A. McGrew
7 * Cisco Systems, Inc.
8 */
9/*
jfigus67b9c732014-11-20 10:17:21 -050010 *
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.
jfigus67b9c732014-11-20 10:17:21 -050013 *
Cullen Jennings235513a2005-09-21 22:51:36 +000014 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
16 * are met:
jfigus67b9c732014-11-20 10:17:21 -050017 *
Cullen Jennings235513a2005-09-21 22:51:36 +000018 * Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
jfigus67b9c732014-11-20 10:17:21 -050020 *
Cullen Jennings235513a2005-09-21 22:51:36 +000021 * 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.
jfigus67b9c732014-11-20 10:17:21 -050025 *
Cullen Jennings235513a2005-09-21 22:51:36 +000026 * 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.
jfigus67b9c732014-11-20 10:17:21 -050029 *
Cullen Jennings235513a2005-09-21 22:51:36 +000030 * 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
jfigus67b9c732014-11-20 10:17:21 -0500100srtp_print_policy(const srtp_policy_t *policy);
Cullen Jennings235513a2005-09-21 22:51:36 +0000101
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
jfigus67b9c732014-11-20 10:17:21 -0500111usage (char *prog_name)
112{
113 printf("usage: %s [ -t ][ -c ][ -v ][-d <debug_module> ]* [ -l ]\n"
114 " -t run timing test\n"
115 " -r run rejection timing test\n"
116 " -c run codec timing test\n"
117 " -v run validation tests\n"
118 " -d <mod> turn on debugging module <mod>\n"
119 " -l list debugging modules\n", prog_name);
120 exit(1);
Cullen Jennings235513a2005-09-21 22:51:36 +0000121}
122
123/*
124 * The policy_array is a null-terminated array of policy structs. it
125 * is declared at the end of this file
126 */
127
128extern const srtp_policy_t *policy_array[];
129
130
131/* the wildcard_policy is declared below; it has a wildcard ssrc */
132
133extern const srtp_policy_t wildcard_policy;
134
135/*
136 * mod_driver debug module - debugging module for this test driver
137 *
jfigus67b9c732014-11-20 10:17:21 -0500138 * we use the crypto_kernel debugging system in this driver, which
Cullen Jennings235513a2005-09-21 22:51:36 +0000139 * makes the interface uniform and increases portability
jfigus67b9c732014-11-20 10:17:21 -0500140 */
Cullen Jennings235513a2005-09-21 22:51:36 +0000141
142debug_module_t mod_driver = {
jfigus67b9c732014-11-20 10:17:21 -0500143 0, /* debugging is off by default */
144 "driver" /* printable name for module */
Cullen Jennings235513a2005-09-21 22:51:36 +0000145};
146
147int
jfigus67b9c732014-11-20 10:17:21 -0500148main (int argc, char *argv[])
149{
150 int q;
151 unsigned do_timing_test = 0;
152 unsigned do_rejection_test = 0;
153 unsigned do_codec_timing = 0;
154 unsigned do_validation = 0;
155 unsigned do_list_mods = 0;
156 srtp_err_status_t status;
Cullen Jennings235513a2005-09-21 22:51:36 +0000157
158 /*
jfigus67b9c732014-11-20 10:17:21 -0500159 * verify that the compiler has interpreted the header data
160 * structure srtp_hdr_t correctly
Cullen Jennings235513a2005-09-21 22:51:36 +0000161 */
jfigus67b9c732014-11-20 10:17:21 -0500162 if (sizeof(srtp_hdr_t) != 12) {
163 printf("error: srtp_hdr_t has incorrect size"
164 "(size is %ld bytes, expected 12)\n",
165 (long)sizeof(srtp_hdr_t));
166 exit(1);
Cullen Jennings235513a2005-09-21 22:51:36 +0000167 }
168
jfigus67b9c732014-11-20 10:17:21 -0500169 /* initialize srtp library */
170 status = srtp_init();
171 if (status) {
172 printf("error: srtp init failed with error code %d\n", status);
173 exit(1);
174 }
175
176 /* load srtp_driver debug module */
jfigus92736bc2014-11-21 10:30:54 -0500177 status = srtp_crypto_kernel_load_debug_module(&mod_driver);
jfigus67b9c732014-11-20 10:17:21 -0500178 if (status) {
179 printf("error: load of srtp_driver debug module failed "
180 "with error code %d\n", status);
181 exit(1);
182 }
183
184 /* process input arguments */
185 while (1) {
186 q = getopt_s(argc, argv, "trcvld:");
187 if (q == -1) {
188 break;
189 }
190 switch (q) {
191 case 't':
192 do_timing_test = 1;
193 break;
194 case 'r':
195 do_rejection_test = 1;
196 break;
197 case 'c':
198 do_codec_timing = 1;
199 break;
200 case 'v':
201 do_validation = 1;
202 break;
203 case 'l':
204 do_list_mods = 1;
205 break;
206 case 'd':
jfigus92736bc2014-11-21 10:30:54 -0500207 status = srtp_crypto_kernel_set_debug_module(optarg_s, 1);
jfigus67b9c732014-11-20 10:17:21 -0500208 if (status) {
209 printf("error: set debug module (%s) failed\n", optarg_s);
210 exit(1);
211 }
212 break;
213 default:
214 usage(argv[0]);
215 }
216 }
217
218 if (!do_validation && !do_timing_test && !do_codec_timing
219 && !do_list_mods && !do_rejection_test) {
220 usage(argv[0]);
221 }
222
223 if (do_list_mods) {
jfigus92736bc2014-11-21 10:30:54 -0500224 status = srtp_crypto_kernel_list_debug_modules();
jfigus67b9c732014-11-20 10:17:21 -0500225 if (status) {
226 printf("error: list of debug modules failed\n");
227 exit(1);
228 }
229 }
230
231 if (do_validation) {
232 const srtp_policy_t **policy = policy_array;
233 srtp_policy_t *big_policy;
234
235 /* loop over policy array, testing srtp and srtcp for each policy */
236 while (*policy != NULL) {
237 printf("testing srtp_protect and srtp_unprotect\n");
238 if (srtp_test(*policy) == srtp_err_status_ok) {
239 printf("passed\n\n");
240 } else{
241 printf("failed\n");
242 exit(1);
243 }
244 printf("testing srtp_protect_rtcp and srtp_unprotect_rtcp\n");
245 if (srtcp_test(*policy) == srtp_err_status_ok) {
246 printf("passed\n\n");
247 } else{
248 printf("failed\n");
249 exit(1);
250 }
251 policy++;
252 }
253
254 /* create a big policy list and run tests on it */
255 status = srtp_create_big_policy(&big_policy);
256 if (status) {
257 printf("unexpected failure with error code %d\n", status);
258 exit(1);
259 }
260 printf("testing srtp_protect and srtp_unprotect with big policy\n");
261 if (srtp_test(big_policy) == srtp_err_status_ok) {
262 printf("passed\n\n");
263 } else{
264 printf("failed\n");
265 exit(1);
266 }
267 status = srtp_dealloc_big_policy(big_policy);
268 if (status) {
269 printf("unexpected failure with error code %d\n", status);
270 exit(1);
271 }
272
273 /* run test on wildcard policy */
274 printf("testing srtp_protect and srtp_unprotect on "
275 "wildcard ssrc policy\n");
276 if (srtp_test(&wildcard_policy) == srtp_err_status_ok) {
277 printf("passed\n\n");
278 } else{
279 printf("failed\n");
280 exit(1);
281 }
282
283 /*
284 * run validation test against the reference packets - note
285 * that this test only covers the default policy
286 */
287 printf("testing srtp_protect and srtp_unprotect against "
288 "reference packets\n");
289 if (srtp_validate() == srtp_err_status_ok) {
290 printf("passed\n\n");
291 } else{
292 printf("failed\n");
293 exit(1);
294 }
295
jfigusa14b5a02013-03-29 12:24:12 -0400296//FIXME: need to get this working with the OpenSSL AES module
297#ifndef OPENSSL
jfigus67b9c732014-11-20 10:17:21 -0500298 /*
299 * run validation test against the reference packets for
300 * AES-256
301 */
302 printf("testing srtp_protect and srtp_unprotect against "
303 "reference packets (AES-256)\n");
304 if (srtp_validate_aes_256() == srtp_err_status_ok) {
305 printf("passed\n\n");
306 } else{
307 printf("failed\n");
308 exit(1);
309 }
jfigusa14b5a02013-03-29 12:24:12 -0400310#endif
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000311
jfigus67b9c732014-11-20 10:17:21 -0500312 /*
313 * test the function srtp_remove_stream()
314 */
315 printf("testing srtp_remove_stream()...");
316 if (srtp_test_remove_stream() == srtp_err_status_ok) {
317 printf("passed\n");
318 } else{
319 printf("failed\n");
320 exit(1);
321 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000322 }
jfigus67b9c732014-11-20 10:17:21 -0500323
324 if (do_timing_test) {
325 const srtp_policy_t **policy = policy_array;
326
327 /* loop over policies, run timing test for each */
328 while (*policy != NULL) {
329 srtp_print_policy(*policy);
330 srtp_do_timing(*policy);
331 policy++;
332 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000333 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000334
jfigus67b9c732014-11-20 10:17:21 -0500335 if (do_rejection_test) {
336 const srtp_policy_t **policy = policy_array;
337
338 /* loop over policies, run rejection timing test for each */
339 while (*policy != NULL) {
340 srtp_print_policy(*policy);
341 srtp_do_rejection_timing(*policy);
342 policy++;
343 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000344 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000345
jfigus67b9c732014-11-20 10:17:21 -0500346 if (do_codec_timing) {
347 srtp_policy_t policy;
348 int ignore;
349 double mips = mips_estimate(1000000000, &ignore);
Cullen Jennings235513a2005-09-21 22:51:36 +0000350
jfigus67b9c732014-11-20 10:17:21 -0500351 srtp_crypto_policy_set_rtp_default(&policy.rtp);
352 srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
353 policy.ssrc.type = ssrc_specific;
354 policy.ssrc.value = 0xdecafbad;
355 policy.key = test_key;
356 policy.ekt = NULL;
357 policy.window_size = 128;
358 policy.allow_repeat_tx = 0;
359 policy.next = NULL;
Cullen Jennings235513a2005-09-21 22:51:36 +0000360
jfigus67b9c732014-11-20 10:17:21 -0500361 printf("mips estimate: %e\n", mips);
Cullen Jennings235513a2005-09-21 22:51:36 +0000362
jfigus67b9c732014-11-20 10:17:21 -0500363 printf("testing srtp processing time for voice codecs:\n");
364 printf("codec\t\tlength (octets)\t\tsrtp instructions/second\n");
365 printf("G.711\t\t%d\t\t\t%e\n", 80,
366 (double)mips * (80 * 8) /
367 srtp_bits_per_second(80, &policy) / .01 );
368 printf("G.711\t\t%d\t\t\t%e\n", 160,
369 (double)mips * (160 * 8) /
370 srtp_bits_per_second(160, &policy) / .02);
371 printf("G.726-32\t%d\t\t\t%e\n", 40,
372 (double)mips * (40 * 8) /
373 srtp_bits_per_second(40, &policy) / .01 );
374 printf("G.726-32\t%d\t\t\t%e\n", 80,
375 (double)mips * (80 * 8) /
376 srtp_bits_per_second(80, &policy) / .02);
377 printf("G.729\t\t%d\t\t\t%e\n", 10,
378 (double)mips * (10 * 8) /
379 srtp_bits_per_second(10, &policy) / .01 );
380 printf("G.729\t\t%d\t\t\t%e\n", 20,
381 (double)mips * (20 * 8) /
382 srtp_bits_per_second(20, &policy) / .02 );
383 printf("Wideband\t%d\t\t\t%e\n", 320,
384 (double)mips * (320 * 8) /
385 srtp_bits_per_second(320, &policy) / .01 );
386 printf("Wideband\t%d\t\t\t%e\n", 640,
387 (double)mips * (640 * 8) /
388 srtp_bits_per_second(640, &policy) / .02 );
389 }
Jonathan Lennoxdfb30842010-05-15 04:52:01 +0000390
jfigus67b9c732014-11-20 10:17:21 -0500391 status = srtp_shutdown();
392 if (status) {
393 printf("error: srtp shutdown failed with error code %d\n", status);
394 exit(1);
395 }
396
397 return 0;
Cullen Jennings235513a2005-09-21 22:51:36 +0000398}
399
400
401
402/*
403 * srtp_create_test_packet(len, ssrc) returns a pointer to a
404 * (malloced) example RTP packet whose data field has the length given
405 * by pkt_octet_len and the SSRC value ssrc. The total length of the
406 * packet is twelve octets longer, since the header is at the
407 * beginning. There is room at the end of the packet for a trailer,
408 * and the four octets following the packet are filled with 0xff
409 * values to enable testing for overwrites.
410 *
411 * note that the location of the test packet can (and should) be
412 * deallocated with the free() call once it is no longer needed.
413 */
414
415srtp_hdr_t *
jfigus67b9c732014-11-20 10:17:21 -0500416srtp_create_test_packet (int pkt_octet_len, uint32_t ssrc)
417{
418 int i;
419 uint8_t *buffer;
420 srtp_hdr_t *hdr;
421 int bytes_in_hdr = 12;
Cullen Jennings235513a2005-09-21 22:51:36 +0000422
jfigus67b9c732014-11-20 10:17:21 -0500423 /* allocate memory for test packet */
424 hdr = (srtp_hdr_t*)malloc(pkt_octet_len + bytes_in_hdr
425 + SRTP_MAX_TRAILER_LEN + 4);
426 if (!hdr) {
427 return NULL;
428 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000429
jfigus67b9c732014-11-20 10:17:21 -0500430 hdr->version = 2; /* RTP version two */
431 hdr->p = 0; /* no padding needed */
432 hdr->x = 0; /* no header extension */
433 hdr->cc = 0; /* no CSRCs */
434 hdr->m = 0; /* marker bit */
435 hdr->pt = 0xf; /* payload type */
436 hdr->seq = htons(0x1234); /* sequence number */
437 hdr->ts = htonl(0xdecafbad); /* timestamp */
438 hdr->ssrc = htonl(ssrc); /* synch. source */
Cullen Jennings235513a2005-09-21 22:51:36 +0000439
jfigus67b9c732014-11-20 10:17:21 -0500440 buffer = (uint8_t*)hdr;
441 buffer += bytes_in_hdr;
Cullen Jennings235513a2005-09-21 22:51:36 +0000442
jfigus67b9c732014-11-20 10:17:21 -0500443 /* set RTP data to 0xab */
444 for (i = 0; i < pkt_octet_len; i++) {
445 *buffer++ = 0xab;
446 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000447
jfigus67b9c732014-11-20 10:17:21 -0500448 /* set post-data value to 0xffff to enable overrun checking */
449 for (i = 0; i < SRTP_MAX_TRAILER_LEN + 4; i++) {
450 *buffer++ = 0xff;
451 }
452
453 return hdr;
Cullen Jennings235513a2005-09-21 22:51:36 +0000454}
455
456void
jfigus67b9c732014-11-20 10:17:21 -0500457srtp_do_timing (const srtp_policy_t *policy)
458{
459 int len;
Cullen Jennings235513a2005-09-21 22:51:36 +0000460
jfigus67b9c732014-11-20 10:17:21 -0500461 /*
462 * note: the output of this function is formatted so that it
463 * can be used in gnuplot. '#' indicates a comment, and "\r\n"
464 * terminates a record
465 */
466
467 printf("# testing srtp throughput:\r\n");
468 printf("# mesg length (octets)\tthroughput (megabits per second)\r\n");
469
470 for (len = 16; len <= 2048; len *= 2) {
471 printf("%d\t\t\t%f\r\n", len,
472 srtp_bits_per_second(len, policy) / 1.0E6);
473 }
474
475 /* these extra linefeeds let gnuplot know that a dataset is done */
476 printf("\r\n\r\n");
Cullen Jennings235513a2005-09-21 22:51:36 +0000477
478}
479
480void
jfigus67b9c732014-11-20 10:17:21 -0500481srtp_do_rejection_timing (const srtp_policy_t *policy)
482{
483 int len;
Cullen Jennings235513a2005-09-21 22:51:36 +0000484
jfigus67b9c732014-11-20 10:17:21 -0500485 /*
486 * note: the output of this function is formatted so that it
487 * can be used in gnuplot. '#' indicates a comment, and "\r\n"
488 * terminates a record
489 */
490
491 printf("# testing srtp rejection throughput:\r\n");
492 printf("# mesg length (octets)\trejections per second\r\n");
493
494 for (len = 8; len <= 2048; len *= 2) {
495 printf("%d\t\t\t%e\r\n", len, srtp_rejections_per_second(len, policy));
496 }
497
498 /* these extra linefeeds let gnuplot know that a dataset is done */
499 printf("\r\n\r\n");
Cullen Jennings235513a2005-09-21 22:51:36 +0000500
501}
502
503
504#define MAX_MSG_LEN 1024
505
506double
jfigus67b9c732014-11-20 10:17:21 -0500507srtp_bits_per_second (int msg_len_octets, const srtp_policy_t *policy)
508{
509 srtp_t srtp;
510 srtp_hdr_t *mesg;
511 int i;
512 clock_t timer;
513 int num_trials = 100000;
514 int len;
515 uint32_t ssrc;
516 srtp_err_status_t status;
Cullen Jennings235513a2005-09-21 22:51:36 +0000517
jfigus67b9c732014-11-20 10:17:21 -0500518 /*
519 * allocate and initialize an srtp session
520 */
521 status = srtp_create(&srtp, policy);
Cullen Jennings235513a2005-09-21 22:51:36 +0000522 if (status) {
jfigus67b9c732014-11-20 10:17:21 -0500523 printf("error: srtp_create() failed with error code %d\n", status);
524 exit(1);
Cullen Jennings235513a2005-09-21 22:51:36 +0000525 }
526
jfigus67b9c732014-11-20 10:17:21 -0500527 /*
528 * if the ssrc is unspecified, use a predetermined one
529 */
530 if (policy->ssrc.type != ssrc_specific) {
531 ssrc = 0xdeadbeef;
532 } else {
533 ssrc = policy->ssrc.value;
Jonathan Lennox75b36872010-05-21 00:30:21 +0000534 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000535
jfigus67b9c732014-11-20 10:17:21 -0500536 /*
537 * create a test packet
538 */
539 mesg = srtp_create_test_packet(msg_len_octets, ssrc);
540 if (mesg == NULL) {
541 return 0.0; /* indicate failure by returning zero */
Jonathan Lennox80c4c832010-05-17 19:30:28 +0000542
jfigus67b9c732014-11-20 10:17:21 -0500543 }
544 timer = clock();
545 for (i = 0; i < num_trials; i++) {
546 len = msg_len_octets + 12; /* add in rtp header length */
547
548 /* srtp protect message */
549 status = srtp_protect(srtp, mesg, &len);
550 if (status) {
551 printf("error: srtp_protect() failed with error code %d\n", status);
552 exit(1);
553 }
554
555 /* increment message number */
556 {
557 /* hack sequence to avoid problems with macros for htons/ntohs on some systems */
558 short new_seq = ntohs(mesg->seq) + 1;
559 mesg->seq = htons(new_seq);
560 }
561 }
562 timer = clock() - timer;
563
564 free(mesg);
565
566 status = srtp_dealloc(srtp);
567 if (status) {
568 printf("error: srtp_dealloc() failed with error code %d\n", status);
569 exit(1);
570 }
571
572 return (double)(msg_len_octets) * 8 *
573 num_trials * CLOCKS_PER_SEC / timer;
Cullen Jennings235513a2005-09-21 22:51:36 +0000574}
575
576double
jfigus67b9c732014-11-20 10:17:21 -0500577srtp_rejections_per_second (int msg_len_octets, const srtp_policy_t *policy)
578{
579 srtp_ctx_t *srtp;
580 srtp_hdr_t *mesg;
581 int i;
582 int len;
583 clock_t timer;
584 int num_trials = 1000000;
585 uint32_t ssrc = policy->ssrc.value;
586 srtp_err_status_t status;
Cullen Jennings235513a2005-09-21 22:51:36 +0000587
jfigus67b9c732014-11-20 10:17:21 -0500588 /*
589 * allocate and initialize an srtp session
590 */
591 status = srtp_create(&srtp, policy);
592 if (status) {
593 printf("error: srtp_create() failed with error code %d\n", status);
594 exit(1);
595 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000596
jfigus67b9c732014-11-20 10:17:21 -0500597 mesg = srtp_create_test_packet(msg_len_octets, ssrc);
598 if (mesg == NULL) {
599 return 0.0; /* indicate failure by returning zero */
600
601 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000602 len = msg_len_octets;
jfigus67b9c732014-11-20 10:17:21 -0500603 srtp_protect(srtp, (srtp_hdr_t*)mesg, &len);
Cullen Jennings235513a2005-09-21 22:51:36 +0000604
jfigus67b9c732014-11-20 10:17:21 -0500605 timer = clock();
606 for (i = 0; i < num_trials; i++) {
607 len = msg_len_octets;
608 srtp_unprotect(srtp, (srtp_hdr_t*)mesg, &len);
609 }
610 timer = clock() - timer;
Jonathan Lennox80c4c832010-05-17 19:30:28 +0000611
jfigus67b9c732014-11-20 10:17:21 -0500612 free(mesg);
Jonathan Lennox80c4c832010-05-17 19:30:28 +0000613
jfigus67b9c732014-11-20 10:17:21 -0500614 status = srtp_dealloc(srtp);
615 if (status) {
616 printf("error: srtp_dealloc() failed with error code %d\n", status);
617 exit(1);
618 }
619
620 return (double)num_trials * CLOCKS_PER_SEC / timer;
Cullen Jennings235513a2005-09-21 22:51:36 +0000621}
622
623
624void
jfigus67b9c732014-11-20 10:17:21 -0500625err_check (srtp_err_status_t s)
626{
627 if (s == srtp_err_status_ok) {
628 return;
629 } else{
630 fprintf(stderr, "error: unexpected srtp failure (code %d)\n", s);
631 }
632 exit(1);
Cullen Jennings235513a2005-09-21 22:51:36 +0000633}
634
jfigus857009c2014-11-05 11:17:43 -0500635srtp_err_status_t
jfigus67b9c732014-11-20 10:17:21 -0500636srtp_test (const srtp_policy_t *policy)
637{
638 int i;
639 srtp_t srtp_sender;
640 srtp_t srtp_rcvr;
641 srtp_err_status_t status = srtp_err_status_ok;
642 srtp_hdr_t *hdr, *hdr2;
643 uint8_t hdr_enc[64];
644 uint8_t *pkt_end;
645 int msg_len_octets, msg_len_enc;
646 int len;
647 int tag_length = policy->rtp.auth_tag_len;
648 uint32_t ssrc;
649 srtp_policy_t *rcvr_policy;
Cullen Jennings235513a2005-09-21 22:51:36 +0000650
jfigus67b9c732014-11-20 10:17:21 -0500651 err_check(srtp_create(&srtp_sender, policy));
Cullen Jennings235513a2005-09-21 22:51:36 +0000652
jfigus67b9c732014-11-20 10:17:21 -0500653 /* print out policy */
654 err_check(srtp_session_print_policy(srtp_sender));
Cullen Jennings235513a2005-09-21 22:51:36 +0000655
jfigus67b9c732014-11-20 10:17:21 -0500656 /*
657 * initialize data buffer, using the ssrc in the policy unless that
658 * value is a wildcard, in which case we'll just use an arbitrary
659 * one
660 */
661 if (policy->ssrc.type != ssrc_specific) {
662 ssrc = 0xdecafbad;
663 } else{
664 ssrc = policy->ssrc.value;
Cullen Jennings235513a2005-09-21 22:51:36 +0000665 }
jfigus67b9c732014-11-20 10:17:21 -0500666 msg_len_octets = 28;
667 hdr = srtp_create_test_packet(msg_len_octets, ssrc);
Cullen Jennings235513a2005-09-21 22:51:36 +0000668
jfigus67b9c732014-11-20 10:17:21 -0500669 if (hdr == NULL) {
670 return srtp_err_status_alloc_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +0000671 }
jfigus67b9c732014-11-20 10:17:21 -0500672 hdr2 = srtp_create_test_packet(msg_len_octets, ssrc);
673 if (hdr2 == NULL) {
674 free(hdr);
675 return srtp_err_status_alloc_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +0000676 }
677
Marcus Sundberg5c40da82005-10-08 18:15:00 +0000678 /* set message length */
679 len = msg_len_octets;
680
jfigus67b9c732014-11-20 10:17:21 -0500681 debug_print(mod_driver, "before protection:\n%s",
682 srtp_packet_to_string(hdr, len));
683
684#if PRINT_REFERENCE_PACKET
685 debug_print(mod_driver, "reference packet before protection:\n%s",
686 octet_string_hex_string((uint8_t*)hdr, len));
687#endif
Cullen Jennings235513a2005-09-21 22:51:36 +0000688 err_check(srtp_protect(srtp_sender, hdr, &len));
Cullen Jennings235513a2005-09-21 22:51:36 +0000689
jfigus67b9c732014-11-20 10:17:21 -0500690 debug_print(mod_driver, "after protection:\n%s",
691 srtp_packet_to_string(hdr, len));
692#if PRINT_REFERENCE_PACKET
693 debug_print(mod_driver, "after protection:\n%s",
694 octet_string_hex_string((uint8_t*)hdr, len));
695#endif
696
697 /* save protected message and length */
698 memcpy(hdr_enc, hdr, len);
699 msg_len_enc = len;
700
701 /*
702 * check for overrun of the srtp_protect() function
703 *
704 * The packet is followed by a value of 0xfffff; if the value of the
705 * data following the packet is different, then we know that the
706 * protect function is overwriting the end of the packet.
707 */
708 pkt_end = (uint8_t*)hdr + sizeof(srtp_hdr_t)
709 + msg_len_octets + tag_length;
710 for (i = 0; i < 4; i++) {
711 if (pkt_end[i] != 0xff) {
712 fprintf(stdout, "overwrite in srtp_protect() function "
713 "(expected %x, found %x in trailing octet %d)\n",
714 0xff, ((uint8_t*)hdr)[i], i);
715 free(hdr);
716 free(hdr2);
717 return srtp_err_status_algo_fail;
718 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000719 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000720
jfigus67b9c732014-11-20 10:17:21 -0500721 /*
722 * if the policy includes confidentiality, check that ciphertext is
723 * different than plaintext
724 *
725 * Note that this check will give false negatives, with some small
726 * probability, especially if the packets are short. For that
727 * reason, we skip this check if the plaintext is less than four
728 * octets long.
729 */
730 if ((policy->rtp.sec_serv & sec_serv_conf) && (msg_len_octets >= 4)) {
731 printf("testing that ciphertext is distinct from plaintext...");
732 status = srtp_err_status_algo_fail;
733 for (i = 12; i < msg_len_octets + 12; i++) {
734 if (((uint8_t*)hdr)[i] != ((uint8_t*)hdr2)[i]) {
735 status = srtp_err_status_ok;
736 }
737 }
738 if (status) {
739 printf("failed\n");
740 free(hdr);
741 free(hdr2);
742 return status;
743 }
744 printf("passed\n");
745 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000746
jfigus67b9c732014-11-20 10:17:21 -0500747 /*
748 * if the policy uses a 'wildcard' ssrc, then we need to make a copy
749 * of the policy that changes the direction to inbound
750 *
751 * we always copy the policy into the rcvr_policy, since otherwise
752 * the compiler would fret about the constness of the policy
753 */
754 rcvr_policy = (srtp_policy_t*)malloc(sizeof(srtp_policy_t));
755 if (rcvr_policy == NULL) {
756 free(hdr);
757 free(hdr2);
758 return srtp_err_status_alloc_fail;
759 }
760 memcpy(rcvr_policy, policy, sizeof(srtp_policy_t));
761 if (policy->ssrc.type == ssrc_any_outbound) {
762 rcvr_policy->ssrc.type = ssrc_any_inbound;
763 }
764
765 err_check(srtp_create(&srtp_rcvr, rcvr_policy));
766
767 err_check(srtp_unprotect(srtp_rcvr, hdr, &len));
768
769 debug_print(mod_driver, "after unprotection:\n%s",
770 srtp_packet_to_string(hdr, len));
771
772 /* verify that the unprotected packet matches the origial one */
773 for (i = 0; i < msg_len_octets; i++) {
774 if (((uint8_t*)hdr)[i] != ((uint8_t*)hdr2)[i]) {
775 fprintf(stdout, "mismatch at octet %d\n", i);
776 status = srtp_err_status_algo_fail;
777 }
778 }
779 if (status) {
780 free(hdr);
781 free(hdr2);
782 free(rcvr_policy);
783 return status;
784 }
785
786 /*
787 * if the policy includes authentication, then test for false positives
788 */
789 if (policy->rtp.sec_serv & sec_serv_auth) {
790 char *data = ((char*)hdr) + 12;
791
792 printf("testing for false positives in replay check...");
793
794 /* set message length */
795 len = msg_len_enc;
796
797 /* unprotect a second time - should fail with a replay error */
798 status = srtp_unprotect(srtp_rcvr, hdr_enc, &len);
799 if (status != srtp_err_status_replay_fail) {
800 printf("failed with error code %d\n", status);
801 free(hdr);
802 free(hdr2);
803 free(rcvr_policy);
804 return status;
805 } else {
806 printf("passed\n");
807 }
808
809 printf("testing for false positives in auth check...");
810
811 /* increment sequence number in header */
812 hdr->seq++;
813
814 /* set message length */
815 len = msg_len_octets;
816
817 /* apply protection */
818 err_check(srtp_protect(srtp_sender, hdr, &len));
819
820 /* flip bits in packet */
821 data[0] ^= 0xff;
822
823 /* unprotect, and check for authentication failure */
824 status = srtp_unprotect(srtp_rcvr, hdr, &len);
825 if (status != srtp_err_status_auth_fail) {
826 printf("failed\n");
827 free(hdr);
828 free(hdr2);
829 free(rcvr_policy);
830 return status;
831 } else {
832 printf("passed\n");
833 }
834
835 }
836
837 err_check(srtp_dealloc(srtp_sender));
838 err_check(srtp_dealloc(srtp_rcvr));
839
840 free(hdr);
841 free(hdr2);
842 free(rcvr_policy);
843 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +0000844}
845
846
jfigus857009c2014-11-05 11:17:43 -0500847srtp_err_status_t
jfigus67b9c732014-11-20 10:17:21 -0500848srtcp_test (const srtp_policy_t *policy)
849{
850 int i;
851 srtp_t srtcp_sender;
852 srtp_t srtcp_rcvr;
853 srtp_err_status_t status = srtp_err_status_ok;
854 srtp_hdr_t *hdr, *hdr2;
855 uint8_t hdr_enc[64];
856 uint8_t *pkt_end;
857 int msg_len_octets, msg_len_enc;
858 int len;
859 int tag_length = policy->rtp.auth_tag_len;
860 uint32_t ssrc;
861 srtp_policy_t *rcvr_policy;
David McGrew9c70f292006-05-03 19:38:38 +0000862
jfigus67b9c732014-11-20 10:17:21 -0500863 err_check(srtp_create(&srtcp_sender, policy));
David McGrew9c70f292006-05-03 19:38:38 +0000864
jfigus67b9c732014-11-20 10:17:21 -0500865 /* print out policy */
866 err_check(srtp_session_print_policy(srtcp_sender));
David McGrew9c70f292006-05-03 19:38:38 +0000867
jfigus67b9c732014-11-20 10:17:21 -0500868 /*
869 * initialize data buffer, using the ssrc in the policy unless that
870 * value is a wildcard, in which case we'll just use an arbitrary
871 * one
872 */
873 if (policy->ssrc.type != ssrc_specific) {
874 ssrc = 0xdecafbad;
875 } else{
876 ssrc = policy->ssrc.value;
David McGrew9c70f292006-05-03 19:38:38 +0000877 }
jfigus67b9c732014-11-20 10:17:21 -0500878 msg_len_octets = 28;
879 hdr = srtp_create_test_packet(msg_len_octets, ssrc);
David McGrew9c70f292006-05-03 19:38:38 +0000880
jfigus67b9c732014-11-20 10:17:21 -0500881 if (hdr == NULL) {
882 return srtp_err_status_alloc_fail;
David McGrew9c70f292006-05-03 19:38:38 +0000883 }
jfigus67b9c732014-11-20 10:17:21 -0500884 hdr2 = srtp_create_test_packet(msg_len_octets, ssrc);
885 if (hdr2 == NULL) {
886 free(hdr);
887 return srtp_err_status_alloc_fail;
David McGrew9c70f292006-05-03 19:38:38 +0000888 }
889
David McGrew9c70f292006-05-03 19:38:38 +0000890 /* set message length */
891 len = msg_len_octets;
892
jfigus67b9c732014-11-20 10:17:21 -0500893 debug_print(mod_driver, "before protection:\n%s",
894 srtp_packet_to_string(hdr, len));
895
896#if PRINT_REFERENCE_PACKET
897 debug_print(mod_driver, "reference packet before protection:\n%s",
898 octet_string_hex_string((uint8_t*)hdr, len));
899#endif
David McGrew9c70f292006-05-03 19:38:38 +0000900 err_check(srtp_protect_rtcp(srtcp_sender, hdr, &len));
David McGrew9c70f292006-05-03 19:38:38 +0000901
jfigus67b9c732014-11-20 10:17:21 -0500902 debug_print(mod_driver, "after protection:\n%s",
903 srtp_packet_to_string(hdr, len));
904#if PRINT_REFERENCE_PACKET
905 debug_print(mod_driver, "after protection:\n%s",
906 octet_string_hex_string((uint8_t*)hdr, len));
907#endif
908
909 /* save protected message and length */
910 memcpy(hdr_enc, hdr, len);
911 msg_len_enc = len;
912
913 /*
914 * check for overrun of the srtp_protect() function
915 *
916 * The packet is followed by a value of 0xfffff; if the value of the
917 * data following the packet is different, then we know that the
918 * protect function is overwriting the end of the packet.
919 */
920 pkt_end = (uint8_t*)hdr + sizeof(srtp_hdr_t)
921 + msg_len_octets + tag_length;
922 for (i = 0; i < 4; i++) {
923 if (pkt_end[i] != 0xff) {
924 fprintf(stdout, "overwrite in srtp_protect_rtcp() function "
925 "(expected %x, found %x in trailing octet %d)\n",
926 0xff, ((uint8_t*)hdr)[i], i);
927 free(hdr);
928 free(hdr2);
929 return srtp_err_status_algo_fail;
930 }
David McGrew9c70f292006-05-03 19:38:38 +0000931 }
David McGrew9c70f292006-05-03 19:38:38 +0000932
jfigus67b9c732014-11-20 10:17:21 -0500933 /*
934 * if the policy includes confidentiality, check that ciphertext is
935 * different than plaintext
936 *
937 * Note that this check will give false negatives, with some small
938 * probability, especially if the packets are short. For that
939 * reason, we skip this check if the plaintext is less than four
940 * octets long.
941 */
942 if ((policy->rtp.sec_serv & sec_serv_conf) && (msg_len_octets >= 4)) {
943 printf("testing that ciphertext is distinct from plaintext...");
944 status = srtp_err_status_algo_fail;
945 for (i = 12; i < msg_len_octets + 12; i++) {
946 if (((uint8_t*)hdr)[i] != ((uint8_t*)hdr2)[i]) {
947 status = srtp_err_status_ok;
948 }
949 }
950 if (status) {
951 printf("failed\n");
952 free(hdr);
953 free(hdr2);
954 return status;
955 }
956 printf("passed\n");
957 }
David McGrew9c70f292006-05-03 19:38:38 +0000958
jfigus67b9c732014-11-20 10:17:21 -0500959 /*
960 * if the policy uses a 'wildcard' ssrc, then we need to make a copy
961 * of the policy that changes the direction to inbound
962 *
963 * we always copy the policy into the rcvr_policy, since otherwise
964 * the compiler would fret about the constness of the policy
965 */
966 rcvr_policy = (srtp_policy_t*)malloc(sizeof(srtp_policy_t));
967 if (rcvr_policy == NULL) {
968 return srtp_err_status_alloc_fail;
969 }
970 memcpy(rcvr_policy, policy, sizeof(srtp_policy_t));
971 if (policy->ssrc.type == ssrc_any_outbound) {
972 rcvr_policy->ssrc.type = ssrc_any_inbound;
973 }
974
975 err_check(srtp_create(&srtcp_rcvr, rcvr_policy));
976
977 err_check(srtp_unprotect_rtcp(srtcp_rcvr, hdr, &len));
978
979 debug_print(mod_driver, "after unprotection:\n%s",
980 srtp_packet_to_string(hdr, len));
981
982 /* verify that the unprotected packet matches the origial one */
983 for (i = 0; i < msg_len_octets; i++) {
984 if (((uint8_t*)hdr)[i] != ((uint8_t*)hdr2)[i]) {
985 fprintf(stdout, "mismatch at octet %d\n", i);
986 status = srtp_err_status_algo_fail;
987 }
988 }
989 if (status) {
990 free(hdr);
991 free(hdr2);
992 free(rcvr_policy);
993 return status;
994 }
995
996 /*
997 * if the policy includes authentication, then test for false positives
998 */
999 if (policy->rtp.sec_serv & sec_serv_auth) {
1000 char *data = ((char*)hdr) + 12;
1001
1002 printf("testing for false positives in replay check...");
1003
1004 /* set message length */
1005 len = msg_len_enc;
1006
1007 /* unprotect a second time - should fail with a replay error */
1008 status = srtp_unprotect_rtcp(srtcp_rcvr, hdr_enc, &len);
1009 if (status != srtp_err_status_replay_fail) {
1010 printf("failed with error code %d\n", status);
1011 free(hdr);
1012 free(hdr2);
1013 free(rcvr_policy);
1014 return status;
1015 } else {
1016 printf("passed\n");
1017 }
1018
1019 printf("testing for false positives in auth check...");
1020
1021 /* increment sequence number in header */
1022 hdr->seq++;
1023
1024 /* set message length */
1025 len = msg_len_octets;
1026
1027 /* apply protection */
1028 err_check(srtp_protect_rtcp(srtcp_sender, hdr, &len));
1029
1030 /* flip bits in packet */
1031 data[0] ^= 0xff;
1032
1033 /* unprotect, and check for authentication failure */
1034 status = srtp_unprotect_rtcp(srtcp_rcvr, hdr, &len);
1035 if (status != srtp_err_status_auth_fail) {
1036 printf("failed\n");
1037 free(hdr);
1038 free(hdr2);
1039 free(rcvr_policy);
1040 return status;
1041 } else {
1042 printf("passed\n");
1043 }
1044
1045 }
1046
1047 err_check(srtp_dealloc(srtcp_sender));
1048 err_check(srtp_dealloc(srtcp_rcvr));
1049
1050 free(hdr);
1051 free(hdr2);
1052 free(rcvr_policy);
1053 return srtp_err_status_ok;
David McGrew9c70f292006-05-03 19:38:38 +00001054}
1055
1056
jfigus857009c2014-11-05 11:17:43 -05001057srtp_err_status_t
jfigus67b9c732014-11-20 10:17:21 -05001058srtp_session_print_policy (srtp_t srtp)
1059{
1060 char *serv_descr[4] = {
1061 "none",
1062 "confidentiality",
1063 "authentication",
1064 "confidentiality and authentication"
1065 };
1066 char *direction[3] = {
1067 "unknown",
1068 "outbound",
1069 "inbound"
1070 };
1071 srtp_stream_t stream;
Cullen Jennings235513a2005-09-21 22:51:36 +00001072
jfigus67b9c732014-11-20 10:17:21 -05001073 /* sanity checking */
1074 if (srtp == NULL) {
1075 return srtp_err_status_fail;
1076 }
Cullen Jennings235513a2005-09-21 22:51:36 +00001077
jfigus67b9c732014-11-20 10:17:21 -05001078 /* if there's a template stream, print it out */
1079 if (srtp->stream_template != NULL) {
1080 stream = srtp->stream_template;
1081 printf("# SSRC: any %s\r\n"
1082 "# rtp cipher: %s\r\n"
1083 "# rtp auth: %s\r\n"
1084 "# rtp services: %s\r\n"
1085 "# rtcp cipher: %s\r\n"
1086 "# rtcp auth: %s\r\n"
1087 "# rtcp services: %s\r\n"
1088 "# window size: %lu\r\n"
1089 "# tx rtx allowed:%s\r\n",
1090 direction[stream->direction],
1091 stream->rtp_cipher->type->description,
1092 stream->rtp_auth->type->description,
1093 serv_descr[stream->rtp_services],
1094 stream->rtcp_cipher->type->description,
1095 stream->rtcp_auth->type->description,
1096 serv_descr[stream->rtcp_services],
1097 rdbx_get_window_size(&stream->rtp_rdbx),
1098 stream->allow_repeat_tx ? "true" : "false");
1099 }
Cullen Jennings235513a2005-09-21 22:51:36 +00001100
jfigus67b9c732014-11-20 10:17:21 -05001101 /* loop over streams in session, printing the policy of each */
1102 stream = srtp->stream_list;
1103 while (stream != NULL) {
1104 if (stream->rtp_services > sec_serv_conf_and_auth) {
1105 return srtp_err_status_bad_param;
1106 }
Cullen Jennings235513a2005-09-21 22:51:36 +00001107
jfigus67b9c732014-11-20 10:17:21 -05001108 printf("# SSRC: 0x%08x\r\n"
1109 "# rtp cipher: %s\r\n"
1110 "# rtp auth: %s\r\n"
1111 "# rtp services: %s\r\n"
1112 "# rtcp cipher: %s\r\n"
1113 "# rtcp auth: %s\r\n"
1114 "# rtcp services: %s\r\n"
1115 "# window size: %lu\r\n"
1116 "# tx rtx allowed:%s\r\n",
1117 stream->ssrc,
1118 stream->rtp_cipher->type->description,
1119 stream->rtp_auth->type->description,
1120 serv_descr[stream->rtp_services],
1121 stream->rtcp_cipher->type->description,
1122 stream->rtcp_auth->type->description,
1123 serv_descr[stream->rtcp_services],
1124 rdbx_get_window_size(&stream->rtp_rdbx),
1125 stream->allow_repeat_tx ? "true" : "false");
1126
1127 /* advance to next stream in the list */
1128 stream = stream->next;
1129 }
1130 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +00001131}
1132
jfigus857009c2014-11-05 11:17:43 -05001133srtp_err_status_t
jfigus67b9c732014-11-20 10:17:21 -05001134srtp_print_policy (const srtp_policy_t *policy)
1135{
1136 srtp_err_status_t status;
1137 srtp_t session;
Cullen Jennings235513a2005-09-21 22:51:36 +00001138
jfigus67b9c732014-11-20 10:17:21 -05001139 status = srtp_create(&session, policy);
1140 if (status) {
1141 return status;
1142 }
1143 status = srtp_session_print_policy(session);
1144 if (status) {
1145 return status;
1146 }
1147 status = srtp_dealloc(session);
1148 if (status) {
1149 return status;
1150 }
1151 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +00001152}
1153
jfigus67b9c732014-11-20 10:17:21 -05001154/*
1155 * srtp_print_packet(...) is for debugging only
Cullen Jennings235513a2005-09-21 22:51:36 +00001156 * it prints an RTP packet to the stdout
1157 *
1158 * note that this function is *not* threadsafe
1159 */
1160
1161#include <stdio.h>
1162
1163#define MTU 2048
1164
1165char packet_string[MTU];
1166
1167char *
jfigus67b9c732014-11-20 10:17:21 -05001168srtp_packet_to_string (srtp_hdr_t *hdr, int pkt_octet_len)
1169{
1170 int octets_in_rtp_header = 12;
1171 uint8_t *data = ((uint8_t*)hdr) + octets_in_rtp_header;
1172 int hex_len = pkt_octet_len - octets_in_rtp_header;
Cullen Jennings235513a2005-09-21 22:51:36 +00001173
jfigus67b9c732014-11-20 10:17:21 -05001174 /* sanity checking */
1175 if ((hdr == NULL) || (pkt_octet_len > MTU)) {
1176 return NULL;
1177 }
Cullen Jennings235513a2005-09-21 22:51:36 +00001178
jfigus67b9c732014-11-20 10:17:21 -05001179 /* write packet into string */
1180 sprintf(packet_string,
1181 "(s)rtp packet: {\n"
1182 " version:\t%d\n"
1183 " p:\t\t%d\n"
1184 " x:\t\t%d\n"
1185 " cc:\t\t%d\n"
1186 " m:\t\t%d\n"
1187 " pt:\t\t%x\n"
1188 " seq:\t\t%x\n"
1189 " ts:\t\t%x\n"
1190 " ssrc:\t%x\n"
1191 " data:\t%s\n"
1192 "} (%d octets in total)\n",
1193 hdr->version,
1194 hdr->p,
1195 hdr->x,
1196 hdr->cc,
1197 hdr->m,
1198 hdr->pt,
1199 hdr->seq,
1200 hdr->ts,
1201 hdr->ssrc,
1202 octet_string_hex_string(data, hex_len),
1203 pkt_octet_len);
Cullen Jennings235513a2005-09-21 22:51:36 +00001204
jfigus67b9c732014-11-20 10:17:21 -05001205 return packet_string;
Cullen Jennings235513a2005-09-21 22:51:36 +00001206}
1207
1208/*
1209 * mips_estimate() is a simple function to estimate the number of
1210 * instructions per second that the host can perform. note that this
1211 * function can be grossly wrong; you may want to have a manual sanity
1212 * check of its output!
1213 *
1214 * the 'ignore' pointer is there to convince the compiler to not just
1215 * optimize away the function
1216 */
1217
1218double
jfigus67b9c732014-11-20 10:17:21 -05001219mips_estimate (int num_trials, int *ignore)
1220{
1221 clock_t t;
1222 volatile int i, sum;
Cullen Jennings235513a2005-09-21 22:51:36 +00001223
jfigus67b9c732014-11-20 10:17:21 -05001224 sum = 0;
1225 t = clock();
1226 for (i = 0; i < num_trials; i++) {
1227 sum += i;
1228 }
1229 t = clock() - t;
Cullen Jennings235513a2005-09-21 22:51:36 +00001230
1231/* printf("%d\n", sum); */
jfigus67b9c732014-11-20 10:17:21 -05001232 *ignore = sum;
Cullen Jennings235513a2005-09-21 22:51:36 +00001233
jfigus67b9c732014-11-20 10:17:21 -05001234 return (double)num_trials * CLOCKS_PER_SEC / t;
Cullen Jennings235513a2005-09-21 22:51:36 +00001235}
1236
1237
1238/*
1239 * srtp_validate() verifies the correctness of libsrtp by comparing
1240 * some computed packets against some pre-computed reference values.
1241 * These packets were made with the default SRTP policy.
1242 */
1243
1244
jfigus857009c2014-11-05 11:17:43 -05001245srtp_err_status_t
jfigus67b9c732014-11-20 10:17:21 -05001246srtp_validate ()
1247{
1248 uint8_t srtp_plaintext_ref[28] = {
1249 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1250 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
1251 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1252 0xab, 0xab, 0xab, 0xab
1253 };
1254 uint8_t srtp_plaintext[38] = {
1255 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1256 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
1257 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1258 0xab, 0xab, 0xab, 0xab, 0x00, 0x00, 0x00, 0x00,
1259 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1260 };
1261 uint8_t srtp_ciphertext[38] = {
1262 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1263 0xca, 0xfe, 0xba, 0xbe, 0x4e, 0x55, 0xdc, 0x4c,
1264 0xe7, 0x99, 0x78, 0xd8, 0x8c, 0xa4, 0xd2, 0x15,
1265 0x94, 0x9d, 0x24, 0x02, 0xb7, 0x8d, 0x6a, 0xcc,
1266 0x99, 0xea, 0x17, 0x9b, 0x8d, 0xbb
1267 };
1268 srtp_t srtp_snd, srtp_recv;
1269 srtp_err_status_t status;
1270 int len;
1271 srtp_policy_t policy;
Cullen Jennings235513a2005-09-21 22:51:36 +00001272
jfigus67b9c732014-11-20 10:17:21 -05001273 /*
1274 * create a session with a single stream using the default srtp
1275 * policy and with the SSRC value 0xcafebabe
1276 */
1277 srtp_crypto_policy_set_rtp_default(&policy.rtp);
1278 srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
1279 policy.ssrc.type = ssrc_specific;
1280 policy.ssrc.value = 0xcafebabe;
1281 policy.key = test_key;
1282 policy.ekt = NULL;
1283 policy.window_size = 128;
1284 policy.allow_repeat_tx = 0;
1285 policy.next = NULL;
Cullen Jennings235513a2005-09-21 22:51:36 +00001286
jfigus67b9c732014-11-20 10:17:21 -05001287 status = srtp_create(&srtp_snd, &policy);
1288 if (status) {
1289 return status;
1290 }
Cullen Jennings235513a2005-09-21 22:51:36 +00001291
jfigus67b9c732014-11-20 10:17:21 -05001292 /*
1293 * protect plaintext, then compare with ciphertext
1294 */
1295 len = 28;
1296 status = srtp_protect(srtp_snd, srtp_plaintext, &len);
1297 if (status || (len != 38)) {
1298 return srtp_err_status_fail;
1299 }
Cullen Jennings235513a2005-09-21 22:51:36 +00001300
jfigus67b9c732014-11-20 10:17:21 -05001301 debug_print(mod_driver, "ciphertext:\n %s",
1302 octet_string_hex_string(srtp_plaintext, len));
1303 debug_print(mod_driver, "ciphertext reference:\n %s",
1304 octet_string_hex_string(srtp_ciphertext, len));
Cullen Jennings235513a2005-09-21 22:51:36 +00001305
jfigus67b9c732014-11-20 10:17:21 -05001306 if (octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len)) {
1307 return srtp_err_status_fail;
1308 }
Jonathan Lennox80c4c832010-05-17 19:30:28 +00001309
jfigus67b9c732014-11-20 10:17:21 -05001310 /*
1311 * create a receiver session context comparable to the one created
1312 * above - we need to do this so that the replay checking doesn't
1313 * complain
1314 */
1315 status = srtp_create(&srtp_recv, &policy);
1316 if (status) {
1317 return status;
1318 }
Jonathan Lennox80c4c832010-05-17 19:30:28 +00001319
jfigus67b9c732014-11-20 10:17:21 -05001320 /*
1321 * unprotect ciphertext, then compare with plaintext
1322 */
1323 status = srtp_unprotect(srtp_recv, srtp_ciphertext, &len);
1324 if (status || (len != 28)) {
1325 return status;
1326 }
1327
1328 if (octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len)) {
1329 return srtp_err_status_fail;
1330 }
1331
1332 status = srtp_dealloc(srtp_snd);
1333 if (status) {
1334 return status;
1335 }
1336
1337 status = srtp_dealloc(srtp_recv);
1338 if (status) {
1339 return status;
1340 }
1341
1342 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +00001343}
1344
1345
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001346/*
1347 * srtp_validate_aes_256() verifies the correctness of libsrtp by comparing
1348 * some computed packets against some pre-computed reference values.
1349 * These packets were made with the AES-CM-256/HMAC-SHA-1-80 policy.
1350 */
1351
1352
jfigus857009c2014-11-05 11:17:43 -05001353srtp_err_status_t
jfigus67b9c732014-11-20 10:17:21 -05001354srtp_validate_aes_256 ()
1355{
1356 unsigned char aes_256_test_key[46] = {
1357 0xf0, 0xf0, 0x49, 0x14, 0xb5, 0x13, 0xf2, 0x76,
1358 0x3a, 0x1b, 0x1f, 0xa1, 0x30, 0xf1, 0x0e, 0x29,
1359 0x98, 0xf6, 0xf6, 0xe4, 0x3e, 0x43, 0x09, 0xd1,
1360 0xe6, 0x22, 0xa0, 0xe3, 0x32, 0xb9, 0xf1, 0xb6,
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001361
jfigus67b9c732014-11-20 10:17:21 -05001362 0x3b, 0x04, 0x80, 0x3d, 0xe5, 0x1e, 0xe7, 0xc9,
1363 0x64, 0x23, 0xab, 0x5b, 0x78, 0xd2
1364 };
1365 uint8_t srtp_plaintext_ref[28] = {
1366 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1367 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
1368 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1369 0xab, 0xab, 0xab, 0xab
1370 };
1371 uint8_t srtp_plaintext[38] = {
1372 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1373 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
1374 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1375 0xab, 0xab, 0xab, 0xab, 0x00, 0x00, 0x00, 0x00,
1376 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1377 };
1378 uint8_t srtp_ciphertext[38] = {
1379 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1380 0xca, 0xfe, 0xba, 0xbe, 0xf1, 0xd9, 0xde, 0x17,
1381 0xff, 0x25, 0x1f, 0xf1, 0xaa, 0x00, 0x77, 0x74,
1382 0xb0, 0xb4, 0xb4, 0x0d, 0xa0, 0x8d, 0x9d, 0x9a,
1383 0x5b, 0x3a, 0x55, 0xd8, 0x87, 0x3b
1384 };
1385 srtp_t srtp_snd, srtp_recv;
1386 srtp_err_status_t status;
1387 int len;
1388 srtp_policy_t policy;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001389
jfigus67b9c732014-11-20 10:17:21 -05001390 /*
1391 * create a session with a single stream using the default srtp
1392 * policy and with the SSRC value 0xcafebabe
1393 */
1394 srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(&policy.rtp);
1395 srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(&policy.rtcp);
1396 policy.ssrc.type = ssrc_specific;
1397 policy.ssrc.value = 0xcafebabe;
1398 policy.key = aes_256_test_key;
1399 policy.ekt = NULL;
1400 policy.window_size = 128;
1401 policy.allow_repeat_tx = 0;
1402 policy.next = NULL;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001403
jfigus67b9c732014-11-20 10:17:21 -05001404 status = srtp_create(&srtp_snd, &policy);
1405 if (status) {
1406 return status;
1407 }
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001408
jfigus67b9c732014-11-20 10:17:21 -05001409 /*
1410 * protect plaintext, then compare with ciphertext
1411 */
1412 len = 28;
1413 status = srtp_protect(srtp_snd, srtp_plaintext, &len);
1414 if (status || (len != 38)) {
1415 return srtp_err_status_fail;
1416 }
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001417
jfigus67b9c732014-11-20 10:17:21 -05001418 debug_print(mod_driver, "ciphertext:\n %s",
1419 octet_string_hex_string(srtp_plaintext, len));
1420 debug_print(mod_driver, "ciphertext reference:\n %s",
1421 octet_string_hex_string(srtp_ciphertext, len));
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001422
jfigus67b9c732014-11-20 10:17:21 -05001423 if (octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len)) {
1424 return srtp_err_status_fail;
1425 }
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001426
jfigus67b9c732014-11-20 10:17:21 -05001427 /*
1428 * create a receiver session context comparable to the one created
1429 * above - we need to do this so that the replay checking doesn't
1430 * complain
1431 */
1432 status = srtp_create(&srtp_recv, &policy);
1433 if (status) {
1434 return status;
1435 }
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001436
jfigus67b9c732014-11-20 10:17:21 -05001437 /*
1438 * unprotect ciphertext, then compare with plaintext
1439 */
1440 status = srtp_unprotect(srtp_recv, srtp_ciphertext, &len);
1441 if (status || (len != 28)) {
1442 return status;
1443 }
1444
1445 if (octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len)) {
1446 return srtp_err_status_fail;
1447 }
1448
1449 status = srtp_dealloc(srtp_snd);
1450 if (status) {
1451 return status;
1452 }
1453
1454 status = srtp_dealloc(srtp_recv);
1455 if (status) {
1456 return status;
1457 }
1458
1459 return srtp_err_status_ok;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001460}
1461
1462
jfigus857009c2014-11-05 11:17:43 -05001463srtp_err_status_t
jfigus67b9c732014-11-20 10:17:21 -05001464srtp_create_big_policy (srtp_policy_t **list)
1465{
1466 extern const srtp_policy_t *policy_array[];
1467 srtp_policy_t *p, *tmp;
1468 int i = 0;
1469 uint32_t ssrc = 0;
Cullen Jennings235513a2005-09-21 22:51:36 +00001470
jfigus67b9c732014-11-20 10:17:21 -05001471 /* sanity checking */
1472 if ((list == NULL) || (policy_array[0] == NULL)) {
1473 return srtp_err_status_bad_param;
1474 }
Cullen Jennings235513a2005-09-21 22:51:36 +00001475
jfigus67b9c732014-11-20 10:17:21 -05001476 /*
1477 * loop over policy list, mallocing a new list and copying values
1478 * into it (and incrementing the SSRC value as we go along)
1479 */
1480 tmp = NULL;
1481 while (policy_array[i] != NULL) {
1482 p = (srtp_policy_t*)malloc(sizeof(srtp_policy_t));
1483 if (p == NULL) {
1484 return srtp_err_status_bad_param;
1485 }
1486 memcpy(p, policy_array[i], sizeof(srtp_policy_t));
1487 p->ssrc.type = ssrc_specific;
1488 p->ssrc.value = ssrc++;
1489 p->next = tmp;
1490 tmp = p;
1491 i++;
1492 }
1493 *list = p;
1494
1495 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +00001496}
1497
jfigus857009c2014-11-05 11:17:43 -05001498srtp_err_status_t
jfigus67b9c732014-11-20 10:17:21 -05001499srtp_dealloc_big_policy (srtp_policy_t *list)
1500{
1501 srtp_policy_t *p, *next;
Jonathan Lennox80c4c832010-05-17 19:30:28 +00001502
jfigus67b9c732014-11-20 10:17:21 -05001503 for (p = list; p != NULL; p = next) {
1504 next = p->next;
1505 free(p);
1506 }
Jonathan Lennox80c4c832010-05-17 19:30:28 +00001507
jfigus67b9c732014-11-20 10:17:21 -05001508 return srtp_err_status_ok;
Jonathan Lennox80c4c832010-05-17 19:30:28 +00001509}
1510
1511
jfigus857009c2014-11-05 11:17:43 -05001512srtp_err_status_t
jfigus67b9c732014-11-20 10:17:21 -05001513srtp_test_remove_stream ()
1514{
1515 srtp_err_status_t status;
1516 srtp_policy_t *policy_list, policy;
1517 srtp_t session;
1518 srtp_stream_t stream;
Cullen Jennings235513a2005-09-21 22:51:36 +00001519
jfigus67b9c732014-11-20 10:17:21 -05001520 /*
1521 * srtp_get_stream() is a libSRTP internal function that we declare
1522 * here so that we can use it to verify the correct operation of the
1523 * library
1524 */
1525 extern srtp_stream_t srtp_get_stream(srtp_t srtp, uint32_t ssrc);
Cullen Jennings235513a2005-09-21 22:51:36 +00001526
Cullen Jennings235513a2005-09-21 22:51:36 +00001527
jfigus67b9c732014-11-20 10:17:21 -05001528 status = srtp_create_big_policy(&policy_list);
1529 if (status) {
1530 return status;
1531 }
Cullen Jennings235513a2005-09-21 22:51:36 +00001532
jfigus67b9c732014-11-20 10:17:21 -05001533 status = srtp_create(&session, policy_list);
1534 if (status) {
1535 return status;
1536 }
Jonathan Lennox80c4c832010-05-17 19:30:28 +00001537
jfigus67b9c732014-11-20 10:17:21 -05001538 /*
1539 * check for false positives by trying to remove a stream that's not
1540 * in the session
1541 */
1542 status = srtp_remove_stream(session, htonl(0xaaaaaaaa));
1543 if (status != srtp_err_status_no_ctx) {
1544 return srtp_err_status_fail;
1545 }
Jonathan Lennox80c4c832010-05-17 19:30:28 +00001546
jfigus67b9c732014-11-20 10:17:21 -05001547 /*
1548 * check for false negatives by removing stream 0x1, then
1549 * searching for streams 0x0 and 0x2
1550 */
1551 status = srtp_remove_stream(session, htonl(0x1));
1552 if (status != srtp_err_status_ok) {
1553 return srtp_err_status_fail;
1554 }
1555 stream = srtp_get_stream(session, htonl(0x0));
1556 if (stream == NULL) {
1557 return srtp_err_status_fail;
1558 }
1559 stream = srtp_get_stream(session, htonl(0x2));
1560 if (stream == NULL) {
1561 return srtp_err_status_fail;
1562 }
Jonathan Lennoxad741b22010-05-27 19:23:05 +00001563
jfigus67b9c732014-11-20 10:17:21 -05001564 status = srtp_dealloc(session);
1565 if (status != srtp_err_status_ok) {
1566 return status;
1567 }
Jonathan Lennoxad741b22010-05-27 19:23:05 +00001568
jfigus67b9c732014-11-20 10:17:21 -05001569 status = srtp_dealloc_big_policy(policy_list);
1570 if (status != srtp_err_status_ok) {
1571 return status;
1572 }
Jonathan Lennoxad741b22010-05-27 19:23:05 +00001573
jfigus67b9c732014-11-20 10:17:21 -05001574 /* Now test adding and removing a single stream */
1575 srtp_crypto_policy_set_rtp_default(&policy.rtp);
1576 srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
1577 policy.ssrc.type = ssrc_specific;
1578 policy.ssrc.value = 0xcafebabe;
1579 policy.key = test_key;
1580 policy.ekt = NULL;
1581 policy.window_size = 128;
1582 policy.allow_repeat_tx = 0;
1583 policy.next = NULL;
Jonathan Lennoxad741b22010-05-27 19:23:05 +00001584
jfigus67b9c732014-11-20 10:17:21 -05001585 status = srtp_create(&session, NULL);
1586 if (status != srtp_err_status_ok) {
1587 return status;
1588 }
1589
1590 status = srtp_add_stream(session, &policy);
1591 if (status != srtp_err_status_ok) {
1592 return status;
1593 }
1594
1595 status = srtp_remove_stream(session, htonl(0xcafebabe));
1596 if (status != srtp_err_status_ok) {
1597 return status;
1598 }
1599
1600 status = srtp_dealloc(session);
1601 if (status != srtp_err_status_ok) {
1602 return status;
1603 }
1604
1605 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +00001606}
1607
1608/*
1609 * srtp policy definitions - these definitions are used above
1610 */
1611
jfigus8c36da22013-10-01 16:41:19 -04001612unsigned char test_key[46] = {
Cullen Jennings235513a2005-09-21 22:51:36 +00001613 0xe1, 0xf9, 0x7a, 0x0d, 0x3e, 0x01, 0x8b, 0xe0,
1614 0xd6, 0x4f, 0xa3, 0x2c, 0x06, 0xde, 0x41, 0x39,
1615 0x0e, 0xc6, 0x75, 0xad, 0x49, 0x8a, 0xfe, 0xeb,
jfigus8c36da22013-10-01 16:41:19 -04001616 0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6, 0xc1, 0x73,
1617 0xc3, 0x17, 0xf2, 0xda, 0xbe, 0x35, 0x77, 0x93,
Cullen Jennings235513a2005-09-21 22:51:36 +00001618 0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6
1619};
1620
1621
1622const srtp_policy_t default_policy = {
jfigus67b9c732014-11-20 10:17:21 -05001623 { ssrc_any_outbound, 0 }, /* SSRC */
1624 { /* SRTP policy */
1625 SRTP_AES_128_ICM, /* cipher type */
1626 30, /* cipher key length in octets */
1627 SRTP_HMAC_SHA1, /* authentication func type */
1628 16, /* auth key length in octets */
1629 10, /* auth tag length in octets */
1630 sec_serv_conf_and_auth /* security services flag */
1631 },
1632 { /* SRTCP policy */
1633 SRTP_AES_128_ICM, /* cipher type */
1634 30, /* cipher key length in octets */
1635 SRTP_HMAC_SHA1, /* authentication func type */
1636 16, /* auth key length in octets */
1637 10, /* auth tag length in octets */
1638 sec_serv_conf_and_auth /* security services flag */
1639 },
1640 test_key,
1641 NULL, /* indicates that EKT is not in use */
1642 128, /* replay window size */
1643 0, /* retransmission not allowed */
1644 NULL
Cullen Jennings235513a2005-09-21 22:51:36 +00001645};
1646
1647const srtp_policy_t aes_only_policy = {
jfigus67b9c732014-11-20 10:17:21 -05001648 { ssrc_any_outbound, 0 }, /* SSRC */
1649 {
1650 SRTP_AES_128_ICM, /* cipher type */
1651 30, /* cipher key length in octets */
1652 SRTP_NULL_AUTH, /* authentication func type */
1653 0, /* auth key length in octets */
1654 0, /* auth tag length in octets */
1655 sec_serv_conf /* security services flag */
1656 },
1657 {
1658 SRTP_AES_128_ICM, /* cipher type */
1659 30, /* cipher key length in octets */
1660 SRTP_NULL_AUTH, /* authentication func type */
1661 0, /* auth key length in octets */
1662 0, /* auth tag length in octets */
1663 sec_serv_conf /* security services flag */
1664 },
1665 test_key,
1666 NULL, /* indicates that EKT is not in use */
1667 128, /* replay window size */
1668 0, /* retransmission not allowed */
1669 NULL
Cullen Jennings235513a2005-09-21 22:51:36 +00001670};
1671
1672const srtp_policy_t hmac_only_policy = {
jfigus67b9c732014-11-20 10:17:21 -05001673 { ssrc_any_outbound, 0 }, /* SSRC */
1674 {
1675 SRTP_NULL_CIPHER, /* cipher type */
1676 0, /* cipher key length in octets */
1677 SRTP_HMAC_SHA1, /* authentication func type */
1678 20, /* auth key length in octets */
1679 4, /* auth tag length in octets */
1680 sec_serv_auth /* security services flag */
1681 },
1682 {
1683 SRTP_NULL_CIPHER, /* cipher type */
1684 0, /* cipher key length in octets */
1685 SRTP_HMAC_SHA1, /* authentication func type */
1686 20, /* auth key length in octets */
1687 4, /* auth tag length in octets */
1688 sec_serv_auth /* security services flag */
1689 },
1690 test_key,
1691 NULL, /* indicates that EKT is not in use */
1692 128, /* replay window size */
1693 0, /* retransmission not allowed */
1694 NULL
Cullen Jennings235513a2005-09-21 22:51:36 +00001695};
1696
jfigus8c36da22013-10-01 16:41:19 -04001697#ifdef OPENSSL
1698const srtp_policy_t aes128_gcm_8_policy = {
jfigus67b9c732014-11-20 10:17:21 -05001699 { ssrc_any_outbound, 0 }, /* SSRC */
1700 { /* SRTP policy */
1701 SRTP_AES_128_GCM, /* cipher type */
1702 SRTP_AES_128_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
1703 SRTP_NULL_AUTH, /* authentication func type */
1704 0, /* auth key length in octets */
1705 8, /* auth tag length in octets */
1706 sec_serv_conf_and_auth /* security services flag */
jfigus8c36da22013-10-01 16:41:19 -04001707 },
jfigus67b9c732014-11-20 10:17:21 -05001708 { /* SRTCP policy */
1709 SRTP_AES_128_GCM, /* cipher type */
1710 SRTP_AES_128_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
1711 SRTP_NULL_AUTH, /* authentication func type */
1712 0, /* auth key length in octets */
1713 8, /* auth tag length in octets */
1714 sec_serv_conf_and_auth /* security services flag */
jfigus8c36da22013-10-01 16:41:19 -04001715 },
1716 test_key,
1717 NULL, /* indicates that EKT is not in use */
1718 128, /* replay window size */
1719 0, /* retransmission not allowed */
1720 NULL
1721};
1722
1723const srtp_policy_t aes128_gcm_8_cauth_policy = {
jfigus67b9c732014-11-20 10:17:21 -05001724 { ssrc_any_outbound, 0 }, /* SSRC */
1725 { /* SRTP policy */
1726 SRTP_AES_128_GCM, /* cipher type */
1727 SRTP_AES_128_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
1728 SRTP_NULL_AUTH, /* authentication func type */
1729 0, /* auth key length in octets */
1730 8, /* auth tag length in octets */
1731 sec_serv_conf_and_auth /* security services flag */
jfigus8c36da22013-10-01 16:41:19 -04001732 },
jfigus67b9c732014-11-20 10:17:21 -05001733 { /* SRTCP policy */
1734 SRTP_AES_128_GCM, /* cipher type */
1735 SRTP_AES_128_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
1736 SRTP_NULL_AUTH, /* authentication func type */
1737 0, /* auth key length in octets */
1738 8, /* auth tag length in octets */
1739 sec_serv_auth /* security services flag */
jfigus8c36da22013-10-01 16:41:19 -04001740 },
1741 test_key,
1742 NULL, /* indicates that EKT is not in use */
1743 128, /* replay window size */
1744 0, /* retransmission not allowed */
1745 NULL
1746};
jfigus67b9c732014-11-20 10:17:21 -05001747
jfigus8c36da22013-10-01 16:41:19 -04001748const srtp_policy_t aes256_gcm_8_policy = {
jfigus67b9c732014-11-20 10:17:21 -05001749 { ssrc_any_outbound, 0 }, /* SSRC */
1750 { /* SRTP policy */
1751 SRTP_AES_256_GCM, /* cipher type */
1752 SRTP_AES_256_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
1753 SRTP_NULL_AUTH, /* authentication func type */
1754 0, /* auth key length in octets */
1755 8, /* auth tag length in octets */
1756 sec_serv_conf_and_auth /* security services flag */
jfigus8c36da22013-10-01 16:41:19 -04001757 },
jfigus67b9c732014-11-20 10:17:21 -05001758 { /* SRTCP policy */
1759 SRTP_AES_256_GCM, /* cipher type */
1760 SRTP_AES_256_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
1761 SRTP_NULL_AUTH, /* authentication func type */
1762 0, /* auth key length in octets */
1763 8, /* auth tag length in octets */
1764 sec_serv_conf_and_auth /* security services flag */
jfigus8c36da22013-10-01 16:41:19 -04001765 },
1766 test_key,
1767 NULL, /* indicates that EKT is not in use */
1768 128, /* replay window size */
1769 0, /* retransmission not allowed */
1770 NULL
1771};
jfigus67b9c732014-11-20 10:17:21 -05001772
jfigus8c36da22013-10-01 16:41:19 -04001773const srtp_policy_t aes256_gcm_8_cauth_policy = {
jfigus67b9c732014-11-20 10:17:21 -05001774 { ssrc_any_outbound, 0 }, /* SSRC */
1775 { /* SRTP policy */
1776 SRTP_AES_256_GCM, /* cipher type */
1777 SRTP_AES_256_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
1778 SRTP_NULL_AUTH, /* authentication func type */
1779 0, /* auth key length in octets */
1780 8, /* auth tag length in octets */
1781 sec_serv_conf_and_auth /* security services flag */
jfigus8c36da22013-10-01 16:41:19 -04001782 },
jfigus67b9c732014-11-20 10:17:21 -05001783 { /* SRTCP policy */
1784 SRTP_AES_256_GCM, /* cipher type */
1785 SRTP_AES_256_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
1786 SRTP_NULL_AUTH, /* authentication func type */
1787 0, /* auth key length in octets */
1788 8, /* auth tag length in octets */
1789 sec_serv_auth /* security services flag */
jfigus8c36da22013-10-01 16:41:19 -04001790 },
1791 test_key,
1792 NULL, /* indicates that EKT is not in use */
1793 128, /* replay window size */
1794 0, /* retransmission not allowed */
1795 NULL
1796};
1797#endif
1798
Cullen Jennings235513a2005-09-21 22:51:36 +00001799const srtp_policy_t null_policy = {
jfigus67b9c732014-11-20 10:17:21 -05001800 { ssrc_any_outbound, 0 }, /* SSRC */
1801 {
1802 SRTP_NULL_CIPHER, /* cipher type */
1803 0, /* cipher key length in octets */
1804 SRTP_NULL_AUTH, /* authentication func type */
1805 0, /* auth key length in octets */
1806 0, /* auth tag length in octets */
1807 sec_serv_none /* security services flag */
1808 },
1809 {
1810 SRTP_NULL_CIPHER, /* cipher type */
1811 0, /* cipher key length in octets */
1812 SRTP_NULL_AUTH, /* authentication func type */
1813 0, /* auth key length in octets */
1814 0, /* auth tag length in octets */
1815 sec_serv_none /* security services flag */
1816 },
1817 test_key,
1818 NULL, /* indicates that EKT is not in use */
1819 128, /* replay window size */
1820 0, /* retransmission not allowed */
1821 NULL
David McGrew79870d62007-06-15 18:17:39 +00001822};
1823
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001824unsigned char test_256_key[46] = {
jfigus67b9c732014-11-20 10:17:21 -05001825 0xf0, 0xf0, 0x49, 0x14, 0xb5, 0x13, 0xf2, 0x76,
1826 0x3a, 0x1b, 0x1f, 0xa1, 0x30, 0xf1, 0x0e, 0x29,
1827 0x98, 0xf6, 0xf6, 0xe4, 0x3e, 0x43, 0x09, 0xd1,
1828 0xe6, 0x22, 0xa0, 0xe3, 0x32, 0xb9, 0xf1, 0xb6,
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001829
jfigus67b9c732014-11-20 10:17:21 -05001830 0x3b, 0x04, 0x80, 0x3d, 0xe5, 0x1e, 0xe7, 0xc9,
1831 0x64, 0x23, 0xab, 0x5b, 0x78, 0xd2
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001832};
1833
1834const srtp_policy_t aes_256_hmac_policy = {
jfigus67b9c732014-11-20 10:17:21 -05001835 { ssrc_any_outbound, 0 }, /* SSRC */
1836 { /* SRTP policy */
1837 SRTP_AES_ICM, /* cipher type */
1838 46, /* cipher key length in octets */
1839 SRTP_HMAC_SHA1, /* authentication func type */
1840 20, /* auth key length in octets */
1841 10, /* auth tag length in octets */
1842 sec_serv_conf_and_auth /* security services flag */
1843 },
1844 { /* SRTCP policy */
1845 SRTP_AES_ICM, /* cipher type */
1846 46, /* cipher key length in octets */
1847 SRTP_HMAC_SHA1, /* authentication func type */
1848 20, /* auth key length in octets */
1849 10, /* auth tag length in octets */
1850 sec_serv_conf_and_auth /* security services flag */
1851 },
1852 test_256_key,
1853 NULL, /* indicates that EKT is not in use */
1854 128, /* replay window size */
1855 0, /* retransmission not allowed */
1856 NULL
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001857};
1858
David McGrew79870d62007-06-15 18:17:39 +00001859uint8_t ekt_test_key[16] = {
jfigus67b9c732014-11-20 10:17:21 -05001860 0x77, 0x26, 0x9d, 0xac, 0x16, 0xa3, 0x28, 0xca,
1861 0x8e, 0xc9, 0x68, 0x4b, 0xcc, 0xc4, 0xd2, 0x1b
David McGrew79870d62007-06-15 18:17:39 +00001862};
1863
1864#include "ekt.h"
1865
jfigusc5887e72014-11-06 09:46:18 -05001866srtp_ekt_policy_ctx_t ekt_test_policy = {
jfigus67b9c732014-11-20 10:17:21 -05001867 0xa5a5, /* SPI */
1868 SRTP_EKT_CIPHER_AES_128_ECB,
1869 ekt_test_key,
1870 NULL
David McGrew79870d62007-06-15 18:17:39 +00001871};
1872
1873const srtp_policy_t hmac_only_with_ekt_policy = {
jfigus67b9c732014-11-20 10:17:21 -05001874 { ssrc_any_outbound, 0 }, /* SSRC */
1875 {
1876 SRTP_NULL_CIPHER, /* cipher type */
1877 0, /* cipher key length in octets */
1878 SRTP_HMAC_SHA1, /* authentication func type */
1879 20, /* auth key length in octets */
1880 4, /* auth tag length in octets */
1881 sec_serv_auth /* security services flag */
1882 },
1883 {
1884 SRTP_NULL_CIPHER, /* cipher type */
1885 0, /* cipher key length in octets */
1886 SRTP_HMAC_SHA1, /* authentication func type */
1887 20, /* auth key length in octets */
1888 4, /* auth tag length in octets */
1889 sec_serv_auth /* security services flag */
1890 },
1891 test_key,
1892 &ekt_test_policy, /* indicates that EKT is not in use */
1893 128, /* replay window size */
1894 0, /* retransmission not allowed */
1895 NULL
Cullen Jennings235513a2005-09-21 22:51:36 +00001896};
1897
1898
1899/*
1900 * an array of pointers to the policies listed above
1901 *
1902 * This array is used to test various aspects of libSRTP for
1903 * different cryptographic policies. The order of the elements
1904 * matters - the timing test generates output that can be used
jfigus67b9c732014-11-20 10:17:21 -05001905 * in a plot (see the gnuplot script file 'timing'). If you
Cullen Jennings235513a2005-09-21 22:51:36 +00001906 * add to this list, you should do it at the end.
1907 */
1908
Cullen Jennings235513a2005-09-21 22:51:36 +00001909const srtp_policy_t *
1910policy_array[] = {
jfigus67b9c732014-11-20 10:17:21 -05001911 &hmac_only_policy,
1912 &aes_only_policy,
1913 &default_policy,
jfigus8c36da22013-10-01 16:41:19 -04001914#ifdef OPENSSL
jfigus67b9c732014-11-20 10:17:21 -05001915 &aes128_gcm_8_policy,
1916 &aes128_gcm_8_cauth_policy,
1917 &aes256_gcm_8_policy,
1918 &aes256_gcm_8_cauth_policy,
jfigus8c36da22013-10-01 16:41:19 -04001919#endif
jfigus67b9c732014-11-20 10:17:21 -05001920 &null_policy,
1921 &aes_256_hmac_policy,
1922 &hmac_only_with_ekt_policy,
1923 NULL
Cullen Jennings235513a2005-09-21 22:51:36 +00001924};
1925
1926const srtp_policy_t wildcard_policy = {
jfigus67b9c732014-11-20 10:17:21 -05001927 { ssrc_any_outbound, 0 }, /* SSRC */
1928 { /* SRTP policy */
1929 SRTP_AES_128_ICM, /* cipher type */
1930 30, /* cipher key length in octets */
1931 SRTP_HMAC_SHA1, /* authentication func type */
1932 16, /* auth key length in octets */
1933 10, /* auth tag length in octets */
1934 sec_serv_conf_and_auth /* security services flag */
1935 },
1936 { /* SRTCP policy */
1937 SRTP_AES_128_ICM, /* cipher type */
1938 30, /* cipher key length in octets */
1939 SRTP_HMAC_SHA1, /* authentication func type */
1940 16, /* auth key length in octets */
1941 10, /* auth tag length in octets */
1942 sec_serv_conf_and_auth /* security services flag */
1943 },
1944 test_key,
1945 NULL,
1946 128, /* replay window size */
1947 0, /* retransmission not allowed */
1948 NULL
Cullen Jennings235513a2005-09-21 22:51:36 +00001949};