blob: 0e6efa3567969b33a3d9140c75a1fba214e1ff68 [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);
Joachim Baucha9ecefe2015-12-14 21:40:42 +01001624 if (status) {
Joachim Bauch99a74822015-11-17 00:08:19 +01001625 return status;
Joachim Baucha9ecefe2015-12-14 21:40:42 +01001626 } else if (len != sizeof(srtp_plaintext_ref)) {
1627 return srtp_err_status_fail;
1628 }
Joachim Bauch99a74822015-11-17 00:08:19 +01001629
1630 if (octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len))
1631 return srtp_err_status_fail;
1632
1633 status = srtp_dealloc(srtp_snd);
1634 if (status)
1635 return status;
1636
1637 status = srtp_dealloc(srtp_recv);
1638 if (status)
1639 return status;
1640
1641 return srtp_err_status_ok;
1642}
1643
Cullen Jennings235513a2005-09-21 22:51:36 +00001644
Joachim Bauch80a45b52015-12-06 22:57:58 +01001645#ifdef OPENSSL
Joachim Baucha9ecefe2015-12-14 21:40:42 +01001646
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001647/*
Joachim Bauchfa1e8c22015-11-24 23:38:48 +01001648 * Headers of test vectors taken from RFC 6904, Appendix A
1649 */
1650srtp_err_status_t
1651srtp_validate_encrypted_extensions_headers_gcm() {
1652 unsigned char test_key_ext_headers[30] = {
1653 0xe1, 0xf9, 0x7a, 0x0d, 0x3e, 0x01, 0x8b, 0xe0,
1654 0xd6, 0x4f, 0xa3, 0x2c, 0x06, 0xde, 0x41, 0x39,
1655 0x0e, 0xc6, 0x75, 0xad, 0x49, 0x8a, 0xfe, 0xeb,
1656 0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6
1657 };
1658 uint8_t srtp_plaintext_ref[56] = {
1659 0x90, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1660 0xca, 0xfe, 0xba, 0xbe, 0xBE, 0xDE, 0x00, 0x06,
1661 0x17, 0x41, 0x42, 0x73, 0xA4, 0x75, 0x26, 0x27,
1662 0x48, 0x22, 0x00, 0x00, 0xC8, 0x30, 0x8E, 0x46,
1663 0x55, 0x99, 0x63, 0x86, 0xB3, 0x95, 0xFB, 0x00,
1664 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1665 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab
1666 };
1667 uint8_t srtp_plaintext[64] = {
1668 0x90, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1669 0xca, 0xfe, 0xba, 0xbe, 0xBE, 0xDE, 0x00, 0x06,
1670 0x17, 0x41, 0x42, 0x73, 0xA4, 0x75, 0x26, 0x27,
1671 0x48, 0x22, 0x00, 0x00, 0xC8, 0x30, 0x8E, 0x46,
1672 0x55, 0x99, 0x63, 0x86, 0xB3, 0x95, 0xFB, 0x00,
1673 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1674 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1675 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1676 };
1677 uint8_t srtp_ciphertext[64] = {
1678 0x90, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1679 0xca, 0xfe, 0xba, 0xbe, 0xBE, 0xDE, 0x00, 0x06,
1680 0x17, 0x58, 0x8A, 0x92, 0x70, 0xF4, 0xE1, 0x5E,
1681 0x1C, 0x22, 0x00, 0x00, 0xC8, 0x30, 0x95, 0x46,
1682 0xA9, 0x94, 0xF0, 0xBC, 0x54, 0x78, 0x97, 0x00,
1683 0x0e, 0xca, 0x0c, 0xf9, 0x5e, 0xe9, 0x55, 0xb2,
1684 0x6c, 0xd3, 0xd2, 0x88, 0xb4, 0x9f, 0x6c, 0xa9,
1685 0xbb, 0x4e, 0x15, 0xc2, 0xe9, 0xf2, 0x66, 0x78
1686 };
1687 srtp_t srtp_snd, srtp_recv;
1688 srtp_err_status_t status;
1689 int len;
1690 srtp_policy_t policy;
1691 int headers[3] = {1, 3, 4};
1692
1693 /*
1694 * create a session with a single stream using the default srtp
1695 * policy and with the SSRC value 0xcafebabe
1696 */
1697 memset(&policy, 0, sizeof(policy));
1698 srtp_crypto_policy_set_aes_gcm_128_8_auth(&policy.rtp);
1699 srtp_crypto_policy_set_aes_gcm_128_8_auth(&policy.rtcp);
1700 policy.ssrc.type = ssrc_specific;
1701 policy.ssrc.value = 0xcafebabe;
1702 policy.key = test_key_ext_headers;
1703 policy.ekt = NULL;
1704 policy.window_size = 128;
1705 policy.allow_repeat_tx = 0;
1706 policy.enc_xtn_hdr = headers;
1707 policy.enc_xtn_hdr_count = sizeof(headers) / sizeof(headers[0]);
1708 policy.next = NULL;
1709
1710 status = srtp_create(&srtp_snd, &policy);
1711 if (status)
1712 return status;
1713
1714 /*
1715 * protect plaintext, then compare with ciphertext
1716 */
1717 len = sizeof(srtp_plaintext_ref);
1718 status = srtp_protect(srtp_snd, srtp_plaintext, &len);
1719 if (status || (len != sizeof(srtp_plaintext)))
1720 return srtp_err_status_fail;
1721
1722 debug_print(mod_driver, "ciphertext:\n %s",
1723 srtp_octet_string_hex_string(srtp_plaintext, len));
1724 debug_print(mod_driver, "ciphertext reference:\n %s",
1725 srtp_octet_string_hex_string(srtp_ciphertext, len));
1726
1727 if (octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len))
1728 return srtp_err_status_fail;
1729
1730 /*
1731 * create a receiver session context comparable to the one created
1732 * above - we need to do this so that the replay checking doesn't
1733 * complain
1734 */
1735 status = srtp_create(&srtp_recv, &policy);
1736 if (status)
1737 return status;
1738
1739 /*
1740 * unprotect ciphertext, then compare with plaintext
1741 */
1742 status = srtp_unprotect(srtp_recv, srtp_ciphertext, &len);
Joachim Baucha9ecefe2015-12-14 21:40:42 +01001743 if (status) {
Joachim Bauchfa1e8c22015-11-24 23:38:48 +01001744 return status;
Joachim Baucha9ecefe2015-12-14 21:40:42 +01001745 } else if (len != sizeof(srtp_plaintext_ref)) {
1746 return srtp_err_status_fail;
1747 }
Joachim Bauchfa1e8c22015-11-24 23:38:48 +01001748
1749 if (octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len))
1750 return srtp_err_status_fail;
1751
1752 status = srtp_dealloc(srtp_snd);
1753 if (status)
1754 return status;
1755
1756 status = srtp_dealloc(srtp_recv);
1757 if (status)
1758 return status;
1759
1760 return srtp_err_status_ok;
1761}
Joachim Bauch80a45b52015-12-06 22:57:58 +01001762#endif
Cullen Jennings235513a2005-09-21 22:51:36 +00001763
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001764/*
1765 * srtp_validate_aes_256() verifies the correctness of libsrtp by comparing
1766 * some computed packets against some pre-computed reference values.
1767 * These packets were made with the AES-CM-256/HMAC-SHA-1-80 policy.
1768 */
1769
1770
jfigus857009c2014-11-05 11:17:43 -05001771srtp_err_status_t
jfigus67b9c732014-11-20 10:17:21 -05001772srtp_validate_aes_256 ()
1773{
1774 unsigned char aes_256_test_key[46] = {
1775 0xf0, 0xf0, 0x49, 0x14, 0xb5, 0x13, 0xf2, 0x76,
1776 0x3a, 0x1b, 0x1f, 0xa1, 0x30, 0xf1, 0x0e, 0x29,
1777 0x98, 0xf6, 0xf6, 0xe4, 0x3e, 0x43, 0x09, 0xd1,
1778 0xe6, 0x22, 0xa0, 0xe3, 0x32, 0xb9, 0xf1, 0xb6,
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001779
jfigus67b9c732014-11-20 10:17:21 -05001780 0x3b, 0x04, 0x80, 0x3d, 0xe5, 0x1e, 0xe7, 0xc9,
1781 0x64, 0x23, 0xab, 0x5b, 0x78, 0xd2
1782 };
1783 uint8_t srtp_plaintext_ref[28] = {
1784 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1785 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
1786 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1787 0xab, 0xab, 0xab, 0xab
1788 };
1789 uint8_t srtp_plaintext[38] = {
1790 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1791 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
1792 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1793 0xab, 0xab, 0xab, 0xab, 0x00, 0x00, 0x00, 0x00,
1794 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1795 };
1796 uint8_t srtp_ciphertext[38] = {
1797 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1798 0xca, 0xfe, 0xba, 0xbe, 0xf1, 0xd9, 0xde, 0x17,
1799 0xff, 0x25, 0x1f, 0xf1, 0xaa, 0x00, 0x77, 0x74,
1800 0xb0, 0xb4, 0xb4, 0x0d, 0xa0, 0x8d, 0x9d, 0x9a,
1801 0x5b, 0x3a, 0x55, 0xd8, 0x87, 0x3b
1802 };
1803 srtp_t srtp_snd, srtp_recv;
1804 srtp_err_status_t status;
1805 int len;
1806 srtp_policy_t policy;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001807
jfigus67b9c732014-11-20 10:17:21 -05001808 /*
1809 * create a session with a single stream using the default srtp
1810 * policy and with the SSRC value 0xcafebabe
1811 */
Joachim Bauch99a74822015-11-17 00:08:19 +01001812 memset(&policy, 0, sizeof(policy));
jfigus67b9c732014-11-20 10:17:21 -05001813 srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(&policy.rtp);
1814 srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(&policy.rtcp);
1815 policy.ssrc.type = ssrc_specific;
1816 policy.ssrc.value = 0xcafebabe;
1817 policy.key = aes_256_test_key;
1818 policy.ekt = NULL;
1819 policy.window_size = 128;
1820 policy.allow_repeat_tx = 0;
1821 policy.next = NULL;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001822
jfigus67b9c732014-11-20 10:17:21 -05001823 status = srtp_create(&srtp_snd, &policy);
1824 if (status) {
1825 return status;
1826 }
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001827
jfigus67b9c732014-11-20 10:17:21 -05001828 /*
1829 * protect plaintext, then compare with ciphertext
1830 */
1831 len = 28;
1832 status = srtp_protect(srtp_snd, srtp_plaintext, &len);
1833 if (status || (len != 38)) {
1834 return srtp_err_status_fail;
1835 }
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001836
jfigus67b9c732014-11-20 10:17:21 -05001837 debug_print(mod_driver, "ciphertext:\n %s",
1838 octet_string_hex_string(srtp_plaintext, len));
1839 debug_print(mod_driver, "ciphertext reference:\n %s",
1840 octet_string_hex_string(srtp_ciphertext, len));
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001841
jfigus67b9c732014-11-20 10:17:21 -05001842 if (octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len)) {
1843 return srtp_err_status_fail;
1844 }
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001845
jfigus67b9c732014-11-20 10:17:21 -05001846 /*
1847 * create a receiver session context comparable to the one created
1848 * above - we need to do this so that the replay checking doesn't
1849 * complain
1850 */
1851 status = srtp_create(&srtp_recv, &policy);
1852 if (status) {
1853 return status;
1854 }
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001855
jfigus67b9c732014-11-20 10:17:21 -05001856 /*
1857 * unprotect ciphertext, then compare with plaintext
1858 */
1859 status = srtp_unprotect(srtp_recv, srtp_ciphertext, &len);
1860 if (status || (len != 28)) {
1861 return status;
1862 }
1863
1864 if (octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len)) {
1865 return srtp_err_status_fail;
1866 }
1867
1868 status = srtp_dealloc(srtp_snd);
1869 if (status) {
1870 return status;
1871 }
1872
1873 status = srtp_dealloc(srtp_recv);
1874 if (status) {
1875 return status;
1876 }
1877
1878 return srtp_err_status_ok;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001879}
1880
1881
jfigus857009c2014-11-05 11:17:43 -05001882srtp_err_status_t
jfigus67b9c732014-11-20 10:17:21 -05001883srtp_create_big_policy (srtp_policy_t **list)
1884{
1885 extern const srtp_policy_t *policy_array[];
1886 srtp_policy_t *p, *tmp;
1887 int i = 0;
1888 uint32_t ssrc = 0;
Cullen Jennings235513a2005-09-21 22:51:36 +00001889
jfigus67b9c732014-11-20 10:17:21 -05001890 /* sanity checking */
1891 if ((list == NULL) || (policy_array[0] == NULL)) {
1892 return srtp_err_status_bad_param;
1893 }
Cullen Jennings235513a2005-09-21 22:51:36 +00001894
jfigus67b9c732014-11-20 10:17:21 -05001895 /*
1896 * loop over policy list, mallocing a new list and copying values
1897 * into it (and incrementing the SSRC value as we go along)
1898 */
1899 tmp = NULL;
1900 while (policy_array[i] != NULL) {
1901 p = (srtp_policy_t*)malloc(sizeof(srtp_policy_t));
1902 if (p == NULL) {
1903 return srtp_err_status_bad_param;
1904 }
1905 memcpy(p, policy_array[i], sizeof(srtp_policy_t));
1906 p->ssrc.type = ssrc_specific;
1907 p->ssrc.value = ssrc++;
1908 p->next = tmp;
1909 tmp = p;
1910 i++;
1911 }
1912 *list = p;
1913
1914 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +00001915}
1916
jfigus857009c2014-11-05 11:17:43 -05001917srtp_err_status_t
jfigus67b9c732014-11-20 10:17:21 -05001918srtp_dealloc_big_policy (srtp_policy_t *list)
1919{
1920 srtp_policy_t *p, *next;
Jonathan Lennox80c4c832010-05-17 19:30:28 +00001921
jfigus67b9c732014-11-20 10:17:21 -05001922 for (p = list; p != NULL; p = next) {
1923 next = p->next;
1924 free(p);
1925 }
Jonathan Lennox80c4c832010-05-17 19:30:28 +00001926
jfigus67b9c732014-11-20 10:17:21 -05001927 return srtp_err_status_ok;
Jonathan Lennox80c4c832010-05-17 19:30:28 +00001928}
1929
1930
jfigus857009c2014-11-05 11:17:43 -05001931srtp_err_status_t
jfigus67b9c732014-11-20 10:17:21 -05001932srtp_test_remove_stream ()
1933{
1934 srtp_err_status_t status;
1935 srtp_policy_t *policy_list, policy;
1936 srtp_t session;
1937 srtp_stream_t stream;
Cullen Jennings235513a2005-09-21 22:51:36 +00001938
jfigus67b9c732014-11-20 10:17:21 -05001939 /*
1940 * srtp_get_stream() is a libSRTP internal function that we declare
1941 * here so that we can use it to verify the correct operation of the
1942 * library
1943 */
1944 extern srtp_stream_t srtp_get_stream(srtp_t srtp, uint32_t ssrc);
Cullen Jennings235513a2005-09-21 22:51:36 +00001945
Cullen Jennings235513a2005-09-21 22:51:36 +00001946
jfigus67b9c732014-11-20 10:17:21 -05001947 status = srtp_create_big_policy(&policy_list);
1948 if (status) {
1949 return status;
1950 }
Cullen Jennings235513a2005-09-21 22:51:36 +00001951
jfigus67b9c732014-11-20 10:17:21 -05001952 status = srtp_create(&session, policy_list);
1953 if (status) {
1954 return status;
1955 }
Jonathan Lennox80c4c832010-05-17 19:30:28 +00001956
jfigus67b9c732014-11-20 10:17:21 -05001957 /*
1958 * check for false positives by trying to remove a stream that's not
1959 * in the session
1960 */
1961 status = srtp_remove_stream(session, htonl(0xaaaaaaaa));
1962 if (status != srtp_err_status_no_ctx) {
1963 return srtp_err_status_fail;
1964 }
Jonathan Lennox80c4c832010-05-17 19:30:28 +00001965
jfigus67b9c732014-11-20 10:17:21 -05001966 /*
1967 * check for false negatives by removing stream 0x1, then
1968 * searching for streams 0x0 and 0x2
1969 */
1970 status = srtp_remove_stream(session, htonl(0x1));
1971 if (status != srtp_err_status_ok) {
1972 return srtp_err_status_fail;
1973 }
1974 stream = srtp_get_stream(session, htonl(0x0));
1975 if (stream == NULL) {
1976 return srtp_err_status_fail;
1977 }
1978 stream = srtp_get_stream(session, htonl(0x2));
1979 if (stream == NULL) {
1980 return srtp_err_status_fail;
1981 }
Jonathan Lennoxad741b22010-05-27 19:23:05 +00001982
jfigus67b9c732014-11-20 10:17:21 -05001983 status = srtp_dealloc(session);
1984 if (status != srtp_err_status_ok) {
1985 return status;
1986 }
Jonathan Lennoxad741b22010-05-27 19:23:05 +00001987
jfigus67b9c732014-11-20 10:17:21 -05001988 status = srtp_dealloc_big_policy(policy_list);
1989 if (status != srtp_err_status_ok) {
1990 return status;
1991 }
Jonathan Lennoxad741b22010-05-27 19:23:05 +00001992
jfigus67b9c732014-11-20 10:17:21 -05001993 /* Now test adding and removing a single stream */
Joachim Bauch99a74822015-11-17 00:08:19 +01001994 memset(&policy, 0, sizeof(policy));
jfigus67b9c732014-11-20 10:17:21 -05001995 srtp_crypto_policy_set_rtp_default(&policy.rtp);
1996 srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
1997 policy.ssrc.type = ssrc_specific;
1998 policy.ssrc.value = 0xcafebabe;
1999 policy.key = test_key;
2000 policy.ekt = NULL;
2001 policy.window_size = 128;
2002 policy.allow_repeat_tx = 0;
2003 policy.next = NULL;
Jonathan Lennoxad741b22010-05-27 19:23:05 +00002004
jfigus67b9c732014-11-20 10:17:21 -05002005 status = srtp_create(&session, NULL);
2006 if (status != srtp_err_status_ok) {
2007 return status;
2008 }
2009
2010 status = srtp_add_stream(session, &policy);
2011 if (status != srtp_err_status_ok) {
2012 return status;
2013 }
2014
2015 status = srtp_remove_stream(session, htonl(0xcafebabe));
2016 if (status != srtp_err_status_ok) {
2017 return status;
2018 }
2019
2020 status = srtp_dealloc(session);
2021 if (status != srtp_err_status_ok) {
2022 return status;
2023 }
2024
2025 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +00002026}
2027
Pascal Bühlerbd3112a2015-11-06 20:29:15 +01002028
2029unsigned char test_alt_key[46] = {
2030 0xe5, 0x19, 0x6f, 0x01, 0x5e, 0xf1, 0x9b, 0xe1,
2031 0xd7, 0x47, 0xa7, 0x27, 0x07, 0xd7, 0x47, 0x33,
2032 0x01, 0xc2, 0x35, 0x4d, 0x59, 0x6a, 0xf7, 0x84,
2033 0x96, 0x98, 0xeb, 0xaa, 0xac, 0xf6, 0xa1, 0x45,
2034 0xc7, 0x15, 0xe2, 0xea, 0xfe, 0x55, 0x67, 0x96,
2035 0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6
2036};
2037
2038/*
2039 * srtp_test_update() verifies updating/rekeying exsisting streams.
2040 * As stated in https://tools.ietf.org/html/rfc3711#section-3.3.1
2041 * the value of the ROC must not be reset after a rekey, this test
2042 * atempts to prove that srtp_update does not reset the ROC.
2043 */
2044
2045srtp_err_status_t
2046srtp_test_update() {
2047
2048 srtp_err_status_t status;
2049 uint32_t ssrc = 0x12121212;
2050 int msg_len_octets = 32;
2051 int protected_msg_len_octets;
2052 srtp_hdr_t * msg;
2053 srtp_t srtp_snd, srtp_recv;
2054 srtp_policy_t policy;
2055
Joachim Bauch1b793352015-12-14 21:30:44 +01002056 memset(&policy, 0, sizeof(policy));
Pascal Bühlerbd3112a2015-11-06 20:29:15 +01002057 srtp_crypto_policy_set_rtp_default(&policy.rtp);
2058 srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
2059 policy.ekt = NULL;
2060 policy.window_size = 128;
2061 policy.allow_repeat_tx = 0;
2062 policy.next = NULL;
2063 policy.ssrc.type = ssrc_any_outbound;
2064 policy.key = test_key;
2065
2066 /* create a send and recive ctx with defualt profile and test_key */
2067 status = srtp_create(&srtp_recv, &policy);
2068 if (status)
2069 return status;
2070
2071 policy.ssrc.type = ssrc_any_inbound;
2072 status = srtp_create(&srtp_snd, &policy);
2073 if (status)
2074 return status;
2075
2076 /* protect and unprotect two msg's that will cause the ROC to be equal to 1 */
2077 msg = srtp_create_test_packet(msg_len_octets, ssrc);
2078 if (msg == NULL)
2079 return srtp_err_status_alloc_fail;
2080 msg->seq = htons(65535);
2081
2082 protected_msg_len_octets = msg_len_octets;
2083 status = srtp_protect(srtp_snd, msg, &protected_msg_len_octets);
2084 if (status)
2085 return srtp_err_status_fail;
2086
2087 status = srtp_unprotect(srtp_recv, msg, &protected_msg_len_octets);
2088 if (status)
2089 return status;
2090
2091 free(msg);
2092
2093 msg = srtp_create_test_packet(msg_len_octets, ssrc);
2094 if (msg == NULL)
2095 return srtp_err_status_alloc_fail;
2096 msg->seq = htons(1);
2097
2098 protected_msg_len_octets = msg_len_octets;
2099 status = srtp_protect(srtp_snd, msg, &protected_msg_len_octets);
2100 if (status)
2101 return srtp_err_status_fail;
2102
2103 status = srtp_unprotect(srtp_recv, msg, &protected_msg_len_octets);
2104 if (status)
2105 return status;
2106
2107 free(msg);
2108
2109 /* update send ctx to use test_alt_key */
2110 policy.ssrc.type = ssrc_any_outbound;
2111 policy.key = test_alt_key;
2112 status = srtp_update(srtp_snd, &policy);
2113 if (status)
2114 return status;
2115
2116 /* create and protect msg with new key and ROC still equal to 1 */
2117 msg = srtp_create_test_packet(msg_len_octets, ssrc);
2118 if (msg == NULL)
2119 return srtp_err_status_alloc_fail;
2120 msg->seq = htons(2);
2121
2122 protected_msg_len_octets = msg_len_octets;
2123 status = srtp_protect(srtp_snd, msg, &protected_msg_len_octets);
2124 if (status)
2125 return srtp_err_status_fail;
2126
2127 /* verify that recive ctx will fail to unprotect as it still uses test_key */
2128 status = srtp_unprotect(srtp_recv, msg, &protected_msg_len_octets);
2129 if (status == srtp_err_status_ok)
2130 return srtp_err_status_fail;
2131
2132 /* create a new recvieve ctx with test_alt_key but since it is new it will have ROC equal to 1
2133 * and therefore should fail to unprotected */
2134 {
2135 srtp_t srtp_recv_roc_0;
2136
2137 policy.ssrc.type = ssrc_any_inbound;
2138 policy.key = test_alt_key;
2139 status = srtp_create(&srtp_recv_roc_0, &policy);
2140 if (status)
2141 return status;
2142
2143 status = srtp_unprotect(srtp_recv_roc_0, msg, &protected_msg_len_octets);
2144 if (status == srtp_err_status_ok)
2145 return srtp_err_status_fail;
2146
2147 status = srtp_dealloc(srtp_recv_roc_0);
2148 if (status)
2149 return status;
2150 }
2151
2152 /* update recive ctx to use test_alt_key */
2153 policy.ssrc.type = ssrc_any_inbound;
2154 policy.key = test_alt_key;
2155 status = srtp_update(srtp_recv, &policy);
2156 if (status)
2157 return status;
2158
2159 /* verify that can still unprotect, therfore key is updated and ROC value is preserved */
2160 status = srtp_unprotect(srtp_recv, msg, &protected_msg_len_octets);
2161 if (status)
2162 return status;
2163
2164 free(msg);
2165
2166 status = srtp_dealloc(srtp_snd);
2167 if (status)
2168 return status;
2169
2170 status = srtp_dealloc(srtp_recv);
2171 if (status)
2172 return status;
2173
2174 return srtp_err_status_ok;
2175}
2176
Cullen Jennings235513a2005-09-21 22:51:36 +00002177/*
2178 * srtp policy definitions - these definitions are used above
2179 */
2180
jfigus8c36da22013-10-01 16:41:19 -04002181unsigned char test_key[46] = {
Cullen Jennings235513a2005-09-21 22:51:36 +00002182 0xe1, 0xf9, 0x7a, 0x0d, 0x3e, 0x01, 0x8b, 0xe0,
2183 0xd6, 0x4f, 0xa3, 0x2c, 0x06, 0xde, 0x41, 0x39,
2184 0x0e, 0xc6, 0x75, 0xad, 0x49, 0x8a, 0xfe, 0xeb,
jfigus8c36da22013-10-01 16:41:19 -04002185 0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6, 0xc1, 0x73,
2186 0xc3, 0x17, 0xf2, 0xda, 0xbe, 0x35, 0x77, 0x93,
Cullen Jennings235513a2005-09-21 22:51:36 +00002187 0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6
2188};
2189
2190
2191const srtp_policy_t default_policy = {
jfigus67b9c732014-11-20 10:17:21 -05002192 { ssrc_any_outbound, 0 }, /* SSRC */
2193 { /* SRTP policy */
2194 SRTP_AES_128_ICM, /* cipher type */
2195 30, /* cipher key length in octets */
2196 SRTP_HMAC_SHA1, /* authentication func type */
2197 16, /* auth key length in octets */
2198 10, /* auth tag length in octets */
2199 sec_serv_conf_and_auth /* security services flag */
2200 },
2201 { /* SRTCP policy */
2202 SRTP_AES_128_ICM, /* cipher type */
2203 30, /* cipher key length in octets */
2204 SRTP_HMAC_SHA1, /* authentication func type */
2205 16, /* auth key length in octets */
2206 10, /* auth tag length in octets */
2207 sec_serv_conf_and_auth /* security services flag */
2208 },
2209 test_key,
2210 NULL, /* indicates that EKT is not in use */
2211 128, /* replay window size */
2212 0, /* retransmission not allowed */
Joachim Bauch99a74822015-11-17 00:08:19 +01002213 NULL, /* no encrypted extension headers */
2214 0, /* list of encrypted extension headers is empty */
jfigus67b9c732014-11-20 10:17:21 -05002215 NULL
Cullen Jennings235513a2005-09-21 22:51:36 +00002216};
2217
2218const srtp_policy_t aes_only_policy = {
jfigus67b9c732014-11-20 10:17:21 -05002219 { ssrc_any_outbound, 0 }, /* SSRC */
2220 {
2221 SRTP_AES_128_ICM, /* cipher type */
2222 30, /* cipher key length in octets */
2223 SRTP_NULL_AUTH, /* authentication func type */
2224 0, /* auth key length in octets */
2225 0, /* auth tag length in octets */
2226 sec_serv_conf /* security services flag */
2227 },
2228 {
2229 SRTP_AES_128_ICM, /* cipher type */
2230 30, /* cipher key length in octets */
2231 SRTP_NULL_AUTH, /* authentication func type */
2232 0, /* auth key length in octets */
2233 0, /* auth tag length in octets */
2234 sec_serv_conf /* security services flag */
2235 },
2236 test_key,
2237 NULL, /* indicates that EKT is not in use */
2238 128, /* replay window size */
2239 0, /* retransmission not allowed */
Joachim Bauch99a74822015-11-17 00:08:19 +01002240 NULL, /* no encrypted extension headers */
2241 0, /* list of encrypted extension headers is empty */
jfigus67b9c732014-11-20 10:17:21 -05002242 NULL
Cullen Jennings235513a2005-09-21 22:51:36 +00002243};
2244
2245const srtp_policy_t hmac_only_policy = {
jfigus67b9c732014-11-20 10:17:21 -05002246 { ssrc_any_outbound, 0 }, /* SSRC */
2247 {
2248 SRTP_NULL_CIPHER, /* cipher type */
2249 0, /* cipher key length in octets */
2250 SRTP_HMAC_SHA1, /* authentication func type */
2251 20, /* auth key length in octets */
2252 4, /* auth tag length in octets */
2253 sec_serv_auth /* security services flag */
2254 },
2255 {
2256 SRTP_NULL_CIPHER, /* cipher type */
2257 0, /* cipher key length in octets */
2258 SRTP_HMAC_SHA1, /* authentication func type */
2259 20, /* auth key length in octets */
2260 4, /* auth tag length in octets */
2261 sec_serv_auth /* security services flag */
2262 },
2263 test_key,
2264 NULL, /* indicates that EKT is not in use */
2265 128, /* replay window size */
2266 0, /* retransmission not allowed */
Joachim Bauch99a74822015-11-17 00:08:19 +01002267 NULL, /* no encrypted extension headers */
2268 0, /* list of encrypted extension headers is empty */
jfigus67b9c732014-11-20 10:17:21 -05002269 NULL
Cullen Jennings235513a2005-09-21 22:51:36 +00002270};
2271
jfigus8c36da22013-10-01 16:41:19 -04002272#ifdef OPENSSL
2273const srtp_policy_t aes128_gcm_8_policy = {
jfigus67b9c732014-11-20 10:17:21 -05002274 { ssrc_any_outbound, 0 }, /* SSRC */
2275 { /* SRTP policy */
2276 SRTP_AES_128_GCM, /* cipher type */
2277 SRTP_AES_128_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
2278 SRTP_NULL_AUTH, /* authentication func type */
2279 0, /* auth key length in octets */
2280 8, /* auth tag length in octets */
2281 sec_serv_conf_and_auth /* security services flag */
jfigus8c36da22013-10-01 16:41:19 -04002282 },
jfigus67b9c732014-11-20 10:17:21 -05002283 { /* SRTCP policy */
2284 SRTP_AES_128_GCM, /* cipher type */
2285 SRTP_AES_128_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
2286 SRTP_NULL_AUTH, /* authentication func type */
2287 0, /* auth key length in octets */
2288 8, /* auth tag length in octets */
2289 sec_serv_conf_and_auth /* security services flag */
jfigus8c36da22013-10-01 16:41:19 -04002290 },
2291 test_key,
2292 NULL, /* indicates that EKT is not in use */
2293 128, /* replay window size */
2294 0, /* retransmission not allowed */
Joachim Bauch99a74822015-11-17 00:08:19 +01002295 NULL, /* no encrypted extension headers */
2296 0, /* list of encrypted extension headers is empty */
jfigus8c36da22013-10-01 16:41:19 -04002297 NULL
2298};
2299
2300const srtp_policy_t aes128_gcm_8_cauth_policy = {
jfigus67b9c732014-11-20 10:17:21 -05002301 { ssrc_any_outbound, 0 }, /* SSRC */
2302 { /* SRTP policy */
2303 SRTP_AES_128_GCM, /* cipher type */
2304 SRTP_AES_128_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
2305 SRTP_NULL_AUTH, /* authentication func type */
2306 0, /* auth key length in octets */
2307 8, /* auth tag length in octets */
2308 sec_serv_conf_and_auth /* security services flag */
jfigus8c36da22013-10-01 16:41:19 -04002309 },
jfigus67b9c732014-11-20 10:17:21 -05002310 { /* SRTCP policy */
2311 SRTP_AES_128_GCM, /* cipher type */
2312 SRTP_AES_128_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
2313 SRTP_NULL_AUTH, /* authentication func type */
2314 0, /* auth key length in octets */
2315 8, /* auth tag length in octets */
2316 sec_serv_auth /* security services flag */
jfigus8c36da22013-10-01 16:41:19 -04002317 },
2318 test_key,
2319 NULL, /* indicates that EKT is not in use */
2320 128, /* replay window size */
2321 0, /* retransmission not allowed */
Joachim Bauch99a74822015-11-17 00:08:19 +01002322 NULL, /* no encrypted extension headers */
2323 0, /* list of encrypted extension headers is empty */
jfigus8c36da22013-10-01 16:41:19 -04002324 NULL
2325};
jfigus67b9c732014-11-20 10:17:21 -05002326
jfigus8c36da22013-10-01 16:41:19 -04002327const srtp_policy_t aes256_gcm_8_policy = {
jfigus67b9c732014-11-20 10:17:21 -05002328 { ssrc_any_outbound, 0 }, /* SSRC */
2329 { /* SRTP policy */
2330 SRTP_AES_256_GCM, /* cipher type */
2331 SRTP_AES_256_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
2332 SRTP_NULL_AUTH, /* authentication func type */
2333 0, /* auth key length in octets */
2334 8, /* auth tag length in octets */
2335 sec_serv_conf_and_auth /* security services flag */
jfigus8c36da22013-10-01 16:41:19 -04002336 },
jfigus67b9c732014-11-20 10:17:21 -05002337 { /* SRTCP policy */
2338 SRTP_AES_256_GCM, /* cipher type */
2339 SRTP_AES_256_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
2340 SRTP_NULL_AUTH, /* authentication func type */
2341 0, /* auth key length in octets */
2342 8, /* auth tag length in octets */
2343 sec_serv_conf_and_auth /* security services flag */
jfigus8c36da22013-10-01 16:41:19 -04002344 },
2345 test_key,
2346 NULL, /* indicates that EKT is not in use */
2347 128, /* replay window size */
2348 0, /* retransmission not allowed */
Joachim Bauch99a74822015-11-17 00:08:19 +01002349 NULL, /* no encrypted extension headers */
2350 0, /* list of encrypted extension headers is empty */
jfigus8c36da22013-10-01 16:41:19 -04002351 NULL
2352};
jfigus67b9c732014-11-20 10:17:21 -05002353
jfigus8c36da22013-10-01 16:41:19 -04002354const srtp_policy_t aes256_gcm_8_cauth_policy = {
jfigus67b9c732014-11-20 10:17:21 -05002355 { ssrc_any_outbound, 0 }, /* SSRC */
2356 { /* SRTP policy */
2357 SRTP_AES_256_GCM, /* cipher type */
2358 SRTP_AES_256_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
2359 SRTP_NULL_AUTH, /* authentication func type */
2360 0, /* auth key length in octets */
2361 8, /* auth tag length in octets */
2362 sec_serv_conf_and_auth /* security services flag */
jfigus8c36da22013-10-01 16:41:19 -04002363 },
jfigus67b9c732014-11-20 10:17:21 -05002364 { /* SRTCP policy */
2365 SRTP_AES_256_GCM, /* cipher type */
2366 SRTP_AES_256_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
2367 SRTP_NULL_AUTH, /* authentication func type */
2368 0, /* auth key length in octets */
2369 8, /* auth tag length in octets */
2370 sec_serv_auth /* security services flag */
jfigus8c36da22013-10-01 16:41:19 -04002371 },
2372 test_key,
2373 NULL, /* indicates that EKT is not in use */
2374 128, /* replay window size */
2375 0, /* retransmission not allowed */
Joachim Bauch99a74822015-11-17 00:08:19 +01002376 NULL, /* no encrypted extension headers */
2377 0, /* list of encrypted extension headers is empty */
jfigus8c36da22013-10-01 16:41:19 -04002378 NULL
2379};
2380#endif
2381
Cullen Jennings235513a2005-09-21 22:51:36 +00002382const srtp_policy_t null_policy = {
jfigus67b9c732014-11-20 10:17:21 -05002383 { ssrc_any_outbound, 0 }, /* SSRC */
2384 {
2385 SRTP_NULL_CIPHER, /* cipher type */
2386 0, /* cipher key length in octets */
2387 SRTP_NULL_AUTH, /* authentication func type */
2388 0, /* auth key length in octets */
2389 0, /* auth tag length in octets */
2390 sec_serv_none /* security services flag */
2391 },
2392 {
2393 SRTP_NULL_CIPHER, /* cipher type */
2394 0, /* cipher key length in octets */
2395 SRTP_NULL_AUTH, /* authentication func type */
2396 0, /* auth key length in octets */
2397 0, /* auth tag length in octets */
2398 sec_serv_none /* security services flag */
2399 },
2400 test_key,
2401 NULL, /* indicates that EKT is not in use */
2402 128, /* replay window size */
2403 0, /* retransmission not allowed */
Joachim Bauch99a74822015-11-17 00:08:19 +01002404 NULL, /* no encrypted extension headers */
2405 0, /* list of encrypted extension headers is empty */
jfigus67b9c732014-11-20 10:17:21 -05002406 NULL
David McGrew79870d62007-06-15 18:17:39 +00002407};
2408
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002409unsigned char test_256_key[46] = {
jfigus67b9c732014-11-20 10:17:21 -05002410 0xf0, 0xf0, 0x49, 0x14, 0xb5, 0x13, 0xf2, 0x76,
2411 0x3a, 0x1b, 0x1f, 0xa1, 0x30, 0xf1, 0x0e, 0x29,
2412 0x98, 0xf6, 0xf6, 0xe4, 0x3e, 0x43, 0x09, 0xd1,
2413 0xe6, 0x22, 0xa0, 0xe3, 0x32, 0xb9, 0xf1, 0xb6,
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002414
jfigus67b9c732014-11-20 10:17:21 -05002415 0x3b, 0x04, 0x80, 0x3d, 0xe5, 0x1e, 0xe7, 0xc9,
2416 0x64, 0x23, 0xab, 0x5b, 0x78, 0xd2
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002417};
2418
2419const srtp_policy_t aes_256_hmac_policy = {
jfigus67b9c732014-11-20 10:17:21 -05002420 { ssrc_any_outbound, 0 }, /* SSRC */
2421 { /* SRTP policy */
2422 SRTP_AES_ICM, /* cipher type */
2423 46, /* cipher key length in octets */
2424 SRTP_HMAC_SHA1, /* authentication func type */
2425 20, /* auth key length in octets */
2426 10, /* auth tag length in octets */
2427 sec_serv_conf_and_auth /* security services flag */
2428 },
2429 { /* SRTCP policy */
2430 SRTP_AES_ICM, /* cipher type */
2431 46, /* cipher key length in octets */
2432 SRTP_HMAC_SHA1, /* authentication func type */
2433 20, /* auth key length in octets */
2434 10, /* auth tag length in octets */
2435 sec_serv_conf_and_auth /* security services flag */
2436 },
2437 test_256_key,
2438 NULL, /* indicates that EKT is not in use */
2439 128, /* replay window size */
2440 0, /* retransmission not allowed */
Joachim Bauch99a74822015-11-17 00:08:19 +01002441 NULL, /* no encrypted extension headers */
2442 0, /* list of encrypted extension headers is empty */
jfigus67b9c732014-11-20 10:17:21 -05002443 NULL
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002444};
2445
David McGrew79870d62007-06-15 18:17:39 +00002446uint8_t ekt_test_key[16] = {
jfigus67b9c732014-11-20 10:17:21 -05002447 0x77, 0x26, 0x9d, 0xac, 0x16, 0xa3, 0x28, 0xca,
2448 0x8e, 0xc9, 0x68, 0x4b, 0xcc, 0xc4, 0xd2, 0x1b
David McGrew79870d62007-06-15 18:17:39 +00002449};
2450
2451#include "ekt.h"
2452
jfigusc5887e72014-11-06 09:46:18 -05002453srtp_ekt_policy_ctx_t ekt_test_policy = {
jfigus67b9c732014-11-20 10:17:21 -05002454 0xa5a5, /* SPI */
2455 SRTP_EKT_CIPHER_AES_128_ECB,
2456 ekt_test_key,
2457 NULL
David McGrew79870d62007-06-15 18:17:39 +00002458};
2459
2460const srtp_policy_t hmac_only_with_ekt_policy = {
jfigus67b9c732014-11-20 10:17:21 -05002461 { ssrc_any_outbound, 0 }, /* SSRC */
2462 {
2463 SRTP_NULL_CIPHER, /* cipher type */
2464 0, /* cipher key length in octets */
2465 SRTP_HMAC_SHA1, /* authentication func type */
2466 20, /* auth key length in octets */
2467 4, /* auth tag length in octets */
2468 sec_serv_auth /* security services flag */
2469 },
2470 {
2471 SRTP_NULL_CIPHER, /* cipher type */
2472 0, /* cipher key length in octets */
2473 SRTP_HMAC_SHA1, /* authentication func type */
2474 20, /* auth key length in octets */
2475 4, /* auth tag length in octets */
2476 sec_serv_auth /* security services flag */
2477 },
2478 test_key,
2479 &ekt_test_policy, /* indicates that EKT is not in use */
2480 128, /* replay window size */
2481 0, /* retransmission not allowed */
Joachim Bauch99a74822015-11-17 00:08:19 +01002482 NULL, /* no encrypted extension headers */
2483 0, /* list of encrypted extension headers is empty */
jfigus67b9c732014-11-20 10:17:21 -05002484 NULL
Cullen Jennings235513a2005-09-21 22:51:36 +00002485};
2486
2487
2488/*
2489 * an array of pointers to the policies listed above
2490 *
2491 * This array is used to test various aspects of libSRTP for
2492 * different cryptographic policies. The order of the elements
2493 * matters - the timing test generates output that can be used
jfigus67b9c732014-11-20 10:17:21 -05002494 * in a plot (see the gnuplot script file 'timing'). If you
Cullen Jennings235513a2005-09-21 22:51:36 +00002495 * add to this list, you should do it at the end.
2496 */
2497
Cullen Jennings235513a2005-09-21 22:51:36 +00002498const srtp_policy_t *
2499policy_array[] = {
jfigus67b9c732014-11-20 10:17:21 -05002500 &hmac_only_policy,
2501 &aes_only_policy,
2502 &default_policy,
jfigus8c36da22013-10-01 16:41:19 -04002503#ifdef OPENSSL
jfigus67b9c732014-11-20 10:17:21 -05002504 &aes128_gcm_8_policy,
2505 &aes128_gcm_8_cauth_policy,
2506 &aes256_gcm_8_policy,
2507 &aes256_gcm_8_cauth_policy,
jfigus8c36da22013-10-01 16:41:19 -04002508#endif
jfigus67b9c732014-11-20 10:17:21 -05002509 &null_policy,
2510 &aes_256_hmac_policy,
2511 &hmac_only_with_ekt_policy,
2512 NULL
Cullen Jennings235513a2005-09-21 22:51:36 +00002513};
2514
2515const srtp_policy_t wildcard_policy = {
jfigus67b9c732014-11-20 10:17:21 -05002516 { ssrc_any_outbound, 0 }, /* SSRC */
2517 { /* SRTP policy */
2518 SRTP_AES_128_ICM, /* cipher type */
2519 30, /* cipher key length in octets */
2520 SRTP_HMAC_SHA1, /* authentication func type */
2521 16, /* auth key length in octets */
2522 10, /* auth tag length in octets */
2523 sec_serv_conf_and_auth /* security services flag */
2524 },
2525 { /* SRTCP policy */
2526 SRTP_AES_128_ICM, /* cipher type */
2527 30, /* cipher key length in octets */
2528 SRTP_HMAC_SHA1, /* authentication func type */
2529 16, /* auth key length in octets */
2530 10, /* auth tag length in octets */
2531 sec_serv_conf_and_auth /* security services flag */
2532 },
2533 test_key,
2534 NULL,
2535 128, /* replay window size */
2536 0, /* retransmission not allowed */
Joachim Bauch99a74822015-11-17 00:08:19 +01002537 NULL, /* no encrypted extension headers */
2538 0, /* list of encrypted extension headers is empty */
jfigus67b9c732014-11-20 10:17:21 -05002539 NULL
Cullen Jennings235513a2005-09-21 22:51:36 +00002540};