blob: 32f1b70c7a7a3aaa73584379773c1c0bb597f836 [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
Joachim Bauch99a74822015-11-17 00:08:19 +010067srtp_validate_encrypted_extensions_headers(void);
68
Joachim Bauch80a45b52015-12-06 22:57:58 +010069#ifdef OPENSSL
Joachim Bauch99a74822015-11-17 00:08:19 +010070srtp_err_status_t
Joachim Bauchfa1e8c22015-11-24 23:38:48 +010071srtp_validate_encrypted_extensions_headers_gcm(void);
Joachim Bauch80a45b52015-12-06 22:57:58 +010072#endif
Joachim Bauchfa1e8c22015-11-24 23:38:48 +010073
74srtp_err_status_t
Jonathan Lennox5df951a2010-05-20 20:55:54 +000075srtp_validate_aes_256(void);
76
jfigus857009c2014-11-05 11:17:43 -050077srtp_err_status_t
Cullen Jennings235513a2005-09-21 22:51:36 +000078srtp_create_big_policy(srtp_policy_t **list);
79
jfigus857009c2014-11-05 11:17:43 -050080srtp_err_status_t
Jonathan Lennox80c4c832010-05-17 19:30:28 +000081srtp_dealloc_big_policy(srtp_policy_t *list);
82
jfigus857009c2014-11-05 11:17:43 -050083srtp_err_status_t
Marcus Sundberga3f95fe2005-09-29 12:48:41 +000084srtp_test_remove_stream(void);
Cullen Jennings235513a2005-09-21 22:51:36 +000085
Pascal Bühlerbd3112a2015-11-06 20:29:15 +010086srtp_err_status_t
87srtp_test_update(void);
88
Cullen Jennings235513a2005-09-21 22:51:36 +000089double
90srtp_bits_per_second(int msg_len_octets, const srtp_policy_t *policy);
91
92double
93srtp_rejections_per_second(int msg_len_octets, const srtp_policy_t *policy);
94
95void
96srtp_do_timing(const srtp_policy_t *policy);
97
98void
99srtp_do_rejection_timing(const srtp_policy_t *policy);
100
jfigus857009c2014-11-05 11:17:43 -0500101srtp_err_status_t
Joachim Bauch99a74822015-11-17 00:08:19 +0100102srtp_test(const srtp_policy_t *policy, int extension_header);
Cullen Jennings235513a2005-09-21 22:51:36 +0000103
jfigus857009c2014-11-05 11:17:43 -0500104srtp_err_status_t
David McGrew9c70f292006-05-03 19:38:38 +0000105srtcp_test(const srtp_policy_t *policy);
106
jfigus857009c2014-11-05 11:17:43 -0500107srtp_err_status_t
Cullen Jennings235513a2005-09-21 22:51:36 +0000108srtp_session_print_policy(srtp_t srtp);
109
jfigus857009c2014-11-05 11:17:43 -0500110srtp_err_status_t
jfigus67b9c732014-11-20 10:17:21 -0500111srtp_print_policy(const srtp_policy_t *policy);
Cullen Jennings235513a2005-09-21 22:51:36 +0000112
113char *
114srtp_packet_to_string(srtp_hdr_t *hdr, int packet_len);
115
116double
117mips_estimate(int num_trials, int *ignore);
118
jfigus8c36da22013-10-01 16:41:19 -0400119extern uint8_t test_key[46];
Cullen Jennings235513a2005-09-21 22:51:36 +0000120
121void
jfigus67b9c732014-11-20 10:17:21 -0500122usage (char *prog_name)
123{
124 printf("usage: %s [ -t ][ -c ][ -v ][-d <debug_module> ]* [ -l ]\n"
125 " -t run timing test\n"
126 " -r run rejection timing test\n"
127 " -c run codec timing test\n"
128 " -v run validation tests\n"
129 " -d <mod> turn on debugging module <mod>\n"
130 " -l list debugging modules\n", prog_name);
131 exit(1);
Cullen Jennings235513a2005-09-21 22:51:36 +0000132}
133
134/*
135 * The policy_array is a null-terminated array of policy structs. it
136 * is declared at the end of this file
137 */
138
139extern const srtp_policy_t *policy_array[];
140
141
142/* the wildcard_policy is declared below; it has a wildcard ssrc */
143
144extern const srtp_policy_t wildcard_policy;
145
146/*
147 * mod_driver debug module - debugging module for this test driver
148 *
jfigus67b9c732014-11-20 10:17:21 -0500149 * we use the crypto_kernel debugging system in this driver, which
Cullen Jennings235513a2005-09-21 22:51:36 +0000150 * makes the interface uniform and increases portability
jfigus67b9c732014-11-20 10:17:21 -0500151 */
Cullen Jennings235513a2005-09-21 22:51:36 +0000152
jfigus02d6f032014-11-21 10:56:42 -0500153srtp_debug_module_t mod_driver = {
jfigus67b9c732014-11-20 10:17:21 -0500154 0, /* debugging is off by default */
155 "driver" /* printable name for module */
Cullen Jennings235513a2005-09-21 22:51:36 +0000156};
157
158int
jfigus67b9c732014-11-20 10:17:21 -0500159main (int argc, char *argv[])
160{
161 int q;
162 unsigned do_timing_test = 0;
163 unsigned do_rejection_test = 0;
164 unsigned do_codec_timing = 0;
165 unsigned do_validation = 0;
166 unsigned do_list_mods = 0;
167 srtp_err_status_t status;
Cullen Jennings235513a2005-09-21 22:51:36 +0000168
169 /*
jfigus67b9c732014-11-20 10:17:21 -0500170 * verify that the compiler has interpreted the header data
171 * structure srtp_hdr_t correctly
Cullen Jennings235513a2005-09-21 22:51:36 +0000172 */
jfigus67b9c732014-11-20 10:17:21 -0500173 if (sizeof(srtp_hdr_t) != 12) {
174 printf("error: srtp_hdr_t has incorrect size"
175 "(size is %ld bytes, expected 12)\n",
176 (long)sizeof(srtp_hdr_t));
177 exit(1);
Cullen Jennings235513a2005-09-21 22:51:36 +0000178 }
179
jfigus67b9c732014-11-20 10:17:21 -0500180 /* initialize srtp library */
181 status = srtp_init();
182 if (status) {
183 printf("error: srtp init failed with error code %d\n", status);
184 exit(1);
185 }
186
187 /* load srtp_driver debug module */
jfigus92736bc2014-11-21 10:30:54 -0500188 status = srtp_crypto_kernel_load_debug_module(&mod_driver);
jfigus67b9c732014-11-20 10:17:21 -0500189 if (status) {
190 printf("error: load of srtp_driver debug module failed "
191 "with error code %d\n", status);
192 exit(1);
193 }
194
195 /* process input arguments */
196 while (1) {
197 q = getopt_s(argc, argv, "trcvld:");
198 if (q == -1) {
199 break;
200 }
201 switch (q) {
202 case 't':
203 do_timing_test = 1;
204 break;
205 case 'r':
206 do_rejection_test = 1;
207 break;
208 case 'c':
209 do_codec_timing = 1;
210 break;
211 case 'v':
212 do_validation = 1;
213 break;
214 case 'l':
215 do_list_mods = 1;
216 break;
217 case 'd':
jfigus92736bc2014-11-21 10:30:54 -0500218 status = srtp_crypto_kernel_set_debug_module(optarg_s, 1);
jfigus67b9c732014-11-20 10:17:21 -0500219 if (status) {
220 printf("error: set debug module (%s) failed\n", optarg_s);
221 exit(1);
222 }
223 break;
224 default:
225 usage(argv[0]);
226 }
227 }
228
229 if (!do_validation && !do_timing_test && !do_codec_timing
230 && !do_list_mods && !do_rejection_test) {
231 usage(argv[0]);
232 }
233
234 if (do_list_mods) {
jfigus92736bc2014-11-21 10:30:54 -0500235 status = srtp_crypto_kernel_list_debug_modules();
jfigus67b9c732014-11-20 10:17:21 -0500236 if (status) {
237 printf("error: list of debug modules failed\n");
238 exit(1);
239 }
240 }
241
242 if (do_validation) {
243 const srtp_policy_t **policy = policy_array;
244 srtp_policy_t *big_policy;
245
246 /* loop over policy array, testing srtp and srtcp for each policy */
247 while (*policy != NULL) {
248 printf("testing srtp_protect and srtp_unprotect\n");
Joachim Bauch99a74822015-11-17 00:08:19 +0100249 if (srtp_test(*policy, 0) == srtp_err_status_ok) {
250 printf("passed\n\n");
251 } else{
252 printf("failed\n");
253 exit(1);
254 }
255 printf("testing srtp_protect and srtp_unprotect with encrypted extensions headers\n");
256 if (srtp_test(*policy, 1) == srtp_err_status_ok) {
jfigus67b9c732014-11-20 10:17:21 -0500257 printf("passed\n\n");
258 } else{
259 printf("failed\n");
260 exit(1);
261 }
262 printf("testing srtp_protect_rtcp and srtp_unprotect_rtcp\n");
263 if (srtcp_test(*policy) == srtp_err_status_ok) {
264 printf("passed\n\n");
265 } else{
266 printf("failed\n");
267 exit(1);
268 }
269 policy++;
270 }
271
272 /* create a big policy list and run tests on it */
273 status = srtp_create_big_policy(&big_policy);
274 if (status) {
275 printf("unexpected failure with error code %d\n", status);
276 exit(1);
277 }
278 printf("testing srtp_protect and srtp_unprotect with big policy\n");
Joachim Bauch99a74822015-11-17 00:08:19 +0100279 if (srtp_test(big_policy, 0) == srtp_err_status_ok) {
280 printf("passed\n\n");
281 } else{
282 printf("failed\n");
283 exit(1);
284 }
285 printf("testing srtp_protect and srtp_unprotect with big policy and encrypted extensions headers\n");
286 if (srtp_test(big_policy, 1) == srtp_err_status_ok) {
jfigus67b9c732014-11-20 10:17:21 -0500287 printf("passed\n\n");
288 } else{
289 printf("failed\n");
290 exit(1);
291 }
292 status = srtp_dealloc_big_policy(big_policy);
293 if (status) {
294 printf("unexpected failure with error code %d\n", status);
295 exit(1);
296 }
297
298 /* run test on wildcard policy */
299 printf("testing srtp_protect and srtp_unprotect on "
300 "wildcard ssrc policy\n");
Joachim Bauch99a74822015-11-17 00:08:19 +0100301 if (srtp_test(&wildcard_policy, 0) == srtp_err_status_ok) {
302 printf("passed\n\n");
303 } else{
304 printf("failed\n");
305 exit(1);
306 }
307 printf("testing srtp_protect and srtp_unprotect on "
308 "wildcard ssrc policy and encrypted extensions headers\n");
309 if (srtp_test(&wildcard_policy, 1) == srtp_err_status_ok) {
jfigus67b9c732014-11-20 10:17:21 -0500310 printf("passed\n\n");
311 } else{
312 printf("failed\n");
313 exit(1);
314 }
315
316 /*
317 * run validation test against the reference packets - note
318 * that this test only covers the default policy
319 */
320 printf("testing srtp_protect and srtp_unprotect against "
321 "reference packets\n");
322 if (srtp_validate() == srtp_err_status_ok) {
323 printf("passed\n\n");
324 } else{
325 printf("failed\n");
326 exit(1);
327 }
Joachim Bauch99a74822015-11-17 00:08:19 +0100328 printf("testing srtp_protect and srtp_unprotect against "
329 "reference packets with encrypted extensions headers\n");
330 if (srtp_validate_encrypted_extensions_headers() == srtp_err_status_ok)
331 printf("passed\n\n");
332 else {
333 printf("failed\n");
334 exit(1);
335 }
jfigus67b9c732014-11-20 10:17:21 -0500336
Joachim Bauchb8cb5772015-11-24 21:46:25 +0100337#ifdef OPENSSL
Joachim Bauchfa1e8c22015-11-24 23:38:48 +0100338 printf("testing srtp_protect and srtp_unprotect against "
339 "reference packets with encrypted extension headers (GCM)\n");
340 if (srtp_validate_encrypted_extensions_headers_gcm() == srtp_err_status_ok) {
341 printf("passed\n\n");
342 } else{
343 printf("failed\n");
344 exit(1);
345 }
Joachim Bauch80a45b52015-12-06 22:57:58 +0100346#endif
Joachim Bauchfa1e8c22015-11-24 23:38:48 +0100347
jfigus67b9c732014-11-20 10:17:21 -0500348 /*
349 * run validation test against the reference packets for
350 * AES-256
351 */
352 printf("testing srtp_protect and srtp_unprotect against "
353 "reference packets (AES-256)\n");
354 if (srtp_validate_aes_256() == srtp_err_status_ok) {
355 printf("passed\n\n");
356 } else{
357 printf("failed\n");
358 exit(1);
359 }
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000360
jfigus67b9c732014-11-20 10:17:21 -0500361 /*
362 * test the function srtp_remove_stream()
363 */
364 printf("testing srtp_remove_stream()...");
365 if (srtp_test_remove_stream() == srtp_err_status_ok) {
366 printf("passed\n");
367 } else{
368 printf("failed\n");
369 exit(1);
370 }
Pascal Bühlerbd3112a2015-11-06 20:29:15 +0100371
372 /*
373 * test the function srtp_update()
374 */
375 printf("testing srtp_update()...");
376 if (srtp_test_update() == srtp_err_status_ok) {
377 printf("passed\n");
378 } else {
379 printf("failed\n");
380 exit(1);
381 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000382 }
jfigus67b9c732014-11-20 10:17:21 -0500383
384 if (do_timing_test) {
385 const srtp_policy_t **policy = policy_array;
386
387 /* loop over policies, run timing test for each */
388 while (*policy != NULL) {
389 srtp_print_policy(*policy);
390 srtp_do_timing(*policy);
391 policy++;
392 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000393 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000394
jfigus67b9c732014-11-20 10:17:21 -0500395 if (do_rejection_test) {
396 const srtp_policy_t **policy = policy_array;
397
398 /* loop over policies, run rejection timing test for each */
399 while (*policy != NULL) {
400 srtp_print_policy(*policy);
401 srtp_do_rejection_timing(*policy);
402 policy++;
403 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000404 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000405
jfigus67b9c732014-11-20 10:17:21 -0500406 if (do_codec_timing) {
407 srtp_policy_t policy;
408 int ignore;
409 double mips = mips_estimate(1000000000, &ignore);
Cullen Jennings235513a2005-09-21 22:51:36 +0000410
Joachim Bauch99a74822015-11-17 00:08:19 +0100411 memset(&policy, 0, sizeof(policy));
jfigus67b9c732014-11-20 10:17:21 -0500412 srtp_crypto_policy_set_rtp_default(&policy.rtp);
413 srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
414 policy.ssrc.type = ssrc_specific;
415 policy.ssrc.value = 0xdecafbad;
416 policy.key = test_key;
417 policy.ekt = NULL;
418 policy.window_size = 128;
419 policy.allow_repeat_tx = 0;
420 policy.next = NULL;
Cullen Jennings235513a2005-09-21 22:51:36 +0000421
jfigus67b9c732014-11-20 10:17:21 -0500422 printf("mips estimate: %e\n", mips);
Cullen Jennings235513a2005-09-21 22:51:36 +0000423
jfigus67b9c732014-11-20 10:17:21 -0500424 printf("testing srtp processing time for voice codecs:\n");
425 printf("codec\t\tlength (octets)\t\tsrtp instructions/second\n");
426 printf("G.711\t\t%d\t\t\t%e\n", 80,
427 (double)mips * (80 * 8) /
428 srtp_bits_per_second(80, &policy) / .01 );
429 printf("G.711\t\t%d\t\t\t%e\n", 160,
430 (double)mips * (160 * 8) /
431 srtp_bits_per_second(160, &policy) / .02);
432 printf("G.726-32\t%d\t\t\t%e\n", 40,
433 (double)mips * (40 * 8) /
434 srtp_bits_per_second(40, &policy) / .01 );
435 printf("G.726-32\t%d\t\t\t%e\n", 80,
436 (double)mips * (80 * 8) /
437 srtp_bits_per_second(80, &policy) / .02);
438 printf("G.729\t\t%d\t\t\t%e\n", 10,
439 (double)mips * (10 * 8) /
440 srtp_bits_per_second(10, &policy) / .01 );
441 printf("G.729\t\t%d\t\t\t%e\n", 20,
442 (double)mips * (20 * 8) /
443 srtp_bits_per_second(20, &policy) / .02 );
444 printf("Wideband\t%d\t\t\t%e\n", 320,
445 (double)mips * (320 * 8) /
446 srtp_bits_per_second(320, &policy) / .01 );
447 printf("Wideband\t%d\t\t\t%e\n", 640,
448 (double)mips * (640 * 8) /
449 srtp_bits_per_second(640, &policy) / .02 );
450 }
Jonathan Lennoxdfb30842010-05-15 04:52:01 +0000451
jfigus67b9c732014-11-20 10:17:21 -0500452 status = srtp_shutdown();
453 if (status) {
454 printf("error: srtp shutdown failed with error code %d\n", status);
455 exit(1);
456 }
457
458 return 0;
Cullen Jennings235513a2005-09-21 22:51:36 +0000459}
460
461
462
463/*
464 * srtp_create_test_packet(len, ssrc) returns a pointer to a
465 * (malloced) example RTP packet whose data field has the length given
466 * by pkt_octet_len and the SSRC value ssrc. The total length of the
467 * packet is twelve octets longer, since the header is at the
468 * beginning. There is room at the end of the packet for a trailer,
469 * and the four octets following the packet are filled with 0xff
470 * values to enable testing for overwrites.
471 *
472 * note that the location of the test packet can (and should) be
473 * deallocated with the free() call once it is no longer needed.
474 */
475
476srtp_hdr_t *
jfigus67b9c732014-11-20 10:17:21 -0500477srtp_create_test_packet (int pkt_octet_len, uint32_t ssrc)
478{
479 int i;
480 uint8_t *buffer;
481 srtp_hdr_t *hdr;
482 int bytes_in_hdr = 12;
Cullen Jennings235513a2005-09-21 22:51:36 +0000483
jfigus67b9c732014-11-20 10:17:21 -0500484 /* allocate memory for test packet */
485 hdr = (srtp_hdr_t*)malloc(pkt_octet_len + bytes_in_hdr
486 + SRTP_MAX_TRAILER_LEN + 4);
487 if (!hdr) {
488 return NULL;
489 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000490
jfigus67b9c732014-11-20 10:17:21 -0500491 hdr->version = 2; /* RTP version two */
492 hdr->p = 0; /* no padding needed */
493 hdr->x = 0; /* no header extension */
494 hdr->cc = 0; /* no CSRCs */
495 hdr->m = 0; /* marker bit */
496 hdr->pt = 0xf; /* payload type */
497 hdr->seq = htons(0x1234); /* sequence number */
498 hdr->ts = htonl(0xdecafbad); /* timestamp */
499 hdr->ssrc = htonl(ssrc); /* synch. source */
Cullen Jennings235513a2005-09-21 22:51:36 +0000500
jfigus67b9c732014-11-20 10:17:21 -0500501 buffer = (uint8_t*)hdr;
502 buffer += bytes_in_hdr;
Cullen Jennings235513a2005-09-21 22:51:36 +0000503
jfigus67b9c732014-11-20 10:17:21 -0500504 /* set RTP data to 0xab */
505 for (i = 0; i < pkt_octet_len; i++) {
506 *buffer++ = 0xab;
507 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000508
jfigus67b9c732014-11-20 10:17:21 -0500509 /* set post-data value to 0xffff to enable overrun checking */
510 for (i = 0; i < SRTP_MAX_TRAILER_LEN + 4; i++) {
511 *buffer++ = 0xff;
512 }
513
514 return hdr;
Cullen Jennings235513a2005-09-21 22:51:36 +0000515}
516
Joachim Bauch99a74822015-11-17 00:08:19 +0100517srtp_hdr_t *
518srtp_create_test_packet_ext_hdr(int pkt_octet_len, uint32_t ssrc) {
519 int i;
520 uint8_t *buffer;
521 srtp_hdr_t *hdr;
522 int bytes_in_hdr = 12;
523 uint8_t extension_header[12] = {
524 /* one-byte header */
525 0xbe, 0xde,
526 /* size */
527 0x00, 0x02,
528 /* id 1, length 1 (i.e. 2 bytes) */
529 0x11,
530 /* payload */
531 0xca,
532 0xfe,
533 /* padding */
534 0x00,
535 /* id 2, length 0 (i.e. 1 byte) */
536 0x20,
537 /* payload */
538 0xba,
539 /* padding */
540 0x00,
541 0x00
542 };
543
544 /* allocate memory for test packet */
545 hdr = (srtp_hdr_t*) malloc(pkt_octet_len + bytes_in_hdr
546 + sizeof(extension_header) + SRTP_MAX_TRAILER_LEN + 4);
547 if (!hdr)
548 return NULL;
549
550 hdr->version = 2; /* RTP version two */
551 hdr->p = 0; /* no padding needed */
552 hdr->x = 1; /* no header extension */
553 hdr->cc = 0; /* no CSRCs */
554 hdr->m = 0; /* marker bit */
555 hdr->pt = 0xf; /* payload type */
556 hdr->seq = htons(0x1234); /* sequence number */
557 hdr->ts = htonl(0xdecafbad); /* timestamp */
558 hdr->ssrc = htonl(ssrc); /* synch. source */
559
560 buffer = (uint8_t *)hdr;
561 buffer += bytes_in_hdr;
562
563 memcpy(buffer, extension_header, sizeof(extension_header));
564 buffer += sizeof(extension_header);
565
566 /* set RTP data to 0xab */
567 for (i=0; i < pkt_octet_len; i++)
568 *buffer++ = 0xab;
569
570 /* set post-data value to 0xffff to enable overrun checking */
571 for (i=0; i < SRTP_MAX_TRAILER_LEN+4; i++)
572 *buffer++ = 0xff;
573
574 return hdr;
575}
576
Cullen Jennings235513a2005-09-21 22:51:36 +0000577void
jfigus67b9c732014-11-20 10:17:21 -0500578srtp_do_timing (const srtp_policy_t *policy)
579{
580 int len;
Cullen Jennings235513a2005-09-21 22:51:36 +0000581
jfigus67b9c732014-11-20 10:17:21 -0500582 /*
583 * note: the output of this function is formatted so that it
584 * can be used in gnuplot. '#' indicates a comment, and "\r\n"
585 * terminates a record
586 */
587
588 printf("# testing srtp throughput:\r\n");
589 printf("# mesg length (octets)\tthroughput (megabits per second)\r\n");
590
591 for (len = 16; len <= 2048; len *= 2) {
592 printf("%d\t\t\t%f\r\n", len,
593 srtp_bits_per_second(len, policy) / 1.0E6);
594 }
595
596 /* these extra linefeeds let gnuplot know that a dataset is done */
597 printf("\r\n\r\n");
Cullen Jennings235513a2005-09-21 22:51:36 +0000598
599}
600
601void
jfigus67b9c732014-11-20 10:17:21 -0500602srtp_do_rejection_timing (const srtp_policy_t *policy)
603{
604 int len;
Cullen Jennings235513a2005-09-21 22:51:36 +0000605
jfigus67b9c732014-11-20 10:17:21 -0500606 /*
607 * note: the output of this function is formatted so that it
608 * can be used in gnuplot. '#' indicates a comment, and "\r\n"
609 * terminates a record
610 */
611
612 printf("# testing srtp rejection throughput:\r\n");
613 printf("# mesg length (octets)\trejections per second\r\n");
614
615 for (len = 8; len <= 2048; len *= 2) {
616 printf("%d\t\t\t%e\r\n", len, srtp_rejections_per_second(len, policy));
617 }
618
619 /* these extra linefeeds let gnuplot know that a dataset is done */
620 printf("\r\n\r\n");
Cullen Jennings235513a2005-09-21 22:51:36 +0000621
622}
623
624
625#define MAX_MSG_LEN 1024
626
627double
jfigus67b9c732014-11-20 10:17:21 -0500628srtp_bits_per_second (int msg_len_octets, const srtp_policy_t *policy)
629{
630 srtp_t srtp;
631 srtp_hdr_t *mesg;
632 int i;
633 clock_t timer;
634 int num_trials = 100000;
635 int len;
636 uint32_t ssrc;
637 srtp_err_status_t status;
Cullen Jennings235513a2005-09-21 22:51:36 +0000638
jfigus67b9c732014-11-20 10:17:21 -0500639 /*
640 * allocate and initialize an srtp session
641 */
642 status = srtp_create(&srtp, policy);
Cullen Jennings235513a2005-09-21 22:51:36 +0000643 if (status) {
jfigus67b9c732014-11-20 10:17:21 -0500644 printf("error: srtp_create() failed with error code %d\n", status);
645 exit(1);
Cullen Jennings235513a2005-09-21 22:51:36 +0000646 }
647
jfigus67b9c732014-11-20 10:17:21 -0500648 /*
649 * if the ssrc is unspecified, use a predetermined one
650 */
651 if (policy->ssrc.type != ssrc_specific) {
652 ssrc = 0xdeadbeef;
653 } else {
654 ssrc = policy->ssrc.value;
Jonathan Lennox75b36872010-05-21 00:30:21 +0000655 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000656
jfigus67b9c732014-11-20 10:17:21 -0500657 /*
658 * create a test packet
659 */
660 mesg = srtp_create_test_packet(msg_len_octets, ssrc);
661 if (mesg == NULL) {
662 return 0.0; /* indicate failure by returning zero */
Jonathan Lennox80c4c832010-05-17 19:30:28 +0000663
jfigus67b9c732014-11-20 10:17:21 -0500664 }
665 timer = clock();
666 for (i = 0; i < num_trials; i++) {
667 len = msg_len_octets + 12; /* add in rtp header length */
668
669 /* srtp protect message */
670 status = srtp_protect(srtp, mesg, &len);
671 if (status) {
672 printf("error: srtp_protect() failed with error code %d\n", status);
673 exit(1);
674 }
675
676 /* increment message number */
677 {
678 /* hack sequence to avoid problems with macros for htons/ntohs on some systems */
679 short new_seq = ntohs(mesg->seq) + 1;
680 mesg->seq = htons(new_seq);
681 }
682 }
683 timer = clock() - timer;
684
685 free(mesg);
686
687 status = srtp_dealloc(srtp);
688 if (status) {
689 printf("error: srtp_dealloc() failed with error code %d\n", status);
690 exit(1);
691 }
692
693 return (double)(msg_len_octets) * 8 *
694 num_trials * CLOCKS_PER_SEC / timer;
Cullen Jennings235513a2005-09-21 22:51:36 +0000695}
696
697double
jfigus67b9c732014-11-20 10:17:21 -0500698srtp_rejections_per_second (int msg_len_octets, const srtp_policy_t *policy)
699{
700 srtp_ctx_t *srtp;
701 srtp_hdr_t *mesg;
702 int i;
703 int len;
704 clock_t timer;
705 int num_trials = 1000000;
706 uint32_t ssrc = policy->ssrc.value;
707 srtp_err_status_t status;
Cullen Jennings235513a2005-09-21 22:51:36 +0000708
jfigus67b9c732014-11-20 10:17:21 -0500709 /*
710 * allocate and initialize an srtp session
711 */
712 status = srtp_create(&srtp, policy);
713 if (status) {
714 printf("error: srtp_create() failed with error code %d\n", status);
715 exit(1);
716 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000717
jfigus67b9c732014-11-20 10:17:21 -0500718 mesg = srtp_create_test_packet(msg_len_octets, ssrc);
719 if (mesg == NULL) {
720 return 0.0; /* indicate failure by returning zero */
721
722 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000723 len = msg_len_octets;
jfigus67b9c732014-11-20 10:17:21 -0500724 srtp_protect(srtp, (srtp_hdr_t*)mesg, &len);
Cullen Jennings235513a2005-09-21 22:51:36 +0000725
jfigus67b9c732014-11-20 10:17:21 -0500726 timer = clock();
727 for (i = 0; i < num_trials; i++) {
728 len = msg_len_octets;
729 srtp_unprotect(srtp, (srtp_hdr_t*)mesg, &len);
730 }
731 timer = clock() - timer;
Jonathan Lennox80c4c832010-05-17 19:30:28 +0000732
jfigus67b9c732014-11-20 10:17:21 -0500733 free(mesg);
Jonathan Lennox80c4c832010-05-17 19:30:28 +0000734
jfigus67b9c732014-11-20 10:17:21 -0500735 status = srtp_dealloc(srtp);
736 if (status) {
737 printf("error: srtp_dealloc() failed with error code %d\n", status);
738 exit(1);
739 }
740
741 return (double)num_trials * CLOCKS_PER_SEC / timer;
Cullen Jennings235513a2005-09-21 22:51:36 +0000742}
743
744
745void
jfigus67b9c732014-11-20 10:17:21 -0500746err_check (srtp_err_status_t s)
747{
748 if (s == srtp_err_status_ok) {
749 return;
750 } else{
751 fprintf(stderr, "error: unexpected srtp failure (code %d)\n", s);
752 }
753 exit(1);
Cullen Jennings235513a2005-09-21 22:51:36 +0000754}
755
jfigus857009c2014-11-05 11:17:43 -0500756srtp_err_status_t
Joachim Bauch99a74822015-11-17 00:08:19 +0100757srtp_test (const srtp_policy_t *policy, int extension_header)
jfigus67b9c732014-11-20 10:17:21 -0500758{
759 int i;
760 srtp_t srtp_sender;
761 srtp_t srtp_rcvr;
762 srtp_err_status_t status = srtp_err_status_ok;
763 srtp_hdr_t *hdr, *hdr2;
764 uint8_t hdr_enc[64];
765 uint8_t *pkt_end;
766 int msg_len_octets, msg_len_enc;
767 int len;
768 int tag_length = policy->rtp.auth_tag_len;
769 uint32_t ssrc;
770 srtp_policy_t *rcvr_policy;
Joachim Bauch99a74822015-11-17 00:08:19 +0100771 srtp_policy_t tmp_policy;
772 int header = 1;
Cullen Jennings235513a2005-09-21 22:51:36 +0000773
Joachim Bauch99a74822015-11-17 00:08:19 +0100774 if (extension_header) {
775 memcpy(&tmp_policy, policy, sizeof(srtp_policy_t));
776 tmp_policy.enc_xtn_hdr = &header;
777 tmp_policy.enc_xtn_hdr_count = 1;
778 err_check(srtp_create(&srtp_sender, &tmp_policy));
779 } else {
780 err_check(srtp_create(&srtp_sender, policy));
781 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000782
jfigus67b9c732014-11-20 10:17:21 -0500783 /* print out policy */
784 err_check(srtp_session_print_policy(srtp_sender));
Cullen Jennings235513a2005-09-21 22:51:36 +0000785
jfigus67b9c732014-11-20 10:17:21 -0500786 /*
787 * initialize data buffer, using the ssrc in the policy unless that
788 * value is a wildcard, in which case we'll just use an arbitrary
789 * one
790 */
791 if (policy->ssrc.type != ssrc_specific) {
792 ssrc = 0xdecafbad;
793 } else{
794 ssrc = policy->ssrc.value;
Cullen Jennings235513a2005-09-21 22:51:36 +0000795 }
jfigus67b9c732014-11-20 10:17:21 -0500796 msg_len_octets = 28;
Joachim Bauch99a74822015-11-17 00:08:19 +0100797 if (extension_header) {
798 hdr = srtp_create_test_packet_ext_hdr(msg_len_octets, ssrc);
799 hdr2 = srtp_create_test_packet_ext_hdr(msg_len_octets, ssrc);
800 } else {
801 hdr = srtp_create_test_packet(msg_len_octets, ssrc);
802 hdr2 = srtp_create_test_packet(msg_len_octets, ssrc);
803 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000804
jfigus67b9c732014-11-20 10:17:21 -0500805 if (hdr == NULL) {
Joachim Bauch99a74822015-11-17 00:08:19 +0100806 free(hdr2);
jfigus67b9c732014-11-20 10:17:21 -0500807 return srtp_err_status_alloc_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +0000808 }
jfigus67b9c732014-11-20 10:17:21 -0500809 if (hdr2 == NULL) {
810 free(hdr);
811 return srtp_err_status_alloc_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +0000812 }
813
Marcus Sundberg5c40da82005-10-08 18:15:00 +0000814 /* set message length */
815 len = msg_len_octets;
Joachim Bauch99a74822015-11-17 00:08:19 +0100816 if (extension_header) {
817 len += 12;
818 }
Marcus Sundberg5c40da82005-10-08 18:15:00 +0000819
jfigus67b9c732014-11-20 10:17:21 -0500820 debug_print(mod_driver, "before protection:\n%s",
821 srtp_packet_to_string(hdr, len));
822
823#if PRINT_REFERENCE_PACKET
824 debug_print(mod_driver, "reference packet before protection:\n%s",
825 octet_string_hex_string((uint8_t*)hdr, len));
826#endif
Cullen Jennings235513a2005-09-21 22:51:36 +0000827 err_check(srtp_protect(srtp_sender, hdr, &len));
Cullen Jennings235513a2005-09-21 22:51:36 +0000828
jfigus67b9c732014-11-20 10:17:21 -0500829 debug_print(mod_driver, "after protection:\n%s",
830 srtp_packet_to_string(hdr, len));
831#if PRINT_REFERENCE_PACKET
832 debug_print(mod_driver, "after protection:\n%s",
833 octet_string_hex_string((uint8_t*)hdr, len));
834#endif
835
836 /* save protected message and length */
837 memcpy(hdr_enc, hdr, len);
838 msg_len_enc = len;
839
840 /*
841 * check for overrun of the srtp_protect() function
842 *
843 * The packet is followed by a value of 0xfffff; if the value of the
844 * data following the packet is different, then we know that the
845 * protect function is overwriting the end of the packet.
846 */
847 pkt_end = (uint8_t*)hdr + sizeof(srtp_hdr_t)
848 + msg_len_octets + tag_length;
Joachim Bauch99a74822015-11-17 00:08:19 +0100849 if (extension_header) {
850 pkt_end += 12;
851 }
jfigus67b9c732014-11-20 10:17:21 -0500852 for (i = 0; i < 4; i++) {
853 if (pkt_end[i] != 0xff) {
854 fprintf(stdout, "overwrite in srtp_protect() function "
855 "(expected %x, found %x in trailing octet %d)\n",
856 0xff, ((uint8_t*)hdr)[i], i);
857 free(hdr);
858 free(hdr2);
859 return srtp_err_status_algo_fail;
860 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000861 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000862
jfigus67b9c732014-11-20 10:17:21 -0500863 /*
864 * if the policy includes confidentiality, check that ciphertext is
865 * different than plaintext
866 *
867 * Note that this check will give false negatives, with some small
868 * probability, especially if the packets are short. For that
869 * reason, we skip this check if the plaintext is less than four
870 * octets long.
871 */
872 if ((policy->rtp.sec_serv & sec_serv_conf) && (msg_len_octets >= 4)) {
873 printf("testing that ciphertext is distinct from plaintext...");
874 status = srtp_err_status_algo_fail;
875 for (i = 12; i < msg_len_octets + 12; i++) {
876 if (((uint8_t*)hdr)[i] != ((uint8_t*)hdr2)[i]) {
877 status = srtp_err_status_ok;
878 }
879 }
880 if (status) {
881 printf("failed\n");
882 free(hdr);
883 free(hdr2);
884 return status;
885 }
886 printf("passed\n");
887 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000888
jfigus67b9c732014-11-20 10:17:21 -0500889 /*
890 * if the policy uses a 'wildcard' ssrc, then we need to make a copy
891 * of the policy that changes the direction to inbound
892 *
893 * we always copy the policy into the rcvr_policy, since otherwise
894 * the compiler would fret about the constness of the policy
895 */
896 rcvr_policy = (srtp_policy_t*)malloc(sizeof(srtp_policy_t));
897 if (rcvr_policy == NULL) {
898 free(hdr);
899 free(hdr2);
900 return srtp_err_status_alloc_fail;
901 }
Joachim Bauch99a74822015-11-17 00:08:19 +0100902 if (extension_header) {
903 memcpy(rcvr_policy, &tmp_policy, sizeof(srtp_policy_t));
904 if (tmp_policy.ssrc.type == ssrc_any_outbound) {
905 rcvr_policy->ssrc.type = ssrc_any_inbound;
906 }
907 } else {
908 memcpy(rcvr_policy, policy, sizeof(srtp_policy_t));
909 if (policy->ssrc.type == ssrc_any_outbound) {
910 rcvr_policy->ssrc.type = ssrc_any_inbound;
911 }
jfigus67b9c732014-11-20 10:17:21 -0500912 }
913
914 err_check(srtp_create(&srtp_rcvr, rcvr_policy));
915
916 err_check(srtp_unprotect(srtp_rcvr, hdr, &len));
917
918 debug_print(mod_driver, "after unprotection:\n%s",
919 srtp_packet_to_string(hdr, len));
920
921 /* verify that the unprotected packet matches the origial one */
922 for (i = 0; i < msg_len_octets; i++) {
923 if (((uint8_t*)hdr)[i] != ((uint8_t*)hdr2)[i]) {
924 fprintf(stdout, "mismatch at octet %d\n", i);
925 status = srtp_err_status_algo_fail;
926 }
927 }
928 if (status) {
929 free(hdr);
930 free(hdr2);
931 free(rcvr_policy);
932 return status;
933 }
934
935 /*
936 * if the policy includes authentication, then test for false positives
937 */
938 if (policy->rtp.sec_serv & sec_serv_auth) {
939 char *data = ((char*)hdr) + 12;
940
941 printf("testing for false positives in replay check...");
942
943 /* set message length */
944 len = msg_len_enc;
945
946 /* unprotect a second time - should fail with a replay error */
947 status = srtp_unprotect(srtp_rcvr, hdr_enc, &len);
948 if (status != srtp_err_status_replay_fail) {
949 printf("failed with error code %d\n", status);
950 free(hdr);
951 free(hdr2);
952 free(rcvr_policy);
953 return status;
954 } else {
955 printf("passed\n");
956 }
957
958 printf("testing for false positives in auth check...");
959
960 /* increment sequence number in header */
961 hdr->seq++;
962
963 /* set message length */
964 len = msg_len_octets;
Joachim Bauch99a74822015-11-17 00:08:19 +0100965 if (extension_header) {
966 len += 12;
967 }
jfigus67b9c732014-11-20 10:17:21 -0500968
969 /* apply protection */
970 err_check(srtp_protect(srtp_sender, hdr, &len));
971
972 /* flip bits in packet */
Joachim Bauchfa1e8c22015-11-24 23:38:48 +0100973 data[extension_header ? 12 : 0] ^= 0xff;
jfigus67b9c732014-11-20 10:17:21 -0500974
975 /* unprotect, and check for authentication failure */
976 status = srtp_unprotect(srtp_rcvr, hdr, &len);
977 if (status != srtp_err_status_auth_fail) {
978 printf("failed\n");
979 free(hdr);
980 free(hdr2);
981 free(rcvr_policy);
982 return status;
983 } else {
984 printf("passed\n");
985 }
986
987 }
988
989 err_check(srtp_dealloc(srtp_sender));
990 err_check(srtp_dealloc(srtp_rcvr));
991
992 free(hdr);
993 free(hdr2);
994 free(rcvr_policy);
995 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +0000996}
997
998
jfigus857009c2014-11-05 11:17:43 -0500999srtp_err_status_t
jfigus67b9c732014-11-20 10:17:21 -05001000srtcp_test (const srtp_policy_t *policy)
1001{
1002 int i;
1003 srtp_t srtcp_sender;
1004 srtp_t srtcp_rcvr;
1005 srtp_err_status_t status = srtp_err_status_ok;
1006 srtp_hdr_t *hdr, *hdr2;
1007 uint8_t hdr_enc[64];
1008 uint8_t *pkt_end;
1009 int msg_len_octets, msg_len_enc;
1010 int len;
1011 int tag_length = policy->rtp.auth_tag_len;
1012 uint32_t ssrc;
1013 srtp_policy_t *rcvr_policy;
David McGrew9c70f292006-05-03 19:38:38 +00001014
jfigus67b9c732014-11-20 10:17:21 -05001015 err_check(srtp_create(&srtcp_sender, policy));
David McGrew9c70f292006-05-03 19:38:38 +00001016
jfigus67b9c732014-11-20 10:17:21 -05001017 /* print out policy */
1018 err_check(srtp_session_print_policy(srtcp_sender));
David McGrew9c70f292006-05-03 19:38:38 +00001019
jfigus67b9c732014-11-20 10:17:21 -05001020 /*
1021 * initialize data buffer, using the ssrc in the policy unless that
1022 * value is a wildcard, in which case we'll just use an arbitrary
1023 * one
1024 */
1025 if (policy->ssrc.type != ssrc_specific) {
1026 ssrc = 0xdecafbad;
1027 } else{
1028 ssrc = policy->ssrc.value;
David McGrew9c70f292006-05-03 19:38:38 +00001029 }
jfigus67b9c732014-11-20 10:17:21 -05001030 msg_len_octets = 28;
1031 hdr = srtp_create_test_packet(msg_len_octets, ssrc);
David McGrew9c70f292006-05-03 19:38:38 +00001032
jfigus67b9c732014-11-20 10:17:21 -05001033 if (hdr == NULL) {
1034 return srtp_err_status_alloc_fail;
David McGrew9c70f292006-05-03 19:38:38 +00001035 }
jfigus67b9c732014-11-20 10:17:21 -05001036 hdr2 = srtp_create_test_packet(msg_len_octets, ssrc);
1037 if (hdr2 == NULL) {
1038 free(hdr);
1039 return srtp_err_status_alloc_fail;
David McGrew9c70f292006-05-03 19:38:38 +00001040 }
1041
David McGrew9c70f292006-05-03 19:38:38 +00001042 /* set message length */
1043 len = msg_len_octets;
1044
jfigus67b9c732014-11-20 10:17:21 -05001045 debug_print(mod_driver, "before protection:\n%s",
1046 srtp_packet_to_string(hdr, len));
1047
1048#if PRINT_REFERENCE_PACKET
1049 debug_print(mod_driver, "reference packet before protection:\n%s",
1050 octet_string_hex_string((uint8_t*)hdr, len));
1051#endif
David McGrew9c70f292006-05-03 19:38:38 +00001052 err_check(srtp_protect_rtcp(srtcp_sender, hdr, &len));
David McGrew9c70f292006-05-03 19:38:38 +00001053
jfigus67b9c732014-11-20 10:17:21 -05001054 debug_print(mod_driver, "after protection:\n%s",
1055 srtp_packet_to_string(hdr, len));
1056#if PRINT_REFERENCE_PACKET
1057 debug_print(mod_driver, "after protection:\n%s",
1058 octet_string_hex_string((uint8_t*)hdr, len));
1059#endif
1060
1061 /* save protected message and length */
1062 memcpy(hdr_enc, hdr, len);
1063 msg_len_enc = len;
1064
1065 /*
1066 * check for overrun of the srtp_protect() function
1067 *
1068 * The packet is followed by a value of 0xfffff; if the value of the
1069 * data following the packet is different, then we know that the
1070 * protect function is overwriting the end of the packet.
1071 */
1072 pkt_end = (uint8_t*)hdr + sizeof(srtp_hdr_t)
1073 + msg_len_octets + tag_length;
1074 for (i = 0; i < 4; i++) {
1075 if (pkt_end[i] != 0xff) {
1076 fprintf(stdout, "overwrite in srtp_protect_rtcp() function "
1077 "(expected %x, found %x in trailing octet %d)\n",
1078 0xff, ((uint8_t*)hdr)[i], i);
1079 free(hdr);
1080 free(hdr2);
1081 return srtp_err_status_algo_fail;
1082 }
David McGrew9c70f292006-05-03 19:38:38 +00001083 }
David McGrew9c70f292006-05-03 19:38:38 +00001084
jfigus67b9c732014-11-20 10:17:21 -05001085 /*
1086 * if the policy includes confidentiality, check that ciphertext is
1087 * different than plaintext
1088 *
1089 * Note that this check will give false negatives, with some small
1090 * probability, especially if the packets are short. For that
1091 * reason, we skip this check if the plaintext is less than four
1092 * octets long.
1093 */
1094 if ((policy->rtp.sec_serv & sec_serv_conf) && (msg_len_octets >= 4)) {
1095 printf("testing that ciphertext is distinct from plaintext...");
1096 status = srtp_err_status_algo_fail;
1097 for (i = 12; i < msg_len_octets + 12; i++) {
1098 if (((uint8_t*)hdr)[i] != ((uint8_t*)hdr2)[i]) {
1099 status = srtp_err_status_ok;
1100 }
1101 }
1102 if (status) {
1103 printf("failed\n");
1104 free(hdr);
1105 free(hdr2);
1106 return status;
1107 }
1108 printf("passed\n");
1109 }
David McGrew9c70f292006-05-03 19:38:38 +00001110
jfigus67b9c732014-11-20 10:17:21 -05001111 /*
1112 * if the policy uses a 'wildcard' ssrc, then we need to make a copy
1113 * of the policy that changes the direction to inbound
1114 *
1115 * we always copy the policy into the rcvr_policy, since otherwise
1116 * the compiler would fret about the constness of the policy
1117 */
1118 rcvr_policy = (srtp_policy_t*)malloc(sizeof(srtp_policy_t));
1119 if (rcvr_policy == NULL) {
1120 return srtp_err_status_alloc_fail;
1121 }
1122 memcpy(rcvr_policy, policy, sizeof(srtp_policy_t));
1123 if (policy->ssrc.type == ssrc_any_outbound) {
1124 rcvr_policy->ssrc.type = ssrc_any_inbound;
1125 }
1126
1127 err_check(srtp_create(&srtcp_rcvr, rcvr_policy));
1128
1129 err_check(srtp_unprotect_rtcp(srtcp_rcvr, hdr, &len));
1130
1131 debug_print(mod_driver, "after unprotection:\n%s",
1132 srtp_packet_to_string(hdr, len));
1133
1134 /* verify that the unprotected packet matches the origial one */
1135 for (i = 0; i < msg_len_octets; i++) {
1136 if (((uint8_t*)hdr)[i] != ((uint8_t*)hdr2)[i]) {
1137 fprintf(stdout, "mismatch at octet %d\n", i);
1138 status = srtp_err_status_algo_fail;
1139 }
1140 }
1141 if (status) {
1142 free(hdr);
1143 free(hdr2);
1144 free(rcvr_policy);
1145 return status;
1146 }
1147
1148 /*
1149 * if the policy includes authentication, then test for false positives
1150 */
1151 if (policy->rtp.sec_serv & sec_serv_auth) {
1152 char *data = ((char*)hdr) + 12;
1153
1154 printf("testing for false positives in replay check...");
1155
1156 /* set message length */
1157 len = msg_len_enc;
1158
1159 /* unprotect a second time - should fail with a replay error */
1160 status = srtp_unprotect_rtcp(srtcp_rcvr, hdr_enc, &len);
1161 if (status != srtp_err_status_replay_fail) {
1162 printf("failed with error code %d\n", status);
1163 free(hdr);
1164 free(hdr2);
1165 free(rcvr_policy);
1166 return status;
1167 } else {
1168 printf("passed\n");
1169 }
1170
1171 printf("testing for false positives in auth check...");
1172
1173 /* increment sequence number in header */
1174 hdr->seq++;
1175
1176 /* set message length */
1177 len = msg_len_octets;
1178
1179 /* apply protection */
1180 err_check(srtp_protect_rtcp(srtcp_sender, hdr, &len));
1181
1182 /* flip bits in packet */
1183 data[0] ^= 0xff;
1184
1185 /* unprotect, and check for authentication failure */
1186 status = srtp_unprotect_rtcp(srtcp_rcvr, hdr, &len);
1187 if (status != srtp_err_status_auth_fail) {
1188 printf("failed\n");
1189 free(hdr);
1190 free(hdr2);
1191 free(rcvr_policy);
1192 return status;
1193 } else {
1194 printf("passed\n");
1195 }
1196
1197 }
1198
1199 err_check(srtp_dealloc(srtcp_sender));
1200 err_check(srtp_dealloc(srtcp_rcvr));
1201
1202 free(hdr);
1203 free(hdr2);
1204 free(rcvr_policy);
1205 return srtp_err_status_ok;
David McGrew9c70f292006-05-03 19:38:38 +00001206}
1207
1208
jfigus857009c2014-11-05 11:17:43 -05001209srtp_err_status_t
jfigus67b9c732014-11-20 10:17:21 -05001210srtp_session_print_policy (srtp_t srtp)
1211{
1212 char *serv_descr[4] = {
1213 "none",
1214 "confidentiality",
1215 "authentication",
1216 "confidentiality and authentication"
1217 };
1218 char *direction[3] = {
1219 "unknown",
1220 "outbound",
1221 "inbound"
1222 };
1223 srtp_stream_t stream;
Cullen Jennings235513a2005-09-21 22:51:36 +00001224
jfigus67b9c732014-11-20 10:17:21 -05001225 /* sanity checking */
1226 if (srtp == NULL) {
1227 return srtp_err_status_fail;
1228 }
Cullen Jennings235513a2005-09-21 22:51:36 +00001229
jfigus67b9c732014-11-20 10:17:21 -05001230 /* if there's a template stream, print it out */
1231 if (srtp->stream_template != NULL) {
1232 stream = srtp->stream_template;
1233 printf("# SSRC: any %s\r\n"
1234 "# rtp cipher: %s\r\n"
1235 "# rtp auth: %s\r\n"
1236 "# rtp services: %s\r\n"
1237 "# rtcp cipher: %s\r\n"
1238 "# rtcp auth: %s\r\n"
1239 "# rtcp services: %s\r\n"
1240 "# window size: %lu\r\n"
1241 "# tx rtx allowed:%s\r\n",
1242 direction[stream->direction],
1243 stream->rtp_cipher->type->description,
1244 stream->rtp_auth->type->description,
1245 serv_descr[stream->rtp_services],
1246 stream->rtcp_cipher->type->description,
1247 stream->rtcp_auth->type->description,
1248 serv_descr[stream->rtcp_services],
jfigusde8deb32014-11-25 12:58:11 -05001249 srtp_rdbx_get_window_size(&stream->rtp_rdbx),
jfigus67b9c732014-11-20 10:17:21 -05001250 stream->allow_repeat_tx ? "true" : "false");
Joachim Bauch99a74822015-11-17 00:08:19 +01001251
1252 printf("# Encrypted extension headers: ");
1253 if (stream->enc_xtn_hdr && stream->enc_xtn_hdr_count > 0) {
1254 int* enc_xtn_hdr = stream->enc_xtn_hdr;
1255 int count = stream->enc_xtn_hdr_count;
1256 while (count > 0) {
1257 printf("%d ", *enc_xtn_hdr);
1258 enc_xtn_hdr++;
1259 count--;
1260 }
1261 printf("\n");
1262 } else {
1263 printf("none\n");
1264 }
jfigus67b9c732014-11-20 10:17:21 -05001265 }
Cullen Jennings235513a2005-09-21 22:51:36 +00001266
jfigus67b9c732014-11-20 10:17:21 -05001267 /* loop over streams in session, printing the policy of each */
1268 stream = srtp->stream_list;
1269 while (stream != NULL) {
1270 if (stream->rtp_services > sec_serv_conf_and_auth) {
1271 return srtp_err_status_bad_param;
1272 }
Cullen Jennings235513a2005-09-21 22:51:36 +00001273
jfigus67b9c732014-11-20 10:17:21 -05001274 printf("# SSRC: 0x%08x\r\n"
1275 "# rtp cipher: %s\r\n"
1276 "# rtp auth: %s\r\n"
1277 "# rtp services: %s\r\n"
1278 "# rtcp cipher: %s\r\n"
1279 "# rtcp auth: %s\r\n"
1280 "# rtcp services: %s\r\n"
1281 "# window size: %lu\r\n"
1282 "# tx rtx allowed:%s\r\n",
1283 stream->ssrc,
1284 stream->rtp_cipher->type->description,
1285 stream->rtp_auth->type->description,
1286 serv_descr[stream->rtp_services],
1287 stream->rtcp_cipher->type->description,
1288 stream->rtcp_auth->type->description,
1289 serv_descr[stream->rtcp_services],
jfigusde8deb32014-11-25 12:58:11 -05001290 srtp_rdbx_get_window_size(&stream->rtp_rdbx),
jfigus67b9c732014-11-20 10:17:21 -05001291 stream->allow_repeat_tx ? "true" : "false");
1292
Joachim Bauch99a74822015-11-17 00:08:19 +01001293 printf("# Encrypted extension headers: ");
1294 if (stream->enc_xtn_hdr && stream->enc_xtn_hdr_count > 0) {
1295 int* enc_xtn_hdr = stream->enc_xtn_hdr;
1296 int count = stream->enc_xtn_hdr_count;
1297 while (count > 0) {
1298 printf("%d ", *enc_xtn_hdr);
1299 enc_xtn_hdr++;
1300 count--;
1301 }
1302 printf("\n");
1303 } else {
1304 printf("none\n");
1305 }
1306
jfigus67b9c732014-11-20 10:17:21 -05001307 /* advance to next stream in the list */
1308 stream = stream->next;
1309 }
1310 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +00001311}
1312
jfigus857009c2014-11-05 11:17:43 -05001313srtp_err_status_t
jfigus67b9c732014-11-20 10:17:21 -05001314srtp_print_policy (const srtp_policy_t *policy)
1315{
1316 srtp_err_status_t status;
1317 srtp_t session;
Cullen Jennings235513a2005-09-21 22:51:36 +00001318
jfigus67b9c732014-11-20 10:17:21 -05001319 status = srtp_create(&session, policy);
1320 if (status) {
1321 return status;
1322 }
1323 status = srtp_session_print_policy(session);
1324 if (status) {
1325 return status;
1326 }
1327 status = srtp_dealloc(session);
1328 if (status) {
1329 return status;
1330 }
1331 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +00001332}
1333
jfigus67b9c732014-11-20 10:17:21 -05001334/*
1335 * srtp_print_packet(...) is for debugging only
Cullen Jennings235513a2005-09-21 22:51:36 +00001336 * it prints an RTP packet to the stdout
1337 *
1338 * note that this function is *not* threadsafe
1339 */
1340
1341#include <stdio.h>
1342
1343#define MTU 2048
1344
1345char packet_string[MTU];
1346
1347char *
jfigus67b9c732014-11-20 10:17:21 -05001348srtp_packet_to_string (srtp_hdr_t *hdr, int pkt_octet_len)
1349{
1350 int octets_in_rtp_header = 12;
1351 uint8_t *data = ((uint8_t*)hdr) + octets_in_rtp_header;
1352 int hex_len = pkt_octet_len - octets_in_rtp_header;
Cullen Jennings235513a2005-09-21 22:51:36 +00001353
jfigus67b9c732014-11-20 10:17:21 -05001354 /* sanity checking */
1355 if ((hdr == NULL) || (pkt_octet_len > MTU)) {
1356 return NULL;
1357 }
Cullen Jennings235513a2005-09-21 22:51:36 +00001358
jfigus67b9c732014-11-20 10:17:21 -05001359 /* write packet into string */
1360 sprintf(packet_string,
1361 "(s)rtp packet: {\n"
1362 " version:\t%d\n"
1363 " p:\t\t%d\n"
1364 " x:\t\t%d\n"
1365 " cc:\t\t%d\n"
1366 " m:\t\t%d\n"
1367 " pt:\t\t%x\n"
1368 " seq:\t\t%x\n"
1369 " ts:\t\t%x\n"
1370 " ssrc:\t%x\n"
1371 " data:\t%s\n"
1372 "} (%d octets in total)\n",
1373 hdr->version,
1374 hdr->p,
1375 hdr->x,
1376 hdr->cc,
1377 hdr->m,
1378 hdr->pt,
1379 hdr->seq,
1380 hdr->ts,
1381 hdr->ssrc,
1382 octet_string_hex_string(data, hex_len),
1383 pkt_octet_len);
Cullen Jennings235513a2005-09-21 22:51:36 +00001384
jfigus67b9c732014-11-20 10:17:21 -05001385 return packet_string;
Cullen Jennings235513a2005-09-21 22:51:36 +00001386}
1387
1388/*
1389 * mips_estimate() is a simple function to estimate the number of
1390 * instructions per second that the host can perform. note that this
1391 * function can be grossly wrong; you may want to have a manual sanity
1392 * check of its output!
1393 *
1394 * the 'ignore' pointer is there to convince the compiler to not just
1395 * optimize away the function
1396 */
1397
1398double
jfigus67b9c732014-11-20 10:17:21 -05001399mips_estimate (int num_trials, int *ignore)
1400{
1401 clock_t t;
1402 volatile int i, sum;
Cullen Jennings235513a2005-09-21 22:51:36 +00001403
jfigus67b9c732014-11-20 10:17:21 -05001404 sum = 0;
1405 t = clock();
1406 for (i = 0; i < num_trials; i++) {
1407 sum += i;
1408 }
1409 t = clock() - t;
Cullen Jennings235513a2005-09-21 22:51:36 +00001410
1411/* printf("%d\n", sum); */
jfigus67b9c732014-11-20 10:17:21 -05001412 *ignore = sum;
Cullen Jennings235513a2005-09-21 22:51:36 +00001413
jfigus67b9c732014-11-20 10:17:21 -05001414 return (double)num_trials * CLOCKS_PER_SEC / t;
Cullen Jennings235513a2005-09-21 22:51:36 +00001415}
1416
1417
1418/*
1419 * srtp_validate() verifies the correctness of libsrtp by comparing
1420 * some computed packets against some pre-computed reference values.
1421 * These packets were made with the default SRTP policy.
1422 */
1423
1424
jfigus857009c2014-11-05 11:17:43 -05001425srtp_err_status_t
jfigus67b9c732014-11-20 10:17:21 -05001426srtp_validate ()
1427{
1428 uint8_t srtp_plaintext_ref[28] = {
1429 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1430 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
1431 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1432 0xab, 0xab, 0xab, 0xab
1433 };
1434 uint8_t srtp_plaintext[38] = {
1435 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1436 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
1437 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1438 0xab, 0xab, 0xab, 0xab, 0x00, 0x00, 0x00, 0x00,
1439 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1440 };
1441 uint8_t srtp_ciphertext[38] = {
1442 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1443 0xca, 0xfe, 0xba, 0xbe, 0x4e, 0x55, 0xdc, 0x4c,
1444 0xe7, 0x99, 0x78, 0xd8, 0x8c, 0xa4, 0xd2, 0x15,
1445 0x94, 0x9d, 0x24, 0x02, 0xb7, 0x8d, 0x6a, 0xcc,
1446 0x99, 0xea, 0x17, 0x9b, 0x8d, 0xbb
1447 };
1448 srtp_t srtp_snd, srtp_recv;
1449 srtp_err_status_t status;
1450 int len;
1451 srtp_policy_t policy;
Cullen Jennings235513a2005-09-21 22:51:36 +00001452
jfigus67b9c732014-11-20 10:17:21 -05001453 /*
1454 * create a session with a single stream using the default srtp
1455 * policy and with the SSRC value 0xcafebabe
1456 */
Joachim Bauch99a74822015-11-17 00:08:19 +01001457 memset(&policy, 0, sizeof(policy));
jfigus67b9c732014-11-20 10:17:21 -05001458 srtp_crypto_policy_set_rtp_default(&policy.rtp);
1459 srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
1460 policy.ssrc.type = ssrc_specific;
1461 policy.ssrc.value = 0xcafebabe;
1462 policy.key = test_key;
1463 policy.ekt = NULL;
1464 policy.window_size = 128;
1465 policy.allow_repeat_tx = 0;
1466 policy.next = NULL;
Cullen Jennings235513a2005-09-21 22:51:36 +00001467
jfigus67b9c732014-11-20 10:17:21 -05001468 status = srtp_create(&srtp_snd, &policy);
1469 if (status) {
1470 return status;
1471 }
Cullen Jennings235513a2005-09-21 22:51:36 +00001472
jfigus67b9c732014-11-20 10:17:21 -05001473 /*
1474 * protect plaintext, then compare with ciphertext
1475 */
1476 len = 28;
1477 status = srtp_protect(srtp_snd, srtp_plaintext, &len);
1478 if (status || (len != 38)) {
1479 return srtp_err_status_fail;
1480 }
Cullen Jennings235513a2005-09-21 22:51:36 +00001481
jfigus67b9c732014-11-20 10:17:21 -05001482 debug_print(mod_driver, "ciphertext:\n %s",
1483 octet_string_hex_string(srtp_plaintext, len));
1484 debug_print(mod_driver, "ciphertext reference:\n %s",
1485 octet_string_hex_string(srtp_ciphertext, len));
Cullen Jennings235513a2005-09-21 22:51:36 +00001486
jfigus67b9c732014-11-20 10:17:21 -05001487 if (octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len)) {
1488 return srtp_err_status_fail;
1489 }
Jonathan Lennox80c4c832010-05-17 19:30:28 +00001490
jfigus67b9c732014-11-20 10:17:21 -05001491 /*
1492 * create a receiver session context comparable to the one created
1493 * above - we need to do this so that the replay checking doesn't
1494 * complain
1495 */
1496 status = srtp_create(&srtp_recv, &policy);
1497 if (status) {
1498 return status;
1499 }
Jonathan Lennox80c4c832010-05-17 19:30:28 +00001500
jfigus67b9c732014-11-20 10:17:21 -05001501 /*
1502 * unprotect ciphertext, then compare with plaintext
1503 */
1504 status = srtp_unprotect(srtp_recv, srtp_ciphertext, &len);
1505 if (status || (len != 28)) {
1506 return status;
1507 }
1508
1509 if (octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len)) {
1510 return srtp_err_status_fail;
1511 }
1512
1513 status = srtp_dealloc(srtp_snd);
1514 if (status) {
1515 return status;
1516 }
1517
1518 status = srtp_dealloc(srtp_recv);
1519 if (status) {
1520 return status;
1521 }
1522
1523 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +00001524}
1525
Joachim Bauch99a74822015-11-17 00:08:19 +01001526/*
1527 * Test vectors taken from RFC 6904, Appendix A
1528 */
1529srtp_err_status_t
1530srtp_validate_encrypted_extensions_headers() {
1531 unsigned char test_key_ext_headers[30] = {
1532 0xe1, 0xf9, 0x7a, 0x0d, 0x3e, 0x01, 0x8b, 0xe0,
1533 0xd6, 0x4f, 0xa3, 0x2c, 0x06, 0xde, 0x41, 0x39,
1534 0x0e, 0xc6, 0x75, 0xad, 0x49, 0x8a, 0xfe, 0xeb,
1535 0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6
1536 };
1537 uint8_t srtp_plaintext_ref[56] = {
1538 0x90, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1539 0xca, 0xfe, 0xba, 0xbe, 0xBE, 0xDE, 0x00, 0x06,
1540 0x17, 0x41, 0x42, 0x73, 0xA4, 0x75, 0x26, 0x27,
1541 0x48, 0x22, 0x00, 0x00, 0xC8, 0x30, 0x8E, 0x46,
1542 0x55, 0x99, 0x63, 0x86, 0xB3, 0x95, 0xFB, 0x00,
1543 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1544 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab
1545 };
1546 uint8_t srtp_plaintext[66] = {
1547 0x90, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1548 0xca, 0xfe, 0xba, 0xbe, 0xBE, 0xDE, 0x00, 0x06,
1549 0x17, 0x41, 0x42, 0x73, 0xA4, 0x75, 0x26, 0x27,
1550 0x48, 0x22, 0x00, 0x00, 0xC8, 0x30, 0x8E, 0x46,
1551 0x55, 0x99, 0x63, 0x86, 0xB3, 0x95, 0xFB, 0x00,
1552 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1553 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1554 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1555 0x00, 0x00
1556 };
1557 uint8_t srtp_ciphertext[66] = {
1558 0x90, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1559 0xca, 0xfe, 0xba, 0xbe, 0xBE, 0xDE, 0x00, 0x06,
1560 0x17, 0x58, 0x8A, 0x92, 0x70, 0xF4, 0xE1, 0x5E,
1561 0x1C, 0x22, 0x00, 0x00, 0xC8, 0x30, 0x95, 0x46,
1562 0xA9, 0x94, 0xF0, 0xBC, 0x54, 0x78, 0x97, 0x00,
1563 0x4e, 0x55, 0xdc, 0x4c, 0xe7, 0x99, 0x78, 0xd8,
1564 0x8c, 0xa4, 0xd2, 0x15, 0x94, 0x9d, 0x24, 0x02,
1565 0x5a, 0x46, 0xb3, 0xca, 0x35, 0xc5, 0x35, 0xa8,
1566 0x91, 0xc7
1567 };
1568 srtp_t srtp_snd, srtp_recv;
1569 srtp_err_status_t status;
1570 int len;
1571 srtp_policy_t policy;
1572 int headers[3] = {1, 3, 4};
1573
1574 /*
1575 * create a session with a single stream using the default srtp
1576 * policy and with the SSRC value 0xcafebabe
1577 */
1578 memset(&policy, 0, sizeof(policy));
1579 srtp_crypto_policy_set_rtp_default(&policy.rtp);
1580 srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
1581 policy.ssrc.type = ssrc_specific;
1582 policy.ssrc.value = 0xcafebabe;
1583 policy.key = test_key_ext_headers;
1584 policy.ekt = NULL;
1585 policy.window_size = 128;
1586 policy.allow_repeat_tx = 0;
1587 policy.enc_xtn_hdr = headers;
1588 policy.enc_xtn_hdr_count = sizeof(headers) / sizeof(headers[0]);
1589 policy.next = NULL;
1590
1591 status = srtp_create(&srtp_snd, &policy);
1592 if (status)
1593 return status;
1594
1595 /*
1596 * protect plaintext, then compare with ciphertext
1597 */
1598 len = sizeof(srtp_plaintext_ref);
1599 status = srtp_protect(srtp_snd, srtp_plaintext, &len);
1600 if (status || (len != sizeof(srtp_plaintext)))
1601 return srtp_err_status_fail;
1602
1603 debug_print(mod_driver, "ciphertext:\n %s",
1604 srtp_octet_string_hex_string(srtp_plaintext, len));
1605 debug_print(mod_driver, "ciphertext reference:\n %s",
1606 srtp_octet_string_hex_string(srtp_ciphertext, len));
1607
1608 if (octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len))
1609 return srtp_err_status_fail;
1610
1611 /*
1612 * create a receiver session context comparable to the one created
1613 * above - we need to do this so that the replay checking doesn't
1614 * complain
1615 */
1616 status = srtp_create(&srtp_recv, &policy);
1617 if (status)
1618 return status;
1619
1620 /*
1621 * unprotect ciphertext, then compare with plaintext
1622 */
1623 status = srtp_unprotect(srtp_recv, srtp_ciphertext, &len);
1624 if (status || (len != 28))
1625 return status;
1626
1627 if (octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len))
1628 return srtp_err_status_fail;
1629
1630 status = srtp_dealloc(srtp_snd);
1631 if (status)
1632 return status;
1633
1634 status = srtp_dealloc(srtp_recv);
1635 if (status)
1636 return status;
1637
1638 return srtp_err_status_ok;
1639}
1640
Cullen Jennings235513a2005-09-21 22:51:36 +00001641
Joachim Bauch80a45b52015-12-06 22:57:58 +01001642#ifdef OPENSSL
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001643/*
Joachim Bauchfa1e8c22015-11-24 23:38:48 +01001644 * Headers of test vectors taken from RFC 6904, Appendix A
1645 */
1646srtp_err_status_t
1647srtp_validate_encrypted_extensions_headers_gcm() {
1648 unsigned char test_key_ext_headers[30] = {
1649 0xe1, 0xf9, 0x7a, 0x0d, 0x3e, 0x01, 0x8b, 0xe0,
1650 0xd6, 0x4f, 0xa3, 0x2c, 0x06, 0xde, 0x41, 0x39,
1651 0x0e, 0xc6, 0x75, 0xad, 0x49, 0x8a, 0xfe, 0xeb,
1652 0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6
1653 };
1654 uint8_t srtp_plaintext_ref[56] = {
1655 0x90, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1656 0xca, 0xfe, 0xba, 0xbe, 0xBE, 0xDE, 0x00, 0x06,
1657 0x17, 0x41, 0x42, 0x73, 0xA4, 0x75, 0x26, 0x27,
1658 0x48, 0x22, 0x00, 0x00, 0xC8, 0x30, 0x8E, 0x46,
1659 0x55, 0x99, 0x63, 0x86, 0xB3, 0x95, 0xFB, 0x00,
1660 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1661 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab
1662 };
1663 uint8_t srtp_plaintext[64] = {
1664 0x90, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1665 0xca, 0xfe, 0xba, 0xbe, 0xBE, 0xDE, 0x00, 0x06,
1666 0x17, 0x41, 0x42, 0x73, 0xA4, 0x75, 0x26, 0x27,
1667 0x48, 0x22, 0x00, 0x00, 0xC8, 0x30, 0x8E, 0x46,
1668 0x55, 0x99, 0x63, 0x86, 0xB3, 0x95, 0xFB, 0x00,
1669 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1670 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1671 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1672 };
1673 uint8_t srtp_ciphertext[64] = {
1674 0x90, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1675 0xca, 0xfe, 0xba, 0xbe, 0xBE, 0xDE, 0x00, 0x06,
1676 0x17, 0x58, 0x8A, 0x92, 0x70, 0xF4, 0xE1, 0x5E,
1677 0x1C, 0x22, 0x00, 0x00, 0xC8, 0x30, 0x95, 0x46,
1678 0xA9, 0x94, 0xF0, 0xBC, 0x54, 0x78, 0x97, 0x00,
1679 0x0e, 0xca, 0x0c, 0xf9, 0x5e, 0xe9, 0x55, 0xb2,
1680 0x6c, 0xd3, 0xd2, 0x88, 0xb4, 0x9f, 0x6c, 0xa9,
1681 0xbb, 0x4e, 0x15, 0xc2, 0xe9, 0xf2, 0x66, 0x78
1682 };
1683 srtp_t srtp_snd, srtp_recv;
1684 srtp_err_status_t status;
1685 int len;
1686 srtp_policy_t policy;
1687 int headers[3] = {1, 3, 4};
1688
1689 /*
1690 * create a session with a single stream using the default srtp
1691 * policy and with the SSRC value 0xcafebabe
1692 */
1693 memset(&policy, 0, sizeof(policy));
1694 srtp_crypto_policy_set_aes_gcm_128_8_auth(&policy.rtp);
1695 srtp_crypto_policy_set_aes_gcm_128_8_auth(&policy.rtcp);
1696 policy.ssrc.type = ssrc_specific;
1697 policy.ssrc.value = 0xcafebabe;
1698 policy.key = test_key_ext_headers;
1699 policy.ekt = NULL;
1700 policy.window_size = 128;
1701 policy.allow_repeat_tx = 0;
1702 policy.enc_xtn_hdr = headers;
1703 policy.enc_xtn_hdr_count = sizeof(headers) / sizeof(headers[0]);
1704 policy.next = NULL;
1705
1706 status = srtp_create(&srtp_snd, &policy);
1707 if (status)
1708 return status;
1709
1710 /*
1711 * protect plaintext, then compare with ciphertext
1712 */
1713 len = sizeof(srtp_plaintext_ref);
1714 status = srtp_protect(srtp_snd, srtp_plaintext, &len);
1715 if (status || (len != sizeof(srtp_plaintext)))
1716 return srtp_err_status_fail;
1717
1718 debug_print(mod_driver, "ciphertext:\n %s",
1719 srtp_octet_string_hex_string(srtp_plaintext, len));
1720 debug_print(mod_driver, "ciphertext reference:\n %s",
1721 srtp_octet_string_hex_string(srtp_ciphertext, len));
1722
1723 if (octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len))
1724 return srtp_err_status_fail;
1725
1726 /*
1727 * create a receiver session context comparable to the one created
1728 * above - we need to do this so that the replay checking doesn't
1729 * complain
1730 */
1731 status = srtp_create(&srtp_recv, &policy);
1732 if (status)
1733 return status;
1734
1735 /*
1736 * unprotect ciphertext, then compare with plaintext
1737 */
1738 status = srtp_unprotect(srtp_recv, srtp_ciphertext, &len);
1739 if (status || (len != 28))
1740 return status;
1741
1742 if (octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len))
1743 return srtp_err_status_fail;
1744
1745 status = srtp_dealloc(srtp_snd);
1746 if (status)
1747 return status;
1748
1749 status = srtp_dealloc(srtp_recv);
1750 if (status)
1751 return status;
1752
1753 return srtp_err_status_ok;
1754}
Joachim Bauch80a45b52015-12-06 22:57:58 +01001755#endif
Cullen Jennings235513a2005-09-21 22:51:36 +00001756
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001757/*
1758 * srtp_validate_aes_256() verifies the correctness of libsrtp by comparing
1759 * some computed packets against some pre-computed reference values.
1760 * These packets were made with the AES-CM-256/HMAC-SHA-1-80 policy.
1761 */
1762
1763
jfigus857009c2014-11-05 11:17:43 -05001764srtp_err_status_t
jfigus67b9c732014-11-20 10:17:21 -05001765srtp_validate_aes_256 ()
1766{
1767 unsigned char aes_256_test_key[46] = {
1768 0xf0, 0xf0, 0x49, 0x14, 0xb5, 0x13, 0xf2, 0x76,
1769 0x3a, 0x1b, 0x1f, 0xa1, 0x30, 0xf1, 0x0e, 0x29,
1770 0x98, 0xf6, 0xf6, 0xe4, 0x3e, 0x43, 0x09, 0xd1,
1771 0xe6, 0x22, 0xa0, 0xe3, 0x32, 0xb9, 0xf1, 0xb6,
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001772
jfigus67b9c732014-11-20 10:17:21 -05001773 0x3b, 0x04, 0x80, 0x3d, 0xe5, 0x1e, 0xe7, 0xc9,
1774 0x64, 0x23, 0xab, 0x5b, 0x78, 0xd2
1775 };
1776 uint8_t srtp_plaintext_ref[28] = {
1777 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1778 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
1779 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1780 0xab, 0xab, 0xab, 0xab
1781 };
1782 uint8_t srtp_plaintext[38] = {
1783 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1784 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
1785 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1786 0xab, 0xab, 0xab, 0xab, 0x00, 0x00, 0x00, 0x00,
1787 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1788 };
1789 uint8_t srtp_ciphertext[38] = {
1790 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1791 0xca, 0xfe, 0xba, 0xbe, 0xf1, 0xd9, 0xde, 0x17,
1792 0xff, 0x25, 0x1f, 0xf1, 0xaa, 0x00, 0x77, 0x74,
1793 0xb0, 0xb4, 0xb4, 0x0d, 0xa0, 0x8d, 0x9d, 0x9a,
1794 0x5b, 0x3a, 0x55, 0xd8, 0x87, 0x3b
1795 };
1796 srtp_t srtp_snd, srtp_recv;
1797 srtp_err_status_t status;
1798 int len;
1799 srtp_policy_t policy;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001800
jfigus67b9c732014-11-20 10:17:21 -05001801 /*
1802 * create a session with a single stream using the default srtp
1803 * policy and with the SSRC value 0xcafebabe
1804 */
Joachim Bauch99a74822015-11-17 00:08:19 +01001805 memset(&policy, 0, sizeof(policy));
jfigus67b9c732014-11-20 10:17:21 -05001806 srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(&policy.rtp);
1807 srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(&policy.rtcp);
1808 policy.ssrc.type = ssrc_specific;
1809 policy.ssrc.value = 0xcafebabe;
1810 policy.key = aes_256_test_key;
1811 policy.ekt = NULL;
1812 policy.window_size = 128;
1813 policy.allow_repeat_tx = 0;
1814 policy.next = NULL;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001815
jfigus67b9c732014-11-20 10:17:21 -05001816 status = srtp_create(&srtp_snd, &policy);
1817 if (status) {
1818 return status;
1819 }
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001820
jfigus67b9c732014-11-20 10:17:21 -05001821 /*
1822 * protect plaintext, then compare with ciphertext
1823 */
1824 len = 28;
1825 status = srtp_protect(srtp_snd, srtp_plaintext, &len);
1826 if (status || (len != 38)) {
1827 return srtp_err_status_fail;
1828 }
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001829
jfigus67b9c732014-11-20 10:17:21 -05001830 debug_print(mod_driver, "ciphertext:\n %s",
1831 octet_string_hex_string(srtp_plaintext, len));
1832 debug_print(mod_driver, "ciphertext reference:\n %s",
1833 octet_string_hex_string(srtp_ciphertext, len));
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001834
jfigus67b9c732014-11-20 10:17:21 -05001835 if (octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len)) {
1836 return srtp_err_status_fail;
1837 }
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001838
jfigus67b9c732014-11-20 10:17:21 -05001839 /*
1840 * create a receiver session context comparable to the one created
1841 * above - we need to do this so that the replay checking doesn't
1842 * complain
1843 */
1844 status = srtp_create(&srtp_recv, &policy);
1845 if (status) {
1846 return status;
1847 }
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001848
jfigus67b9c732014-11-20 10:17:21 -05001849 /*
1850 * unprotect ciphertext, then compare with plaintext
1851 */
1852 status = srtp_unprotect(srtp_recv, srtp_ciphertext, &len);
1853 if (status || (len != 28)) {
1854 return status;
1855 }
1856
1857 if (octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len)) {
1858 return srtp_err_status_fail;
1859 }
1860
1861 status = srtp_dealloc(srtp_snd);
1862 if (status) {
1863 return status;
1864 }
1865
1866 status = srtp_dealloc(srtp_recv);
1867 if (status) {
1868 return status;
1869 }
1870
1871 return srtp_err_status_ok;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001872}
1873
1874
jfigus857009c2014-11-05 11:17:43 -05001875srtp_err_status_t
jfigus67b9c732014-11-20 10:17:21 -05001876srtp_create_big_policy (srtp_policy_t **list)
1877{
1878 extern const srtp_policy_t *policy_array[];
1879 srtp_policy_t *p, *tmp;
1880 int i = 0;
1881 uint32_t ssrc = 0;
Cullen Jennings235513a2005-09-21 22:51:36 +00001882
jfigus67b9c732014-11-20 10:17:21 -05001883 /* sanity checking */
1884 if ((list == NULL) || (policy_array[0] == NULL)) {
1885 return srtp_err_status_bad_param;
1886 }
Cullen Jennings235513a2005-09-21 22:51:36 +00001887
jfigus67b9c732014-11-20 10:17:21 -05001888 /*
1889 * loop over policy list, mallocing a new list and copying values
1890 * into it (and incrementing the SSRC value as we go along)
1891 */
1892 tmp = NULL;
1893 while (policy_array[i] != NULL) {
1894 p = (srtp_policy_t*)malloc(sizeof(srtp_policy_t));
1895 if (p == NULL) {
1896 return srtp_err_status_bad_param;
1897 }
1898 memcpy(p, policy_array[i], sizeof(srtp_policy_t));
1899 p->ssrc.type = ssrc_specific;
1900 p->ssrc.value = ssrc++;
1901 p->next = tmp;
1902 tmp = p;
1903 i++;
1904 }
1905 *list = p;
1906
1907 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +00001908}
1909
jfigus857009c2014-11-05 11:17:43 -05001910srtp_err_status_t
jfigus67b9c732014-11-20 10:17:21 -05001911srtp_dealloc_big_policy (srtp_policy_t *list)
1912{
1913 srtp_policy_t *p, *next;
Jonathan Lennox80c4c832010-05-17 19:30:28 +00001914
jfigus67b9c732014-11-20 10:17:21 -05001915 for (p = list; p != NULL; p = next) {
1916 next = p->next;
1917 free(p);
1918 }
Jonathan Lennox80c4c832010-05-17 19:30:28 +00001919
jfigus67b9c732014-11-20 10:17:21 -05001920 return srtp_err_status_ok;
Jonathan Lennox80c4c832010-05-17 19:30:28 +00001921}
1922
1923
jfigus857009c2014-11-05 11:17:43 -05001924srtp_err_status_t
jfigus67b9c732014-11-20 10:17:21 -05001925srtp_test_remove_stream ()
1926{
1927 srtp_err_status_t status;
1928 srtp_policy_t *policy_list, policy;
1929 srtp_t session;
1930 srtp_stream_t stream;
Cullen Jennings235513a2005-09-21 22:51:36 +00001931
jfigus67b9c732014-11-20 10:17:21 -05001932 /*
1933 * srtp_get_stream() is a libSRTP internal function that we declare
1934 * here so that we can use it to verify the correct operation of the
1935 * library
1936 */
1937 extern srtp_stream_t srtp_get_stream(srtp_t srtp, uint32_t ssrc);
Cullen Jennings235513a2005-09-21 22:51:36 +00001938
Cullen Jennings235513a2005-09-21 22:51:36 +00001939
jfigus67b9c732014-11-20 10:17:21 -05001940 status = srtp_create_big_policy(&policy_list);
1941 if (status) {
1942 return status;
1943 }
Cullen Jennings235513a2005-09-21 22:51:36 +00001944
jfigus67b9c732014-11-20 10:17:21 -05001945 status = srtp_create(&session, policy_list);
1946 if (status) {
1947 return status;
1948 }
Jonathan Lennox80c4c832010-05-17 19:30:28 +00001949
jfigus67b9c732014-11-20 10:17:21 -05001950 /*
1951 * check for false positives by trying to remove a stream that's not
1952 * in the session
1953 */
1954 status = srtp_remove_stream(session, htonl(0xaaaaaaaa));
1955 if (status != srtp_err_status_no_ctx) {
1956 return srtp_err_status_fail;
1957 }
Jonathan Lennox80c4c832010-05-17 19:30:28 +00001958
jfigus67b9c732014-11-20 10:17:21 -05001959 /*
1960 * check for false negatives by removing stream 0x1, then
1961 * searching for streams 0x0 and 0x2
1962 */
1963 status = srtp_remove_stream(session, htonl(0x1));
1964 if (status != srtp_err_status_ok) {
1965 return srtp_err_status_fail;
1966 }
1967 stream = srtp_get_stream(session, htonl(0x0));
1968 if (stream == NULL) {
1969 return srtp_err_status_fail;
1970 }
1971 stream = srtp_get_stream(session, htonl(0x2));
1972 if (stream == NULL) {
1973 return srtp_err_status_fail;
1974 }
Jonathan Lennoxad741b22010-05-27 19:23:05 +00001975
jfigus67b9c732014-11-20 10:17:21 -05001976 status = srtp_dealloc(session);
1977 if (status != srtp_err_status_ok) {
1978 return status;
1979 }
Jonathan Lennoxad741b22010-05-27 19:23:05 +00001980
jfigus67b9c732014-11-20 10:17:21 -05001981 status = srtp_dealloc_big_policy(policy_list);
1982 if (status != srtp_err_status_ok) {
1983 return status;
1984 }
Jonathan Lennoxad741b22010-05-27 19:23:05 +00001985
jfigus67b9c732014-11-20 10:17:21 -05001986 /* Now test adding and removing a single stream */
Joachim Bauch99a74822015-11-17 00:08:19 +01001987 memset(&policy, 0, sizeof(policy));
jfigus67b9c732014-11-20 10:17:21 -05001988 srtp_crypto_policy_set_rtp_default(&policy.rtp);
1989 srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
1990 policy.ssrc.type = ssrc_specific;
1991 policy.ssrc.value = 0xcafebabe;
1992 policy.key = test_key;
1993 policy.ekt = NULL;
1994 policy.window_size = 128;
1995 policy.allow_repeat_tx = 0;
1996 policy.next = NULL;
Jonathan Lennoxad741b22010-05-27 19:23:05 +00001997
jfigus67b9c732014-11-20 10:17:21 -05001998 status = srtp_create(&session, NULL);
1999 if (status != srtp_err_status_ok) {
2000 return status;
2001 }
2002
2003 status = srtp_add_stream(session, &policy);
2004 if (status != srtp_err_status_ok) {
2005 return status;
2006 }
2007
2008 status = srtp_remove_stream(session, htonl(0xcafebabe));
2009 if (status != srtp_err_status_ok) {
2010 return status;
2011 }
2012
2013 status = srtp_dealloc(session);
2014 if (status != srtp_err_status_ok) {
2015 return status;
2016 }
2017
2018 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +00002019}
2020
Pascal Bühlerbd3112a2015-11-06 20:29:15 +01002021
2022unsigned char test_alt_key[46] = {
2023 0xe5, 0x19, 0x6f, 0x01, 0x5e, 0xf1, 0x9b, 0xe1,
2024 0xd7, 0x47, 0xa7, 0x27, 0x07, 0xd7, 0x47, 0x33,
2025 0x01, 0xc2, 0x35, 0x4d, 0x59, 0x6a, 0xf7, 0x84,
2026 0x96, 0x98, 0xeb, 0xaa, 0xac, 0xf6, 0xa1, 0x45,
2027 0xc7, 0x15, 0xe2, 0xea, 0xfe, 0x55, 0x67, 0x96,
2028 0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6
2029};
2030
2031/*
2032 * srtp_test_update() verifies updating/rekeying exsisting streams.
2033 * As stated in https://tools.ietf.org/html/rfc3711#section-3.3.1
2034 * the value of the ROC must not be reset after a rekey, this test
2035 * atempts to prove that srtp_update does not reset the ROC.
2036 */
2037
2038srtp_err_status_t
2039srtp_test_update() {
2040
2041 srtp_err_status_t status;
2042 uint32_t ssrc = 0x12121212;
2043 int msg_len_octets = 32;
2044 int protected_msg_len_octets;
2045 srtp_hdr_t * msg;
2046 srtp_t srtp_snd, srtp_recv;
2047 srtp_policy_t policy;
2048
Joachim Bauch1b793352015-12-14 21:30:44 +01002049 memset(&policy, 0, sizeof(policy));
Pascal Bühlerbd3112a2015-11-06 20:29:15 +01002050 srtp_crypto_policy_set_rtp_default(&policy.rtp);
2051 srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
2052 policy.ekt = NULL;
2053 policy.window_size = 128;
2054 policy.allow_repeat_tx = 0;
2055 policy.next = NULL;
2056 policy.ssrc.type = ssrc_any_outbound;
2057 policy.key = test_key;
2058
2059 /* create a send and recive ctx with defualt profile and test_key */
2060 status = srtp_create(&srtp_recv, &policy);
2061 if (status)
2062 return status;
2063
2064 policy.ssrc.type = ssrc_any_inbound;
2065 status = srtp_create(&srtp_snd, &policy);
2066 if (status)
2067 return status;
2068
2069 /* protect and unprotect two msg's that will cause the ROC to be equal to 1 */
2070 msg = srtp_create_test_packet(msg_len_octets, ssrc);
2071 if (msg == NULL)
2072 return srtp_err_status_alloc_fail;
2073 msg->seq = htons(65535);
2074
2075 protected_msg_len_octets = msg_len_octets;
2076 status = srtp_protect(srtp_snd, msg, &protected_msg_len_octets);
2077 if (status)
2078 return srtp_err_status_fail;
2079
2080 status = srtp_unprotect(srtp_recv, msg, &protected_msg_len_octets);
2081 if (status)
2082 return status;
2083
2084 free(msg);
2085
2086 msg = srtp_create_test_packet(msg_len_octets, ssrc);
2087 if (msg == NULL)
2088 return srtp_err_status_alloc_fail;
2089 msg->seq = htons(1);
2090
2091 protected_msg_len_octets = msg_len_octets;
2092 status = srtp_protect(srtp_snd, msg, &protected_msg_len_octets);
2093 if (status)
2094 return srtp_err_status_fail;
2095
2096 status = srtp_unprotect(srtp_recv, msg, &protected_msg_len_octets);
2097 if (status)
2098 return status;
2099
2100 free(msg);
2101
2102 /* update send ctx to use test_alt_key */
2103 policy.ssrc.type = ssrc_any_outbound;
2104 policy.key = test_alt_key;
2105 status = srtp_update(srtp_snd, &policy);
2106 if (status)
2107 return status;
2108
2109 /* create and protect msg with new key and ROC still equal to 1 */
2110 msg = srtp_create_test_packet(msg_len_octets, ssrc);
2111 if (msg == NULL)
2112 return srtp_err_status_alloc_fail;
2113 msg->seq = htons(2);
2114
2115 protected_msg_len_octets = msg_len_octets;
2116 status = srtp_protect(srtp_snd, msg, &protected_msg_len_octets);
2117 if (status)
2118 return srtp_err_status_fail;
2119
2120 /* verify that recive ctx will fail to unprotect as it still uses test_key */
2121 status = srtp_unprotect(srtp_recv, msg, &protected_msg_len_octets);
2122 if (status == srtp_err_status_ok)
2123 return srtp_err_status_fail;
2124
2125 /* create a new recvieve ctx with test_alt_key but since it is new it will have ROC equal to 1
2126 * and therefore should fail to unprotected */
2127 {
2128 srtp_t srtp_recv_roc_0;
2129
2130 policy.ssrc.type = ssrc_any_inbound;
2131 policy.key = test_alt_key;
2132 status = srtp_create(&srtp_recv_roc_0, &policy);
2133 if (status)
2134 return status;
2135
2136 status = srtp_unprotect(srtp_recv_roc_0, msg, &protected_msg_len_octets);
2137 if (status == srtp_err_status_ok)
2138 return srtp_err_status_fail;
2139
2140 status = srtp_dealloc(srtp_recv_roc_0);
2141 if (status)
2142 return status;
2143 }
2144
2145 /* update recive ctx to use test_alt_key */
2146 policy.ssrc.type = ssrc_any_inbound;
2147 policy.key = test_alt_key;
2148 status = srtp_update(srtp_recv, &policy);
2149 if (status)
2150 return status;
2151
2152 /* verify that can still unprotect, therfore key is updated and ROC value is preserved */
2153 status = srtp_unprotect(srtp_recv, msg, &protected_msg_len_octets);
2154 if (status)
2155 return status;
2156
2157 free(msg);
2158
2159 status = srtp_dealloc(srtp_snd);
2160 if (status)
2161 return status;
2162
2163 status = srtp_dealloc(srtp_recv);
2164 if (status)
2165 return status;
2166
2167 return srtp_err_status_ok;
2168}
2169
Cullen Jennings235513a2005-09-21 22:51:36 +00002170/*
2171 * srtp policy definitions - these definitions are used above
2172 */
2173
jfigus8c36da22013-10-01 16:41:19 -04002174unsigned char test_key[46] = {
Cullen Jennings235513a2005-09-21 22:51:36 +00002175 0xe1, 0xf9, 0x7a, 0x0d, 0x3e, 0x01, 0x8b, 0xe0,
2176 0xd6, 0x4f, 0xa3, 0x2c, 0x06, 0xde, 0x41, 0x39,
2177 0x0e, 0xc6, 0x75, 0xad, 0x49, 0x8a, 0xfe, 0xeb,
jfigus8c36da22013-10-01 16:41:19 -04002178 0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6, 0xc1, 0x73,
2179 0xc3, 0x17, 0xf2, 0xda, 0xbe, 0x35, 0x77, 0x93,
Cullen Jennings235513a2005-09-21 22:51:36 +00002180 0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6
2181};
2182
2183
2184const srtp_policy_t default_policy = {
jfigus67b9c732014-11-20 10:17:21 -05002185 { ssrc_any_outbound, 0 }, /* SSRC */
2186 { /* SRTP policy */
2187 SRTP_AES_128_ICM, /* cipher type */
2188 30, /* cipher key length in octets */
2189 SRTP_HMAC_SHA1, /* authentication func type */
2190 16, /* auth key length in octets */
2191 10, /* auth tag length in octets */
2192 sec_serv_conf_and_auth /* security services flag */
2193 },
2194 { /* SRTCP policy */
2195 SRTP_AES_128_ICM, /* cipher type */
2196 30, /* cipher key length in octets */
2197 SRTP_HMAC_SHA1, /* authentication func type */
2198 16, /* auth key length in octets */
2199 10, /* auth tag length in octets */
2200 sec_serv_conf_and_auth /* security services flag */
2201 },
2202 test_key,
2203 NULL, /* indicates that EKT is not in use */
2204 128, /* replay window size */
2205 0, /* retransmission not allowed */
Joachim Bauch99a74822015-11-17 00:08:19 +01002206 NULL, /* no encrypted extension headers */
2207 0, /* list of encrypted extension headers is empty */
jfigus67b9c732014-11-20 10:17:21 -05002208 NULL
Cullen Jennings235513a2005-09-21 22:51:36 +00002209};
2210
2211const srtp_policy_t aes_only_policy = {
jfigus67b9c732014-11-20 10:17:21 -05002212 { ssrc_any_outbound, 0 }, /* SSRC */
2213 {
2214 SRTP_AES_128_ICM, /* cipher type */
2215 30, /* cipher key length in octets */
2216 SRTP_NULL_AUTH, /* authentication func type */
2217 0, /* auth key length in octets */
2218 0, /* auth tag length in octets */
2219 sec_serv_conf /* security services flag */
2220 },
2221 {
2222 SRTP_AES_128_ICM, /* cipher type */
2223 30, /* cipher key length in octets */
2224 SRTP_NULL_AUTH, /* authentication func type */
2225 0, /* auth key length in octets */
2226 0, /* auth tag length in octets */
2227 sec_serv_conf /* security services flag */
2228 },
2229 test_key,
2230 NULL, /* indicates that EKT is not in use */
2231 128, /* replay window size */
2232 0, /* retransmission not allowed */
Joachim Bauch99a74822015-11-17 00:08:19 +01002233 NULL, /* no encrypted extension headers */
2234 0, /* list of encrypted extension headers is empty */
jfigus67b9c732014-11-20 10:17:21 -05002235 NULL
Cullen Jennings235513a2005-09-21 22:51:36 +00002236};
2237
2238const srtp_policy_t hmac_only_policy = {
jfigus67b9c732014-11-20 10:17:21 -05002239 { ssrc_any_outbound, 0 }, /* SSRC */
2240 {
2241 SRTP_NULL_CIPHER, /* cipher type */
2242 0, /* cipher key length in octets */
2243 SRTP_HMAC_SHA1, /* authentication func type */
2244 20, /* auth key length in octets */
2245 4, /* auth tag length in octets */
2246 sec_serv_auth /* security services flag */
2247 },
2248 {
2249 SRTP_NULL_CIPHER, /* cipher type */
2250 0, /* cipher key length in octets */
2251 SRTP_HMAC_SHA1, /* authentication func type */
2252 20, /* auth key length in octets */
2253 4, /* auth tag length in octets */
2254 sec_serv_auth /* security services flag */
2255 },
2256 test_key,
2257 NULL, /* indicates that EKT is not in use */
2258 128, /* replay window size */
2259 0, /* retransmission not allowed */
Joachim Bauch99a74822015-11-17 00:08:19 +01002260 NULL, /* no encrypted extension headers */
2261 0, /* list of encrypted extension headers is empty */
jfigus67b9c732014-11-20 10:17:21 -05002262 NULL
Cullen Jennings235513a2005-09-21 22:51:36 +00002263};
2264
jfigus8c36da22013-10-01 16:41:19 -04002265#ifdef OPENSSL
2266const srtp_policy_t aes128_gcm_8_policy = {
jfigus67b9c732014-11-20 10:17:21 -05002267 { ssrc_any_outbound, 0 }, /* SSRC */
2268 { /* SRTP policy */
2269 SRTP_AES_128_GCM, /* cipher type */
2270 SRTP_AES_128_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
2271 SRTP_NULL_AUTH, /* authentication func type */
2272 0, /* auth key length in octets */
2273 8, /* auth tag length in octets */
2274 sec_serv_conf_and_auth /* security services flag */
jfigus8c36da22013-10-01 16:41:19 -04002275 },
jfigus67b9c732014-11-20 10:17:21 -05002276 { /* SRTCP policy */
2277 SRTP_AES_128_GCM, /* cipher type */
2278 SRTP_AES_128_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
2279 SRTP_NULL_AUTH, /* authentication func type */
2280 0, /* auth key length in octets */
2281 8, /* auth tag length in octets */
2282 sec_serv_conf_and_auth /* security services flag */
jfigus8c36da22013-10-01 16:41:19 -04002283 },
2284 test_key,
2285 NULL, /* indicates that EKT is not in use */
2286 128, /* replay window size */
2287 0, /* retransmission not allowed */
Joachim Bauch99a74822015-11-17 00:08:19 +01002288 NULL, /* no encrypted extension headers */
2289 0, /* list of encrypted extension headers is empty */
jfigus8c36da22013-10-01 16:41:19 -04002290 NULL
2291};
2292
2293const srtp_policy_t aes128_gcm_8_cauth_policy = {
jfigus67b9c732014-11-20 10:17:21 -05002294 { ssrc_any_outbound, 0 }, /* SSRC */
2295 { /* SRTP policy */
2296 SRTP_AES_128_GCM, /* cipher type */
2297 SRTP_AES_128_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
2298 SRTP_NULL_AUTH, /* authentication func type */
2299 0, /* auth key length in octets */
2300 8, /* auth tag length in octets */
2301 sec_serv_conf_and_auth /* security services flag */
jfigus8c36da22013-10-01 16:41:19 -04002302 },
jfigus67b9c732014-11-20 10:17:21 -05002303 { /* SRTCP policy */
2304 SRTP_AES_128_GCM, /* cipher type */
2305 SRTP_AES_128_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
2306 SRTP_NULL_AUTH, /* authentication func type */
2307 0, /* auth key length in octets */
2308 8, /* auth tag length in octets */
2309 sec_serv_auth /* security services flag */
jfigus8c36da22013-10-01 16:41:19 -04002310 },
2311 test_key,
2312 NULL, /* indicates that EKT is not in use */
2313 128, /* replay window size */
2314 0, /* retransmission not allowed */
Joachim Bauch99a74822015-11-17 00:08:19 +01002315 NULL, /* no encrypted extension headers */
2316 0, /* list of encrypted extension headers is empty */
jfigus8c36da22013-10-01 16:41:19 -04002317 NULL
2318};
jfigus67b9c732014-11-20 10:17:21 -05002319
jfigus8c36da22013-10-01 16:41:19 -04002320const srtp_policy_t aes256_gcm_8_policy = {
jfigus67b9c732014-11-20 10:17:21 -05002321 { ssrc_any_outbound, 0 }, /* SSRC */
2322 { /* SRTP policy */
2323 SRTP_AES_256_GCM, /* cipher type */
2324 SRTP_AES_256_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
2325 SRTP_NULL_AUTH, /* authentication func type */
2326 0, /* auth key length in octets */
2327 8, /* auth tag length in octets */
2328 sec_serv_conf_and_auth /* security services flag */
jfigus8c36da22013-10-01 16:41:19 -04002329 },
jfigus67b9c732014-11-20 10:17:21 -05002330 { /* SRTCP policy */
2331 SRTP_AES_256_GCM, /* cipher type */
2332 SRTP_AES_256_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
2333 SRTP_NULL_AUTH, /* authentication func type */
2334 0, /* auth key length in octets */
2335 8, /* auth tag length in octets */
2336 sec_serv_conf_and_auth /* security services flag */
jfigus8c36da22013-10-01 16:41:19 -04002337 },
2338 test_key,
2339 NULL, /* indicates that EKT is not in use */
2340 128, /* replay window size */
2341 0, /* retransmission not allowed */
Joachim Bauch99a74822015-11-17 00:08:19 +01002342 NULL, /* no encrypted extension headers */
2343 0, /* list of encrypted extension headers is empty */
jfigus8c36da22013-10-01 16:41:19 -04002344 NULL
2345};
jfigus67b9c732014-11-20 10:17:21 -05002346
jfigus8c36da22013-10-01 16:41:19 -04002347const srtp_policy_t aes256_gcm_8_cauth_policy = {
jfigus67b9c732014-11-20 10:17:21 -05002348 { ssrc_any_outbound, 0 }, /* SSRC */
2349 { /* SRTP policy */
2350 SRTP_AES_256_GCM, /* cipher type */
2351 SRTP_AES_256_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
2352 SRTP_NULL_AUTH, /* authentication func type */
2353 0, /* auth key length in octets */
2354 8, /* auth tag length in octets */
2355 sec_serv_conf_and_auth /* security services flag */
jfigus8c36da22013-10-01 16:41:19 -04002356 },
jfigus67b9c732014-11-20 10:17:21 -05002357 { /* SRTCP policy */
2358 SRTP_AES_256_GCM, /* cipher type */
2359 SRTP_AES_256_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
2360 SRTP_NULL_AUTH, /* authentication func type */
2361 0, /* auth key length in octets */
2362 8, /* auth tag length in octets */
2363 sec_serv_auth /* security services flag */
jfigus8c36da22013-10-01 16:41:19 -04002364 },
2365 test_key,
2366 NULL, /* indicates that EKT is not in use */
2367 128, /* replay window size */
2368 0, /* retransmission not allowed */
Joachim Bauch99a74822015-11-17 00:08:19 +01002369 NULL, /* no encrypted extension headers */
2370 0, /* list of encrypted extension headers is empty */
jfigus8c36da22013-10-01 16:41:19 -04002371 NULL
2372};
2373#endif
2374
Cullen Jennings235513a2005-09-21 22:51:36 +00002375const srtp_policy_t null_policy = {
jfigus67b9c732014-11-20 10:17:21 -05002376 { ssrc_any_outbound, 0 }, /* SSRC */
2377 {
2378 SRTP_NULL_CIPHER, /* cipher type */
2379 0, /* cipher key length in octets */
2380 SRTP_NULL_AUTH, /* authentication func type */
2381 0, /* auth key length in octets */
2382 0, /* auth tag length in octets */
2383 sec_serv_none /* security services flag */
2384 },
2385 {
2386 SRTP_NULL_CIPHER, /* cipher type */
2387 0, /* cipher key length in octets */
2388 SRTP_NULL_AUTH, /* authentication func type */
2389 0, /* auth key length in octets */
2390 0, /* auth tag length in octets */
2391 sec_serv_none /* security services flag */
2392 },
2393 test_key,
2394 NULL, /* indicates that EKT is not in use */
2395 128, /* replay window size */
2396 0, /* retransmission not allowed */
Joachim Bauch99a74822015-11-17 00:08:19 +01002397 NULL, /* no encrypted extension headers */
2398 0, /* list of encrypted extension headers is empty */
jfigus67b9c732014-11-20 10:17:21 -05002399 NULL
David McGrew79870d62007-06-15 18:17:39 +00002400};
2401
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002402unsigned char test_256_key[46] = {
jfigus67b9c732014-11-20 10:17:21 -05002403 0xf0, 0xf0, 0x49, 0x14, 0xb5, 0x13, 0xf2, 0x76,
2404 0x3a, 0x1b, 0x1f, 0xa1, 0x30, 0xf1, 0x0e, 0x29,
2405 0x98, 0xf6, 0xf6, 0xe4, 0x3e, 0x43, 0x09, 0xd1,
2406 0xe6, 0x22, 0xa0, 0xe3, 0x32, 0xb9, 0xf1, 0xb6,
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002407
jfigus67b9c732014-11-20 10:17:21 -05002408 0x3b, 0x04, 0x80, 0x3d, 0xe5, 0x1e, 0xe7, 0xc9,
2409 0x64, 0x23, 0xab, 0x5b, 0x78, 0xd2
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002410};
2411
2412const srtp_policy_t aes_256_hmac_policy = {
jfigus67b9c732014-11-20 10:17:21 -05002413 { ssrc_any_outbound, 0 }, /* SSRC */
2414 { /* SRTP policy */
2415 SRTP_AES_ICM, /* cipher type */
2416 46, /* cipher key length in octets */
2417 SRTP_HMAC_SHA1, /* authentication func type */
2418 20, /* auth key length in octets */
2419 10, /* auth tag length in octets */
2420 sec_serv_conf_and_auth /* security services flag */
2421 },
2422 { /* SRTCP policy */
2423 SRTP_AES_ICM, /* cipher type */
2424 46, /* cipher key length in octets */
2425 SRTP_HMAC_SHA1, /* authentication func type */
2426 20, /* auth key length in octets */
2427 10, /* auth tag length in octets */
2428 sec_serv_conf_and_auth /* security services flag */
2429 },
2430 test_256_key,
2431 NULL, /* indicates that EKT is not in use */
2432 128, /* replay window size */
2433 0, /* retransmission not allowed */
Joachim Bauch99a74822015-11-17 00:08:19 +01002434 NULL, /* no encrypted extension headers */
2435 0, /* list of encrypted extension headers is empty */
jfigus67b9c732014-11-20 10:17:21 -05002436 NULL
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002437};
2438
David McGrew79870d62007-06-15 18:17:39 +00002439uint8_t ekt_test_key[16] = {
jfigus67b9c732014-11-20 10:17:21 -05002440 0x77, 0x26, 0x9d, 0xac, 0x16, 0xa3, 0x28, 0xca,
2441 0x8e, 0xc9, 0x68, 0x4b, 0xcc, 0xc4, 0xd2, 0x1b
David McGrew79870d62007-06-15 18:17:39 +00002442};
2443
2444#include "ekt.h"
2445
jfigusc5887e72014-11-06 09:46:18 -05002446srtp_ekt_policy_ctx_t ekt_test_policy = {
jfigus67b9c732014-11-20 10:17:21 -05002447 0xa5a5, /* SPI */
2448 SRTP_EKT_CIPHER_AES_128_ECB,
2449 ekt_test_key,
2450 NULL
David McGrew79870d62007-06-15 18:17:39 +00002451};
2452
2453const srtp_policy_t hmac_only_with_ekt_policy = {
jfigus67b9c732014-11-20 10:17:21 -05002454 { ssrc_any_outbound, 0 }, /* SSRC */
2455 {
2456 SRTP_NULL_CIPHER, /* cipher type */
2457 0, /* cipher key length in octets */
2458 SRTP_HMAC_SHA1, /* authentication func type */
2459 20, /* auth key length in octets */
2460 4, /* auth tag length in octets */
2461 sec_serv_auth /* security services flag */
2462 },
2463 {
2464 SRTP_NULL_CIPHER, /* cipher type */
2465 0, /* cipher key length in octets */
2466 SRTP_HMAC_SHA1, /* authentication func type */
2467 20, /* auth key length in octets */
2468 4, /* auth tag length in octets */
2469 sec_serv_auth /* security services flag */
2470 },
2471 test_key,
2472 &ekt_test_policy, /* indicates that EKT is not in use */
2473 128, /* replay window size */
2474 0, /* retransmission not allowed */
Joachim Bauch99a74822015-11-17 00:08:19 +01002475 NULL, /* no encrypted extension headers */
2476 0, /* list of encrypted extension headers is empty */
jfigus67b9c732014-11-20 10:17:21 -05002477 NULL
Cullen Jennings235513a2005-09-21 22:51:36 +00002478};
2479
2480
2481/*
2482 * an array of pointers to the policies listed above
2483 *
2484 * This array is used to test various aspects of libSRTP for
2485 * different cryptographic policies. The order of the elements
2486 * matters - the timing test generates output that can be used
jfigus67b9c732014-11-20 10:17:21 -05002487 * in a plot (see the gnuplot script file 'timing'). If you
Cullen Jennings235513a2005-09-21 22:51:36 +00002488 * add to this list, you should do it at the end.
2489 */
2490
Cullen Jennings235513a2005-09-21 22:51:36 +00002491const srtp_policy_t *
2492policy_array[] = {
jfigus67b9c732014-11-20 10:17:21 -05002493 &hmac_only_policy,
2494 &aes_only_policy,
2495 &default_policy,
jfigus8c36da22013-10-01 16:41:19 -04002496#ifdef OPENSSL
jfigus67b9c732014-11-20 10:17:21 -05002497 &aes128_gcm_8_policy,
2498 &aes128_gcm_8_cauth_policy,
2499 &aes256_gcm_8_policy,
2500 &aes256_gcm_8_cauth_policy,
jfigus8c36da22013-10-01 16:41:19 -04002501#endif
jfigus67b9c732014-11-20 10:17:21 -05002502 &null_policy,
2503 &aes_256_hmac_policy,
2504 &hmac_only_with_ekt_policy,
2505 NULL
Cullen Jennings235513a2005-09-21 22:51:36 +00002506};
2507
2508const srtp_policy_t wildcard_policy = {
jfigus67b9c732014-11-20 10:17:21 -05002509 { ssrc_any_outbound, 0 }, /* SSRC */
2510 { /* SRTP policy */
2511 SRTP_AES_128_ICM, /* cipher type */
2512 30, /* cipher key length in octets */
2513 SRTP_HMAC_SHA1, /* authentication func type */
2514 16, /* auth key length in octets */
2515 10, /* auth tag length in octets */
2516 sec_serv_conf_and_auth /* security services flag */
2517 },
2518 { /* SRTCP policy */
2519 SRTP_AES_128_ICM, /* cipher type */
2520 30, /* cipher key length in octets */
2521 SRTP_HMAC_SHA1, /* authentication func type */
2522 16, /* auth key length in octets */
2523 10, /* auth tag length in octets */
2524 sec_serv_conf_and_auth /* security services flag */
2525 },
2526 test_key,
2527 NULL,
2528 128, /* replay window size */
2529 0, /* retransmission not allowed */
Joachim Bauch99a74822015-11-17 00:08:19 +01002530 NULL, /* no encrypted extension headers */
2531 0, /* list of encrypted extension headers is empty */
jfigus67b9c732014-11-20 10:17:21 -05002532 NULL
Cullen Jennings235513a2005-09-21 22:51:36 +00002533};