blob: ca40156976e37791d3f472a727b8ec136346fbeb [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
Paul E. Jones9fc018c2016-06-03 02:56:56 -040066#ifdef OPENSSL
jfigus857009c2014-11-05 11:17:43 -050067srtp_err_status_t
Paul E. Jonese2ab5f22016-05-29 16:18:24 -040068srtp_validate_gcm(void);
Paul E. Jones9fc018c2016-06-03 02:56:56 -040069#endif
Paul E. Jonese2ab5f22016-05-29 16:18:24 -040070
71srtp_err_status_t
Joachim Bauch99a74822015-11-17 00:08:19 +010072srtp_validate_encrypted_extensions_headers(void);
73
Joachim Bauch80a45b52015-12-06 22:57:58 +010074#ifdef OPENSSL
Joachim Bauch99a74822015-11-17 00:08:19 +010075srtp_err_status_t
Joachim Bauchfa1e8c22015-11-24 23:38:48 +010076srtp_validate_encrypted_extensions_headers_gcm(void);
Joachim Bauch80a45b52015-12-06 22:57:58 +010077#endif
Joachim Bauchfa1e8c22015-11-24 23:38:48 +010078
79srtp_err_status_t
Jonathan Lennox5df951a2010-05-20 20:55:54 +000080srtp_validate_aes_256(void);
81
jfigus857009c2014-11-05 11:17:43 -050082srtp_err_status_t
Cullen Jennings235513a2005-09-21 22:51:36 +000083srtp_create_big_policy(srtp_policy_t **list);
84
jfigus857009c2014-11-05 11:17:43 -050085srtp_err_status_t
Jonathan Lennox80c4c832010-05-17 19:30:28 +000086srtp_dealloc_big_policy(srtp_policy_t *list);
87
jfigus857009c2014-11-05 11:17:43 -050088srtp_err_status_t
Joachim Bauchc8a19ae2015-12-14 22:50:36 +010089srtp_test_empty_payload(void);
90
91#ifdef OPENSSL
92srtp_err_status_t
93srtp_test_empty_payload_gcm(void);
94#endif
95
96srtp_err_status_t
Marcus Sundberga3f95fe2005-09-29 12:48:41 +000097srtp_test_remove_stream(void);
Cullen Jennings235513a2005-09-21 22:51:36 +000098
Pascal Bühlerbd3112a2015-11-06 20:29:15 +010099srtp_err_status_t
100srtp_test_update(void);
101
Cullen Jennings235513a2005-09-21 22:51:36 +0000102double
103srtp_bits_per_second(int msg_len_octets, const srtp_policy_t *policy);
104
105double
106srtp_rejections_per_second(int msg_len_octets, const srtp_policy_t *policy);
107
108void
109srtp_do_timing(const srtp_policy_t *policy);
110
111void
112srtp_do_rejection_timing(const srtp_policy_t *policy);
113
jfigus857009c2014-11-05 11:17:43 -0500114srtp_err_status_t
Joachim Bauch99a74822015-11-17 00:08:19 +0100115srtp_test(const srtp_policy_t *policy, int extension_header);
Cullen Jennings235513a2005-09-21 22:51:36 +0000116
jfigus857009c2014-11-05 11:17:43 -0500117srtp_err_status_t
David McGrew9c70f292006-05-03 19:38:38 +0000118srtcp_test(const srtp_policy_t *policy);
119
jfigus857009c2014-11-05 11:17:43 -0500120srtp_err_status_t
Cullen Jennings235513a2005-09-21 22:51:36 +0000121srtp_session_print_policy(srtp_t srtp);
122
jfigus857009c2014-11-05 11:17:43 -0500123srtp_err_status_t
jfigus67b9c732014-11-20 10:17:21 -0500124srtp_print_policy(const srtp_policy_t *policy);
Cullen Jennings235513a2005-09-21 22:51:36 +0000125
126char *
127srtp_packet_to_string(srtp_hdr_t *hdr, int packet_len);
128
129double
130mips_estimate(int num_trials, int *ignore);
131
jfigus8c36da22013-10-01 16:41:19 -0400132extern uint8_t test_key[46];
Cullen Jennings235513a2005-09-21 22:51:36 +0000133
134void
jfigus67b9c732014-11-20 10:17:21 -0500135usage (char *prog_name)
136{
137 printf("usage: %s [ -t ][ -c ][ -v ][-d <debug_module> ]* [ -l ]\n"
138 " -t run timing test\n"
139 " -r run rejection timing test\n"
140 " -c run codec timing test\n"
141 " -v run validation tests\n"
142 " -d <mod> turn on debugging module <mod>\n"
143 " -l list debugging modules\n", prog_name);
144 exit(1);
Cullen Jennings235513a2005-09-21 22:51:36 +0000145}
146
147/*
148 * The policy_array is a null-terminated array of policy structs. it
149 * is declared at the end of this file
150 */
151
152extern const srtp_policy_t *policy_array[];
153
154
155/* the wildcard_policy is declared below; it has a wildcard ssrc */
156
157extern const srtp_policy_t wildcard_policy;
158
159/*
160 * mod_driver debug module - debugging module for this test driver
161 *
jfigus67b9c732014-11-20 10:17:21 -0500162 * we use the crypto_kernel debugging system in this driver, which
Cullen Jennings235513a2005-09-21 22:51:36 +0000163 * makes the interface uniform and increases portability
jfigus67b9c732014-11-20 10:17:21 -0500164 */
Cullen Jennings235513a2005-09-21 22:51:36 +0000165
jfigus02d6f032014-11-21 10:56:42 -0500166srtp_debug_module_t mod_driver = {
jfigus67b9c732014-11-20 10:17:21 -0500167 0, /* debugging is off by default */
168 "driver" /* printable name for module */
Cullen Jennings235513a2005-09-21 22:51:36 +0000169};
170
171int
jfigus67b9c732014-11-20 10:17:21 -0500172main (int argc, char *argv[])
173{
174 int q;
175 unsigned do_timing_test = 0;
176 unsigned do_rejection_test = 0;
177 unsigned do_codec_timing = 0;
178 unsigned do_validation = 0;
179 unsigned do_list_mods = 0;
180 srtp_err_status_t status;
Cullen Jennings235513a2005-09-21 22:51:36 +0000181
182 /*
jfigus67b9c732014-11-20 10:17:21 -0500183 * verify that the compiler has interpreted the header data
184 * structure srtp_hdr_t correctly
Cullen Jennings235513a2005-09-21 22:51:36 +0000185 */
jfigus67b9c732014-11-20 10:17:21 -0500186 if (sizeof(srtp_hdr_t) != 12) {
187 printf("error: srtp_hdr_t has incorrect size"
188 "(size is %ld bytes, expected 12)\n",
189 (long)sizeof(srtp_hdr_t));
190 exit(1);
Cullen Jennings235513a2005-09-21 22:51:36 +0000191 }
192
jfigus67b9c732014-11-20 10:17:21 -0500193 /* initialize srtp library */
194 status = srtp_init();
195 if (status) {
196 printf("error: srtp init failed with error code %d\n", status);
197 exit(1);
198 }
199
200 /* load srtp_driver debug module */
jfigus92736bc2014-11-21 10:30:54 -0500201 status = srtp_crypto_kernel_load_debug_module(&mod_driver);
jfigus67b9c732014-11-20 10:17:21 -0500202 if (status) {
203 printf("error: load of srtp_driver debug module failed "
204 "with error code %d\n", status);
205 exit(1);
206 }
207
208 /* process input arguments */
209 while (1) {
210 q = getopt_s(argc, argv, "trcvld:");
211 if (q == -1) {
212 break;
213 }
214 switch (q) {
215 case 't':
216 do_timing_test = 1;
217 break;
218 case 'r':
219 do_rejection_test = 1;
220 break;
221 case 'c':
222 do_codec_timing = 1;
223 break;
224 case 'v':
225 do_validation = 1;
226 break;
227 case 'l':
228 do_list_mods = 1;
229 break;
230 case 'd':
jfigus92736bc2014-11-21 10:30:54 -0500231 status = srtp_crypto_kernel_set_debug_module(optarg_s, 1);
jfigus67b9c732014-11-20 10:17:21 -0500232 if (status) {
233 printf("error: set debug module (%s) failed\n", optarg_s);
234 exit(1);
235 }
236 break;
237 default:
238 usage(argv[0]);
239 }
240 }
241
242 if (!do_validation && !do_timing_test && !do_codec_timing
243 && !do_list_mods && !do_rejection_test) {
244 usage(argv[0]);
245 }
246
247 if (do_list_mods) {
jfigus92736bc2014-11-21 10:30:54 -0500248 status = srtp_crypto_kernel_list_debug_modules();
jfigus67b9c732014-11-20 10:17:21 -0500249 if (status) {
250 printf("error: list of debug modules failed\n");
251 exit(1);
252 }
253 }
254
255 if (do_validation) {
256 const srtp_policy_t **policy = policy_array;
257 srtp_policy_t *big_policy;
258
259 /* loop over policy array, testing srtp and srtcp for each policy */
260 while (*policy != NULL) {
261 printf("testing srtp_protect and srtp_unprotect\n");
Joachim Bauch99a74822015-11-17 00:08:19 +0100262 if (srtp_test(*policy, 0) == srtp_err_status_ok) {
263 printf("passed\n\n");
264 } else{
265 printf("failed\n");
266 exit(1);
267 }
268 printf("testing srtp_protect and srtp_unprotect with encrypted extensions headers\n");
269 if (srtp_test(*policy, 1) == srtp_err_status_ok) {
jfigus67b9c732014-11-20 10:17:21 -0500270 printf("passed\n\n");
271 } else{
272 printf("failed\n");
273 exit(1);
274 }
275 printf("testing srtp_protect_rtcp and srtp_unprotect_rtcp\n");
276 if (srtcp_test(*policy) == srtp_err_status_ok) {
277 printf("passed\n\n");
278 } else{
279 printf("failed\n");
280 exit(1);
281 }
282 policy++;
283 }
284
285 /* create a big policy list and run tests on it */
286 status = srtp_create_big_policy(&big_policy);
287 if (status) {
288 printf("unexpected failure with error code %d\n", status);
289 exit(1);
290 }
291 printf("testing srtp_protect and srtp_unprotect with big policy\n");
Joachim Bauch99a74822015-11-17 00:08:19 +0100292 if (srtp_test(big_policy, 0) == srtp_err_status_ok) {
293 printf("passed\n\n");
294 } else{
295 printf("failed\n");
296 exit(1);
297 }
298 printf("testing srtp_protect and srtp_unprotect with big policy and encrypted extensions headers\n");
299 if (srtp_test(big_policy, 1) == srtp_err_status_ok) {
jfigus67b9c732014-11-20 10:17:21 -0500300 printf("passed\n\n");
301 } else{
302 printf("failed\n");
303 exit(1);
304 }
305 status = srtp_dealloc_big_policy(big_policy);
306 if (status) {
307 printf("unexpected failure with error code %d\n", status);
308 exit(1);
309 }
310
311 /* run test on wildcard policy */
312 printf("testing srtp_protect and srtp_unprotect on "
313 "wildcard ssrc policy\n");
Joachim Bauch99a74822015-11-17 00:08:19 +0100314 if (srtp_test(&wildcard_policy, 0) == srtp_err_status_ok) {
315 printf("passed\n\n");
316 } else{
317 printf("failed\n");
318 exit(1);
319 }
320 printf("testing srtp_protect and srtp_unprotect on "
321 "wildcard ssrc policy and encrypted extensions headers\n");
322 if (srtp_test(&wildcard_policy, 1) == srtp_err_status_ok) {
jfigus67b9c732014-11-20 10:17:21 -0500323 printf("passed\n\n");
324 } else{
325 printf("failed\n");
326 exit(1);
327 }
328
329 /*
330 * run validation test against the reference packets - note
331 * that this test only covers the default policy
332 */
333 printf("testing srtp_protect and srtp_unprotect against "
Paul E. Jonese2ab5f22016-05-29 16:18:24 -0400334 "reference packet\n");
jfigus67b9c732014-11-20 10:17:21 -0500335 if (srtp_validate() == srtp_err_status_ok) {
336 printf("passed\n\n");
337 } else{
338 printf("failed\n");
339 exit(1);
340 }
Paul E. Jonese2ab5f22016-05-29 16:18:24 -0400341
342#ifdef OPENSSL
Joachim Bauch99a74822015-11-17 00:08:19 +0100343 printf("testing srtp_protect and srtp_unprotect against "
Paul E. Jonese2ab5f22016-05-29 16:18:24 -0400344 "reference packet using GCM\n");
345 if (srtp_validate_gcm() == srtp_err_status_ok) {
346 printf("passed\n\n");
347 } else{
348 printf("failed\n");
349 exit(1);
350 }
351#endif
352
353 printf("testing srtp_protect and srtp_unprotect against "
354 "reference packet with encrypted extensions headers\n");
Joachim Bauch99a74822015-11-17 00:08:19 +0100355 if (srtp_validate_encrypted_extensions_headers() == srtp_err_status_ok)
356 printf("passed\n\n");
357 else {
358 printf("failed\n");
359 exit(1);
360 }
jfigus67b9c732014-11-20 10:17:21 -0500361
Joachim Bauchb8cb5772015-11-24 21:46:25 +0100362#ifdef OPENSSL
Joachim Bauchfa1e8c22015-11-24 23:38:48 +0100363 printf("testing srtp_protect and srtp_unprotect against "
Paul E. Jonese2ab5f22016-05-29 16:18:24 -0400364 "reference packet with encrypted extension headers (GCM)\n");
Joachim Bauchfa1e8c22015-11-24 23:38:48 +0100365 if (srtp_validate_encrypted_extensions_headers_gcm() == srtp_err_status_ok) {
366 printf("passed\n\n");
367 } else{
368 printf("failed\n");
369 exit(1);
370 }
Joachim Bauch80a45b52015-12-06 22:57:58 +0100371#endif
Joachim Bauchfa1e8c22015-11-24 23:38:48 +0100372
jfigus67b9c732014-11-20 10:17:21 -0500373 /*
374 * run validation test against the reference packets for
375 * AES-256
376 */
377 printf("testing srtp_protect and srtp_unprotect against "
Paul E. Jonese2ab5f22016-05-29 16:18:24 -0400378 "reference packet (AES-256)\n");
jfigus67b9c732014-11-20 10:17:21 -0500379 if (srtp_validate_aes_256() == srtp_err_status_ok) {
380 printf("passed\n\n");
381 } else{
382 printf("failed\n");
383 exit(1);
384 }
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000385
jfigus67b9c732014-11-20 10:17:21 -0500386 /*
Joachim Bauchc8a19ae2015-12-14 22:50:36 +0100387 * test packets with empty payload
388 */
389 printf("testing srtp_protect and srtp_unprotect against "
Paul E. Jonese2ab5f22016-05-29 16:18:24 -0400390 "packet with empty payload\n");
Joachim Bauchc8a19ae2015-12-14 22:50:36 +0100391 if (srtp_test_empty_payload() == srtp_err_status_ok) {
392 printf("passed\n");
393 } else{
394 printf("failed\n");
395 exit(1);
396 }
397#ifdef OPENSSL
398 printf("testing srtp_protect and srtp_unprotect against "
Paul E. Jonese2ab5f22016-05-29 16:18:24 -0400399 "packet with empty payload (GCM)\n");
Joachim Bauchc8a19ae2015-12-14 22:50:36 +0100400 if (srtp_test_empty_payload_gcm() == srtp_err_status_ok) {
401 printf("passed\n");
402 } else{
403 printf("failed\n");
404 exit(1);
405 }
406#endif
407
408 /*
jfigus67b9c732014-11-20 10:17:21 -0500409 * test the function srtp_remove_stream()
410 */
411 printf("testing srtp_remove_stream()...");
412 if (srtp_test_remove_stream() == srtp_err_status_ok) {
413 printf("passed\n");
414 } else{
415 printf("failed\n");
416 exit(1);
417 }
Pascal Bühlerbd3112a2015-11-06 20:29:15 +0100418
419 /*
420 * test the function srtp_update()
421 */
422 printf("testing srtp_update()...");
423 if (srtp_test_update() == srtp_err_status_ok) {
424 printf("passed\n");
425 } else {
426 printf("failed\n");
427 exit(1);
428 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000429 }
jfigus67b9c732014-11-20 10:17:21 -0500430
431 if (do_timing_test) {
432 const srtp_policy_t **policy = policy_array;
433
434 /* loop over policies, run timing test for each */
435 while (*policy != NULL) {
436 srtp_print_policy(*policy);
437 srtp_do_timing(*policy);
438 policy++;
439 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000440 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000441
jfigus67b9c732014-11-20 10:17:21 -0500442 if (do_rejection_test) {
443 const srtp_policy_t **policy = policy_array;
444
445 /* loop over policies, run rejection timing test for each */
446 while (*policy != NULL) {
447 srtp_print_policy(*policy);
448 srtp_do_rejection_timing(*policy);
449 policy++;
450 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000451 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000452
jfigus67b9c732014-11-20 10:17:21 -0500453 if (do_codec_timing) {
454 srtp_policy_t policy;
455 int ignore;
Joachim Bauchdc53dcb2016-03-10 20:32:44 +0100456 double mips_value = mips_estimate(1000000000, &ignore);
Cullen Jennings235513a2005-09-21 22:51:36 +0000457
Joachim Bauch99a74822015-11-17 00:08:19 +0100458 memset(&policy, 0, sizeof(policy));
jfigus67b9c732014-11-20 10:17:21 -0500459 srtp_crypto_policy_set_rtp_default(&policy.rtp);
460 srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
461 policy.ssrc.type = ssrc_specific;
462 policy.ssrc.value = 0xdecafbad;
463 policy.key = test_key;
464 policy.ekt = NULL;
465 policy.window_size = 128;
466 policy.allow_repeat_tx = 0;
467 policy.next = NULL;
Cullen Jennings235513a2005-09-21 22:51:36 +0000468
Joachim Bauchdc53dcb2016-03-10 20:32:44 +0100469 printf("mips estimate: %e\n", mips_value);
Cullen Jennings235513a2005-09-21 22:51:36 +0000470
jfigus67b9c732014-11-20 10:17:21 -0500471 printf("testing srtp processing time for voice codecs:\n");
472 printf("codec\t\tlength (octets)\t\tsrtp instructions/second\n");
473 printf("G.711\t\t%d\t\t\t%e\n", 80,
Joachim Bauchdc53dcb2016-03-10 20:32:44 +0100474 (double)mips_value * (80 * 8) /
jfigus67b9c732014-11-20 10:17:21 -0500475 srtp_bits_per_second(80, &policy) / .01 );
476 printf("G.711\t\t%d\t\t\t%e\n", 160,
Joachim Bauchdc53dcb2016-03-10 20:32:44 +0100477 (double)mips_value * (160 * 8) /
jfigus67b9c732014-11-20 10:17:21 -0500478 srtp_bits_per_second(160, &policy) / .02);
479 printf("G.726-32\t%d\t\t\t%e\n", 40,
Joachim Bauchdc53dcb2016-03-10 20:32:44 +0100480 (double)mips_value * (40 * 8) /
jfigus67b9c732014-11-20 10:17:21 -0500481 srtp_bits_per_second(40, &policy) / .01 );
482 printf("G.726-32\t%d\t\t\t%e\n", 80,
Joachim Bauchdc53dcb2016-03-10 20:32:44 +0100483 (double)mips_value * (80 * 8) /
jfigus67b9c732014-11-20 10:17:21 -0500484 srtp_bits_per_second(80, &policy) / .02);
485 printf("G.729\t\t%d\t\t\t%e\n", 10,
Joachim Bauchdc53dcb2016-03-10 20:32:44 +0100486 (double)mips_value * (10 * 8) /
jfigus67b9c732014-11-20 10:17:21 -0500487 srtp_bits_per_second(10, &policy) / .01 );
488 printf("G.729\t\t%d\t\t\t%e\n", 20,
Joachim Bauchdc53dcb2016-03-10 20:32:44 +0100489 (double)mips_value * (20 * 8) /
jfigus67b9c732014-11-20 10:17:21 -0500490 srtp_bits_per_second(20, &policy) / .02 );
491 printf("Wideband\t%d\t\t\t%e\n", 320,
Joachim Bauchdc53dcb2016-03-10 20:32:44 +0100492 (double)mips_value * (320 * 8) /
jfigus67b9c732014-11-20 10:17:21 -0500493 srtp_bits_per_second(320, &policy) / .01 );
494 printf("Wideband\t%d\t\t\t%e\n", 640,
Joachim Bauchdc53dcb2016-03-10 20:32:44 +0100495 (double)mips_value * (640 * 8) /
jfigus67b9c732014-11-20 10:17:21 -0500496 srtp_bits_per_second(640, &policy) / .02 );
497 }
Jonathan Lennoxdfb30842010-05-15 04:52:01 +0000498
jfigus67b9c732014-11-20 10:17:21 -0500499 status = srtp_shutdown();
500 if (status) {
501 printf("error: srtp shutdown failed with error code %d\n", status);
502 exit(1);
503 }
504
505 return 0;
Cullen Jennings235513a2005-09-21 22:51:36 +0000506}
507
508
509
510/*
511 * srtp_create_test_packet(len, ssrc) returns a pointer to a
512 * (malloced) example RTP packet whose data field has the length given
513 * by pkt_octet_len and the SSRC value ssrc. The total length of the
514 * packet is twelve octets longer, since the header is at the
515 * beginning. There is room at the end of the packet for a trailer,
516 * and the four octets following the packet are filled with 0xff
517 * values to enable testing for overwrites.
518 *
519 * note that the location of the test packet can (and should) be
520 * deallocated with the free() call once it is no longer needed.
521 */
522
523srtp_hdr_t *
jfigus67b9c732014-11-20 10:17:21 -0500524srtp_create_test_packet (int pkt_octet_len, uint32_t ssrc)
525{
526 int i;
527 uint8_t *buffer;
528 srtp_hdr_t *hdr;
529 int bytes_in_hdr = 12;
Cullen Jennings235513a2005-09-21 22:51:36 +0000530
jfigus67b9c732014-11-20 10:17:21 -0500531 /* allocate memory for test packet */
532 hdr = (srtp_hdr_t*)malloc(pkt_octet_len + bytes_in_hdr
533 + SRTP_MAX_TRAILER_LEN + 4);
534 if (!hdr) {
535 return NULL;
536 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000537
jfigus67b9c732014-11-20 10:17:21 -0500538 hdr->version = 2; /* RTP version two */
539 hdr->p = 0; /* no padding needed */
540 hdr->x = 0; /* no header extension */
541 hdr->cc = 0; /* no CSRCs */
542 hdr->m = 0; /* marker bit */
543 hdr->pt = 0xf; /* payload type */
544 hdr->seq = htons(0x1234); /* sequence number */
545 hdr->ts = htonl(0xdecafbad); /* timestamp */
546 hdr->ssrc = htonl(ssrc); /* synch. source */
Cullen Jennings235513a2005-09-21 22:51:36 +0000547
jfigus67b9c732014-11-20 10:17:21 -0500548 buffer = (uint8_t*)hdr;
549 buffer += bytes_in_hdr;
Cullen Jennings235513a2005-09-21 22:51:36 +0000550
jfigus67b9c732014-11-20 10:17:21 -0500551 /* set RTP data to 0xab */
552 for (i = 0; i < pkt_octet_len; i++) {
553 *buffer++ = 0xab;
554 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000555
jfigus67b9c732014-11-20 10:17:21 -0500556 /* set post-data value to 0xffff to enable overrun checking */
557 for (i = 0; i < SRTP_MAX_TRAILER_LEN + 4; i++) {
558 *buffer++ = 0xff;
559 }
560
561 return hdr;
Cullen Jennings235513a2005-09-21 22:51:36 +0000562}
563
Joachim Bauch99a74822015-11-17 00:08:19 +0100564srtp_hdr_t *
565srtp_create_test_packet_ext_hdr(int pkt_octet_len, uint32_t ssrc) {
566 int i;
567 uint8_t *buffer;
568 srtp_hdr_t *hdr;
569 int bytes_in_hdr = 12;
570 uint8_t extension_header[12] = {
571 /* one-byte header */
572 0xbe, 0xde,
573 /* size */
574 0x00, 0x02,
575 /* id 1, length 1 (i.e. 2 bytes) */
576 0x11,
577 /* payload */
578 0xca,
579 0xfe,
580 /* padding */
581 0x00,
582 /* id 2, length 0 (i.e. 1 byte) */
583 0x20,
584 /* payload */
585 0xba,
586 /* padding */
587 0x00,
588 0x00
589 };
590
591 /* allocate memory for test packet */
592 hdr = (srtp_hdr_t*) malloc(pkt_octet_len + bytes_in_hdr
593 + sizeof(extension_header) + SRTP_MAX_TRAILER_LEN + 4);
594 if (!hdr)
595 return NULL;
596
597 hdr->version = 2; /* RTP version two */
598 hdr->p = 0; /* no padding needed */
599 hdr->x = 1; /* no header extension */
600 hdr->cc = 0; /* no CSRCs */
601 hdr->m = 0; /* marker bit */
602 hdr->pt = 0xf; /* payload type */
603 hdr->seq = htons(0x1234); /* sequence number */
604 hdr->ts = htonl(0xdecafbad); /* timestamp */
605 hdr->ssrc = htonl(ssrc); /* synch. source */
606
607 buffer = (uint8_t *)hdr;
608 buffer += bytes_in_hdr;
609
610 memcpy(buffer, extension_header, sizeof(extension_header));
611 buffer += sizeof(extension_header);
612
613 /* set RTP data to 0xab */
614 for (i=0; i < pkt_octet_len; i++)
615 *buffer++ = 0xab;
616
617 /* set post-data value to 0xffff to enable overrun checking */
618 for (i=0; i < SRTP_MAX_TRAILER_LEN+4; i++)
619 *buffer++ = 0xff;
620
621 return hdr;
622}
623
Cullen Jennings235513a2005-09-21 22:51:36 +0000624void
jfigus67b9c732014-11-20 10:17:21 -0500625srtp_do_timing (const srtp_policy_t *policy)
626{
627 int len;
Cullen Jennings235513a2005-09-21 22:51:36 +0000628
jfigus67b9c732014-11-20 10:17:21 -0500629 /*
630 * note: the output of this function is formatted so that it
631 * can be used in gnuplot. '#' indicates a comment, and "\r\n"
632 * terminates a record
633 */
634
635 printf("# testing srtp throughput:\r\n");
636 printf("# mesg length (octets)\tthroughput (megabits per second)\r\n");
637
638 for (len = 16; len <= 2048; len *= 2) {
639 printf("%d\t\t\t%f\r\n", len,
640 srtp_bits_per_second(len, policy) / 1.0E6);
641 }
642
643 /* these extra linefeeds let gnuplot know that a dataset is done */
644 printf("\r\n\r\n");
Cullen Jennings235513a2005-09-21 22:51:36 +0000645
646}
647
648void
jfigus67b9c732014-11-20 10:17:21 -0500649srtp_do_rejection_timing (const srtp_policy_t *policy)
650{
651 int len;
Cullen Jennings235513a2005-09-21 22:51:36 +0000652
jfigus67b9c732014-11-20 10:17:21 -0500653 /*
654 * note: the output of this function is formatted so that it
655 * can be used in gnuplot. '#' indicates a comment, and "\r\n"
656 * terminates a record
657 */
658
659 printf("# testing srtp rejection throughput:\r\n");
660 printf("# mesg length (octets)\trejections per second\r\n");
661
662 for (len = 8; len <= 2048; len *= 2) {
663 printf("%d\t\t\t%e\r\n", len, srtp_rejections_per_second(len, policy));
664 }
665
666 /* these extra linefeeds let gnuplot know that a dataset is done */
667 printf("\r\n\r\n");
Cullen Jennings235513a2005-09-21 22:51:36 +0000668
669}
670
671
672#define MAX_MSG_LEN 1024
673
674double
jfigus67b9c732014-11-20 10:17:21 -0500675srtp_bits_per_second (int msg_len_octets, const srtp_policy_t *policy)
676{
677 srtp_t srtp;
678 srtp_hdr_t *mesg;
679 int i;
680 clock_t timer;
681 int num_trials = 100000;
682 int len;
683 uint32_t ssrc;
684 srtp_err_status_t status;
Cullen Jennings235513a2005-09-21 22:51:36 +0000685
jfigus67b9c732014-11-20 10:17:21 -0500686 /*
687 * allocate and initialize an srtp session
688 */
689 status = srtp_create(&srtp, policy);
Cullen Jennings235513a2005-09-21 22:51:36 +0000690 if (status) {
jfigus67b9c732014-11-20 10:17:21 -0500691 printf("error: srtp_create() failed with error code %d\n", status);
692 exit(1);
Cullen Jennings235513a2005-09-21 22:51:36 +0000693 }
694
jfigus67b9c732014-11-20 10:17:21 -0500695 /*
696 * if the ssrc is unspecified, use a predetermined one
697 */
698 if (policy->ssrc.type != ssrc_specific) {
699 ssrc = 0xdeadbeef;
700 } else {
701 ssrc = policy->ssrc.value;
Jonathan Lennox75b36872010-05-21 00:30:21 +0000702 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000703
jfigus67b9c732014-11-20 10:17:21 -0500704 /*
705 * create a test packet
706 */
707 mesg = srtp_create_test_packet(msg_len_octets, ssrc);
708 if (mesg == NULL) {
709 return 0.0; /* indicate failure by returning zero */
Jonathan Lennox80c4c832010-05-17 19:30:28 +0000710
jfigus67b9c732014-11-20 10:17:21 -0500711 }
712 timer = clock();
713 for (i = 0; i < num_trials; i++) {
714 len = msg_len_octets + 12; /* add in rtp header length */
715
716 /* srtp protect message */
717 status = srtp_protect(srtp, mesg, &len);
718 if (status) {
719 printf("error: srtp_protect() failed with error code %d\n", status);
720 exit(1);
721 }
722
723 /* increment message number */
724 {
725 /* hack sequence to avoid problems with macros for htons/ntohs on some systems */
726 short new_seq = ntohs(mesg->seq) + 1;
727 mesg->seq = htons(new_seq);
728 }
729 }
730 timer = clock() - timer;
731
732 free(mesg);
733
734 status = srtp_dealloc(srtp);
735 if (status) {
736 printf("error: srtp_dealloc() failed with error code %d\n", status);
737 exit(1);
738 }
739
740 return (double)(msg_len_octets) * 8 *
741 num_trials * CLOCKS_PER_SEC / timer;
Cullen Jennings235513a2005-09-21 22:51:36 +0000742}
743
744double
jfigus67b9c732014-11-20 10:17:21 -0500745srtp_rejections_per_second (int msg_len_octets, const srtp_policy_t *policy)
746{
747 srtp_ctx_t *srtp;
748 srtp_hdr_t *mesg;
749 int i;
750 int len;
751 clock_t timer;
752 int num_trials = 1000000;
753 uint32_t ssrc = policy->ssrc.value;
754 srtp_err_status_t status;
Cullen Jennings235513a2005-09-21 22:51:36 +0000755
jfigus67b9c732014-11-20 10:17:21 -0500756 /*
757 * allocate and initialize an srtp session
758 */
759 status = srtp_create(&srtp, policy);
760 if (status) {
761 printf("error: srtp_create() failed with error code %d\n", status);
762 exit(1);
763 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000764
jfigus67b9c732014-11-20 10:17:21 -0500765 mesg = srtp_create_test_packet(msg_len_octets, ssrc);
766 if (mesg == NULL) {
767 return 0.0; /* indicate failure by returning zero */
768
769 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000770 len = msg_len_octets;
jfigus67b9c732014-11-20 10:17:21 -0500771 srtp_protect(srtp, (srtp_hdr_t*)mesg, &len);
Cullen Jennings235513a2005-09-21 22:51:36 +0000772
jfigus67b9c732014-11-20 10:17:21 -0500773 timer = clock();
774 for (i = 0; i < num_trials; i++) {
775 len = msg_len_octets;
776 srtp_unprotect(srtp, (srtp_hdr_t*)mesg, &len);
777 }
778 timer = clock() - timer;
Jonathan Lennox80c4c832010-05-17 19:30:28 +0000779
jfigus67b9c732014-11-20 10:17:21 -0500780 free(mesg);
Jonathan Lennox80c4c832010-05-17 19:30:28 +0000781
jfigus67b9c732014-11-20 10:17:21 -0500782 status = srtp_dealloc(srtp);
783 if (status) {
784 printf("error: srtp_dealloc() failed with error code %d\n", status);
785 exit(1);
786 }
787
788 return (double)num_trials * CLOCKS_PER_SEC / timer;
Cullen Jennings235513a2005-09-21 22:51:36 +0000789}
790
791
792void
jfigus67b9c732014-11-20 10:17:21 -0500793err_check (srtp_err_status_t s)
794{
795 if (s == srtp_err_status_ok) {
796 return;
797 } else{
798 fprintf(stderr, "error: unexpected srtp failure (code %d)\n", s);
799 }
800 exit(1);
Cullen Jennings235513a2005-09-21 22:51:36 +0000801}
802
jfigus857009c2014-11-05 11:17:43 -0500803srtp_err_status_t
Joachim Bauch99a74822015-11-17 00:08:19 +0100804srtp_test (const srtp_policy_t *policy, int extension_header)
jfigus67b9c732014-11-20 10:17:21 -0500805{
806 int i;
807 srtp_t srtp_sender;
808 srtp_t srtp_rcvr;
809 srtp_err_status_t status = srtp_err_status_ok;
810 srtp_hdr_t *hdr, *hdr2;
811 uint8_t hdr_enc[64];
812 uint8_t *pkt_end;
813 int msg_len_octets, msg_len_enc;
814 int len;
815 int tag_length = policy->rtp.auth_tag_len;
816 uint32_t ssrc;
817 srtp_policy_t *rcvr_policy;
Joachim Bauch99a74822015-11-17 00:08:19 +0100818 srtp_policy_t tmp_policy;
819 int header = 1;
Cullen Jennings235513a2005-09-21 22:51:36 +0000820
Joachim Bauch99a74822015-11-17 00:08:19 +0100821 if (extension_header) {
822 memcpy(&tmp_policy, policy, sizeof(srtp_policy_t));
823 tmp_policy.enc_xtn_hdr = &header;
824 tmp_policy.enc_xtn_hdr_count = 1;
825 err_check(srtp_create(&srtp_sender, &tmp_policy));
826 } else {
827 err_check(srtp_create(&srtp_sender, policy));
828 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000829
jfigus67b9c732014-11-20 10:17:21 -0500830 /* print out policy */
831 err_check(srtp_session_print_policy(srtp_sender));
Cullen Jennings235513a2005-09-21 22:51:36 +0000832
jfigus67b9c732014-11-20 10:17:21 -0500833 /*
834 * initialize data buffer, using the ssrc in the policy unless that
835 * value is a wildcard, in which case we'll just use an arbitrary
836 * one
837 */
838 if (policy->ssrc.type != ssrc_specific) {
839 ssrc = 0xdecafbad;
840 } else{
841 ssrc = policy->ssrc.value;
Cullen Jennings235513a2005-09-21 22:51:36 +0000842 }
jfigus67b9c732014-11-20 10:17:21 -0500843 msg_len_octets = 28;
Joachim Bauch99a74822015-11-17 00:08:19 +0100844 if (extension_header) {
845 hdr = srtp_create_test_packet_ext_hdr(msg_len_octets, ssrc);
846 hdr2 = srtp_create_test_packet_ext_hdr(msg_len_octets, ssrc);
847 } else {
848 hdr = srtp_create_test_packet(msg_len_octets, ssrc);
849 hdr2 = srtp_create_test_packet(msg_len_octets, ssrc);
850 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000851
jfigus67b9c732014-11-20 10:17:21 -0500852 if (hdr == NULL) {
Joachim Bauch99a74822015-11-17 00:08:19 +0100853 free(hdr2);
jfigus67b9c732014-11-20 10:17:21 -0500854 return srtp_err_status_alloc_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +0000855 }
jfigus67b9c732014-11-20 10:17:21 -0500856 if (hdr2 == NULL) {
857 free(hdr);
858 return srtp_err_status_alloc_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +0000859 }
860
Marcus Sundberg5c40da82005-10-08 18:15:00 +0000861 /* set message length */
862 len = msg_len_octets;
Joachim Bauch99a74822015-11-17 00:08:19 +0100863 if (extension_header) {
864 len += 12;
865 }
Marcus Sundberg5c40da82005-10-08 18:15:00 +0000866
jfigus67b9c732014-11-20 10:17:21 -0500867 debug_print(mod_driver, "before protection:\n%s",
868 srtp_packet_to_string(hdr, len));
869
870#if PRINT_REFERENCE_PACKET
871 debug_print(mod_driver, "reference packet before protection:\n%s",
872 octet_string_hex_string((uint8_t*)hdr, len));
873#endif
Cullen Jennings235513a2005-09-21 22:51:36 +0000874 err_check(srtp_protect(srtp_sender, hdr, &len));
Cullen Jennings235513a2005-09-21 22:51:36 +0000875
jfigus67b9c732014-11-20 10:17:21 -0500876 debug_print(mod_driver, "after protection:\n%s",
877 srtp_packet_to_string(hdr, len));
878#if PRINT_REFERENCE_PACKET
879 debug_print(mod_driver, "after protection:\n%s",
880 octet_string_hex_string((uint8_t*)hdr, len));
881#endif
882
883 /* save protected message and length */
884 memcpy(hdr_enc, hdr, len);
885 msg_len_enc = len;
886
887 /*
888 * check for overrun of the srtp_protect() function
889 *
890 * The packet is followed by a value of 0xfffff; if the value of the
891 * data following the packet is different, then we know that the
892 * protect function is overwriting the end of the packet.
893 */
894 pkt_end = (uint8_t*)hdr + sizeof(srtp_hdr_t)
895 + msg_len_octets + tag_length;
Joachim Bauch99a74822015-11-17 00:08:19 +0100896 if (extension_header) {
897 pkt_end += 12;
898 }
jfigus67b9c732014-11-20 10:17:21 -0500899 for (i = 0; i < 4; i++) {
900 if (pkt_end[i] != 0xff) {
901 fprintf(stdout, "overwrite in srtp_protect() function "
902 "(expected %x, found %x in trailing octet %d)\n",
903 0xff, ((uint8_t*)hdr)[i], i);
904 free(hdr);
905 free(hdr2);
906 return srtp_err_status_algo_fail;
907 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000908 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000909
jfigus67b9c732014-11-20 10:17:21 -0500910 /*
911 * if the policy includes confidentiality, check that ciphertext is
912 * different than plaintext
913 *
914 * Note that this check will give false negatives, with some small
915 * probability, especially if the packets are short. For that
916 * reason, we skip this check if the plaintext is less than four
917 * octets long.
918 */
919 if ((policy->rtp.sec_serv & sec_serv_conf) && (msg_len_octets >= 4)) {
920 printf("testing that ciphertext is distinct from plaintext...");
921 status = srtp_err_status_algo_fail;
922 for (i = 12; i < msg_len_octets + 12; i++) {
923 if (((uint8_t*)hdr)[i] != ((uint8_t*)hdr2)[i]) {
924 status = srtp_err_status_ok;
925 }
926 }
927 if (status) {
928 printf("failed\n");
929 free(hdr);
930 free(hdr2);
931 return status;
932 }
933 printf("passed\n");
934 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000935
jfigus67b9c732014-11-20 10:17:21 -0500936 /*
937 * if the policy uses a 'wildcard' ssrc, then we need to make a copy
938 * of the policy that changes the direction to inbound
939 *
940 * we always copy the policy into the rcvr_policy, since otherwise
941 * the compiler would fret about the constness of the policy
942 */
943 rcvr_policy = (srtp_policy_t*)malloc(sizeof(srtp_policy_t));
944 if (rcvr_policy == NULL) {
945 free(hdr);
946 free(hdr2);
947 return srtp_err_status_alloc_fail;
948 }
Joachim Bauch99a74822015-11-17 00:08:19 +0100949 if (extension_header) {
950 memcpy(rcvr_policy, &tmp_policy, sizeof(srtp_policy_t));
951 if (tmp_policy.ssrc.type == ssrc_any_outbound) {
952 rcvr_policy->ssrc.type = ssrc_any_inbound;
953 }
954 } else {
955 memcpy(rcvr_policy, policy, sizeof(srtp_policy_t));
956 if (policy->ssrc.type == ssrc_any_outbound) {
957 rcvr_policy->ssrc.type = ssrc_any_inbound;
958 }
jfigus67b9c732014-11-20 10:17:21 -0500959 }
960
961 err_check(srtp_create(&srtp_rcvr, rcvr_policy));
962
963 err_check(srtp_unprotect(srtp_rcvr, hdr, &len));
964
965 debug_print(mod_driver, "after unprotection:\n%s",
966 srtp_packet_to_string(hdr, len));
967
968 /* verify that the unprotected packet matches the origial one */
969 for (i = 0; i < msg_len_octets; i++) {
970 if (((uint8_t*)hdr)[i] != ((uint8_t*)hdr2)[i]) {
971 fprintf(stdout, "mismatch at octet %d\n", i);
972 status = srtp_err_status_algo_fail;
973 }
974 }
975 if (status) {
976 free(hdr);
977 free(hdr2);
978 free(rcvr_policy);
979 return status;
980 }
981
982 /*
983 * if the policy includes authentication, then test for false positives
984 */
985 if (policy->rtp.sec_serv & sec_serv_auth) {
986 char *data = ((char*)hdr) + 12;
987
988 printf("testing for false positives in replay check...");
989
990 /* set message length */
991 len = msg_len_enc;
992
993 /* unprotect a second time - should fail with a replay error */
994 status = srtp_unprotect(srtp_rcvr, hdr_enc, &len);
995 if (status != srtp_err_status_replay_fail) {
996 printf("failed with error code %d\n", status);
997 free(hdr);
998 free(hdr2);
999 free(rcvr_policy);
1000 return status;
1001 } else {
1002 printf("passed\n");
1003 }
1004
1005 printf("testing for false positives in auth check...");
1006
1007 /* increment sequence number in header */
1008 hdr->seq++;
1009
1010 /* set message length */
1011 len = msg_len_octets;
Joachim Bauch99a74822015-11-17 00:08:19 +01001012 if (extension_header) {
1013 len += 12;
1014 }
jfigus67b9c732014-11-20 10:17:21 -05001015
1016 /* apply protection */
1017 err_check(srtp_protect(srtp_sender, hdr, &len));
1018
1019 /* flip bits in packet */
Joachim Bauchfa1e8c22015-11-24 23:38:48 +01001020 data[extension_header ? 12 : 0] ^= 0xff;
jfigus67b9c732014-11-20 10:17:21 -05001021
1022 /* unprotect, and check for authentication failure */
1023 status = srtp_unprotect(srtp_rcvr, hdr, &len);
1024 if (status != srtp_err_status_auth_fail) {
1025 printf("failed\n");
1026 free(hdr);
1027 free(hdr2);
1028 free(rcvr_policy);
1029 return status;
1030 } else {
1031 printf("passed\n");
1032 }
1033
1034 }
1035
1036 err_check(srtp_dealloc(srtp_sender));
1037 err_check(srtp_dealloc(srtp_rcvr));
1038
1039 free(hdr);
1040 free(hdr2);
1041 free(rcvr_policy);
1042 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +00001043}
1044
1045
jfigus857009c2014-11-05 11:17:43 -05001046srtp_err_status_t
jfigus67b9c732014-11-20 10:17:21 -05001047srtcp_test (const srtp_policy_t *policy)
1048{
1049 int i;
1050 srtp_t srtcp_sender;
1051 srtp_t srtcp_rcvr;
1052 srtp_err_status_t status = srtp_err_status_ok;
1053 srtp_hdr_t *hdr, *hdr2;
1054 uint8_t hdr_enc[64];
1055 uint8_t *pkt_end;
1056 int msg_len_octets, msg_len_enc;
1057 int len;
1058 int tag_length = policy->rtp.auth_tag_len;
1059 uint32_t ssrc;
1060 srtp_policy_t *rcvr_policy;
David McGrew9c70f292006-05-03 19:38:38 +00001061
jfigus67b9c732014-11-20 10:17:21 -05001062 err_check(srtp_create(&srtcp_sender, policy));
David McGrew9c70f292006-05-03 19:38:38 +00001063
jfigus67b9c732014-11-20 10:17:21 -05001064 /* print out policy */
1065 err_check(srtp_session_print_policy(srtcp_sender));
David McGrew9c70f292006-05-03 19:38:38 +00001066
jfigus67b9c732014-11-20 10:17:21 -05001067 /*
1068 * initialize data buffer, using the ssrc in the policy unless that
1069 * value is a wildcard, in which case we'll just use an arbitrary
1070 * one
1071 */
1072 if (policy->ssrc.type != ssrc_specific) {
1073 ssrc = 0xdecafbad;
1074 } else{
1075 ssrc = policy->ssrc.value;
David McGrew9c70f292006-05-03 19:38:38 +00001076 }
jfigus67b9c732014-11-20 10:17:21 -05001077 msg_len_octets = 28;
1078 hdr = srtp_create_test_packet(msg_len_octets, ssrc);
David McGrew9c70f292006-05-03 19:38:38 +00001079
jfigus67b9c732014-11-20 10:17:21 -05001080 if (hdr == NULL) {
1081 return srtp_err_status_alloc_fail;
David McGrew9c70f292006-05-03 19:38:38 +00001082 }
jfigus67b9c732014-11-20 10:17:21 -05001083 hdr2 = srtp_create_test_packet(msg_len_octets, ssrc);
1084 if (hdr2 == NULL) {
1085 free(hdr);
1086 return srtp_err_status_alloc_fail;
David McGrew9c70f292006-05-03 19:38:38 +00001087 }
1088
David McGrew9c70f292006-05-03 19:38:38 +00001089 /* set message length */
1090 len = msg_len_octets;
1091
jfigus67b9c732014-11-20 10:17:21 -05001092 debug_print(mod_driver, "before protection:\n%s",
1093 srtp_packet_to_string(hdr, len));
1094
1095#if PRINT_REFERENCE_PACKET
1096 debug_print(mod_driver, "reference packet before protection:\n%s",
1097 octet_string_hex_string((uint8_t*)hdr, len));
1098#endif
David McGrew9c70f292006-05-03 19:38:38 +00001099 err_check(srtp_protect_rtcp(srtcp_sender, hdr, &len));
David McGrew9c70f292006-05-03 19:38:38 +00001100
jfigus67b9c732014-11-20 10:17:21 -05001101 debug_print(mod_driver, "after protection:\n%s",
1102 srtp_packet_to_string(hdr, len));
1103#if PRINT_REFERENCE_PACKET
1104 debug_print(mod_driver, "after protection:\n%s",
1105 octet_string_hex_string((uint8_t*)hdr, len));
1106#endif
1107
1108 /* save protected message and length */
1109 memcpy(hdr_enc, hdr, len);
1110 msg_len_enc = len;
1111
1112 /*
1113 * check for overrun of the srtp_protect() function
1114 *
1115 * The packet is followed by a value of 0xfffff; if the value of the
1116 * data following the packet is different, then we know that the
1117 * protect function is overwriting the end of the packet.
1118 */
1119 pkt_end = (uint8_t*)hdr + sizeof(srtp_hdr_t)
1120 + msg_len_octets + tag_length;
1121 for (i = 0; i < 4; i++) {
1122 if (pkt_end[i] != 0xff) {
1123 fprintf(stdout, "overwrite in srtp_protect_rtcp() function "
1124 "(expected %x, found %x in trailing octet %d)\n",
1125 0xff, ((uint8_t*)hdr)[i], i);
1126 free(hdr);
1127 free(hdr2);
1128 return srtp_err_status_algo_fail;
1129 }
David McGrew9c70f292006-05-03 19:38:38 +00001130 }
David McGrew9c70f292006-05-03 19:38:38 +00001131
jfigus67b9c732014-11-20 10:17:21 -05001132 /*
1133 * if the policy includes confidentiality, check that ciphertext is
1134 * different than plaintext
1135 *
1136 * Note that this check will give false negatives, with some small
1137 * probability, especially if the packets are short. For that
1138 * reason, we skip this check if the plaintext is less than four
1139 * octets long.
1140 */
1141 if ((policy->rtp.sec_serv & sec_serv_conf) && (msg_len_octets >= 4)) {
1142 printf("testing that ciphertext is distinct from plaintext...");
1143 status = srtp_err_status_algo_fail;
1144 for (i = 12; i < msg_len_octets + 12; i++) {
1145 if (((uint8_t*)hdr)[i] != ((uint8_t*)hdr2)[i]) {
1146 status = srtp_err_status_ok;
1147 }
1148 }
1149 if (status) {
1150 printf("failed\n");
1151 free(hdr);
1152 free(hdr2);
1153 return status;
1154 }
1155 printf("passed\n");
1156 }
David McGrew9c70f292006-05-03 19:38:38 +00001157
jfigus67b9c732014-11-20 10:17:21 -05001158 /*
1159 * if the policy uses a 'wildcard' ssrc, then we need to make a copy
1160 * of the policy that changes the direction to inbound
1161 *
1162 * we always copy the policy into the rcvr_policy, since otherwise
1163 * the compiler would fret about the constness of the policy
1164 */
1165 rcvr_policy = (srtp_policy_t*)malloc(sizeof(srtp_policy_t));
1166 if (rcvr_policy == NULL) {
1167 return srtp_err_status_alloc_fail;
1168 }
1169 memcpy(rcvr_policy, policy, sizeof(srtp_policy_t));
1170 if (policy->ssrc.type == ssrc_any_outbound) {
1171 rcvr_policy->ssrc.type = ssrc_any_inbound;
1172 }
1173
1174 err_check(srtp_create(&srtcp_rcvr, rcvr_policy));
1175
1176 err_check(srtp_unprotect_rtcp(srtcp_rcvr, hdr, &len));
1177
1178 debug_print(mod_driver, "after unprotection:\n%s",
1179 srtp_packet_to_string(hdr, len));
1180
1181 /* verify that the unprotected packet matches the origial one */
1182 for (i = 0; i < msg_len_octets; i++) {
1183 if (((uint8_t*)hdr)[i] != ((uint8_t*)hdr2)[i]) {
1184 fprintf(stdout, "mismatch at octet %d\n", i);
1185 status = srtp_err_status_algo_fail;
1186 }
1187 }
1188 if (status) {
1189 free(hdr);
1190 free(hdr2);
1191 free(rcvr_policy);
1192 return status;
1193 }
1194
1195 /*
1196 * if the policy includes authentication, then test for false positives
1197 */
1198 if (policy->rtp.sec_serv & sec_serv_auth) {
1199 char *data = ((char*)hdr) + 12;
1200
1201 printf("testing for false positives in replay check...");
1202
1203 /* set message length */
1204 len = msg_len_enc;
1205
1206 /* unprotect a second time - should fail with a replay error */
1207 status = srtp_unprotect_rtcp(srtcp_rcvr, hdr_enc, &len);
1208 if (status != srtp_err_status_replay_fail) {
1209 printf("failed with error code %d\n", status);
1210 free(hdr);
1211 free(hdr2);
1212 free(rcvr_policy);
1213 return status;
1214 } else {
1215 printf("passed\n");
1216 }
1217
1218 printf("testing for false positives in auth check...");
1219
1220 /* increment sequence number in header */
1221 hdr->seq++;
1222
1223 /* set message length */
1224 len = msg_len_octets;
1225
1226 /* apply protection */
1227 err_check(srtp_protect_rtcp(srtcp_sender, hdr, &len));
1228
1229 /* flip bits in packet */
1230 data[0] ^= 0xff;
1231
1232 /* unprotect, and check for authentication failure */
1233 status = srtp_unprotect_rtcp(srtcp_rcvr, hdr, &len);
1234 if (status != srtp_err_status_auth_fail) {
1235 printf("failed\n");
1236 free(hdr);
1237 free(hdr2);
1238 free(rcvr_policy);
1239 return status;
1240 } else {
1241 printf("passed\n");
1242 }
1243
1244 }
1245
1246 err_check(srtp_dealloc(srtcp_sender));
1247 err_check(srtp_dealloc(srtcp_rcvr));
1248
1249 free(hdr);
1250 free(hdr2);
1251 free(rcvr_policy);
1252 return srtp_err_status_ok;
David McGrew9c70f292006-05-03 19:38:38 +00001253}
1254
1255
jfigus857009c2014-11-05 11:17:43 -05001256srtp_err_status_t
jfigus67b9c732014-11-20 10:17:21 -05001257srtp_session_print_policy (srtp_t srtp)
1258{
1259 char *serv_descr[4] = {
1260 "none",
1261 "confidentiality",
1262 "authentication",
1263 "confidentiality and authentication"
1264 };
1265 char *direction[3] = {
1266 "unknown",
1267 "outbound",
1268 "inbound"
1269 };
1270 srtp_stream_t stream;
Cullen Jennings235513a2005-09-21 22:51:36 +00001271
jfigus67b9c732014-11-20 10:17:21 -05001272 /* sanity checking */
1273 if (srtp == NULL) {
1274 return srtp_err_status_fail;
1275 }
Cullen Jennings235513a2005-09-21 22:51:36 +00001276
jfigus67b9c732014-11-20 10:17:21 -05001277 /* if there's a template stream, print it out */
1278 if (srtp->stream_template != NULL) {
1279 stream = srtp->stream_template;
1280 printf("# SSRC: any %s\r\n"
1281 "# rtp cipher: %s\r\n"
1282 "# rtp auth: %s\r\n"
1283 "# rtp services: %s\r\n"
1284 "# rtcp cipher: %s\r\n"
1285 "# rtcp auth: %s\r\n"
1286 "# rtcp services: %s\r\n"
1287 "# window size: %lu\r\n"
1288 "# tx rtx allowed:%s\r\n",
1289 direction[stream->direction],
1290 stream->rtp_cipher->type->description,
1291 stream->rtp_auth->type->description,
1292 serv_descr[stream->rtp_services],
1293 stream->rtcp_cipher->type->description,
1294 stream->rtcp_auth->type->description,
1295 serv_descr[stream->rtcp_services],
jfigusde8deb32014-11-25 12:58:11 -05001296 srtp_rdbx_get_window_size(&stream->rtp_rdbx),
jfigus67b9c732014-11-20 10:17:21 -05001297 stream->allow_repeat_tx ? "true" : "false");
Joachim Bauch99a74822015-11-17 00:08:19 +01001298
1299 printf("# Encrypted extension headers: ");
1300 if (stream->enc_xtn_hdr && stream->enc_xtn_hdr_count > 0) {
1301 int* enc_xtn_hdr = stream->enc_xtn_hdr;
1302 int count = stream->enc_xtn_hdr_count;
1303 while (count > 0) {
1304 printf("%d ", *enc_xtn_hdr);
1305 enc_xtn_hdr++;
1306 count--;
1307 }
1308 printf("\n");
1309 } else {
1310 printf("none\n");
1311 }
jfigus67b9c732014-11-20 10:17:21 -05001312 }
Cullen Jennings235513a2005-09-21 22:51:36 +00001313
jfigus67b9c732014-11-20 10:17:21 -05001314 /* loop over streams in session, printing the policy of each */
1315 stream = srtp->stream_list;
1316 while (stream != NULL) {
1317 if (stream->rtp_services > sec_serv_conf_and_auth) {
1318 return srtp_err_status_bad_param;
1319 }
Cullen Jennings235513a2005-09-21 22:51:36 +00001320
jfigus67b9c732014-11-20 10:17:21 -05001321 printf("# SSRC: 0x%08x\r\n"
1322 "# rtp cipher: %s\r\n"
1323 "# rtp auth: %s\r\n"
1324 "# rtp services: %s\r\n"
1325 "# rtcp cipher: %s\r\n"
1326 "# rtcp auth: %s\r\n"
1327 "# rtcp services: %s\r\n"
1328 "# window size: %lu\r\n"
1329 "# tx rtx allowed:%s\r\n",
1330 stream->ssrc,
1331 stream->rtp_cipher->type->description,
1332 stream->rtp_auth->type->description,
1333 serv_descr[stream->rtp_services],
1334 stream->rtcp_cipher->type->description,
1335 stream->rtcp_auth->type->description,
1336 serv_descr[stream->rtcp_services],
jfigusde8deb32014-11-25 12:58:11 -05001337 srtp_rdbx_get_window_size(&stream->rtp_rdbx),
jfigus67b9c732014-11-20 10:17:21 -05001338 stream->allow_repeat_tx ? "true" : "false");
1339
Joachim Bauch99a74822015-11-17 00:08:19 +01001340 printf("# Encrypted extension headers: ");
1341 if (stream->enc_xtn_hdr && stream->enc_xtn_hdr_count > 0) {
1342 int* enc_xtn_hdr = stream->enc_xtn_hdr;
1343 int count = stream->enc_xtn_hdr_count;
1344 while (count > 0) {
1345 printf("%d ", *enc_xtn_hdr);
1346 enc_xtn_hdr++;
1347 count--;
1348 }
1349 printf("\n");
1350 } else {
1351 printf("none\n");
1352 }
1353
jfigus67b9c732014-11-20 10:17:21 -05001354 /* advance to next stream in the list */
1355 stream = stream->next;
1356 }
1357 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +00001358}
1359
jfigus857009c2014-11-05 11:17:43 -05001360srtp_err_status_t
jfigus67b9c732014-11-20 10:17:21 -05001361srtp_print_policy (const srtp_policy_t *policy)
1362{
1363 srtp_err_status_t status;
1364 srtp_t session;
Cullen Jennings235513a2005-09-21 22:51:36 +00001365
jfigus67b9c732014-11-20 10:17:21 -05001366 status = srtp_create(&session, policy);
1367 if (status) {
1368 return status;
1369 }
1370 status = srtp_session_print_policy(session);
1371 if (status) {
1372 return status;
1373 }
1374 status = srtp_dealloc(session);
1375 if (status) {
1376 return status;
1377 }
1378 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +00001379}
1380
jfigus67b9c732014-11-20 10:17:21 -05001381/*
1382 * srtp_print_packet(...) is for debugging only
Cullen Jennings235513a2005-09-21 22:51:36 +00001383 * it prints an RTP packet to the stdout
1384 *
1385 * note that this function is *not* threadsafe
1386 */
1387
1388#include <stdio.h>
1389
1390#define MTU 2048
1391
1392char packet_string[MTU];
1393
1394char *
jfigus67b9c732014-11-20 10:17:21 -05001395srtp_packet_to_string (srtp_hdr_t *hdr, int pkt_octet_len)
1396{
1397 int octets_in_rtp_header = 12;
1398 uint8_t *data = ((uint8_t*)hdr) + octets_in_rtp_header;
1399 int hex_len = pkt_octet_len - octets_in_rtp_header;
Cullen Jennings235513a2005-09-21 22:51:36 +00001400
jfigus67b9c732014-11-20 10:17:21 -05001401 /* sanity checking */
1402 if ((hdr == NULL) || (pkt_octet_len > MTU)) {
1403 return NULL;
1404 }
Cullen Jennings235513a2005-09-21 22:51:36 +00001405
jfigus67b9c732014-11-20 10:17:21 -05001406 /* write packet into string */
1407 sprintf(packet_string,
1408 "(s)rtp packet: {\n"
1409 " version:\t%d\n"
1410 " p:\t\t%d\n"
1411 " x:\t\t%d\n"
1412 " cc:\t\t%d\n"
1413 " m:\t\t%d\n"
1414 " pt:\t\t%x\n"
1415 " seq:\t\t%x\n"
1416 " ts:\t\t%x\n"
1417 " ssrc:\t%x\n"
1418 " data:\t%s\n"
1419 "} (%d octets in total)\n",
1420 hdr->version,
1421 hdr->p,
1422 hdr->x,
1423 hdr->cc,
1424 hdr->m,
1425 hdr->pt,
1426 hdr->seq,
1427 hdr->ts,
1428 hdr->ssrc,
1429 octet_string_hex_string(data, hex_len),
1430 pkt_octet_len);
Cullen Jennings235513a2005-09-21 22:51:36 +00001431
jfigus67b9c732014-11-20 10:17:21 -05001432 return packet_string;
Cullen Jennings235513a2005-09-21 22:51:36 +00001433}
1434
1435/*
1436 * mips_estimate() is a simple function to estimate the number of
1437 * instructions per second that the host can perform. note that this
1438 * function can be grossly wrong; you may want to have a manual sanity
1439 * check of its output!
1440 *
1441 * the 'ignore' pointer is there to convince the compiler to not just
1442 * optimize away the function
1443 */
1444
1445double
jfigus67b9c732014-11-20 10:17:21 -05001446mips_estimate (int num_trials, int *ignore)
1447{
1448 clock_t t;
1449 volatile int i, sum;
Cullen Jennings235513a2005-09-21 22:51:36 +00001450
jfigus67b9c732014-11-20 10:17:21 -05001451 sum = 0;
1452 t = clock();
1453 for (i = 0; i < num_trials; i++) {
1454 sum += i;
1455 }
1456 t = clock() - t;
Cullen Jennings235513a2005-09-21 22:51:36 +00001457
1458/* printf("%d\n", sum); */
jfigus67b9c732014-11-20 10:17:21 -05001459 *ignore = sum;
Cullen Jennings235513a2005-09-21 22:51:36 +00001460
jfigus67b9c732014-11-20 10:17:21 -05001461 return (double)num_trials * CLOCKS_PER_SEC / t;
Cullen Jennings235513a2005-09-21 22:51:36 +00001462}
1463
1464
1465/*
1466 * srtp_validate() verifies the correctness of libsrtp by comparing
1467 * some computed packets against some pre-computed reference values.
1468 * These packets were made with the default SRTP policy.
1469 */
1470
1471
jfigus857009c2014-11-05 11:17:43 -05001472srtp_err_status_t
jfigus67b9c732014-11-20 10:17:21 -05001473srtp_validate ()
1474{
1475 uint8_t srtp_plaintext_ref[28] = {
1476 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1477 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
1478 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1479 0xab, 0xab, 0xab, 0xab
1480 };
1481 uint8_t srtp_plaintext[38] = {
1482 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1483 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
1484 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1485 0xab, 0xab, 0xab, 0xab, 0x00, 0x00, 0x00, 0x00,
1486 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1487 };
1488 uint8_t srtp_ciphertext[38] = {
1489 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1490 0xca, 0xfe, 0xba, 0xbe, 0x4e, 0x55, 0xdc, 0x4c,
1491 0xe7, 0x99, 0x78, 0xd8, 0x8c, 0xa4, 0xd2, 0x15,
1492 0x94, 0x9d, 0x24, 0x02, 0xb7, 0x8d, 0x6a, 0xcc,
1493 0x99, 0xea, 0x17, 0x9b, 0x8d, 0xbb
1494 };
1495 srtp_t srtp_snd, srtp_recv;
1496 srtp_err_status_t status;
1497 int len;
1498 srtp_policy_t policy;
Cullen Jennings235513a2005-09-21 22:51:36 +00001499
jfigus67b9c732014-11-20 10:17:21 -05001500 /*
1501 * create a session with a single stream using the default srtp
1502 * policy and with the SSRC value 0xcafebabe
1503 */
Joachim Bauch99a74822015-11-17 00:08:19 +01001504 memset(&policy, 0, sizeof(policy));
jfigus67b9c732014-11-20 10:17:21 -05001505 srtp_crypto_policy_set_rtp_default(&policy.rtp);
1506 srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
1507 policy.ssrc.type = ssrc_specific;
1508 policy.ssrc.value = 0xcafebabe;
1509 policy.key = test_key;
1510 policy.ekt = NULL;
1511 policy.window_size = 128;
1512 policy.allow_repeat_tx = 0;
1513 policy.next = NULL;
Cullen Jennings235513a2005-09-21 22:51:36 +00001514
jfigus67b9c732014-11-20 10:17:21 -05001515 status = srtp_create(&srtp_snd, &policy);
1516 if (status) {
1517 return status;
1518 }
Cullen Jennings235513a2005-09-21 22:51:36 +00001519
jfigus67b9c732014-11-20 10:17:21 -05001520 /*
1521 * protect plaintext, then compare with ciphertext
1522 */
1523 len = 28;
1524 status = srtp_protect(srtp_snd, srtp_plaintext, &len);
1525 if (status || (len != 38)) {
1526 return srtp_err_status_fail;
1527 }
Cullen Jennings235513a2005-09-21 22:51:36 +00001528
jfigus67b9c732014-11-20 10:17:21 -05001529 debug_print(mod_driver, "ciphertext:\n %s",
1530 octet_string_hex_string(srtp_plaintext, len));
1531 debug_print(mod_driver, "ciphertext reference:\n %s",
1532 octet_string_hex_string(srtp_ciphertext, len));
Cullen Jennings235513a2005-09-21 22:51:36 +00001533
jfigus67b9c732014-11-20 10:17:21 -05001534 if (octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len)) {
1535 return srtp_err_status_fail;
1536 }
Jonathan Lennox80c4c832010-05-17 19:30:28 +00001537
jfigus67b9c732014-11-20 10:17:21 -05001538 /*
1539 * create a receiver session context comparable to the one created
1540 * above - we need to do this so that the replay checking doesn't
1541 * complain
1542 */
1543 status = srtp_create(&srtp_recv, &policy);
1544 if (status) {
1545 return status;
1546 }
Jonathan Lennox80c4c832010-05-17 19:30:28 +00001547
jfigus67b9c732014-11-20 10:17:21 -05001548 /*
1549 * unprotect ciphertext, then compare with plaintext
1550 */
1551 status = srtp_unprotect(srtp_recv, srtp_ciphertext, &len);
1552 if (status || (len != 28)) {
1553 return status;
1554 }
1555
1556 if (octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len)) {
1557 return srtp_err_status_fail;
1558 }
1559
1560 status = srtp_dealloc(srtp_snd);
1561 if (status) {
1562 return status;
1563 }
1564
1565 status = srtp_dealloc(srtp_recv);
1566 if (status) {
1567 return status;
1568 }
1569
1570 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +00001571}
1572
Paul E. Jonese2ab5f22016-05-29 16:18:24 -04001573#ifdef OPENSSL
1574/*
1575 * srtp_validate_gcm() verifies the correctness of libsrtp by comparing
1576 * an computed packet against the known ciphertext for the plaintext.
1577 */
1578srtp_err_status_t
1579srtp_validate_gcm ()
1580{
1581 unsigned char test_key_gcm[28] = {
1582 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1583 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
1584 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
1585 0xa8, 0xa9, 0xaa, 0xab
1586 };
Pascal Bühler45019ae2016-06-10 08:35:12 +02001587 uint8_t rtp_plaintext_ref[28] = {
Paul E. Jonese2ab5f22016-05-29 16:18:24 -04001588 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1589 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
1590 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1591 0xab, 0xab, 0xab, 0xab
1592 };
Pascal Bühler45019ae2016-06-10 08:35:12 +02001593 uint8_t rtp_plaintext[44] = {
Paul E. Jonese2ab5f22016-05-29 16:18:24 -04001594 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1595 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
1596 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1597 0xab, 0xab, 0xab, 0xab, 0x00, 0x00, 0x00, 0x00,
1598 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1599 0x00, 0x00, 0x00, 0x00
1600 };
1601 uint8_t srtp_ciphertext[44] = {
1602 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1603 0xca, 0xfe, 0xba, 0xbe, 0xc5, 0x00, 0x2e, 0xde,
1604 0x04, 0xcf, 0xdd, 0x2e, 0xb9, 0x11, 0x59, 0xe0,
1605 0x88, 0x0a, 0xa0, 0x6e, 0xd2, 0x97, 0x68, 0x26,
1606 0xf7, 0x96, 0xb2, 0x01, 0xdf, 0x31, 0x31, 0xa1,
1607 0x27, 0xe8, 0xa3, 0x92
1608 };
Pascal Bühler45019ae2016-06-10 08:35:12 +02001609 uint8_t rtcp_plaintext_ref[24] = {
1610 0x81, 0xc8, 0x00, 0x0b, 0xca, 0xfe, 0xba, 0xbe,
1611 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1612 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1613 };
1614 uint8_t rtcp_plaintext[44] = {
1615 0x81, 0xc8, 0x00, 0x0b, 0xca, 0xfe, 0xba, 0xbe,
1616 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1617 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1618 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1619 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1620 0x00, 0x00, 0x00, 0x00
1621 };
1622 uint8_t srtcp_ciphertext[44] = {
1623 0x81, 0xc8, 0x00, 0x0b, 0xca, 0xfe, 0xba, 0xbe,
1624 0xc9, 0x8b, 0x8b, 0x5d, 0xf0, 0x39, 0x2a, 0x55,
1625 0x85, 0x2b, 0x6c, 0x21, 0xac, 0x8e, 0x70, 0x25,
1626 0xc5, 0x2c, 0x6f, 0xbe, 0xa2, 0xb3, 0xb4, 0x46,
1627 0xea, 0x31, 0x12, 0x3b, 0xa8, 0x8c, 0xe6, 0x1e,
1628 0x80, 0x00, 0x00, 0x01
1629 };
1630
Paul E. Jonese2ab5f22016-05-29 16:18:24 -04001631 srtp_t srtp_snd, srtp_recv;
1632 srtp_err_status_t status;
1633 int len;
1634 srtp_policy_t policy;
1635
1636 /*
1637 * create a session with a single stream using the default srtp
1638 * policy and with the SSRC value 0xcafebabe
1639 */
1640 memset(&policy, 0, sizeof(policy));
1641 srtp_crypto_policy_set_aes_gcm_128_16_auth(&policy.rtp);
1642 srtp_crypto_policy_set_aes_gcm_128_16_auth(&policy.rtcp);
1643 policy.ssrc.type = ssrc_specific;
1644 policy.ssrc.value = 0xcafebabe;
1645 policy.key = test_key_gcm;
1646 policy.ekt = NULL;
1647 policy.window_size = 128;
1648 policy.allow_repeat_tx = 0;
1649 policy.next = NULL;
1650
1651 status = srtp_create(&srtp_snd, &policy);
1652 if (status) {
1653 return status;
1654 }
1655
1656 /*
Pascal Bühler45019ae2016-06-10 08:35:12 +02001657 * protect plaintext rtp, then compare with srtp ciphertext
Paul E. Jonese2ab5f22016-05-29 16:18:24 -04001658 */
1659 len = 28;
Pascal Bühler45019ae2016-06-10 08:35:12 +02001660 status = srtp_protect(srtp_snd, rtp_plaintext, &len);
Paul E. Jonese2ab5f22016-05-29 16:18:24 -04001661 if (status || (len != 44)) {
1662 return srtp_err_status_fail;
1663 }
1664
Pascal Bühler45019ae2016-06-10 08:35:12 +02001665 debug_print(mod_driver, "srtp ciphertext:\n %s",
1666 octet_string_hex_string(rtp_plaintext, len));
1667 debug_print(mod_driver, "srtp ciphertext reference:\n %s",
Paul E. Jonese2ab5f22016-05-29 16:18:24 -04001668 octet_string_hex_string(srtp_ciphertext, len));
1669
Pascal Bühler45019ae2016-06-10 08:35:12 +02001670 if (octet_string_is_eq(rtp_plaintext, srtp_ciphertext, len)) {
1671 return srtp_err_status_fail;
1672 }
1673
1674 /*
1675 * protect plaintext rtcp, then compare with srtcp ciphertext
1676 */
1677 len = 24;
1678 status = srtp_protect_rtcp(srtp_snd, rtcp_plaintext, &len);
1679 if (status || (len != 44)) {
1680 return srtp_err_status_fail;
1681 }
1682
1683 debug_print(mod_driver, "srtcp ciphertext:\n %s",
1684 octet_string_hex_string(rtcp_plaintext, len));
1685 debug_print(mod_driver, "srtcp ciphertext reference:\n %s",
1686 octet_string_hex_string(srtcp_ciphertext, len));
1687
1688 if (octet_string_is_eq(rtcp_plaintext, srtcp_ciphertext, len)) {
Paul E. Jonese2ab5f22016-05-29 16:18:24 -04001689 return srtp_err_status_fail;
1690 }
1691
1692 /*
1693 * create a receiver session context comparable to the one created
1694 * above - we need to do this so that the replay checking doesn't
1695 * complain
1696 */
1697 status = srtp_create(&srtp_recv, &policy);
1698 if (status) {
1699 return status;
1700 }
1701
1702 /*
Pascal Bühler45019ae2016-06-10 08:35:12 +02001703 * unprotect srtp ciphertext, then compare with rtp plaintext
Paul E. Jonese2ab5f22016-05-29 16:18:24 -04001704 */
Pascal Bühler45019ae2016-06-10 08:35:12 +02001705 len = 44;
Paul E. Jonese2ab5f22016-05-29 16:18:24 -04001706 status = srtp_unprotect(srtp_recv, srtp_ciphertext, &len);
1707 if (status || (len != 28)) {
1708 return status;
1709 }
1710
Pascal Bühler45019ae2016-06-10 08:35:12 +02001711 if (octet_string_is_eq(srtp_ciphertext, rtp_plaintext_ref, len)) {
1712 return srtp_err_status_fail;
1713 }
1714
1715 /*
1716 * unprotect srtcp ciphertext, then compare with rtcp plaintext
1717 */
1718 len = 44;
1719 status = srtp_unprotect_rtcp(srtp_recv, srtcp_ciphertext, &len);
1720 if (status || (len != 24)) {
1721 return status;
1722 }
1723
1724 if (octet_string_is_eq(srtcp_ciphertext, rtcp_plaintext_ref, len)) {
Paul E. Jonese2ab5f22016-05-29 16:18:24 -04001725 return srtp_err_status_fail;
1726 }
1727
1728 status = srtp_dealloc(srtp_snd);
1729 if (status) {
1730 return status;
1731 }
1732
1733 status = srtp_dealloc(srtp_recv);
1734 if (status) {
1735 return status;
1736 }
1737
1738 return srtp_err_status_ok;
1739}
1740#endif
1741
Joachim Bauch99a74822015-11-17 00:08:19 +01001742/*
1743 * Test vectors taken from RFC 6904, Appendix A
1744 */
1745srtp_err_status_t
1746srtp_validate_encrypted_extensions_headers() {
1747 unsigned char test_key_ext_headers[30] = {
1748 0xe1, 0xf9, 0x7a, 0x0d, 0x3e, 0x01, 0x8b, 0xe0,
1749 0xd6, 0x4f, 0xa3, 0x2c, 0x06, 0xde, 0x41, 0x39,
1750 0x0e, 0xc6, 0x75, 0xad, 0x49, 0x8a, 0xfe, 0xeb,
1751 0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6
1752 };
1753 uint8_t srtp_plaintext_ref[56] = {
1754 0x90, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1755 0xca, 0xfe, 0xba, 0xbe, 0xBE, 0xDE, 0x00, 0x06,
1756 0x17, 0x41, 0x42, 0x73, 0xA4, 0x75, 0x26, 0x27,
1757 0x48, 0x22, 0x00, 0x00, 0xC8, 0x30, 0x8E, 0x46,
1758 0x55, 0x99, 0x63, 0x86, 0xB3, 0x95, 0xFB, 0x00,
1759 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1760 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab
1761 };
1762 uint8_t srtp_plaintext[66] = {
1763 0x90, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1764 0xca, 0xfe, 0xba, 0xbe, 0xBE, 0xDE, 0x00, 0x06,
1765 0x17, 0x41, 0x42, 0x73, 0xA4, 0x75, 0x26, 0x27,
1766 0x48, 0x22, 0x00, 0x00, 0xC8, 0x30, 0x8E, 0x46,
1767 0x55, 0x99, 0x63, 0x86, 0xB3, 0x95, 0xFB, 0x00,
1768 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1769 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1770 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1771 0x00, 0x00
1772 };
1773 uint8_t srtp_ciphertext[66] = {
1774 0x90, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1775 0xca, 0xfe, 0xba, 0xbe, 0xBE, 0xDE, 0x00, 0x06,
1776 0x17, 0x58, 0x8A, 0x92, 0x70, 0xF4, 0xE1, 0x5E,
1777 0x1C, 0x22, 0x00, 0x00, 0xC8, 0x30, 0x95, 0x46,
1778 0xA9, 0x94, 0xF0, 0xBC, 0x54, 0x78, 0x97, 0x00,
1779 0x4e, 0x55, 0xdc, 0x4c, 0xe7, 0x99, 0x78, 0xd8,
1780 0x8c, 0xa4, 0xd2, 0x15, 0x94, 0x9d, 0x24, 0x02,
1781 0x5a, 0x46, 0xb3, 0xca, 0x35, 0xc5, 0x35, 0xa8,
1782 0x91, 0xc7
1783 };
1784 srtp_t srtp_snd, srtp_recv;
1785 srtp_err_status_t status;
1786 int len;
1787 srtp_policy_t policy;
1788 int headers[3] = {1, 3, 4};
1789
1790 /*
1791 * create a session with a single stream using the default srtp
1792 * policy and with the SSRC value 0xcafebabe
1793 */
1794 memset(&policy, 0, sizeof(policy));
1795 srtp_crypto_policy_set_rtp_default(&policy.rtp);
1796 srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
1797 policy.ssrc.type = ssrc_specific;
1798 policy.ssrc.value = 0xcafebabe;
1799 policy.key = test_key_ext_headers;
1800 policy.ekt = NULL;
1801 policy.window_size = 128;
1802 policy.allow_repeat_tx = 0;
1803 policy.enc_xtn_hdr = headers;
1804 policy.enc_xtn_hdr_count = sizeof(headers) / sizeof(headers[0]);
1805 policy.next = NULL;
1806
1807 status = srtp_create(&srtp_snd, &policy);
1808 if (status)
1809 return status;
1810
1811 /*
1812 * protect plaintext, then compare with ciphertext
1813 */
1814 len = sizeof(srtp_plaintext_ref);
1815 status = srtp_protect(srtp_snd, srtp_plaintext, &len);
1816 if (status || (len != sizeof(srtp_plaintext)))
1817 return srtp_err_status_fail;
1818
1819 debug_print(mod_driver, "ciphertext:\n %s",
1820 srtp_octet_string_hex_string(srtp_plaintext, len));
1821 debug_print(mod_driver, "ciphertext reference:\n %s",
1822 srtp_octet_string_hex_string(srtp_ciphertext, len));
1823
1824 if (octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len))
1825 return srtp_err_status_fail;
1826
1827 /*
1828 * create a receiver session context comparable to the one created
1829 * above - we need to do this so that the replay checking doesn't
1830 * complain
1831 */
1832 status = srtp_create(&srtp_recv, &policy);
1833 if (status)
1834 return status;
1835
1836 /*
1837 * unprotect ciphertext, then compare with plaintext
1838 */
1839 status = srtp_unprotect(srtp_recv, srtp_ciphertext, &len);
Joachim Baucha9ecefe2015-12-14 21:40:42 +01001840 if (status) {
Joachim Bauch99a74822015-11-17 00:08:19 +01001841 return status;
Joachim Baucha9ecefe2015-12-14 21:40:42 +01001842 } else if (len != sizeof(srtp_plaintext_ref)) {
1843 return srtp_err_status_fail;
1844 }
Joachim Bauch99a74822015-11-17 00:08:19 +01001845
1846 if (octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len))
1847 return srtp_err_status_fail;
1848
1849 status = srtp_dealloc(srtp_snd);
1850 if (status)
1851 return status;
1852
1853 status = srtp_dealloc(srtp_recv);
1854 if (status)
1855 return status;
1856
1857 return srtp_err_status_ok;
1858}
1859
Cullen Jennings235513a2005-09-21 22:51:36 +00001860
Joachim Bauch80a45b52015-12-06 22:57:58 +01001861#ifdef OPENSSL
Joachim Baucha9ecefe2015-12-14 21:40:42 +01001862
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001863/*
Joachim Bauchfa1e8c22015-11-24 23:38:48 +01001864 * Headers of test vectors taken from RFC 6904, Appendix A
1865 */
1866srtp_err_status_t
1867srtp_validate_encrypted_extensions_headers_gcm() {
1868 unsigned char test_key_ext_headers[30] = {
1869 0xe1, 0xf9, 0x7a, 0x0d, 0x3e, 0x01, 0x8b, 0xe0,
1870 0xd6, 0x4f, 0xa3, 0x2c, 0x06, 0xde, 0x41, 0x39,
1871 0x0e, 0xc6, 0x75, 0xad, 0x49, 0x8a, 0xfe, 0xeb,
1872 0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6
1873 };
1874 uint8_t srtp_plaintext_ref[56] = {
1875 0x90, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1876 0xca, 0xfe, 0xba, 0xbe, 0xBE, 0xDE, 0x00, 0x06,
1877 0x17, 0x41, 0x42, 0x73, 0xA4, 0x75, 0x26, 0x27,
1878 0x48, 0x22, 0x00, 0x00, 0xC8, 0x30, 0x8E, 0x46,
1879 0x55, 0x99, 0x63, 0x86, 0xB3, 0x95, 0xFB, 0x00,
1880 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1881 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab
1882 };
1883 uint8_t srtp_plaintext[64] = {
1884 0x90, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1885 0xca, 0xfe, 0xba, 0xbe, 0xBE, 0xDE, 0x00, 0x06,
1886 0x17, 0x41, 0x42, 0x73, 0xA4, 0x75, 0x26, 0x27,
1887 0x48, 0x22, 0x00, 0x00, 0xC8, 0x30, 0x8E, 0x46,
1888 0x55, 0x99, 0x63, 0x86, 0xB3, 0x95, 0xFB, 0x00,
1889 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1890 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1891 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1892 };
1893 uint8_t srtp_ciphertext[64] = {
1894 0x90, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1895 0xca, 0xfe, 0xba, 0xbe, 0xBE, 0xDE, 0x00, 0x06,
1896 0x17, 0x58, 0x8A, 0x92, 0x70, 0xF4, 0xE1, 0x5E,
1897 0x1C, 0x22, 0x00, 0x00, 0xC8, 0x30, 0x95, 0x46,
1898 0xA9, 0x94, 0xF0, 0xBC, 0x54, 0x78, 0x97, 0x00,
1899 0x0e, 0xca, 0x0c, 0xf9, 0x5e, 0xe9, 0x55, 0xb2,
1900 0x6c, 0xd3, 0xd2, 0x88, 0xb4, 0x9f, 0x6c, 0xa9,
1901 0xbb, 0x4e, 0x15, 0xc2, 0xe9, 0xf2, 0x66, 0x78
1902 };
1903 srtp_t srtp_snd, srtp_recv;
1904 srtp_err_status_t status;
1905 int len;
1906 srtp_policy_t policy;
1907 int headers[3] = {1, 3, 4};
1908
1909 /*
1910 * create a session with a single stream using the default srtp
1911 * policy and with the SSRC value 0xcafebabe
1912 */
1913 memset(&policy, 0, sizeof(policy));
1914 srtp_crypto_policy_set_aes_gcm_128_8_auth(&policy.rtp);
1915 srtp_crypto_policy_set_aes_gcm_128_8_auth(&policy.rtcp);
1916 policy.ssrc.type = ssrc_specific;
1917 policy.ssrc.value = 0xcafebabe;
1918 policy.key = test_key_ext_headers;
1919 policy.ekt = NULL;
1920 policy.window_size = 128;
1921 policy.allow_repeat_tx = 0;
1922 policy.enc_xtn_hdr = headers;
1923 policy.enc_xtn_hdr_count = sizeof(headers) / sizeof(headers[0]);
1924 policy.next = NULL;
1925
1926 status = srtp_create(&srtp_snd, &policy);
1927 if (status)
1928 return status;
1929
1930 /*
1931 * protect plaintext, then compare with ciphertext
1932 */
1933 len = sizeof(srtp_plaintext_ref);
1934 status = srtp_protect(srtp_snd, srtp_plaintext, &len);
1935 if (status || (len != sizeof(srtp_plaintext)))
1936 return srtp_err_status_fail;
1937
1938 debug_print(mod_driver, "ciphertext:\n %s",
1939 srtp_octet_string_hex_string(srtp_plaintext, len));
1940 debug_print(mod_driver, "ciphertext reference:\n %s",
1941 srtp_octet_string_hex_string(srtp_ciphertext, len));
1942
1943 if (octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len))
1944 return srtp_err_status_fail;
1945
1946 /*
1947 * create a receiver session context comparable to the one created
1948 * above - we need to do this so that the replay checking doesn't
1949 * complain
1950 */
1951 status = srtp_create(&srtp_recv, &policy);
1952 if (status)
1953 return status;
1954
1955 /*
1956 * unprotect ciphertext, then compare with plaintext
1957 */
1958 status = srtp_unprotect(srtp_recv, srtp_ciphertext, &len);
Joachim Baucha9ecefe2015-12-14 21:40:42 +01001959 if (status) {
Joachim Bauchfa1e8c22015-11-24 23:38:48 +01001960 return status;
Joachim Baucha9ecefe2015-12-14 21:40:42 +01001961 } else if (len != sizeof(srtp_plaintext_ref)) {
1962 return srtp_err_status_fail;
1963 }
Joachim Bauchfa1e8c22015-11-24 23:38:48 +01001964
1965 if (octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len))
1966 return srtp_err_status_fail;
1967
1968 status = srtp_dealloc(srtp_snd);
1969 if (status)
1970 return status;
1971
1972 status = srtp_dealloc(srtp_recv);
1973 if (status)
1974 return status;
1975
1976 return srtp_err_status_ok;
1977}
Joachim Bauch80a45b52015-12-06 22:57:58 +01001978#endif
Cullen Jennings235513a2005-09-21 22:51:36 +00001979
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001980/*
1981 * srtp_validate_aes_256() verifies the correctness of libsrtp by comparing
1982 * some computed packets against some pre-computed reference values.
1983 * These packets were made with the AES-CM-256/HMAC-SHA-1-80 policy.
1984 */
1985
1986
jfigus857009c2014-11-05 11:17:43 -05001987srtp_err_status_t
jfigus67b9c732014-11-20 10:17:21 -05001988srtp_validate_aes_256 ()
1989{
1990 unsigned char aes_256_test_key[46] = {
1991 0xf0, 0xf0, 0x49, 0x14, 0xb5, 0x13, 0xf2, 0x76,
1992 0x3a, 0x1b, 0x1f, 0xa1, 0x30, 0xf1, 0x0e, 0x29,
1993 0x98, 0xf6, 0xf6, 0xe4, 0x3e, 0x43, 0x09, 0xd1,
1994 0xe6, 0x22, 0xa0, 0xe3, 0x32, 0xb9, 0xf1, 0xb6,
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001995
jfigus67b9c732014-11-20 10:17:21 -05001996 0x3b, 0x04, 0x80, 0x3d, 0xe5, 0x1e, 0xe7, 0xc9,
1997 0x64, 0x23, 0xab, 0x5b, 0x78, 0xd2
1998 };
1999 uint8_t srtp_plaintext_ref[28] = {
2000 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
2001 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
2002 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
2003 0xab, 0xab, 0xab, 0xab
2004 };
2005 uint8_t srtp_plaintext[38] = {
2006 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
2007 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
2008 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
2009 0xab, 0xab, 0xab, 0xab, 0x00, 0x00, 0x00, 0x00,
2010 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
2011 };
2012 uint8_t srtp_ciphertext[38] = {
2013 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
2014 0xca, 0xfe, 0xba, 0xbe, 0xf1, 0xd9, 0xde, 0x17,
2015 0xff, 0x25, 0x1f, 0xf1, 0xaa, 0x00, 0x77, 0x74,
2016 0xb0, 0xb4, 0xb4, 0x0d, 0xa0, 0x8d, 0x9d, 0x9a,
2017 0x5b, 0x3a, 0x55, 0xd8, 0x87, 0x3b
2018 };
2019 srtp_t srtp_snd, srtp_recv;
2020 srtp_err_status_t status;
2021 int len;
2022 srtp_policy_t policy;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002023
jfigus67b9c732014-11-20 10:17:21 -05002024 /*
2025 * create a session with a single stream using the default srtp
2026 * policy and with the SSRC value 0xcafebabe
2027 */
Joachim Bauch99a74822015-11-17 00:08:19 +01002028 memset(&policy, 0, sizeof(policy));
jfigus67b9c732014-11-20 10:17:21 -05002029 srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(&policy.rtp);
2030 srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(&policy.rtcp);
2031 policy.ssrc.type = ssrc_specific;
2032 policy.ssrc.value = 0xcafebabe;
2033 policy.key = aes_256_test_key;
2034 policy.ekt = NULL;
2035 policy.window_size = 128;
2036 policy.allow_repeat_tx = 0;
2037 policy.next = NULL;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002038
jfigus67b9c732014-11-20 10:17:21 -05002039 status = srtp_create(&srtp_snd, &policy);
2040 if (status) {
2041 return status;
2042 }
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002043
jfigus67b9c732014-11-20 10:17:21 -05002044 /*
2045 * protect plaintext, then compare with ciphertext
2046 */
2047 len = 28;
2048 status = srtp_protect(srtp_snd, srtp_plaintext, &len);
2049 if (status || (len != 38)) {
2050 return srtp_err_status_fail;
2051 }
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002052
jfigus67b9c732014-11-20 10:17:21 -05002053 debug_print(mod_driver, "ciphertext:\n %s",
2054 octet_string_hex_string(srtp_plaintext, len));
2055 debug_print(mod_driver, "ciphertext reference:\n %s",
2056 octet_string_hex_string(srtp_ciphertext, len));
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002057
jfigus67b9c732014-11-20 10:17:21 -05002058 if (octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len)) {
2059 return srtp_err_status_fail;
2060 }
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002061
jfigus67b9c732014-11-20 10:17:21 -05002062 /*
2063 * create a receiver session context comparable to the one created
2064 * above - we need to do this so that the replay checking doesn't
2065 * complain
2066 */
2067 status = srtp_create(&srtp_recv, &policy);
2068 if (status) {
2069 return status;
2070 }
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002071
jfigus67b9c732014-11-20 10:17:21 -05002072 /*
2073 * unprotect ciphertext, then compare with plaintext
2074 */
2075 status = srtp_unprotect(srtp_recv, srtp_ciphertext, &len);
2076 if (status || (len != 28)) {
2077 return status;
2078 }
2079
2080 if (octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len)) {
2081 return srtp_err_status_fail;
2082 }
2083
2084 status = srtp_dealloc(srtp_snd);
2085 if (status) {
2086 return status;
2087 }
2088
2089 status = srtp_dealloc(srtp_recv);
2090 if (status) {
2091 return status;
2092 }
2093
2094 return srtp_err_status_ok;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002095}
2096
2097
jfigus857009c2014-11-05 11:17:43 -05002098srtp_err_status_t
jfigus67b9c732014-11-20 10:17:21 -05002099srtp_create_big_policy (srtp_policy_t **list)
2100{
2101 extern const srtp_policy_t *policy_array[];
2102 srtp_policy_t *p, *tmp;
2103 int i = 0;
2104 uint32_t ssrc = 0;
Cullen Jennings235513a2005-09-21 22:51:36 +00002105
jfigus67b9c732014-11-20 10:17:21 -05002106 /* sanity checking */
2107 if ((list == NULL) || (policy_array[0] == NULL)) {
2108 return srtp_err_status_bad_param;
2109 }
Cullen Jennings235513a2005-09-21 22:51:36 +00002110
jfigus67b9c732014-11-20 10:17:21 -05002111 /*
2112 * loop over policy list, mallocing a new list and copying values
2113 * into it (and incrementing the SSRC value as we go along)
2114 */
2115 tmp = NULL;
2116 while (policy_array[i] != NULL) {
2117 p = (srtp_policy_t*)malloc(sizeof(srtp_policy_t));
2118 if (p == NULL) {
2119 return srtp_err_status_bad_param;
2120 }
2121 memcpy(p, policy_array[i], sizeof(srtp_policy_t));
2122 p->ssrc.type = ssrc_specific;
2123 p->ssrc.value = ssrc++;
2124 p->next = tmp;
2125 tmp = p;
2126 i++;
2127 }
2128 *list = p;
2129
2130 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +00002131}
2132
jfigus857009c2014-11-05 11:17:43 -05002133srtp_err_status_t
jfigus67b9c732014-11-20 10:17:21 -05002134srtp_dealloc_big_policy (srtp_policy_t *list)
2135{
2136 srtp_policy_t *p, *next;
Jonathan Lennox80c4c832010-05-17 19:30:28 +00002137
jfigus67b9c732014-11-20 10:17:21 -05002138 for (p = list; p != NULL; p = next) {
2139 next = p->next;
2140 free(p);
2141 }
Jonathan Lennox80c4c832010-05-17 19:30:28 +00002142
jfigus67b9c732014-11-20 10:17:21 -05002143 return srtp_err_status_ok;
Jonathan Lennox80c4c832010-05-17 19:30:28 +00002144}
2145
Joachim Bauchc8a19ae2015-12-14 22:50:36 +01002146srtp_err_status_t
2147srtp_test_empty_payload()
2148{
2149 srtp_t srtp_snd, srtp_recv;
2150 srtp_err_status_t status;
2151 int len;
2152 srtp_policy_t policy;
2153 srtp_hdr_t *mesg;
2154
2155 /*
2156 * create a session with a single stream using the default srtp
2157 * policy and with the SSRC value 0xcafebabe
2158 */
2159 memset(&policy, 0, sizeof(policy));
2160 srtp_crypto_policy_set_rtp_default(&policy.rtp);
2161 srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
2162 policy.ssrc.type = ssrc_specific;
2163 policy.ssrc.value = 0xcafebabe;
2164 policy.key = test_key;
2165 policy.ekt = NULL;
2166 policy.window_size = 128;
2167 policy.allow_repeat_tx = 0;
2168 policy.next = NULL;
2169
2170 status = srtp_create(&srtp_snd, &policy);
2171 if (status) {
2172 return status;
2173 }
2174
2175 mesg = srtp_create_test_packet(0, policy.ssrc.value);
2176 if (mesg == NULL) {
2177 return srtp_err_status_fail;
2178 }
2179
2180 len = 12; /* only the header */
2181 status = srtp_protect(srtp_snd, mesg, &len);
2182 if (status) {
2183 return status;
2184 } else if (len != 12 + 10) {
2185 return srtp_err_status_fail;
2186 }
2187
2188 /*
2189 * create a receiver session context comparable to the one created
2190 * above - we need to do this so that the replay checking doesn't
2191 * complain
2192 */
2193 status = srtp_create(&srtp_recv, &policy);
2194 if (status) {
2195 return status;
2196 }
2197
2198 /*
2199 * unprotect ciphertext, then compare with plaintext
2200 */
2201 status = srtp_unprotect(srtp_recv, mesg, &len);
2202 if (status) {
2203 return status;
2204 } else if (len != 12) {
2205 return srtp_err_status_fail;
2206 }
2207
2208 status = srtp_dealloc(srtp_snd);
2209 if (status) {
2210 return status;
2211 }
2212
2213 status = srtp_dealloc(srtp_recv);
2214 if (status) {
2215 return status;
2216 }
2217
2218 free(mesg);
2219
2220 return srtp_err_status_ok;
2221}
2222
2223#ifdef OPENSSL
2224srtp_err_status_t
2225srtp_test_empty_payload_gcm()
2226{
2227 srtp_t srtp_snd, srtp_recv;
2228 srtp_err_status_t status;
2229 int len;
2230 srtp_policy_t policy;
2231 srtp_hdr_t *mesg;
2232
2233 /*
2234 * create a session with a single stream using the default srtp
2235 * policy and with the SSRC value 0xcafebabe
2236 */
2237 memset(&policy, 0, sizeof(policy));
2238 srtp_crypto_policy_set_aes_gcm_128_8_auth(&policy.rtp);
2239 srtp_crypto_policy_set_aes_gcm_128_8_auth(&policy.rtcp);
2240 policy.ssrc.type = ssrc_specific;
2241 policy.ssrc.value = 0xcafebabe;
2242 policy.key = test_key;
2243 policy.ekt = NULL;
2244 policy.window_size = 128;
2245 policy.allow_repeat_tx = 0;
2246 policy.next = NULL;
2247
2248 status = srtp_create(&srtp_snd, &policy);
2249 if (status) {
2250 return status;
2251 }
2252
2253 mesg = srtp_create_test_packet(0, policy.ssrc.value);
2254 if (mesg == NULL) {
2255 return srtp_err_status_fail;
2256 }
2257
2258 len = 12; /* only the header */
2259 status = srtp_protect(srtp_snd, mesg, &len);
2260 if (status) {
2261 return status;
2262 } else if (len != 12 + 8) {
2263 return srtp_err_status_fail;
2264 }
2265
2266 /*
2267 * create a receiver session context comparable to the one created
2268 * above - we need to do this so that the replay checking doesn't
2269 * complain
2270 */
2271 status = srtp_create(&srtp_recv, &policy);
2272 if (status) {
2273 return status;
2274 }
2275
2276 /*
2277 * unprotect ciphertext, then compare with plaintext
2278 */
2279 status = srtp_unprotect(srtp_recv, mesg, &len);
2280 if (status) {
2281 return status;
2282 } else if (len != 12) {
2283 return srtp_err_status_fail;
2284 }
2285
2286 status = srtp_dealloc(srtp_snd);
2287 if (status) {
2288 return status;
2289 }
2290
2291 status = srtp_dealloc(srtp_recv);
2292 if (status) {
2293 return status;
2294 }
2295
2296 free(mesg);
2297
2298 return srtp_err_status_ok;
2299}
2300#endif // OPENSSL
Jonathan Lennox80c4c832010-05-17 19:30:28 +00002301
jfigus857009c2014-11-05 11:17:43 -05002302srtp_err_status_t
jfigus67b9c732014-11-20 10:17:21 -05002303srtp_test_remove_stream ()
2304{
2305 srtp_err_status_t status;
2306 srtp_policy_t *policy_list, policy;
2307 srtp_t session;
2308 srtp_stream_t stream;
Cullen Jennings235513a2005-09-21 22:51:36 +00002309
jfigus67b9c732014-11-20 10:17:21 -05002310 /*
2311 * srtp_get_stream() is a libSRTP internal function that we declare
2312 * here so that we can use it to verify the correct operation of the
2313 * library
2314 */
2315 extern srtp_stream_t srtp_get_stream(srtp_t srtp, uint32_t ssrc);
Cullen Jennings235513a2005-09-21 22:51:36 +00002316
Cullen Jennings235513a2005-09-21 22:51:36 +00002317
jfigus67b9c732014-11-20 10:17:21 -05002318 status = srtp_create_big_policy(&policy_list);
2319 if (status) {
2320 return status;
2321 }
Cullen Jennings235513a2005-09-21 22:51:36 +00002322
jfigus67b9c732014-11-20 10:17:21 -05002323 status = srtp_create(&session, policy_list);
2324 if (status) {
2325 return status;
2326 }
Jonathan Lennox80c4c832010-05-17 19:30:28 +00002327
jfigus67b9c732014-11-20 10:17:21 -05002328 /*
2329 * check for false positives by trying to remove a stream that's not
2330 * in the session
2331 */
2332 status = srtp_remove_stream(session, htonl(0xaaaaaaaa));
2333 if (status != srtp_err_status_no_ctx) {
2334 return srtp_err_status_fail;
2335 }
Jonathan Lennox80c4c832010-05-17 19:30:28 +00002336
jfigus67b9c732014-11-20 10:17:21 -05002337 /*
2338 * check for false negatives by removing stream 0x1, then
2339 * searching for streams 0x0 and 0x2
2340 */
2341 status = srtp_remove_stream(session, htonl(0x1));
2342 if (status != srtp_err_status_ok) {
2343 return srtp_err_status_fail;
2344 }
2345 stream = srtp_get_stream(session, htonl(0x0));
2346 if (stream == NULL) {
2347 return srtp_err_status_fail;
2348 }
2349 stream = srtp_get_stream(session, htonl(0x2));
2350 if (stream == NULL) {
2351 return srtp_err_status_fail;
2352 }
Jonathan Lennoxad741b22010-05-27 19:23:05 +00002353
jfigus67b9c732014-11-20 10:17:21 -05002354 status = srtp_dealloc(session);
2355 if (status != srtp_err_status_ok) {
2356 return status;
2357 }
Jonathan Lennoxad741b22010-05-27 19:23:05 +00002358
jfigus67b9c732014-11-20 10:17:21 -05002359 status = srtp_dealloc_big_policy(policy_list);
2360 if (status != srtp_err_status_ok) {
2361 return status;
2362 }
Jonathan Lennoxad741b22010-05-27 19:23:05 +00002363
jfigus67b9c732014-11-20 10:17:21 -05002364 /* Now test adding and removing a single stream */
Joachim Bauch99a74822015-11-17 00:08:19 +01002365 memset(&policy, 0, sizeof(policy));
jfigus67b9c732014-11-20 10:17:21 -05002366 srtp_crypto_policy_set_rtp_default(&policy.rtp);
2367 srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
2368 policy.ssrc.type = ssrc_specific;
2369 policy.ssrc.value = 0xcafebabe;
2370 policy.key = test_key;
2371 policy.ekt = NULL;
2372 policy.window_size = 128;
2373 policy.allow_repeat_tx = 0;
2374 policy.next = NULL;
Jonathan Lennoxad741b22010-05-27 19:23:05 +00002375
jfigus67b9c732014-11-20 10:17:21 -05002376 status = srtp_create(&session, NULL);
2377 if (status != srtp_err_status_ok) {
2378 return status;
2379 }
2380
2381 status = srtp_add_stream(session, &policy);
2382 if (status != srtp_err_status_ok) {
2383 return status;
2384 }
2385
2386 status = srtp_remove_stream(session, htonl(0xcafebabe));
2387 if (status != srtp_err_status_ok) {
2388 return status;
2389 }
2390
2391 status = srtp_dealloc(session);
2392 if (status != srtp_err_status_ok) {
2393 return status;
2394 }
2395
2396 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +00002397}
2398
Pascal Bühlerbd3112a2015-11-06 20:29:15 +01002399
2400unsigned char test_alt_key[46] = {
2401 0xe5, 0x19, 0x6f, 0x01, 0x5e, 0xf1, 0x9b, 0xe1,
2402 0xd7, 0x47, 0xa7, 0x27, 0x07, 0xd7, 0x47, 0x33,
2403 0x01, 0xc2, 0x35, 0x4d, 0x59, 0x6a, 0xf7, 0x84,
2404 0x96, 0x98, 0xeb, 0xaa, 0xac, 0xf6, 0xa1, 0x45,
2405 0xc7, 0x15, 0xe2, 0xea, 0xfe, 0x55, 0x67, 0x96,
2406 0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6
2407};
2408
2409/*
2410 * srtp_test_update() verifies updating/rekeying exsisting streams.
2411 * As stated in https://tools.ietf.org/html/rfc3711#section-3.3.1
2412 * the value of the ROC must not be reset after a rekey, this test
2413 * atempts to prove that srtp_update does not reset the ROC.
2414 */
2415
2416srtp_err_status_t
2417srtp_test_update() {
2418
2419 srtp_err_status_t status;
2420 uint32_t ssrc = 0x12121212;
2421 int msg_len_octets = 32;
2422 int protected_msg_len_octets;
2423 srtp_hdr_t * msg;
2424 srtp_t srtp_snd, srtp_recv;
2425 srtp_policy_t policy;
2426
Joachim Bauch1b793352015-12-14 21:30:44 +01002427 memset(&policy, 0, sizeof(policy));
Pascal Bühlerbd3112a2015-11-06 20:29:15 +01002428 srtp_crypto_policy_set_rtp_default(&policy.rtp);
2429 srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
2430 policy.ekt = NULL;
2431 policy.window_size = 128;
2432 policy.allow_repeat_tx = 0;
2433 policy.next = NULL;
2434 policy.ssrc.type = ssrc_any_outbound;
2435 policy.key = test_key;
2436
2437 /* create a send and recive ctx with defualt profile and test_key */
2438 status = srtp_create(&srtp_recv, &policy);
2439 if (status)
2440 return status;
2441
2442 policy.ssrc.type = ssrc_any_inbound;
2443 status = srtp_create(&srtp_snd, &policy);
2444 if (status)
2445 return status;
2446
2447 /* protect and unprotect two msg's that will cause the ROC to be equal to 1 */
2448 msg = srtp_create_test_packet(msg_len_octets, ssrc);
2449 if (msg == NULL)
2450 return srtp_err_status_alloc_fail;
2451 msg->seq = htons(65535);
2452
2453 protected_msg_len_octets = msg_len_octets;
2454 status = srtp_protect(srtp_snd, msg, &protected_msg_len_octets);
2455 if (status)
2456 return srtp_err_status_fail;
2457
2458 status = srtp_unprotect(srtp_recv, msg, &protected_msg_len_octets);
2459 if (status)
2460 return status;
2461
2462 free(msg);
2463
2464 msg = srtp_create_test_packet(msg_len_octets, ssrc);
2465 if (msg == NULL)
2466 return srtp_err_status_alloc_fail;
2467 msg->seq = htons(1);
2468
2469 protected_msg_len_octets = msg_len_octets;
2470 status = srtp_protect(srtp_snd, msg, &protected_msg_len_octets);
2471 if (status)
2472 return srtp_err_status_fail;
2473
2474 status = srtp_unprotect(srtp_recv, msg, &protected_msg_len_octets);
2475 if (status)
2476 return status;
2477
2478 free(msg);
2479
2480 /* update send ctx to use test_alt_key */
2481 policy.ssrc.type = ssrc_any_outbound;
2482 policy.key = test_alt_key;
2483 status = srtp_update(srtp_snd, &policy);
2484 if (status)
2485 return status;
2486
2487 /* create and protect msg with new key and ROC still equal to 1 */
2488 msg = srtp_create_test_packet(msg_len_octets, ssrc);
2489 if (msg == NULL)
2490 return srtp_err_status_alloc_fail;
2491 msg->seq = htons(2);
2492
2493 protected_msg_len_octets = msg_len_octets;
2494 status = srtp_protect(srtp_snd, msg, &protected_msg_len_octets);
2495 if (status)
2496 return srtp_err_status_fail;
2497
2498 /* verify that recive ctx will fail to unprotect as it still uses test_key */
2499 status = srtp_unprotect(srtp_recv, msg, &protected_msg_len_octets);
2500 if (status == srtp_err_status_ok)
2501 return srtp_err_status_fail;
2502
2503 /* create a new recvieve ctx with test_alt_key but since it is new it will have ROC equal to 1
2504 * and therefore should fail to unprotected */
2505 {
2506 srtp_t srtp_recv_roc_0;
2507
2508 policy.ssrc.type = ssrc_any_inbound;
2509 policy.key = test_alt_key;
2510 status = srtp_create(&srtp_recv_roc_0, &policy);
2511 if (status)
2512 return status;
2513
2514 status = srtp_unprotect(srtp_recv_roc_0, msg, &protected_msg_len_octets);
2515 if (status == srtp_err_status_ok)
2516 return srtp_err_status_fail;
2517
2518 status = srtp_dealloc(srtp_recv_roc_0);
2519 if (status)
2520 return status;
2521 }
2522
2523 /* update recive ctx to use test_alt_key */
2524 policy.ssrc.type = ssrc_any_inbound;
2525 policy.key = test_alt_key;
2526 status = srtp_update(srtp_recv, &policy);
2527 if (status)
2528 return status;
2529
2530 /* verify that can still unprotect, therfore key is updated and ROC value is preserved */
2531 status = srtp_unprotect(srtp_recv, msg, &protected_msg_len_octets);
2532 if (status)
2533 return status;
2534
2535 free(msg);
2536
2537 status = srtp_dealloc(srtp_snd);
2538 if (status)
2539 return status;
2540
2541 status = srtp_dealloc(srtp_recv);
2542 if (status)
2543 return status;
2544
2545 return srtp_err_status_ok;
2546}
2547
Cullen Jennings235513a2005-09-21 22:51:36 +00002548/*
2549 * srtp policy definitions - these definitions are used above
2550 */
2551
jfigus8c36da22013-10-01 16:41:19 -04002552unsigned char test_key[46] = {
Cullen Jennings235513a2005-09-21 22:51:36 +00002553 0xe1, 0xf9, 0x7a, 0x0d, 0x3e, 0x01, 0x8b, 0xe0,
2554 0xd6, 0x4f, 0xa3, 0x2c, 0x06, 0xde, 0x41, 0x39,
2555 0x0e, 0xc6, 0x75, 0xad, 0x49, 0x8a, 0xfe, 0xeb,
jfigus8c36da22013-10-01 16:41:19 -04002556 0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6, 0xc1, 0x73,
2557 0xc3, 0x17, 0xf2, 0xda, 0xbe, 0x35, 0x77, 0x93,
Cullen Jennings235513a2005-09-21 22:51:36 +00002558 0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6
2559};
2560
2561
2562const srtp_policy_t default_policy = {
jfigus67b9c732014-11-20 10:17:21 -05002563 { ssrc_any_outbound, 0 }, /* SSRC */
2564 { /* SRTP policy */
2565 SRTP_AES_128_ICM, /* cipher type */
2566 30, /* cipher key length in octets */
2567 SRTP_HMAC_SHA1, /* authentication func type */
2568 16, /* auth key length in octets */
2569 10, /* auth tag length in octets */
2570 sec_serv_conf_and_auth /* security services flag */
2571 },
2572 { /* SRTCP policy */
2573 SRTP_AES_128_ICM, /* cipher type */
2574 30, /* cipher key length in octets */
2575 SRTP_HMAC_SHA1, /* authentication func type */
2576 16, /* auth key length in octets */
2577 10, /* auth tag length in octets */
2578 sec_serv_conf_and_auth /* security services flag */
2579 },
2580 test_key,
2581 NULL, /* indicates that EKT is not in use */
2582 128, /* replay window size */
2583 0, /* retransmission not allowed */
Joachim Bauch99a74822015-11-17 00:08:19 +01002584 NULL, /* no encrypted extension headers */
2585 0, /* list of encrypted extension headers is empty */
jfigus67b9c732014-11-20 10:17:21 -05002586 NULL
Cullen Jennings235513a2005-09-21 22:51:36 +00002587};
2588
2589const srtp_policy_t aes_only_policy = {
jfigus67b9c732014-11-20 10:17:21 -05002590 { ssrc_any_outbound, 0 }, /* SSRC */
2591 {
2592 SRTP_AES_128_ICM, /* cipher type */
2593 30, /* cipher key length in octets */
2594 SRTP_NULL_AUTH, /* authentication func type */
2595 0, /* auth key length in octets */
2596 0, /* auth tag length in octets */
2597 sec_serv_conf /* security services flag */
2598 },
2599 {
2600 SRTP_AES_128_ICM, /* cipher type */
2601 30, /* cipher key length in octets */
2602 SRTP_NULL_AUTH, /* authentication func type */
2603 0, /* auth key length in octets */
2604 0, /* auth tag length in octets */
2605 sec_serv_conf /* security services flag */
2606 },
2607 test_key,
2608 NULL, /* indicates that EKT is not in use */
2609 128, /* replay window size */
2610 0, /* retransmission not allowed */
Joachim Bauch99a74822015-11-17 00:08:19 +01002611 NULL, /* no encrypted extension headers */
2612 0, /* list of encrypted extension headers is empty */
jfigus67b9c732014-11-20 10:17:21 -05002613 NULL
Cullen Jennings235513a2005-09-21 22:51:36 +00002614};
2615
2616const srtp_policy_t hmac_only_policy = {
jfigus67b9c732014-11-20 10:17:21 -05002617 { ssrc_any_outbound, 0 }, /* SSRC */
2618 {
2619 SRTP_NULL_CIPHER, /* cipher type */
2620 0, /* cipher key length in octets */
2621 SRTP_HMAC_SHA1, /* authentication func type */
2622 20, /* auth key length in octets */
2623 4, /* auth tag length in octets */
2624 sec_serv_auth /* security services flag */
2625 },
2626 {
2627 SRTP_NULL_CIPHER, /* cipher type */
2628 0, /* cipher key length in octets */
2629 SRTP_HMAC_SHA1, /* authentication func type */
2630 20, /* auth key length in octets */
2631 4, /* auth tag length in octets */
2632 sec_serv_auth /* security services flag */
2633 },
2634 test_key,
2635 NULL, /* indicates that EKT is not in use */
2636 128, /* replay window size */
2637 0, /* retransmission not allowed */
Joachim Bauch99a74822015-11-17 00:08:19 +01002638 NULL, /* no encrypted extension headers */
2639 0, /* list of encrypted extension headers is empty */
jfigus67b9c732014-11-20 10:17:21 -05002640 NULL
Cullen Jennings235513a2005-09-21 22:51:36 +00002641};
2642
jfigus8c36da22013-10-01 16:41:19 -04002643#ifdef OPENSSL
2644const srtp_policy_t aes128_gcm_8_policy = {
jfigus67b9c732014-11-20 10:17:21 -05002645 { ssrc_any_outbound, 0 }, /* SSRC */
2646 { /* SRTP policy */
2647 SRTP_AES_128_GCM, /* cipher type */
2648 SRTP_AES_128_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
2649 SRTP_NULL_AUTH, /* authentication func type */
2650 0, /* auth key length in octets */
2651 8, /* auth tag length in octets */
2652 sec_serv_conf_and_auth /* security services flag */
jfigus8c36da22013-10-01 16:41:19 -04002653 },
jfigus67b9c732014-11-20 10:17:21 -05002654 { /* SRTCP policy */
2655 SRTP_AES_128_GCM, /* cipher type */
2656 SRTP_AES_128_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
2657 SRTP_NULL_AUTH, /* authentication func type */
2658 0, /* auth key length in octets */
2659 8, /* auth tag length in octets */
2660 sec_serv_conf_and_auth /* security services flag */
jfigus8c36da22013-10-01 16:41:19 -04002661 },
2662 test_key,
2663 NULL, /* indicates that EKT is not in use */
2664 128, /* replay window size */
2665 0, /* retransmission not allowed */
Joachim Bauch99a74822015-11-17 00:08:19 +01002666 NULL, /* no encrypted extension headers */
2667 0, /* list of encrypted extension headers is empty */
jfigus8c36da22013-10-01 16:41:19 -04002668 NULL
2669};
2670
2671const srtp_policy_t aes128_gcm_8_cauth_policy = {
jfigus67b9c732014-11-20 10:17:21 -05002672 { ssrc_any_outbound, 0 }, /* SSRC */
2673 { /* SRTP policy */
2674 SRTP_AES_128_GCM, /* cipher type */
2675 SRTP_AES_128_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
2676 SRTP_NULL_AUTH, /* authentication func type */
2677 0, /* auth key length in octets */
2678 8, /* auth tag length in octets */
2679 sec_serv_conf_and_auth /* security services flag */
jfigus8c36da22013-10-01 16:41:19 -04002680 },
jfigus67b9c732014-11-20 10:17:21 -05002681 { /* SRTCP policy */
2682 SRTP_AES_128_GCM, /* cipher type */
2683 SRTP_AES_128_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
2684 SRTP_NULL_AUTH, /* authentication func type */
2685 0, /* auth key length in octets */
2686 8, /* auth tag length in octets */
2687 sec_serv_auth /* security services flag */
jfigus8c36da22013-10-01 16:41:19 -04002688 },
2689 test_key,
2690 NULL, /* indicates that EKT is not in use */
2691 128, /* replay window size */
2692 0, /* retransmission not allowed */
Joachim Bauch99a74822015-11-17 00:08:19 +01002693 NULL, /* no encrypted extension headers */
2694 0, /* list of encrypted extension headers is empty */
jfigus8c36da22013-10-01 16:41:19 -04002695 NULL
2696};
jfigus67b9c732014-11-20 10:17:21 -05002697
jfigus8c36da22013-10-01 16:41:19 -04002698const srtp_policy_t aes256_gcm_8_policy = {
jfigus67b9c732014-11-20 10:17:21 -05002699 { ssrc_any_outbound, 0 }, /* SSRC */
2700 { /* SRTP policy */
2701 SRTP_AES_256_GCM, /* cipher type */
2702 SRTP_AES_256_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
2703 SRTP_NULL_AUTH, /* authentication func type */
2704 0, /* auth key length in octets */
2705 8, /* auth tag length in octets */
2706 sec_serv_conf_and_auth /* security services flag */
jfigus8c36da22013-10-01 16:41:19 -04002707 },
jfigus67b9c732014-11-20 10:17:21 -05002708 { /* SRTCP policy */
2709 SRTP_AES_256_GCM, /* cipher type */
2710 SRTP_AES_256_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
2711 SRTP_NULL_AUTH, /* authentication func type */
2712 0, /* auth key length in octets */
2713 8, /* auth tag length in octets */
2714 sec_serv_conf_and_auth /* security services flag */
jfigus8c36da22013-10-01 16:41:19 -04002715 },
2716 test_key,
2717 NULL, /* indicates that EKT is not in use */
2718 128, /* replay window size */
2719 0, /* retransmission not allowed */
Joachim Bauch99a74822015-11-17 00:08:19 +01002720 NULL, /* no encrypted extension headers */
2721 0, /* list of encrypted extension headers is empty */
jfigus8c36da22013-10-01 16:41:19 -04002722 NULL
2723};
jfigus67b9c732014-11-20 10:17:21 -05002724
jfigus8c36da22013-10-01 16:41:19 -04002725const srtp_policy_t aes256_gcm_8_cauth_policy = {
jfigus67b9c732014-11-20 10:17:21 -05002726 { ssrc_any_outbound, 0 }, /* SSRC */
2727 { /* SRTP policy */
2728 SRTP_AES_256_GCM, /* cipher type */
2729 SRTP_AES_256_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
2730 SRTP_NULL_AUTH, /* authentication func type */
2731 0, /* auth key length in octets */
2732 8, /* auth tag length in octets */
2733 sec_serv_conf_and_auth /* security services flag */
jfigus8c36da22013-10-01 16:41:19 -04002734 },
jfigus67b9c732014-11-20 10:17:21 -05002735 { /* SRTCP policy */
2736 SRTP_AES_256_GCM, /* cipher type */
2737 SRTP_AES_256_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
2738 SRTP_NULL_AUTH, /* authentication func type */
2739 0, /* auth key length in octets */
2740 8, /* auth tag length in octets */
2741 sec_serv_auth /* security services flag */
jfigus8c36da22013-10-01 16:41:19 -04002742 },
2743 test_key,
2744 NULL, /* indicates that EKT is not in use */
2745 128, /* replay window size */
2746 0, /* retransmission not allowed */
Joachim Bauch99a74822015-11-17 00:08:19 +01002747 NULL, /* no encrypted extension headers */
2748 0, /* list of encrypted extension headers is empty */
jfigus8c36da22013-10-01 16:41:19 -04002749 NULL
2750};
2751#endif
2752
Cullen Jennings235513a2005-09-21 22:51:36 +00002753const srtp_policy_t null_policy = {
jfigus67b9c732014-11-20 10:17:21 -05002754 { ssrc_any_outbound, 0 }, /* SSRC */
2755 {
2756 SRTP_NULL_CIPHER, /* cipher type */
2757 0, /* cipher key length in octets */
2758 SRTP_NULL_AUTH, /* authentication func type */
2759 0, /* auth key length in octets */
2760 0, /* auth tag length in octets */
2761 sec_serv_none /* security services flag */
2762 },
2763 {
2764 SRTP_NULL_CIPHER, /* cipher type */
2765 0, /* cipher key length in octets */
2766 SRTP_NULL_AUTH, /* authentication func type */
2767 0, /* auth key length in octets */
2768 0, /* auth tag length in octets */
2769 sec_serv_none /* security services flag */
2770 },
2771 test_key,
2772 NULL, /* indicates that EKT is not in use */
2773 128, /* replay window size */
2774 0, /* retransmission not allowed */
Joachim Bauch99a74822015-11-17 00:08:19 +01002775 NULL, /* no encrypted extension headers */
2776 0, /* list of encrypted extension headers is empty */
jfigus67b9c732014-11-20 10:17:21 -05002777 NULL
David McGrew79870d62007-06-15 18:17:39 +00002778};
2779
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002780unsigned char test_256_key[46] = {
jfigus67b9c732014-11-20 10:17:21 -05002781 0xf0, 0xf0, 0x49, 0x14, 0xb5, 0x13, 0xf2, 0x76,
2782 0x3a, 0x1b, 0x1f, 0xa1, 0x30, 0xf1, 0x0e, 0x29,
2783 0x98, 0xf6, 0xf6, 0xe4, 0x3e, 0x43, 0x09, 0xd1,
2784 0xe6, 0x22, 0xa0, 0xe3, 0x32, 0xb9, 0xf1, 0xb6,
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002785
jfigus67b9c732014-11-20 10:17:21 -05002786 0x3b, 0x04, 0x80, 0x3d, 0xe5, 0x1e, 0xe7, 0xc9,
2787 0x64, 0x23, 0xab, 0x5b, 0x78, 0xd2
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002788};
2789
2790const srtp_policy_t aes_256_hmac_policy = {
jfigus67b9c732014-11-20 10:17:21 -05002791 { ssrc_any_outbound, 0 }, /* SSRC */
2792 { /* SRTP policy */
2793 SRTP_AES_ICM, /* cipher type */
2794 46, /* cipher key length in octets */
2795 SRTP_HMAC_SHA1, /* authentication func type */
2796 20, /* auth key length in octets */
2797 10, /* auth tag length in octets */
2798 sec_serv_conf_and_auth /* security services flag */
2799 },
2800 { /* SRTCP policy */
2801 SRTP_AES_ICM, /* cipher type */
2802 46, /* cipher key length in octets */
2803 SRTP_HMAC_SHA1, /* authentication func type */
2804 20, /* auth key length in octets */
2805 10, /* auth tag length in octets */
2806 sec_serv_conf_and_auth /* security services flag */
2807 },
2808 test_256_key,
2809 NULL, /* indicates that EKT is not in use */
2810 128, /* replay window size */
2811 0, /* retransmission not allowed */
Joachim Bauch99a74822015-11-17 00:08:19 +01002812 NULL, /* no encrypted extension headers */
2813 0, /* list of encrypted extension headers is empty */
jfigus67b9c732014-11-20 10:17:21 -05002814 NULL
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002815};
2816
David McGrew79870d62007-06-15 18:17:39 +00002817uint8_t ekt_test_key[16] = {
jfigus67b9c732014-11-20 10:17:21 -05002818 0x77, 0x26, 0x9d, 0xac, 0x16, 0xa3, 0x28, 0xca,
2819 0x8e, 0xc9, 0x68, 0x4b, 0xcc, 0xc4, 0xd2, 0x1b
David McGrew79870d62007-06-15 18:17:39 +00002820};
2821
2822#include "ekt.h"
2823
jfigusc5887e72014-11-06 09:46:18 -05002824srtp_ekt_policy_ctx_t ekt_test_policy = {
jfigus67b9c732014-11-20 10:17:21 -05002825 0xa5a5, /* SPI */
2826 SRTP_EKT_CIPHER_AES_128_ECB,
2827 ekt_test_key,
2828 NULL
David McGrew79870d62007-06-15 18:17:39 +00002829};
2830
2831const srtp_policy_t hmac_only_with_ekt_policy = {
jfigus67b9c732014-11-20 10:17:21 -05002832 { ssrc_any_outbound, 0 }, /* SSRC */
2833 {
2834 SRTP_NULL_CIPHER, /* cipher type */
2835 0, /* cipher key length in octets */
2836 SRTP_HMAC_SHA1, /* authentication func type */
2837 20, /* auth key length in octets */
2838 4, /* auth tag length in octets */
2839 sec_serv_auth /* security services flag */
2840 },
2841 {
2842 SRTP_NULL_CIPHER, /* cipher type */
2843 0, /* cipher key length in octets */
2844 SRTP_HMAC_SHA1, /* authentication func type */
2845 20, /* auth key length in octets */
2846 4, /* auth tag length in octets */
2847 sec_serv_auth /* security services flag */
2848 },
2849 test_key,
2850 &ekt_test_policy, /* indicates that EKT is not in use */
2851 128, /* replay window size */
2852 0, /* retransmission not allowed */
Joachim Bauch99a74822015-11-17 00:08:19 +01002853 NULL, /* no encrypted extension headers */
2854 0, /* list of encrypted extension headers is empty */
jfigus67b9c732014-11-20 10:17:21 -05002855 NULL
Cullen Jennings235513a2005-09-21 22:51:36 +00002856};
2857
2858
2859/*
2860 * an array of pointers to the policies listed above
2861 *
2862 * This array is used to test various aspects of libSRTP for
2863 * different cryptographic policies. The order of the elements
2864 * matters - the timing test generates output that can be used
jfigus67b9c732014-11-20 10:17:21 -05002865 * in a plot (see the gnuplot script file 'timing'). If you
Cullen Jennings235513a2005-09-21 22:51:36 +00002866 * add to this list, you should do it at the end.
2867 */
2868
Cullen Jennings235513a2005-09-21 22:51:36 +00002869const srtp_policy_t *
2870policy_array[] = {
jfigus67b9c732014-11-20 10:17:21 -05002871 &hmac_only_policy,
2872 &aes_only_policy,
2873 &default_policy,
jfigus8c36da22013-10-01 16:41:19 -04002874#ifdef OPENSSL
jfigus67b9c732014-11-20 10:17:21 -05002875 &aes128_gcm_8_policy,
2876 &aes128_gcm_8_cauth_policy,
2877 &aes256_gcm_8_policy,
2878 &aes256_gcm_8_cauth_policy,
jfigus8c36da22013-10-01 16:41:19 -04002879#endif
jfigus67b9c732014-11-20 10:17:21 -05002880 &null_policy,
2881 &aes_256_hmac_policy,
2882 &hmac_only_with_ekt_policy,
2883 NULL
Cullen Jennings235513a2005-09-21 22:51:36 +00002884};
2885
2886const srtp_policy_t wildcard_policy = {
jfigus67b9c732014-11-20 10:17:21 -05002887 { ssrc_any_outbound, 0 }, /* SSRC */
2888 { /* SRTP policy */
2889 SRTP_AES_128_ICM, /* cipher type */
2890 30, /* cipher key length in octets */
2891 SRTP_HMAC_SHA1, /* authentication func type */
2892 16, /* auth key length in octets */
2893 10, /* auth tag length in octets */
2894 sec_serv_conf_and_auth /* security services flag */
2895 },
2896 { /* SRTCP policy */
2897 SRTP_AES_128_ICM, /* cipher type */
2898 30, /* cipher key length in octets */
2899 SRTP_HMAC_SHA1, /* authentication func type */
2900 16, /* auth key length in octets */
2901 10, /* auth tag length in octets */
2902 sec_serv_conf_and_auth /* security services flag */
2903 },
2904 test_key,
2905 NULL,
2906 128, /* replay window size */
2907 0, /* retransmission not allowed */
Joachim Bauch99a74822015-11-17 00:08:19 +01002908 NULL, /* no encrypted extension headers */
2909 0, /* list of encrypted extension headers is empty */
jfigus67b9c732014-11-20 10:17:21 -05002910 NULL
Cullen Jennings235513a2005-09-21 22:51:36 +00002911};