blob: f851bcda67e2c8dd8ec2f18e3ba3eaa385663f2f [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
Pascal Bühlerbd3112a2015-11-06 20:29:15 +010078srtp_err_status_t
79srtp_test_update(void);
80
Cullen Jennings235513a2005-09-21 22:51:36 +000081double
82srtp_bits_per_second(int msg_len_octets, const srtp_policy_t *policy);
83
84double
85srtp_rejections_per_second(int msg_len_octets, const srtp_policy_t *policy);
86
87void
88srtp_do_timing(const srtp_policy_t *policy);
89
90void
91srtp_do_rejection_timing(const srtp_policy_t *policy);
92
jfigus857009c2014-11-05 11:17:43 -050093srtp_err_status_t
Marcus Sundberga3f95fe2005-09-29 12:48:41 +000094srtp_test(const srtp_policy_t *policy);
Cullen Jennings235513a2005-09-21 22:51:36 +000095
jfigus857009c2014-11-05 11:17:43 -050096srtp_err_status_t
David McGrew9c70f292006-05-03 19:38:38 +000097srtcp_test(const srtp_policy_t *policy);
98
jfigus857009c2014-11-05 11:17:43 -050099srtp_err_status_t
Cullen Jennings235513a2005-09-21 22:51:36 +0000100srtp_session_print_policy(srtp_t srtp);
101
jfigus857009c2014-11-05 11:17:43 -0500102srtp_err_status_t
jfigus67b9c732014-11-20 10:17:21 -0500103srtp_print_policy(const srtp_policy_t *policy);
Cullen Jennings235513a2005-09-21 22:51:36 +0000104
105char *
106srtp_packet_to_string(srtp_hdr_t *hdr, int packet_len);
107
108double
109mips_estimate(int num_trials, int *ignore);
110
jfigus8c36da22013-10-01 16:41:19 -0400111extern uint8_t test_key[46];
Cullen Jennings235513a2005-09-21 22:51:36 +0000112
113void
jfigus67b9c732014-11-20 10:17:21 -0500114usage (char *prog_name)
115{
116 printf("usage: %s [ -t ][ -c ][ -v ][-d <debug_module> ]* [ -l ]\n"
117 " -t run timing test\n"
118 " -r run rejection timing test\n"
119 " -c run codec timing test\n"
120 " -v run validation tests\n"
121 " -d <mod> turn on debugging module <mod>\n"
122 " -l list debugging modules\n", prog_name);
123 exit(1);
Cullen Jennings235513a2005-09-21 22:51:36 +0000124}
125
126/*
127 * The policy_array is a null-terminated array of policy structs. it
128 * is declared at the end of this file
129 */
130
131extern const srtp_policy_t *policy_array[];
132
133
134/* the wildcard_policy is declared below; it has a wildcard ssrc */
135
136extern const srtp_policy_t wildcard_policy;
137
138/*
139 * mod_driver debug module - debugging module for this test driver
140 *
jfigus67b9c732014-11-20 10:17:21 -0500141 * we use the crypto_kernel debugging system in this driver, which
Cullen Jennings235513a2005-09-21 22:51:36 +0000142 * makes the interface uniform and increases portability
jfigus67b9c732014-11-20 10:17:21 -0500143 */
Cullen Jennings235513a2005-09-21 22:51:36 +0000144
jfigus02d6f032014-11-21 10:56:42 -0500145srtp_debug_module_t mod_driver = {
jfigus67b9c732014-11-20 10:17:21 -0500146 0, /* debugging is off by default */
147 "driver" /* printable name for module */
Cullen Jennings235513a2005-09-21 22:51:36 +0000148};
149
150int
jfigus67b9c732014-11-20 10:17:21 -0500151main (int argc, char *argv[])
152{
153 int q;
154 unsigned do_timing_test = 0;
155 unsigned do_rejection_test = 0;
156 unsigned do_codec_timing = 0;
157 unsigned do_validation = 0;
158 unsigned do_list_mods = 0;
159 srtp_err_status_t status;
Cullen Jennings235513a2005-09-21 22:51:36 +0000160
161 /*
jfigus67b9c732014-11-20 10:17:21 -0500162 * verify that the compiler has interpreted the header data
163 * structure srtp_hdr_t correctly
Cullen Jennings235513a2005-09-21 22:51:36 +0000164 */
jfigus67b9c732014-11-20 10:17:21 -0500165 if (sizeof(srtp_hdr_t) != 12) {
166 printf("error: srtp_hdr_t has incorrect size"
167 "(size is %ld bytes, expected 12)\n",
168 (long)sizeof(srtp_hdr_t));
169 exit(1);
Cullen Jennings235513a2005-09-21 22:51:36 +0000170 }
171
jfigus67b9c732014-11-20 10:17:21 -0500172 /* initialize srtp library */
173 status = srtp_init();
174 if (status) {
175 printf("error: srtp init failed with error code %d\n", status);
176 exit(1);
177 }
178
179 /* load srtp_driver debug module */
jfigus92736bc2014-11-21 10:30:54 -0500180 status = srtp_crypto_kernel_load_debug_module(&mod_driver);
jfigus67b9c732014-11-20 10:17:21 -0500181 if (status) {
182 printf("error: load of srtp_driver debug module failed "
183 "with error code %d\n", status);
184 exit(1);
185 }
186
187 /* process input arguments */
188 while (1) {
189 q = getopt_s(argc, argv, "trcvld:");
190 if (q == -1) {
191 break;
192 }
193 switch (q) {
194 case 't':
195 do_timing_test = 1;
196 break;
197 case 'r':
198 do_rejection_test = 1;
199 break;
200 case 'c':
201 do_codec_timing = 1;
202 break;
203 case 'v':
204 do_validation = 1;
205 break;
206 case 'l':
207 do_list_mods = 1;
208 break;
209 case 'd':
jfigus92736bc2014-11-21 10:30:54 -0500210 status = srtp_crypto_kernel_set_debug_module(optarg_s, 1);
jfigus67b9c732014-11-20 10:17:21 -0500211 if (status) {
212 printf("error: set debug module (%s) failed\n", optarg_s);
213 exit(1);
214 }
215 break;
216 default:
217 usage(argv[0]);
218 }
219 }
220
221 if (!do_validation && !do_timing_test && !do_codec_timing
222 && !do_list_mods && !do_rejection_test) {
223 usage(argv[0]);
224 }
225
226 if (do_list_mods) {
jfigus92736bc2014-11-21 10:30:54 -0500227 status = srtp_crypto_kernel_list_debug_modules();
jfigus67b9c732014-11-20 10:17:21 -0500228 if (status) {
229 printf("error: list of debug modules failed\n");
230 exit(1);
231 }
232 }
233
234 if (do_validation) {
235 const srtp_policy_t **policy = policy_array;
236 srtp_policy_t *big_policy;
237
238 /* loop over policy array, testing srtp and srtcp for each policy */
239 while (*policy != NULL) {
240 printf("testing srtp_protect and srtp_unprotect\n");
241 if (srtp_test(*policy) == srtp_err_status_ok) {
242 printf("passed\n\n");
243 } else{
244 printf("failed\n");
245 exit(1);
246 }
247 printf("testing srtp_protect_rtcp and srtp_unprotect_rtcp\n");
248 if (srtcp_test(*policy) == srtp_err_status_ok) {
249 printf("passed\n\n");
250 } else{
251 printf("failed\n");
252 exit(1);
253 }
254 policy++;
255 }
256
257 /* create a big policy list and run tests on it */
258 status = srtp_create_big_policy(&big_policy);
259 if (status) {
260 printf("unexpected failure with error code %d\n", status);
261 exit(1);
262 }
263 printf("testing srtp_protect and srtp_unprotect with big policy\n");
264 if (srtp_test(big_policy) == srtp_err_status_ok) {
265 printf("passed\n\n");
266 } else{
267 printf("failed\n");
268 exit(1);
269 }
270 status = srtp_dealloc_big_policy(big_policy);
271 if (status) {
272 printf("unexpected failure with error code %d\n", status);
273 exit(1);
274 }
275
276 /* run test on wildcard policy */
277 printf("testing srtp_protect and srtp_unprotect on "
278 "wildcard ssrc policy\n");
279 if (srtp_test(&wildcard_policy) == srtp_err_status_ok) {
280 printf("passed\n\n");
281 } else{
282 printf("failed\n");
283 exit(1);
284 }
285
286 /*
287 * run validation test against the reference packets - note
288 * that this test only covers the default policy
289 */
290 printf("testing srtp_protect and srtp_unprotect against "
291 "reference packets\n");
292 if (srtp_validate() == srtp_err_status_ok) {
293 printf("passed\n\n");
294 } else{
295 printf("failed\n");
296 exit(1);
297 }
298
jfigusa14b5a02013-03-29 12:24:12 -0400299//FIXME: need to get this working with the OpenSSL AES module
300#ifndef OPENSSL
jfigus67b9c732014-11-20 10:17:21 -0500301 /*
302 * run validation test against the reference packets for
303 * AES-256
304 */
305 printf("testing srtp_protect and srtp_unprotect against "
306 "reference packets (AES-256)\n");
307 if (srtp_validate_aes_256() == srtp_err_status_ok) {
308 printf("passed\n\n");
309 } else{
310 printf("failed\n");
311 exit(1);
312 }
jfigusa14b5a02013-03-29 12:24:12 -0400313#endif
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000314
jfigus67b9c732014-11-20 10:17:21 -0500315 /*
316 * test the function srtp_remove_stream()
317 */
318 printf("testing srtp_remove_stream()...");
319 if (srtp_test_remove_stream() == srtp_err_status_ok) {
320 printf("passed\n");
321 } else{
322 printf("failed\n");
323 exit(1);
324 }
Pascal Bühlerbd3112a2015-11-06 20:29:15 +0100325
326 /*
327 * test the function srtp_update()
328 */
329 printf("testing srtp_update()...");
330 if (srtp_test_update() == srtp_err_status_ok) {
331 printf("passed\n");
332 } else {
333 printf("failed\n");
334 exit(1);
335 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000336 }
jfigus67b9c732014-11-20 10:17:21 -0500337
338 if (do_timing_test) {
339 const srtp_policy_t **policy = policy_array;
340
341 /* loop over policies, run timing test for each */
342 while (*policy != NULL) {
343 srtp_print_policy(*policy);
344 srtp_do_timing(*policy);
345 policy++;
346 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000347 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000348
jfigus67b9c732014-11-20 10:17:21 -0500349 if (do_rejection_test) {
350 const srtp_policy_t **policy = policy_array;
351
352 /* loop over policies, run rejection timing test for each */
353 while (*policy != NULL) {
354 srtp_print_policy(*policy);
355 srtp_do_rejection_timing(*policy);
356 policy++;
357 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000358 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000359
jfigus67b9c732014-11-20 10:17:21 -0500360 if (do_codec_timing) {
361 srtp_policy_t policy;
362 int ignore;
363 double mips = mips_estimate(1000000000, &ignore);
Cullen Jennings235513a2005-09-21 22:51:36 +0000364
jfigus67b9c732014-11-20 10:17:21 -0500365 srtp_crypto_policy_set_rtp_default(&policy.rtp);
366 srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
367 policy.ssrc.type = ssrc_specific;
368 policy.ssrc.value = 0xdecafbad;
369 policy.key = test_key;
370 policy.ekt = NULL;
371 policy.window_size = 128;
372 policy.allow_repeat_tx = 0;
373 policy.next = NULL;
Cullen Jennings235513a2005-09-21 22:51:36 +0000374
jfigus67b9c732014-11-20 10:17:21 -0500375 printf("mips estimate: %e\n", mips);
Cullen Jennings235513a2005-09-21 22:51:36 +0000376
jfigus67b9c732014-11-20 10:17:21 -0500377 printf("testing srtp processing time for voice codecs:\n");
378 printf("codec\t\tlength (octets)\t\tsrtp instructions/second\n");
379 printf("G.711\t\t%d\t\t\t%e\n", 80,
380 (double)mips * (80 * 8) /
381 srtp_bits_per_second(80, &policy) / .01 );
382 printf("G.711\t\t%d\t\t\t%e\n", 160,
383 (double)mips * (160 * 8) /
384 srtp_bits_per_second(160, &policy) / .02);
385 printf("G.726-32\t%d\t\t\t%e\n", 40,
386 (double)mips * (40 * 8) /
387 srtp_bits_per_second(40, &policy) / .01 );
388 printf("G.726-32\t%d\t\t\t%e\n", 80,
389 (double)mips * (80 * 8) /
390 srtp_bits_per_second(80, &policy) / .02);
391 printf("G.729\t\t%d\t\t\t%e\n", 10,
392 (double)mips * (10 * 8) /
393 srtp_bits_per_second(10, &policy) / .01 );
394 printf("G.729\t\t%d\t\t\t%e\n", 20,
395 (double)mips * (20 * 8) /
396 srtp_bits_per_second(20, &policy) / .02 );
397 printf("Wideband\t%d\t\t\t%e\n", 320,
398 (double)mips * (320 * 8) /
399 srtp_bits_per_second(320, &policy) / .01 );
400 printf("Wideband\t%d\t\t\t%e\n", 640,
401 (double)mips * (640 * 8) /
402 srtp_bits_per_second(640, &policy) / .02 );
403 }
Jonathan Lennoxdfb30842010-05-15 04:52:01 +0000404
jfigus67b9c732014-11-20 10:17:21 -0500405 status = srtp_shutdown();
406 if (status) {
407 printf("error: srtp shutdown failed with error code %d\n", status);
408 exit(1);
409 }
410
411 return 0;
Cullen Jennings235513a2005-09-21 22:51:36 +0000412}
413
414
415
416/*
417 * srtp_create_test_packet(len, ssrc) returns a pointer to a
418 * (malloced) example RTP packet whose data field has the length given
419 * by pkt_octet_len and the SSRC value ssrc. The total length of the
420 * packet is twelve octets longer, since the header is at the
421 * beginning. There is room at the end of the packet for a trailer,
422 * and the four octets following the packet are filled with 0xff
423 * values to enable testing for overwrites.
424 *
425 * note that the location of the test packet can (and should) be
426 * deallocated with the free() call once it is no longer needed.
427 */
428
429srtp_hdr_t *
jfigus67b9c732014-11-20 10:17:21 -0500430srtp_create_test_packet (int pkt_octet_len, uint32_t ssrc)
431{
432 int i;
433 uint8_t *buffer;
434 srtp_hdr_t *hdr;
435 int bytes_in_hdr = 12;
Cullen Jennings235513a2005-09-21 22:51:36 +0000436
jfigus67b9c732014-11-20 10:17:21 -0500437 /* allocate memory for test packet */
438 hdr = (srtp_hdr_t*)malloc(pkt_octet_len + bytes_in_hdr
439 + SRTP_MAX_TRAILER_LEN + 4);
440 if (!hdr) {
441 return NULL;
442 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000443
jfigus67b9c732014-11-20 10:17:21 -0500444 hdr->version = 2; /* RTP version two */
445 hdr->p = 0; /* no padding needed */
446 hdr->x = 0; /* no header extension */
447 hdr->cc = 0; /* no CSRCs */
448 hdr->m = 0; /* marker bit */
449 hdr->pt = 0xf; /* payload type */
450 hdr->seq = htons(0x1234); /* sequence number */
451 hdr->ts = htonl(0xdecafbad); /* timestamp */
452 hdr->ssrc = htonl(ssrc); /* synch. source */
Cullen Jennings235513a2005-09-21 22:51:36 +0000453
jfigus67b9c732014-11-20 10:17:21 -0500454 buffer = (uint8_t*)hdr;
455 buffer += bytes_in_hdr;
Cullen Jennings235513a2005-09-21 22:51:36 +0000456
jfigus67b9c732014-11-20 10:17:21 -0500457 /* set RTP data to 0xab */
458 for (i = 0; i < pkt_octet_len; i++) {
459 *buffer++ = 0xab;
460 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000461
jfigus67b9c732014-11-20 10:17:21 -0500462 /* set post-data value to 0xffff to enable overrun checking */
463 for (i = 0; i < SRTP_MAX_TRAILER_LEN + 4; i++) {
464 *buffer++ = 0xff;
465 }
466
467 return hdr;
Cullen Jennings235513a2005-09-21 22:51:36 +0000468}
469
470void
jfigus67b9c732014-11-20 10:17:21 -0500471srtp_do_timing (const srtp_policy_t *policy)
472{
473 int len;
Cullen Jennings235513a2005-09-21 22:51:36 +0000474
jfigus67b9c732014-11-20 10:17:21 -0500475 /*
476 * note: the output of this function is formatted so that it
477 * can be used in gnuplot. '#' indicates a comment, and "\r\n"
478 * terminates a record
479 */
480
481 printf("# testing srtp throughput:\r\n");
482 printf("# mesg length (octets)\tthroughput (megabits per second)\r\n");
483
484 for (len = 16; len <= 2048; len *= 2) {
485 printf("%d\t\t\t%f\r\n", len,
486 srtp_bits_per_second(len, policy) / 1.0E6);
487 }
488
489 /* these extra linefeeds let gnuplot know that a dataset is done */
490 printf("\r\n\r\n");
Cullen Jennings235513a2005-09-21 22:51:36 +0000491
492}
493
494void
jfigus67b9c732014-11-20 10:17:21 -0500495srtp_do_rejection_timing (const srtp_policy_t *policy)
496{
497 int len;
Cullen Jennings235513a2005-09-21 22:51:36 +0000498
jfigus67b9c732014-11-20 10:17:21 -0500499 /*
500 * note: the output of this function is formatted so that it
501 * can be used in gnuplot. '#' indicates a comment, and "\r\n"
502 * terminates a record
503 */
504
505 printf("# testing srtp rejection throughput:\r\n");
506 printf("# mesg length (octets)\trejections per second\r\n");
507
508 for (len = 8; len <= 2048; len *= 2) {
509 printf("%d\t\t\t%e\r\n", len, srtp_rejections_per_second(len, policy));
510 }
511
512 /* these extra linefeeds let gnuplot know that a dataset is done */
513 printf("\r\n\r\n");
Cullen Jennings235513a2005-09-21 22:51:36 +0000514
515}
516
517
518#define MAX_MSG_LEN 1024
519
520double
jfigus67b9c732014-11-20 10:17:21 -0500521srtp_bits_per_second (int msg_len_octets, const srtp_policy_t *policy)
522{
523 srtp_t srtp;
524 srtp_hdr_t *mesg;
525 int i;
526 clock_t timer;
527 int num_trials = 100000;
528 int len;
529 uint32_t ssrc;
530 srtp_err_status_t status;
Cullen Jennings235513a2005-09-21 22:51:36 +0000531
jfigus67b9c732014-11-20 10:17:21 -0500532 /*
533 * allocate and initialize an srtp session
534 */
535 status = srtp_create(&srtp, policy);
Cullen Jennings235513a2005-09-21 22:51:36 +0000536 if (status) {
jfigus67b9c732014-11-20 10:17:21 -0500537 printf("error: srtp_create() failed with error code %d\n", status);
538 exit(1);
Cullen Jennings235513a2005-09-21 22:51:36 +0000539 }
540
jfigus67b9c732014-11-20 10:17:21 -0500541 /*
542 * if the ssrc is unspecified, use a predetermined one
543 */
544 if (policy->ssrc.type != ssrc_specific) {
545 ssrc = 0xdeadbeef;
546 } else {
547 ssrc = policy->ssrc.value;
Jonathan Lennox75b36872010-05-21 00:30:21 +0000548 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000549
jfigus67b9c732014-11-20 10:17:21 -0500550 /*
551 * create a test packet
552 */
553 mesg = srtp_create_test_packet(msg_len_octets, ssrc);
554 if (mesg == NULL) {
555 return 0.0; /* indicate failure by returning zero */
Jonathan Lennox80c4c832010-05-17 19:30:28 +0000556
jfigus67b9c732014-11-20 10:17:21 -0500557 }
558 timer = clock();
559 for (i = 0; i < num_trials; i++) {
560 len = msg_len_octets + 12; /* add in rtp header length */
561
562 /* srtp protect message */
563 status = srtp_protect(srtp, mesg, &len);
564 if (status) {
565 printf("error: srtp_protect() failed with error code %d\n", status);
566 exit(1);
567 }
568
569 /* increment message number */
570 {
571 /* hack sequence to avoid problems with macros for htons/ntohs on some systems */
572 short new_seq = ntohs(mesg->seq) + 1;
573 mesg->seq = htons(new_seq);
574 }
575 }
576 timer = clock() - timer;
577
578 free(mesg);
579
580 status = srtp_dealloc(srtp);
581 if (status) {
582 printf("error: srtp_dealloc() failed with error code %d\n", status);
583 exit(1);
584 }
585
586 return (double)(msg_len_octets) * 8 *
587 num_trials * CLOCKS_PER_SEC / timer;
Cullen Jennings235513a2005-09-21 22:51:36 +0000588}
589
590double
jfigus67b9c732014-11-20 10:17:21 -0500591srtp_rejections_per_second (int msg_len_octets, const srtp_policy_t *policy)
592{
593 srtp_ctx_t *srtp;
594 srtp_hdr_t *mesg;
595 int i;
596 int len;
597 clock_t timer;
598 int num_trials = 1000000;
599 uint32_t ssrc = policy->ssrc.value;
600 srtp_err_status_t status;
Cullen Jennings235513a2005-09-21 22:51:36 +0000601
jfigus67b9c732014-11-20 10:17:21 -0500602 /*
603 * allocate and initialize an srtp session
604 */
605 status = srtp_create(&srtp, policy);
606 if (status) {
607 printf("error: srtp_create() failed with error code %d\n", status);
608 exit(1);
609 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000610
jfigus67b9c732014-11-20 10:17:21 -0500611 mesg = srtp_create_test_packet(msg_len_octets, ssrc);
612 if (mesg == NULL) {
613 return 0.0; /* indicate failure by returning zero */
614
615 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000616 len = msg_len_octets;
jfigus67b9c732014-11-20 10:17:21 -0500617 srtp_protect(srtp, (srtp_hdr_t*)mesg, &len);
Cullen Jennings235513a2005-09-21 22:51:36 +0000618
jfigus67b9c732014-11-20 10:17:21 -0500619 timer = clock();
620 for (i = 0; i < num_trials; i++) {
621 len = msg_len_octets;
622 srtp_unprotect(srtp, (srtp_hdr_t*)mesg, &len);
623 }
624 timer = clock() - timer;
Jonathan Lennox80c4c832010-05-17 19:30:28 +0000625
jfigus67b9c732014-11-20 10:17:21 -0500626 free(mesg);
Jonathan Lennox80c4c832010-05-17 19:30:28 +0000627
jfigus67b9c732014-11-20 10:17:21 -0500628 status = srtp_dealloc(srtp);
629 if (status) {
630 printf("error: srtp_dealloc() failed with error code %d\n", status);
631 exit(1);
632 }
633
634 return (double)num_trials * CLOCKS_PER_SEC / timer;
Cullen Jennings235513a2005-09-21 22:51:36 +0000635}
636
637
638void
jfigus67b9c732014-11-20 10:17:21 -0500639err_check (srtp_err_status_t s)
640{
641 if (s == srtp_err_status_ok) {
642 return;
643 } else{
644 fprintf(stderr, "error: unexpected srtp failure (code %d)\n", s);
645 }
646 exit(1);
Cullen Jennings235513a2005-09-21 22:51:36 +0000647}
648
jfigus857009c2014-11-05 11:17:43 -0500649srtp_err_status_t
jfigus67b9c732014-11-20 10:17:21 -0500650srtp_test (const srtp_policy_t *policy)
651{
652 int i;
653 srtp_t srtp_sender;
654 srtp_t srtp_rcvr;
655 srtp_err_status_t status = srtp_err_status_ok;
656 srtp_hdr_t *hdr, *hdr2;
657 uint8_t hdr_enc[64];
658 uint8_t *pkt_end;
659 int msg_len_octets, msg_len_enc;
660 int len;
661 int tag_length = policy->rtp.auth_tag_len;
662 uint32_t ssrc;
663 srtp_policy_t *rcvr_policy;
Cullen Jennings235513a2005-09-21 22:51:36 +0000664
jfigus67b9c732014-11-20 10:17:21 -0500665 err_check(srtp_create(&srtp_sender, policy));
Cullen Jennings235513a2005-09-21 22:51:36 +0000666
jfigus67b9c732014-11-20 10:17:21 -0500667 /* print out policy */
668 err_check(srtp_session_print_policy(srtp_sender));
Cullen Jennings235513a2005-09-21 22:51:36 +0000669
jfigus67b9c732014-11-20 10:17:21 -0500670 /*
671 * initialize data buffer, using the ssrc in the policy unless that
672 * value is a wildcard, in which case we'll just use an arbitrary
673 * one
674 */
675 if (policy->ssrc.type != ssrc_specific) {
676 ssrc = 0xdecafbad;
677 } else{
678 ssrc = policy->ssrc.value;
Cullen Jennings235513a2005-09-21 22:51:36 +0000679 }
jfigus67b9c732014-11-20 10:17:21 -0500680 msg_len_octets = 28;
681 hdr = srtp_create_test_packet(msg_len_octets, ssrc);
Cullen Jennings235513a2005-09-21 22:51:36 +0000682
jfigus67b9c732014-11-20 10:17:21 -0500683 if (hdr == NULL) {
684 return srtp_err_status_alloc_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +0000685 }
jfigus67b9c732014-11-20 10:17:21 -0500686 hdr2 = srtp_create_test_packet(msg_len_octets, ssrc);
687 if (hdr2 == NULL) {
688 free(hdr);
689 return srtp_err_status_alloc_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +0000690 }
691
Marcus Sundberg5c40da82005-10-08 18:15:00 +0000692 /* set message length */
693 len = msg_len_octets;
694
jfigus67b9c732014-11-20 10:17:21 -0500695 debug_print(mod_driver, "before protection:\n%s",
696 srtp_packet_to_string(hdr, len));
697
698#if PRINT_REFERENCE_PACKET
699 debug_print(mod_driver, "reference packet before protection:\n%s",
700 octet_string_hex_string((uint8_t*)hdr, len));
701#endif
Cullen Jennings235513a2005-09-21 22:51:36 +0000702 err_check(srtp_protect(srtp_sender, hdr, &len));
Cullen Jennings235513a2005-09-21 22:51:36 +0000703
jfigus67b9c732014-11-20 10:17:21 -0500704 debug_print(mod_driver, "after protection:\n%s",
705 srtp_packet_to_string(hdr, len));
706#if PRINT_REFERENCE_PACKET
707 debug_print(mod_driver, "after protection:\n%s",
708 octet_string_hex_string((uint8_t*)hdr, len));
709#endif
710
711 /* save protected message and length */
712 memcpy(hdr_enc, hdr, len);
713 msg_len_enc = len;
714
715 /*
716 * check for overrun of the srtp_protect() function
717 *
718 * The packet is followed by a value of 0xfffff; if the value of the
719 * data following the packet is different, then we know that the
720 * protect function is overwriting the end of the packet.
721 */
722 pkt_end = (uint8_t*)hdr + sizeof(srtp_hdr_t)
723 + msg_len_octets + tag_length;
724 for (i = 0; i < 4; i++) {
725 if (pkt_end[i] != 0xff) {
726 fprintf(stdout, "overwrite in srtp_protect() function "
727 "(expected %x, found %x in trailing octet %d)\n",
728 0xff, ((uint8_t*)hdr)[i], i);
729 free(hdr);
730 free(hdr2);
731 return srtp_err_status_algo_fail;
732 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000733 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000734
jfigus67b9c732014-11-20 10:17:21 -0500735 /*
736 * if the policy includes confidentiality, check that ciphertext is
737 * different than plaintext
738 *
739 * Note that this check will give false negatives, with some small
740 * probability, especially if the packets are short. For that
741 * reason, we skip this check if the plaintext is less than four
742 * octets long.
743 */
744 if ((policy->rtp.sec_serv & sec_serv_conf) && (msg_len_octets >= 4)) {
745 printf("testing that ciphertext is distinct from plaintext...");
746 status = srtp_err_status_algo_fail;
747 for (i = 12; i < msg_len_octets + 12; i++) {
748 if (((uint8_t*)hdr)[i] != ((uint8_t*)hdr2)[i]) {
749 status = srtp_err_status_ok;
750 }
751 }
752 if (status) {
753 printf("failed\n");
754 free(hdr);
755 free(hdr2);
756 return status;
757 }
758 printf("passed\n");
759 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000760
jfigus67b9c732014-11-20 10:17:21 -0500761 /*
762 * if the policy uses a 'wildcard' ssrc, then we need to make a copy
763 * of the policy that changes the direction to inbound
764 *
765 * we always copy the policy into the rcvr_policy, since otherwise
766 * the compiler would fret about the constness of the policy
767 */
768 rcvr_policy = (srtp_policy_t*)malloc(sizeof(srtp_policy_t));
769 if (rcvr_policy == NULL) {
770 free(hdr);
771 free(hdr2);
772 return srtp_err_status_alloc_fail;
773 }
774 memcpy(rcvr_policy, policy, sizeof(srtp_policy_t));
775 if (policy->ssrc.type == ssrc_any_outbound) {
776 rcvr_policy->ssrc.type = ssrc_any_inbound;
777 }
778
779 err_check(srtp_create(&srtp_rcvr, rcvr_policy));
780
781 err_check(srtp_unprotect(srtp_rcvr, hdr, &len));
782
783 debug_print(mod_driver, "after unprotection:\n%s",
784 srtp_packet_to_string(hdr, len));
785
786 /* verify that the unprotected packet matches the origial one */
787 for (i = 0; i < msg_len_octets; i++) {
788 if (((uint8_t*)hdr)[i] != ((uint8_t*)hdr2)[i]) {
789 fprintf(stdout, "mismatch at octet %d\n", i);
790 status = srtp_err_status_algo_fail;
791 }
792 }
793 if (status) {
794 free(hdr);
795 free(hdr2);
796 free(rcvr_policy);
797 return status;
798 }
799
800 /*
801 * if the policy includes authentication, then test for false positives
802 */
803 if (policy->rtp.sec_serv & sec_serv_auth) {
804 char *data = ((char*)hdr) + 12;
805
806 printf("testing for false positives in replay check...");
807
808 /* set message length */
809 len = msg_len_enc;
810
811 /* unprotect a second time - should fail with a replay error */
812 status = srtp_unprotect(srtp_rcvr, hdr_enc, &len);
813 if (status != srtp_err_status_replay_fail) {
814 printf("failed with error code %d\n", status);
815 free(hdr);
816 free(hdr2);
817 free(rcvr_policy);
818 return status;
819 } else {
820 printf("passed\n");
821 }
822
823 printf("testing for false positives in auth check...");
824
825 /* increment sequence number in header */
826 hdr->seq++;
827
828 /* set message length */
829 len = msg_len_octets;
830
831 /* apply protection */
832 err_check(srtp_protect(srtp_sender, hdr, &len));
833
834 /* flip bits in packet */
835 data[0] ^= 0xff;
836
837 /* unprotect, and check for authentication failure */
838 status = srtp_unprotect(srtp_rcvr, hdr, &len);
839 if (status != srtp_err_status_auth_fail) {
840 printf("failed\n");
841 free(hdr);
842 free(hdr2);
843 free(rcvr_policy);
844 return status;
845 } else {
846 printf("passed\n");
847 }
848
849 }
850
851 err_check(srtp_dealloc(srtp_sender));
852 err_check(srtp_dealloc(srtp_rcvr));
853
854 free(hdr);
855 free(hdr2);
856 free(rcvr_policy);
857 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +0000858}
859
860
jfigus857009c2014-11-05 11:17:43 -0500861srtp_err_status_t
jfigus67b9c732014-11-20 10:17:21 -0500862srtcp_test (const srtp_policy_t *policy)
863{
864 int i;
865 srtp_t srtcp_sender;
866 srtp_t srtcp_rcvr;
867 srtp_err_status_t status = srtp_err_status_ok;
868 srtp_hdr_t *hdr, *hdr2;
869 uint8_t hdr_enc[64];
870 uint8_t *pkt_end;
871 int msg_len_octets, msg_len_enc;
872 int len;
873 int tag_length = policy->rtp.auth_tag_len;
874 uint32_t ssrc;
875 srtp_policy_t *rcvr_policy;
David McGrew9c70f292006-05-03 19:38:38 +0000876
jfigus67b9c732014-11-20 10:17:21 -0500877 err_check(srtp_create(&srtcp_sender, policy));
David McGrew9c70f292006-05-03 19:38:38 +0000878
jfigus67b9c732014-11-20 10:17:21 -0500879 /* print out policy */
880 err_check(srtp_session_print_policy(srtcp_sender));
David McGrew9c70f292006-05-03 19:38:38 +0000881
jfigus67b9c732014-11-20 10:17:21 -0500882 /*
883 * initialize data buffer, using the ssrc in the policy unless that
884 * value is a wildcard, in which case we'll just use an arbitrary
885 * one
886 */
887 if (policy->ssrc.type != ssrc_specific) {
888 ssrc = 0xdecafbad;
889 } else{
890 ssrc = policy->ssrc.value;
David McGrew9c70f292006-05-03 19:38:38 +0000891 }
jfigus67b9c732014-11-20 10:17:21 -0500892 msg_len_octets = 28;
893 hdr = srtp_create_test_packet(msg_len_octets, ssrc);
David McGrew9c70f292006-05-03 19:38:38 +0000894
jfigus67b9c732014-11-20 10:17:21 -0500895 if (hdr == NULL) {
896 return srtp_err_status_alloc_fail;
David McGrew9c70f292006-05-03 19:38:38 +0000897 }
jfigus67b9c732014-11-20 10:17:21 -0500898 hdr2 = srtp_create_test_packet(msg_len_octets, ssrc);
899 if (hdr2 == NULL) {
900 free(hdr);
901 return srtp_err_status_alloc_fail;
David McGrew9c70f292006-05-03 19:38:38 +0000902 }
903
David McGrew9c70f292006-05-03 19:38:38 +0000904 /* set message length */
905 len = msg_len_octets;
906
jfigus67b9c732014-11-20 10:17:21 -0500907 debug_print(mod_driver, "before protection:\n%s",
908 srtp_packet_to_string(hdr, len));
909
910#if PRINT_REFERENCE_PACKET
911 debug_print(mod_driver, "reference packet before protection:\n%s",
912 octet_string_hex_string((uint8_t*)hdr, len));
913#endif
David McGrew9c70f292006-05-03 19:38:38 +0000914 err_check(srtp_protect_rtcp(srtcp_sender, hdr, &len));
David McGrew9c70f292006-05-03 19:38:38 +0000915
jfigus67b9c732014-11-20 10:17:21 -0500916 debug_print(mod_driver, "after protection:\n%s",
917 srtp_packet_to_string(hdr, len));
918#if PRINT_REFERENCE_PACKET
919 debug_print(mod_driver, "after protection:\n%s",
920 octet_string_hex_string((uint8_t*)hdr, len));
921#endif
922
923 /* save protected message and length */
924 memcpy(hdr_enc, hdr, len);
925 msg_len_enc = len;
926
927 /*
928 * check for overrun of the srtp_protect() function
929 *
930 * The packet is followed by a value of 0xfffff; if the value of the
931 * data following the packet is different, then we know that the
932 * protect function is overwriting the end of the packet.
933 */
934 pkt_end = (uint8_t*)hdr + sizeof(srtp_hdr_t)
935 + msg_len_octets + tag_length;
936 for (i = 0; i < 4; i++) {
937 if (pkt_end[i] != 0xff) {
938 fprintf(stdout, "overwrite in srtp_protect_rtcp() function "
939 "(expected %x, found %x in trailing octet %d)\n",
940 0xff, ((uint8_t*)hdr)[i], i);
941 free(hdr);
942 free(hdr2);
943 return srtp_err_status_algo_fail;
944 }
David McGrew9c70f292006-05-03 19:38:38 +0000945 }
David McGrew9c70f292006-05-03 19:38:38 +0000946
jfigus67b9c732014-11-20 10:17:21 -0500947 /*
948 * if the policy includes confidentiality, check that ciphertext is
949 * different than plaintext
950 *
951 * Note that this check will give false negatives, with some small
952 * probability, especially if the packets are short. For that
953 * reason, we skip this check if the plaintext is less than four
954 * octets long.
955 */
956 if ((policy->rtp.sec_serv & sec_serv_conf) && (msg_len_octets >= 4)) {
957 printf("testing that ciphertext is distinct from plaintext...");
958 status = srtp_err_status_algo_fail;
959 for (i = 12; i < msg_len_octets + 12; i++) {
960 if (((uint8_t*)hdr)[i] != ((uint8_t*)hdr2)[i]) {
961 status = srtp_err_status_ok;
962 }
963 }
964 if (status) {
965 printf("failed\n");
966 free(hdr);
967 free(hdr2);
968 return status;
969 }
970 printf("passed\n");
971 }
David McGrew9c70f292006-05-03 19:38:38 +0000972
jfigus67b9c732014-11-20 10:17:21 -0500973 /*
974 * if the policy uses a 'wildcard' ssrc, then we need to make a copy
975 * of the policy that changes the direction to inbound
976 *
977 * we always copy the policy into the rcvr_policy, since otherwise
978 * the compiler would fret about the constness of the policy
979 */
980 rcvr_policy = (srtp_policy_t*)malloc(sizeof(srtp_policy_t));
981 if (rcvr_policy == NULL) {
982 return srtp_err_status_alloc_fail;
983 }
984 memcpy(rcvr_policy, policy, sizeof(srtp_policy_t));
985 if (policy->ssrc.type == ssrc_any_outbound) {
986 rcvr_policy->ssrc.type = ssrc_any_inbound;
987 }
988
989 err_check(srtp_create(&srtcp_rcvr, rcvr_policy));
990
991 err_check(srtp_unprotect_rtcp(srtcp_rcvr, hdr, &len));
992
993 debug_print(mod_driver, "after unprotection:\n%s",
994 srtp_packet_to_string(hdr, len));
995
996 /* verify that the unprotected packet matches the origial one */
997 for (i = 0; i < msg_len_octets; i++) {
998 if (((uint8_t*)hdr)[i] != ((uint8_t*)hdr2)[i]) {
999 fprintf(stdout, "mismatch at octet %d\n", i);
1000 status = srtp_err_status_algo_fail;
1001 }
1002 }
1003 if (status) {
1004 free(hdr);
1005 free(hdr2);
1006 free(rcvr_policy);
1007 return status;
1008 }
1009
1010 /*
1011 * if the policy includes authentication, then test for false positives
1012 */
1013 if (policy->rtp.sec_serv & sec_serv_auth) {
1014 char *data = ((char*)hdr) + 12;
1015
1016 printf("testing for false positives in replay check...");
1017
1018 /* set message length */
1019 len = msg_len_enc;
1020
1021 /* unprotect a second time - should fail with a replay error */
1022 status = srtp_unprotect_rtcp(srtcp_rcvr, hdr_enc, &len);
1023 if (status != srtp_err_status_replay_fail) {
1024 printf("failed with error code %d\n", status);
1025 free(hdr);
1026 free(hdr2);
1027 free(rcvr_policy);
1028 return status;
1029 } else {
1030 printf("passed\n");
1031 }
1032
1033 printf("testing for false positives in auth check...");
1034
1035 /* increment sequence number in header */
1036 hdr->seq++;
1037
1038 /* set message length */
1039 len = msg_len_octets;
1040
1041 /* apply protection */
1042 err_check(srtp_protect_rtcp(srtcp_sender, hdr, &len));
1043
1044 /* flip bits in packet */
1045 data[0] ^= 0xff;
1046
1047 /* unprotect, and check for authentication failure */
1048 status = srtp_unprotect_rtcp(srtcp_rcvr, hdr, &len);
1049 if (status != srtp_err_status_auth_fail) {
1050 printf("failed\n");
1051 free(hdr);
1052 free(hdr2);
1053 free(rcvr_policy);
1054 return status;
1055 } else {
1056 printf("passed\n");
1057 }
1058
1059 }
1060
1061 err_check(srtp_dealloc(srtcp_sender));
1062 err_check(srtp_dealloc(srtcp_rcvr));
1063
1064 free(hdr);
1065 free(hdr2);
1066 free(rcvr_policy);
1067 return srtp_err_status_ok;
David McGrew9c70f292006-05-03 19:38:38 +00001068}
1069
1070
jfigus857009c2014-11-05 11:17:43 -05001071srtp_err_status_t
jfigus67b9c732014-11-20 10:17:21 -05001072srtp_session_print_policy (srtp_t srtp)
1073{
1074 char *serv_descr[4] = {
1075 "none",
1076 "confidentiality",
1077 "authentication",
1078 "confidentiality and authentication"
1079 };
1080 char *direction[3] = {
1081 "unknown",
1082 "outbound",
1083 "inbound"
1084 };
1085 srtp_stream_t stream;
Cullen Jennings235513a2005-09-21 22:51:36 +00001086
jfigus67b9c732014-11-20 10:17:21 -05001087 /* sanity checking */
1088 if (srtp == NULL) {
1089 return srtp_err_status_fail;
1090 }
Cullen Jennings235513a2005-09-21 22:51:36 +00001091
jfigus67b9c732014-11-20 10:17:21 -05001092 /* if there's a template stream, print it out */
1093 if (srtp->stream_template != NULL) {
1094 stream = srtp->stream_template;
1095 printf("# SSRC: any %s\r\n"
1096 "# rtp cipher: %s\r\n"
1097 "# rtp auth: %s\r\n"
1098 "# rtp services: %s\r\n"
1099 "# rtcp cipher: %s\r\n"
1100 "# rtcp auth: %s\r\n"
1101 "# rtcp services: %s\r\n"
1102 "# window size: %lu\r\n"
1103 "# tx rtx allowed:%s\r\n",
1104 direction[stream->direction],
1105 stream->rtp_cipher->type->description,
1106 stream->rtp_auth->type->description,
1107 serv_descr[stream->rtp_services],
1108 stream->rtcp_cipher->type->description,
1109 stream->rtcp_auth->type->description,
1110 serv_descr[stream->rtcp_services],
jfigusde8deb32014-11-25 12:58:11 -05001111 srtp_rdbx_get_window_size(&stream->rtp_rdbx),
jfigus67b9c732014-11-20 10:17:21 -05001112 stream->allow_repeat_tx ? "true" : "false");
1113 }
Cullen Jennings235513a2005-09-21 22:51:36 +00001114
jfigus67b9c732014-11-20 10:17:21 -05001115 /* loop over streams in session, printing the policy of each */
1116 stream = srtp->stream_list;
1117 while (stream != NULL) {
1118 if (stream->rtp_services > sec_serv_conf_and_auth) {
1119 return srtp_err_status_bad_param;
1120 }
Cullen Jennings235513a2005-09-21 22:51:36 +00001121
jfigus67b9c732014-11-20 10:17:21 -05001122 printf("# SSRC: 0x%08x\r\n"
1123 "# rtp cipher: %s\r\n"
1124 "# rtp auth: %s\r\n"
1125 "# rtp services: %s\r\n"
1126 "# rtcp cipher: %s\r\n"
1127 "# rtcp auth: %s\r\n"
1128 "# rtcp services: %s\r\n"
1129 "# window size: %lu\r\n"
1130 "# tx rtx allowed:%s\r\n",
1131 stream->ssrc,
1132 stream->rtp_cipher->type->description,
1133 stream->rtp_auth->type->description,
1134 serv_descr[stream->rtp_services],
1135 stream->rtcp_cipher->type->description,
1136 stream->rtcp_auth->type->description,
1137 serv_descr[stream->rtcp_services],
jfigusde8deb32014-11-25 12:58:11 -05001138 srtp_rdbx_get_window_size(&stream->rtp_rdbx),
jfigus67b9c732014-11-20 10:17:21 -05001139 stream->allow_repeat_tx ? "true" : "false");
1140
1141 /* advance to next stream in the list */
1142 stream = stream->next;
1143 }
1144 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +00001145}
1146
jfigus857009c2014-11-05 11:17:43 -05001147srtp_err_status_t
jfigus67b9c732014-11-20 10:17:21 -05001148srtp_print_policy (const srtp_policy_t *policy)
1149{
1150 srtp_err_status_t status;
1151 srtp_t session;
Cullen Jennings235513a2005-09-21 22:51:36 +00001152
jfigus67b9c732014-11-20 10:17:21 -05001153 status = srtp_create(&session, policy);
1154 if (status) {
1155 return status;
1156 }
1157 status = srtp_session_print_policy(session);
1158 if (status) {
1159 return status;
1160 }
1161 status = srtp_dealloc(session);
1162 if (status) {
1163 return status;
1164 }
1165 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +00001166}
1167
jfigus67b9c732014-11-20 10:17:21 -05001168/*
1169 * srtp_print_packet(...) is for debugging only
Cullen Jennings235513a2005-09-21 22:51:36 +00001170 * it prints an RTP packet to the stdout
1171 *
1172 * note that this function is *not* threadsafe
1173 */
1174
1175#include <stdio.h>
1176
1177#define MTU 2048
1178
1179char packet_string[MTU];
1180
1181char *
jfigus67b9c732014-11-20 10:17:21 -05001182srtp_packet_to_string (srtp_hdr_t *hdr, int pkt_octet_len)
1183{
1184 int octets_in_rtp_header = 12;
1185 uint8_t *data = ((uint8_t*)hdr) + octets_in_rtp_header;
1186 int hex_len = pkt_octet_len - octets_in_rtp_header;
Cullen Jennings235513a2005-09-21 22:51:36 +00001187
jfigus67b9c732014-11-20 10:17:21 -05001188 /* sanity checking */
1189 if ((hdr == NULL) || (pkt_octet_len > MTU)) {
1190 return NULL;
1191 }
Cullen Jennings235513a2005-09-21 22:51:36 +00001192
jfigus67b9c732014-11-20 10:17:21 -05001193 /* write packet into string */
1194 sprintf(packet_string,
1195 "(s)rtp packet: {\n"
1196 " version:\t%d\n"
1197 " p:\t\t%d\n"
1198 " x:\t\t%d\n"
1199 " cc:\t\t%d\n"
1200 " m:\t\t%d\n"
1201 " pt:\t\t%x\n"
1202 " seq:\t\t%x\n"
1203 " ts:\t\t%x\n"
1204 " ssrc:\t%x\n"
1205 " data:\t%s\n"
1206 "} (%d octets in total)\n",
1207 hdr->version,
1208 hdr->p,
1209 hdr->x,
1210 hdr->cc,
1211 hdr->m,
1212 hdr->pt,
1213 hdr->seq,
1214 hdr->ts,
1215 hdr->ssrc,
1216 octet_string_hex_string(data, hex_len),
1217 pkt_octet_len);
Cullen Jennings235513a2005-09-21 22:51:36 +00001218
jfigus67b9c732014-11-20 10:17:21 -05001219 return packet_string;
Cullen Jennings235513a2005-09-21 22:51:36 +00001220}
1221
1222/*
1223 * mips_estimate() is a simple function to estimate the number of
1224 * instructions per second that the host can perform. note that this
1225 * function can be grossly wrong; you may want to have a manual sanity
1226 * check of its output!
1227 *
1228 * the 'ignore' pointer is there to convince the compiler to not just
1229 * optimize away the function
1230 */
1231
1232double
jfigus67b9c732014-11-20 10:17:21 -05001233mips_estimate (int num_trials, int *ignore)
1234{
1235 clock_t t;
1236 volatile int i, sum;
Cullen Jennings235513a2005-09-21 22:51:36 +00001237
jfigus67b9c732014-11-20 10:17:21 -05001238 sum = 0;
1239 t = clock();
1240 for (i = 0; i < num_trials; i++) {
1241 sum += i;
1242 }
1243 t = clock() - t;
Cullen Jennings235513a2005-09-21 22:51:36 +00001244
1245/* printf("%d\n", sum); */
jfigus67b9c732014-11-20 10:17:21 -05001246 *ignore = sum;
Cullen Jennings235513a2005-09-21 22:51:36 +00001247
jfigus67b9c732014-11-20 10:17:21 -05001248 return (double)num_trials * CLOCKS_PER_SEC / t;
Cullen Jennings235513a2005-09-21 22:51:36 +00001249}
1250
1251
1252/*
1253 * srtp_validate() verifies the correctness of libsrtp by comparing
1254 * some computed packets against some pre-computed reference values.
1255 * These packets were made with the default SRTP policy.
1256 */
1257
1258
jfigus857009c2014-11-05 11:17:43 -05001259srtp_err_status_t
jfigus67b9c732014-11-20 10:17:21 -05001260srtp_validate ()
1261{
1262 uint8_t srtp_plaintext_ref[28] = {
1263 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1264 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
1265 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1266 0xab, 0xab, 0xab, 0xab
1267 };
1268 uint8_t srtp_plaintext[38] = {
1269 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1270 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
1271 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1272 0xab, 0xab, 0xab, 0xab, 0x00, 0x00, 0x00, 0x00,
1273 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1274 };
1275 uint8_t srtp_ciphertext[38] = {
1276 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1277 0xca, 0xfe, 0xba, 0xbe, 0x4e, 0x55, 0xdc, 0x4c,
1278 0xe7, 0x99, 0x78, 0xd8, 0x8c, 0xa4, 0xd2, 0x15,
1279 0x94, 0x9d, 0x24, 0x02, 0xb7, 0x8d, 0x6a, 0xcc,
1280 0x99, 0xea, 0x17, 0x9b, 0x8d, 0xbb
1281 };
1282 srtp_t srtp_snd, srtp_recv;
1283 srtp_err_status_t status;
1284 int len;
1285 srtp_policy_t policy;
Cullen Jennings235513a2005-09-21 22:51:36 +00001286
jfigus67b9c732014-11-20 10:17:21 -05001287 /*
1288 * create a session with a single stream using the default srtp
1289 * policy and with the SSRC value 0xcafebabe
1290 */
1291 srtp_crypto_policy_set_rtp_default(&policy.rtp);
1292 srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
1293 policy.ssrc.type = ssrc_specific;
1294 policy.ssrc.value = 0xcafebabe;
1295 policy.key = test_key;
1296 policy.ekt = NULL;
1297 policy.window_size = 128;
1298 policy.allow_repeat_tx = 0;
1299 policy.next = NULL;
Cullen Jennings235513a2005-09-21 22:51:36 +00001300
jfigus67b9c732014-11-20 10:17:21 -05001301 status = srtp_create(&srtp_snd, &policy);
1302 if (status) {
1303 return status;
1304 }
Cullen Jennings235513a2005-09-21 22:51:36 +00001305
jfigus67b9c732014-11-20 10:17:21 -05001306 /*
1307 * protect plaintext, then compare with ciphertext
1308 */
1309 len = 28;
1310 status = srtp_protect(srtp_snd, srtp_plaintext, &len);
1311 if (status || (len != 38)) {
1312 return srtp_err_status_fail;
1313 }
Cullen Jennings235513a2005-09-21 22:51:36 +00001314
jfigus67b9c732014-11-20 10:17:21 -05001315 debug_print(mod_driver, "ciphertext:\n %s",
1316 octet_string_hex_string(srtp_plaintext, len));
1317 debug_print(mod_driver, "ciphertext reference:\n %s",
1318 octet_string_hex_string(srtp_ciphertext, len));
Cullen Jennings235513a2005-09-21 22:51:36 +00001319
jfigus67b9c732014-11-20 10:17:21 -05001320 if (octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len)) {
1321 return srtp_err_status_fail;
1322 }
Jonathan Lennox80c4c832010-05-17 19:30:28 +00001323
jfigus67b9c732014-11-20 10:17:21 -05001324 /*
1325 * create a receiver session context comparable to the one created
1326 * above - we need to do this so that the replay checking doesn't
1327 * complain
1328 */
1329 status = srtp_create(&srtp_recv, &policy);
1330 if (status) {
1331 return status;
1332 }
Jonathan Lennox80c4c832010-05-17 19:30:28 +00001333
jfigus67b9c732014-11-20 10:17:21 -05001334 /*
1335 * unprotect ciphertext, then compare with plaintext
1336 */
1337 status = srtp_unprotect(srtp_recv, srtp_ciphertext, &len);
1338 if (status || (len != 28)) {
1339 return status;
1340 }
1341
1342 if (octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len)) {
1343 return srtp_err_status_fail;
1344 }
1345
1346 status = srtp_dealloc(srtp_snd);
1347 if (status) {
1348 return status;
1349 }
1350
1351 status = srtp_dealloc(srtp_recv);
1352 if (status) {
1353 return status;
1354 }
1355
1356 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +00001357}
1358
1359
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001360/*
1361 * srtp_validate_aes_256() verifies the correctness of libsrtp by comparing
1362 * some computed packets against some pre-computed reference values.
1363 * These packets were made with the AES-CM-256/HMAC-SHA-1-80 policy.
1364 */
1365
1366
jfigus857009c2014-11-05 11:17:43 -05001367srtp_err_status_t
jfigus67b9c732014-11-20 10:17:21 -05001368srtp_validate_aes_256 ()
1369{
1370 unsigned char aes_256_test_key[46] = {
1371 0xf0, 0xf0, 0x49, 0x14, 0xb5, 0x13, 0xf2, 0x76,
1372 0x3a, 0x1b, 0x1f, 0xa1, 0x30, 0xf1, 0x0e, 0x29,
1373 0x98, 0xf6, 0xf6, 0xe4, 0x3e, 0x43, 0x09, 0xd1,
1374 0xe6, 0x22, 0xa0, 0xe3, 0x32, 0xb9, 0xf1, 0xb6,
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001375
jfigus67b9c732014-11-20 10:17:21 -05001376 0x3b, 0x04, 0x80, 0x3d, 0xe5, 0x1e, 0xe7, 0xc9,
1377 0x64, 0x23, 0xab, 0x5b, 0x78, 0xd2
1378 };
1379 uint8_t srtp_plaintext_ref[28] = {
1380 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1381 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
1382 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1383 0xab, 0xab, 0xab, 0xab
1384 };
1385 uint8_t srtp_plaintext[38] = {
1386 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1387 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
1388 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1389 0xab, 0xab, 0xab, 0xab, 0x00, 0x00, 0x00, 0x00,
1390 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1391 };
1392 uint8_t srtp_ciphertext[38] = {
1393 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1394 0xca, 0xfe, 0xba, 0xbe, 0xf1, 0xd9, 0xde, 0x17,
1395 0xff, 0x25, 0x1f, 0xf1, 0xaa, 0x00, 0x77, 0x74,
1396 0xb0, 0xb4, 0xb4, 0x0d, 0xa0, 0x8d, 0x9d, 0x9a,
1397 0x5b, 0x3a, 0x55, 0xd8, 0x87, 0x3b
1398 };
1399 srtp_t srtp_snd, srtp_recv;
1400 srtp_err_status_t status;
1401 int len;
1402 srtp_policy_t policy;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001403
jfigus67b9c732014-11-20 10:17:21 -05001404 /*
1405 * create a session with a single stream using the default srtp
1406 * policy and with the SSRC value 0xcafebabe
1407 */
1408 srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(&policy.rtp);
1409 srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(&policy.rtcp);
1410 policy.ssrc.type = ssrc_specific;
1411 policy.ssrc.value = 0xcafebabe;
1412 policy.key = aes_256_test_key;
1413 policy.ekt = NULL;
1414 policy.window_size = 128;
1415 policy.allow_repeat_tx = 0;
1416 policy.next = NULL;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001417
jfigus67b9c732014-11-20 10:17:21 -05001418 status = srtp_create(&srtp_snd, &policy);
1419 if (status) {
1420 return status;
1421 }
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001422
jfigus67b9c732014-11-20 10:17:21 -05001423 /*
1424 * protect plaintext, then compare with ciphertext
1425 */
1426 len = 28;
1427 status = srtp_protect(srtp_snd, srtp_plaintext, &len);
1428 if (status || (len != 38)) {
1429 return srtp_err_status_fail;
1430 }
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001431
jfigus67b9c732014-11-20 10:17:21 -05001432 debug_print(mod_driver, "ciphertext:\n %s",
1433 octet_string_hex_string(srtp_plaintext, len));
1434 debug_print(mod_driver, "ciphertext reference:\n %s",
1435 octet_string_hex_string(srtp_ciphertext, len));
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001436
jfigus67b9c732014-11-20 10:17:21 -05001437 if (octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len)) {
1438 return srtp_err_status_fail;
1439 }
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001440
jfigus67b9c732014-11-20 10:17:21 -05001441 /*
1442 * create a receiver session context comparable to the one created
1443 * above - we need to do this so that the replay checking doesn't
1444 * complain
1445 */
1446 status = srtp_create(&srtp_recv, &policy);
1447 if (status) {
1448 return status;
1449 }
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001450
jfigus67b9c732014-11-20 10:17:21 -05001451 /*
1452 * unprotect ciphertext, then compare with plaintext
1453 */
1454 status = srtp_unprotect(srtp_recv, srtp_ciphertext, &len);
1455 if (status || (len != 28)) {
1456 return status;
1457 }
1458
1459 if (octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len)) {
1460 return srtp_err_status_fail;
1461 }
1462
1463 status = srtp_dealloc(srtp_snd);
1464 if (status) {
1465 return status;
1466 }
1467
1468 status = srtp_dealloc(srtp_recv);
1469 if (status) {
1470 return status;
1471 }
1472
1473 return srtp_err_status_ok;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001474}
1475
1476
jfigus857009c2014-11-05 11:17:43 -05001477srtp_err_status_t
jfigus67b9c732014-11-20 10:17:21 -05001478srtp_create_big_policy (srtp_policy_t **list)
1479{
1480 extern const srtp_policy_t *policy_array[];
1481 srtp_policy_t *p, *tmp;
1482 int i = 0;
1483 uint32_t ssrc = 0;
Cullen Jennings235513a2005-09-21 22:51:36 +00001484
jfigus67b9c732014-11-20 10:17:21 -05001485 /* sanity checking */
1486 if ((list == NULL) || (policy_array[0] == NULL)) {
1487 return srtp_err_status_bad_param;
1488 }
Cullen Jennings235513a2005-09-21 22:51:36 +00001489
jfigus67b9c732014-11-20 10:17:21 -05001490 /*
1491 * loop over policy list, mallocing a new list and copying values
1492 * into it (and incrementing the SSRC value as we go along)
1493 */
1494 tmp = NULL;
1495 while (policy_array[i] != NULL) {
1496 p = (srtp_policy_t*)malloc(sizeof(srtp_policy_t));
1497 if (p == NULL) {
1498 return srtp_err_status_bad_param;
1499 }
1500 memcpy(p, policy_array[i], sizeof(srtp_policy_t));
1501 p->ssrc.type = ssrc_specific;
1502 p->ssrc.value = ssrc++;
1503 p->next = tmp;
1504 tmp = p;
1505 i++;
1506 }
1507 *list = p;
1508
1509 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +00001510}
1511
jfigus857009c2014-11-05 11:17:43 -05001512srtp_err_status_t
jfigus67b9c732014-11-20 10:17:21 -05001513srtp_dealloc_big_policy (srtp_policy_t *list)
1514{
1515 srtp_policy_t *p, *next;
Jonathan Lennox80c4c832010-05-17 19:30:28 +00001516
jfigus67b9c732014-11-20 10:17:21 -05001517 for (p = list; p != NULL; p = next) {
1518 next = p->next;
1519 free(p);
1520 }
Jonathan Lennox80c4c832010-05-17 19:30:28 +00001521
jfigus67b9c732014-11-20 10:17:21 -05001522 return srtp_err_status_ok;
Jonathan Lennox80c4c832010-05-17 19:30:28 +00001523}
1524
1525
jfigus857009c2014-11-05 11:17:43 -05001526srtp_err_status_t
jfigus67b9c732014-11-20 10:17:21 -05001527srtp_test_remove_stream ()
1528{
1529 srtp_err_status_t status;
1530 srtp_policy_t *policy_list, policy;
1531 srtp_t session;
1532 srtp_stream_t stream;
Cullen Jennings235513a2005-09-21 22:51:36 +00001533
jfigus67b9c732014-11-20 10:17:21 -05001534 /*
1535 * srtp_get_stream() is a libSRTP internal function that we declare
1536 * here so that we can use it to verify the correct operation of the
1537 * library
1538 */
1539 extern srtp_stream_t srtp_get_stream(srtp_t srtp, uint32_t ssrc);
Cullen Jennings235513a2005-09-21 22:51:36 +00001540
Cullen Jennings235513a2005-09-21 22:51:36 +00001541
jfigus67b9c732014-11-20 10:17:21 -05001542 status = srtp_create_big_policy(&policy_list);
1543 if (status) {
1544 return status;
1545 }
Cullen Jennings235513a2005-09-21 22:51:36 +00001546
jfigus67b9c732014-11-20 10:17:21 -05001547 status = srtp_create(&session, policy_list);
1548 if (status) {
1549 return status;
1550 }
Jonathan Lennox80c4c832010-05-17 19:30:28 +00001551
jfigus67b9c732014-11-20 10:17:21 -05001552 /*
1553 * check for false positives by trying to remove a stream that's not
1554 * in the session
1555 */
1556 status = srtp_remove_stream(session, htonl(0xaaaaaaaa));
1557 if (status != srtp_err_status_no_ctx) {
1558 return srtp_err_status_fail;
1559 }
Jonathan Lennox80c4c832010-05-17 19:30:28 +00001560
jfigus67b9c732014-11-20 10:17:21 -05001561 /*
1562 * check for false negatives by removing stream 0x1, then
1563 * searching for streams 0x0 and 0x2
1564 */
1565 status = srtp_remove_stream(session, htonl(0x1));
1566 if (status != srtp_err_status_ok) {
1567 return srtp_err_status_fail;
1568 }
1569 stream = srtp_get_stream(session, htonl(0x0));
1570 if (stream == NULL) {
1571 return srtp_err_status_fail;
1572 }
1573 stream = srtp_get_stream(session, htonl(0x2));
1574 if (stream == NULL) {
1575 return srtp_err_status_fail;
1576 }
Jonathan Lennoxad741b22010-05-27 19:23:05 +00001577
jfigus67b9c732014-11-20 10:17:21 -05001578 status = srtp_dealloc(session);
1579 if (status != srtp_err_status_ok) {
1580 return status;
1581 }
Jonathan Lennoxad741b22010-05-27 19:23:05 +00001582
jfigus67b9c732014-11-20 10:17:21 -05001583 status = srtp_dealloc_big_policy(policy_list);
1584 if (status != srtp_err_status_ok) {
1585 return status;
1586 }
Jonathan Lennoxad741b22010-05-27 19:23:05 +00001587
jfigus67b9c732014-11-20 10:17:21 -05001588 /* Now test adding and removing a single stream */
1589 srtp_crypto_policy_set_rtp_default(&policy.rtp);
1590 srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
1591 policy.ssrc.type = ssrc_specific;
1592 policy.ssrc.value = 0xcafebabe;
1593 policy.key = test_key;
1594 policy.ekt = NULL;
1595 policy.window_size = 128;
1596 policy.allow_repeat_tx = 0;
1597 policy.next = NULL;
Jonathan Lennoxad741b22010-05-27 19:23:05 +00001598
jfigus67b9c732014-11-20 10:17:21 -05001599 status = srtp_create(&session, NULL);
1600 if (status != srtp_err_status_ok) {
1601 return status;
1602 }
1603
1604 status = srtp_add_stream(session, &policy);
1605 if (status != srtp_err_status_ok) {
1606 return status;
1607 }
1608
1609 status = srtp_remove_stream(session, htonl(0xcafebabe));
1610 if (status != srtp_err_status_ok) {
1611 return status;
1612 }
1613
1614 status = srtp_dealloc(session);
1615 if (status != srtp_err_status_ok) {
1616 return status;
1617 }
1618
1619 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +00001620}
1621
Pascal Bühlerbd3112a2015-11-06 20:29:15 +01001622
1623unsigned char test_alt_key[46] = {
1624 0xe5, 0x19, 0x6f, 0x01, 0x5e, 0xf1, 0x9b, 0xe1,
1625 0xd7, 0x47, 0xa7, 0x27, 0x07, 0xd7, 0x47, 0x33,
1626 0x01, 0xc2, 0x35, 0x4d, 0x59, 0x6a, 0xf7, 0x84,
1627 0x96, 0x98, 0xeb, 0xaa, 0xac, 0xf6, 0xa1, 0x45,
1628 0xc7, 0x15, 0xe2, 0xea, 0xfe, 0x55, 0x67, 0x96,
1629 0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6
1630};
1631
1632/*
1633 * srtp_test_update() verifies updating/rekeying exsisting streams.
1634 * As stated in https://tools.ietf.org/html/rfc3711#section-3.3.1
1635 * the value of the ROC must not be reset after a rekey, this test
1636 * atempts to prove that srtp_update does not reset the ROC.
1637 */
1638
1639srtp_err_status_t
1640srtp_test_update() {
1641
1642 srtp_err_status_t status;
1643 uint32_t ssrc = 0x12121212;
1644 int msg_len_octets = 32;
1645 int protected_msg_len_octets;
1646 srtp_hdr_t * msg;
1647 srtp_t srtp_snd, srtp_recv;
1648 srtp_policy_t policy;
1649
1650 srtp_crypto_policy_set_rtp_default(&policy.rtp);
1651 srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
1652 policy.ekt = NULL;
1653 policy.window_size = 128;
1654 policy.allow_repeat_tx = 0;
1655 policy.next = NULL;
1656 policy.ssrc.type = ssrc_any_outbound;
1657 policy.key = test_key;
1658
1659 /* create a send and recive ctx with defualt profile and test_key */
1660 status = srtp_create(&srtp_recv, &policy);
1661 if (status)
1662 return status;
1663
1664 policy.ssrc.type = ssrc_any_inbound;
1665 status = srtp_create(&srtp_snd, &policy);
1666 if (status)
1667 return status;
1668
1669 /* protect and unprotect two msg's that will cause the ROC to be equal to 1 */
1670 msg = srtp_create_test_packet(msg_len_octets, ssrc);
1671 if (msg == NULL)
1672 return srtp_err_status_alloc_fail;
1673 msg->seq = htons(65535);
1674
1675 protected_msg_len_octets = msg_len_octets;
1676 status = srtp_protect(srtp_snd, msg, &protected_msg_len_octets);
1677 if (status)
1678 return srtp_err_status_fail;
1679
1680 status = srtp_unprotect(srtp_recv, msg, &protected_msg_len_octets);
1681 if (status)
1682 return status;
1683
1684 free(msg);
1685
1686 msg = srtp_create_test_packet(msg_len_octets, ssrc);
1687 if (msg == NULL)
1688 return srtp_err_status_alloc_fail;
1689 msg->seq = htons(1);
1690
1691 protected_msg_len_octets = msg_len_octets;
1692 status = srtp_protect(srtp_snd, msg, &protected_msg_len_octets);
1693 if (status)
1694 return srtp_err_status_fail;
1695
1696 status = srtp_unprotect(srtp_recv, msg, &protected_msg_len_octets);
1697 if (status)
1698 return status;
1699
1700 free(msg);
1701
1702 /* update send ctx to use test_alt_key */
1703 policy.ssrc.type = ssrc_any_outbound;
1704 policy.key = test_alt_key;
1705 status = srtp_update(srtp_snd, &policy);
1706 if (status)
1707 return status;
1708
1709 /* create and protect msg with new key and ROC still equal to 1 */
1710 msg = srtp_create_test_packet(msg_len_octets, ssrc);
1711 if (msg == NULL)
1712 return srtp_err_status_alloc_fail;
1713 msg->seq = htons(2);
1714
1715 protected_msg_len_octets = msg_len_octets;
1716 status = srtp_protect(srtp_snd, msg, &protected_msg_len_octets);
1717 if (status)
1718 return srtp_err_status_fail;
1719
1720 /* verify that recive ctx will fail to unprotect as it still uses test_key */
1721 status = srtp_unprotect(srtp_recv, msg, &protected_msg_len_octets);
1722 if (status == srtp_err_status_ok)
1723 return srtp_err_status_fail;
1724
1725 /* create a new recvieve ctx with test_alt_key but since it is new it will have ROC equal to 1
1726 * and therefore should fail to unprotected */
1727 {
1728 srtp_t srtp_recv_roc_0;
1729
1730 policy.ssrc.type = ssrc_any_inbound;
1731 policy.key = test_alt_key;
1732 status = srtp_create(&srtp_recv_roc_0, &policy);
1733 if (status)
1734 return status;
1735
1736 status = srtp_unprotect(srtp_recv_roc_0, msg, &protected_msg_len_octets);
1737 if (status == srtp_err_status_ok)
1738 return srtp_err_status_fail;
1739
1740 status = srtp_dealloc(srtp_recv_roc_0);
1741 if (status)
1742 return status;
1743 }
1744
1745 /* update recive ctx to use test_alt_key */
1746 policy.ssrc.type = ssrc_any_inbound;
1747 policy.key = test_alt_key;
1748 status = srtp_update(srtp_recv, &policy);
1749 if (status)
1750 return status;
1751
1752 /* verify that can still unprotect, therfore key is updated and ROC value is preserved */
1753 status = srtp_unprotect(srtp_recv, msg, &protected_msg_len_octets);
1754 if (status)
1755 return status;
1756
1757 free(msg);
1758
1759 status = srtp_dealloc(srtp_snd);
1760 if (status)
1761 return status;
1762
1763 status = srtp_dealloc(srtp_recv);
1764 if (status)
1765 return status;
1766
1767 return srtp_err_status_ok;
1768}
1769
Cullen Jennings235513a2005-09-21 22:51:36 +00001770/*
1771 * srtp policy definitions - these definitions are used above
1772 */
1773
jfigus8c36da22013-10-01 16:41:19 -04001774unsigned char test_key[46] = {
Cullen Jennings235513a2005-09-21 22:51:36 +00001775 0xe1, 0xf9, 0x7a, 0x0d, 0x3e, 0x01, 0x8b, 0xe0,
1776 0xd6, 0x4f, 0xa3, 0x2c, 0x06, 0xde, 0x41, 0x39,
1777 0x0e, 0xc6, 0x75, 0xad, 0x49, 0x8a, 0xfe, 0xeb,
jfigus8c36da22013-10-01 16:41:19 -04001778 0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6, 0xc1, 0x73,
1779 0xc3, 0x17, 0xf2, 0xda, 0xbe, 0x35, 0x77, 0x93,
Cullen Jennings235513a2005-09-21 22:51:36 +00001780 0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6
1781};
1782
1783
1784const srtp_policy_t default_policy = {
jfigus67b9c732014-11-20 10:17:21 -05001785 { ssrc_any_outbound, 0 }, /* SSRC */
1786 { /* SRTP policy */
1787 SRTP_AES_128_ICM, /* cipher type */
1788 30, /* cipher key length in octets */
1789 SRTP_HMAC_SHA1, /* authentication func type */
1790 16, /* auth key length in octets */
1791 10, /* auth tag length in octets */
1792 sec_serv_conf_and_auth /* security services flag */
1793 },
1794 { /* SRTCP policy */
1795 SRTP_AES_128_ICM, /* cipher type */
1796 30, /* cipher key length in octets */
1797 SRTP_HMAC_SHA1, /* authentication func type */
1798 16, /* auth key length in octets */
1799 10, /* auth tag length in octets */
1800 sec_serv_conf_and_auth /* security services flag */
1801 },
1802 test_key,
1803 NULL, /* indicates that EKT is not in use */
1804 128, /* replay window size */
1805 0, /* retransmission not allowed */
1806 NULL
Cullen Jennings235513a2005-09-21 22:51:36 +00001807};
1808
1809const srtp_policy_t aes_only_policy = {
jfigus67b9c732014-11-20 10:17:21 -05001810 { ssrc_any_outbound, 0 }, /* SSRC */
1811 {
1812 SRTP_AES_128_ICM, /* cipher type */
1813 30, /* cipher key length in octets */
1814 SRTP_NULL_AUTH, /* authentication func type */
1815 0, /* auth key length in octets */
1816 0, /* auth tag length in octets */
1817 sec_serv_conf /* security services flag */
1818 },
1819 {
1820 SRTP_AES_128_ICM, /* cipher type */
1821 30, /* cipher key length in octets */
1822 SRTP_NULL_AUTH, /* authentication func type */
1823 0, /* auth key length in octets */
1824 0, /* auth tag length in octets */
1825 sec_serv_conf /* security services flag */
1826 },
1827 test_key,
1828 NULL, /* indicates that EKT is not in use */
1829 128, /* replay window size */
1830 0, /* retransmission not allowed */
1831 NULL
Cullen Jennings235513a2005-09-21 22:51:36 +00001832};
1833
1834const srtp_policy_t hmac_only_policy = {
jfigus67b9c732014-11-20 10:17:21 -05001835 { ssrc_any_outbound, 0 }, /* SSRC */
1836 {
1837 SRTP_NULL_CIPHER, /* cipher type */
1838 0, /* cipher key length in octets */
1839 SRTP_HMAC_SHA1, /* authentication func type */
1840 20, /* auth key length in octets */
1841 4, /* auth tag length in octets */
1842 sec_serv_auth /* security services flag */
1843 },
1844 {
1845 SRTP_NULL_CIPHER, /* cipher type */
1846 0, /* cipher key length in octets */
1847 SRTP_HMAC_SHA1, /* authentication func type */
1848 20, /* auth key length in octets */
1849 4, /* auth tag length in octets */
1850 sec_serv_auth /* security services flag */
1851 },
1852 test_key,
1853 NULL, /* indicates that EKT is not in use */
1854 128, /* replay window size */
1855 0, /* retransmission not allowed */
1856 NULL
Cullen Jennings235513a2005-09-21 22:51:36 +00001857};
1858
jfigus8c36da22013-10-01 16:41:19 -04001859#ifdef OPENSSL
1860const srtp_policy_t aes128_gcm_8_policy = {
jfigus67b9c732014-11-20 10:17:21 -05001861 { ssrc_any_outbound, 0 }, /* SSRC */
1862 { /* SRTP policy */
1863 SRTP_AES_128_GCM, /* cipher type */
1864 SRTP_AES_128_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
1865 SRTP_NULL_AUTH, /* authentication func type */
1866 0, /* auth key length in octets */
1867 8, /* auth tag length in octets */
1868 sec_serv_conf_and_auth /* security services flag */
jfigus8c36da22013-10-01 16:41:19 -04001869 },
jfigus67b9c732014-11-20 10:17:21 -05001870 { /* SRTCP policy */
1871 SRTP_AES_128_GCM, /* cipher type */
1872 SRTP_AES_128_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
1873 SRTP_NULL_AUTH, /* authentication func type */
1874 0, /* auth key length in octets */
1875 8, /* auth tag length in octets */
1876 sec_serv_conf_and_auth /* security services flag */
jfigus8c36da22013-10-01 16:41:19 -04001877 },
1878 test_key,
1879 NULL, /* indicates that EKT is not in use */
1880 128, /* replay window size */
1881 0, /* retransmission not allowed */
1882 NULL
1883};
1884
1885const srtp_policy_t aes128_gcm_8_cauth_policy = {
jfigus67b9c732014-11-20 10:17:21 -05001886 { ssrc_any_outbound, 0 }, /* SSRC */
1887 { /* SRTP policy */
1888 SRTP_AES_128_GCM, /* cipher type */
1889 SRTP_AES_128_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
1890 SRTP_NULL_AUTH, /* authentication func type */
1891 0, /* auth key length in octets */
1892 8, /* auth tag length in octets */
1893 sec_serv_conf_and_auth /* security services flag */
jfigus8c36da22013-10-01 16:41:19 -04001894 },
jfigus67b9c732014-11-20 10:17:21 -05001895 { /* SRTCP policy */
1896 SRTP_AES_128_GCM, /* cipher type */
1897 SRTP_AES_128_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
1898 SRTP_NULL_AUTH, /* authentication func type */
1899 0, /* auth key length in octets */
1900 8, /* auth tag length in octets */
1901 sec_serv_auth /* security services flag */
jfigus8c36da22013-10-01 16:41:19 -04001902 },
1903 test_key,
1904 NULL, /* indicates that EKT is not in use */
1905 128, /* replay window size */
1906 0, /* retransmission not allowed */
1907 NULL
1908};
jfigus67b9c732014-11-20 10:17:21 -05001909
jfigus8c36da22013-10-01 16:41:19 -04001910const srtp_policy_t aes256_gcm_8_policy = {
jfigus67b9c732014-11-20 10:17:21 -05001911 { ssrc_any_outbound, 0 }, /* SSRC */
1912 { /* SRTP policy */
1913 SRTP_AES_256_GCM, /* cipher type */
1914 SRTP_AES_256_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
1915 SRTP_NULL_AUTH, /* authentication func type */
1916 0, /* auth key length in octets */
1917 8, /* auth tag length in octets */
1918 sec_serv_conf_and_auth /* security services flag */
jfigus8c36da22013-10-01 16:41:19 -04001919 },
jfigus67b9c732014-11-20 10:17:21 -05001920 { /* SRTCP policy */
1921 SRTP_AES_256_GCM, /* cipher type */
1922 SRTP_AES_256_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
1923 SRTP_NULL_AUTH, /* authentication func type */
1924 0, /* auth key length in octets */
1925 8, /* auth tag length in octets */
1926 sec_serv_conf_and_auth /* security services flag */
jfigus8c36da22013-10-01 16:41:19 -04001927 },
1928 test_key,
1929 NULL, /* indicates that EKT is not in use */
1930 128, /* replay window size */
1931 0, /* retransmission not allowed */
1932 NULL
1933};
jfigus67b9c732014-11-20 10:17:21 -05001934
jfigus8c36da22013-10-01 16:41:19 -04001935const srtp_policy_t aes256_gcm_8_cauth_policy = {
jfigus67b9c732014-11-20 10:17:21 -05001936 { ssrc_any_outbound, 0 }, /* SSRC */
1937 { /* SRTP policy */
1938 SRTP_AES_256_GCM, /* cipher type */
1939 SRTP_AES_256_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
1940 SRTP_NULL_AUTH, /* authentication func type */
1941 0, /* auth key length in octets */
1942 8, /* auth tag length in octets */
1943 sec_serv_conf_and_auth /* security services flag */
jfigus8c36da22013-10-01 16:41:19 -04001944 },
jfigus67b9c732014-11-20 10:17:21 -05001945 { /* SRTCP policy */
1946 SRTP_AES_256_GCM, /* cipher type */
1947 SRTP_AES_256_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
1948 SRTP_NULL_AUTH, /* authentication func type */
1949 0, /* auth key length in octets */
1950 8, /* auth tag length in octets */
1951 sec_serv_auth /* security services flag */
jfigus8c36da22013-10-01 16:41:19 -04001952 },
1953 test_key,
1954 NULL, /* indicates that EKT is not in use */
1955 128, /* replay window size */
1956 0, /* retransmission not allowed */
1957 NULL
1958};
1959#endif
1960
Cullen Jennings235513a2005-09-21 22:51:36 +00001961const srtp_policy_t null_policy = {
jfigus67b9c732014-11-20 10:17:21 -05001962 { ssrc_any_outbound, 0 }, /* SSRC */
1963 {
1964 SRTP_NULL_CIPHER, /* cipher type */
1965 0, /* cipher key length in octets */
1966 SRTP_NULL_AUTH, /* authentication func type */
1967 0, /* auth key length in octets */
1968 0, /* auth tag length in octets */
1969 sec_serv_none /* security services flag */
1970 },
1971 {
1972 SRTP_NULL_CIPHER, /* cipher type */
1973 0, /* cipher key length in octets */
1974 SRTP_NULL_AUTH, /* authentication func type */
1975 0, /* auth key length in octets */
1976 0, /* auth tag length in octets */
1977 sec_serv_none /* security services flag */
1978 },
1979 test_key,
1980 NULL, /* indicates that EKT is not in use */
1981 128, /* replay window size */
1982 0, /* retransmission not allowed */
1983 NULL
David McGrew79870d62007-06-15 18:17:39 +00001984};
1985
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001986unsigned char test_256_key[46] = {
jfigus67b9c732014-11-20 10:17:21 -05001987 0xf0, 0xf0, 0x49, 0x14, 0xb5, 0x13, 0xf2, 0x76,
1988 0x3a, 0x1b, 0x1f, 0xa1, 0x30, 0xf1, 0x0e, 0x29,
1989 0x98, 0xf6, 0xf6, 0xe4, 0x3e, 0x43, 0x09, 0xd1,
1990 0xe6, 0x22, 0xa0, 0xe3, 0x32, 0xb9, 0xf1, 0xb6,
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001991
jfigus67b9c732014-11-20 10:17:21 -05001992 0x3b, 0x04, 0x80, 0x3d, 0xe5, 0x1e, 0xe7, 0xc9,
1993 0x64, 0x23, 0xab, 0x5b, 0x78, 0xd2
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001994};
1995
1996const srtp_policy_t aes_256_hmac_policy = {
jfigus67b9c732014-11-20 10:17:21 -05001997 { ssrc_any_outbound, 0 }, /* SSRC */
1998 { /* SRTP policy */
1999 SRTP_AES_ICM, /* cipher type */
2000 46, /* cipher key length in octets */
2001 SRTP_HMAC_SHA1, /* authentication func type */
2002 20, /* auth key length in octets */
2003 10, /* auth tag length in octets */
2004 sec_serv_conf_and_auth /* security services flag */
2005 },
2006 { /* SRTCP policy */
2007 SRTP_AES_ICM, /* cipher type */
2008 46, /* cipher key length in octets */
2009 SRTP_HMAC_SHA1, /* authentication func type */
2010 20, /* auth key length in octets */
2011 10, /* auth tag length in octets */
2012 sec_serv_conf_and_auth /* security services flag */
2013 },
2014 test_256_key,
2015 NULL, /* indicates that EKT is not in use */
2016 128, /* replay window size */
2017 0, /* retransmission not allowed */
2018 NULL
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002019};
2020
David McGrew79870d62007-06-15 18:17:39 +00002021uint8_t ekt_test_key[16] = {
jfigus67b9c732014-11-20 10:17:21 -05002022 0x77, 0x26, 0x9d, 0xac, 0x16, 0xa3, 0x28, 0xca,
2023 0x8e, 0xc9, 0x68, 0x4b, 0xcc, 0xc4, 0xd2, 0x1b
David McGrew79870d62007-06-15 18:17:39 +00002024};
2025
2026#include "ekt.h"
2027
jfigusc5887e72014-11-06 09:46:18 -05002028srtp_ekt_policy_ctx_t ekt_test_policy = {
jfigus67b9c732014-11-20 10:17:21 -05002029 0xa5a5, /* SPI */
2030 SRTP_EKT_CIPHER_AES_128_ECB,
2031 ekt_test_key,
2032 NULL
David McGrew79870d62007-06-15 18:17:39 +00002033};
2034
2035const srtp_policy_t hmac_only_with_ekt_policy = {
jfigus67b9c732014-11-20 10:17:21 -05002036 { ssrc_any_outbound, 0 }, /* SSRC */
2037 {
2038 SRTP_NULL_CIPHER, /* cipher type */
2039 0, /* cipher key length in octets */
2040 SRTP_HMAC_SHA1, /* authentication func type */
2041 20, /* auth key length in octets */
2042 4, /* auth tag length in octets */
2043 sec_serv_auth /* security services flag */
2044 },
2045 {
2046 SRTP_NULL_CIPHER, /* cipher type */
2047 0, /* cipher key length in octets */
2048 SRTP_HMAC_SHA1, /* authentication func type */
2049 20, /* auth key length in octets */
2050 4, /* auth tag length in octets */
2051 sec_serv_auth /* security services flag */
2052 },
2053 test_key,
2054 &ekt_test_policy, /* indicates that EKT is not in use */
2055 128, /* replay window size */
2056 0, /* retransmission not allowed */
2057 NULL
Cullen Jennings235513a2005-09-21 22:51:36 +00002058};
2059
2060
2061/*
2062 * an array of pointers to the policies listed above
2063 *
2064 * This array is used to test various aspects of libSRTP for
2065 * different cryptographic policies. The order of the elements
2066 * matters - the timing test generates output that can be used
jfigus67b9c732014-11-20 10:17:21 -05002067 * in a plot (see the gnuplot script file 'timing'). If you
Cullen Jennings235513a2005-09-21 22:51:36 +00002068 * add to this list, you should do it at the end.
2069 */
2070
Cullen Jennings235513a2005-09-21 22:51:36 +00002071const srtp_policy_t *
2072policy_array[] = {
jfigus67b9c732014-11-20 10:17:21 -05002073 &hmac_only_policy,
2074 &aes_only_policy,
2075 &default_policy,
jfigus8c36da22013-10-01 16:41:19 -04002076#ifdef OPENSSL
jfigus67b9c732014-11-20 10:17:21 -05002077 &aes128_gcm_8_policy,
2078 &aes128_gcm_8_cauth_policy,
2079 &aes256_gcm_8_policy,
2080 &aes256_gcm_8_cauth_policy,
jfigus8c36da22013-10-01 16:41:19 -04002081#endif
jfigus67b9c732014-11-20 10:17:21 -05002082 &null_policy,
2083 &aes_256_hmac_policy,
2084 &hmac_only_with_ekt_policy,
2085 NULL
Cullen Jennings235513a2005-09-21 22:51:36 +00002086};
2087
2088const srtp_policy_t wildcard_policy = {
jfigus67b9c732014-11-20 10:17:21 -05002089 { ssrc_any_outbound, 0 }, /* SSRC */
2090 { /* SRTP policy */
2091 SRTP_AES_128_ICM, /* cipher type */
2092 30, /* cipher key length in octets */
2093 SRTP_HMAC_SHA1, /* authentication func type */
2094 16, /* auth key length in octets */
2095 10, /* auth tag length in octets */
2096 sec_serv_conf_and_auth /* security services flag */
2097 },
2098 { /* SRTCP policy */
2099 SRTP_AES_128_ICM, /* cipher type */
2100 30, /* cipher key length in octets */
2101 SRTP_HMAC_SHA1, /* authentication func type */
2102 16, /* auth key length in octets */
2103 10, /* auth tag length in octets */
2104 sec_serv_conf_and_auth /* security services flag */
2105 },
2106 test_key,
2107 NULL,
2108 128, /* replay window size */
2109 0, /* retransmission not allowed */
2110 NULL
Cullen Jennings235513a2005-09-21 22:51:36 +00002111};