blob: 10103a1f9cc448fae04de59522f16b3b229c8195 [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 };
Pascal Bühler941cf122016-06-10 09:30:52 +02001495 uint8_t rtcp_plaintext_ref[24] = {
1496 0x81, 0xc8, 0x00, 0x0b, 0xca, 0xfe, 0xba, 0xbe,
1497 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1498 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1499 };
1500 uint8_t rtcp_plaintext[38] = {
1501 0x81, 0xc8, 0x00, 0x0b, 0xca, 0xfe, 0xba, 0xbe,
1502 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1503 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1504 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1505 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1506 };
1507 uint8_t srtcp_ciphertext[38] = {
1508 0x81, 0xc8, 0x00, 0x0b, 0xca, 0xfe, 0xba, 0xbe,
1509 0x71, 0x28, 0x03, 0x5b, 0xe4, 0x87, 0xb9, 0xbd,
1510 0xbe, 0xf8, 0x90, 0x41, 0xf9, 0x77, 0xa5, 0xa8,
1511 0x80, 0x00, 0x00, 0x01, 0x99, 0x3e, 0x08, 0xcd,
1512 0x54, 0xd6, 0xc1, 0x23, 0x07, 0x98
1513 };
jfigus67b9c732014-11-20 10:17:21 -05001514 srtp_t srtp_snd, srtp_recv;
1515 srtp_err_status_t status;
1516 int len;
1517 srtp_policy_t policy;
Cullen Jennings235513a2005-09-21 22:51:36 +00001518
jfigus67b9c732014-11-20 10:17:21 -05001519 /*
1520 * create a session with a single stream using the default srtp
1521 * policy and with the SSRC value 0xcafebabe
1522 */
Joachim Bauch99a74822015-11-17 00:08:19 +01001523 memset(&policy, 0, sizeof(policy));
jfigus67b9c732014-11-20 10:17:21 -05001524 srtp_crypto_policy_set_rtp_default(&policy.rtp);
1525 srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
1526 policy.ssrc.type = ssrc_specific;
1527 policy.ssrc.value = 0xcafebabe;
1528 policy.key = test_key;
1529 policy.ekt = NULL;
1530 policy.window_size = 128;
1531 policy.allow_repeat_tx = 0;
1532 policy.next = NULL;
Cullen Jennings235513a2005-09-21 22:51:36 +00001533
jfigus67b9c732014-11-20 10:17:21 -05001534 status = srtp_create(&srtp_snd, &policy);
1535 if (status) {
1536 return status;
1537 }
Cullen Jennings235513a2005-09-21 22:51:36 +00001538
jfigus67b9c732014-11-20 10:17:21 -05001539 /*
1540 * protect plaintext, then compare with ciphertext
1541 */
1542 len = 28;
1543 status = srtp_protect(srtp_snd, srtp_plaintext, &len);
1544 if (status || (len != 38)) {
1545 return srtp_err_status_fail;
1546 }
Cullen Jennings235513a2005-09-21 22:51:36 +00001547
jfigus67b9c732014-11-20 10:17:21 -05001548 debug_print(mod_driver, "ciphertext:\n %s",
1549 octet_string_hex_string(srtp_plaintext, len));
1550 debug_print(mod_driver, "ciphertext reference:\n %s",
1551 octet_string_hex_string(srtp_ciphertext, len));
Cullen Jennings235513a2005-09-21 22:51:36 +00001552
jfigus67b9c732014-11-20 10:17:21 -05001553 if (octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len)) {
1554 return srtp_err_status_fail;
1555 }
Jonathan Lennox80c4c832010-05-17 19:30:28 +00001556
jfigus67b9c732014-11-20 10:17:21 -05001557 /*
Pascal Bühler941cf122016-06-10 09:30:52 +02001558 * protect plaintext rtcp, then compare with srtcp ciphertext
1559 */
1560 len = 24;
1561 status = srtp_protect_rtcp(srtp_snd, rtcp_plaintext, &len);
1562 if (status || (len != 38)) {
1563 return srtp_err_status_fail;
1564 }
1565
1566 debug_print(mod_driver, "srtcp ciphertext:\n %s",
1567 octet_string_hex_string(rtcp_plaintext, len));
1568 debug_print(mod_driver, "srtcp ciphertext reference:\n %s",
1569 octet_string_hex_string(srtcp_ciphertext, len));
1570
1571 if (octet_string_is_eq(rtcp_plaintext, srtcp_ciphertext, len)) {
1572 return srtp_err_status_fail;
1573 }
1574
1575 /*
jfigus67b9c732014-11-20 10:17:21 -05001576 * create a receiver session context comparable to the one created
1577 * above - we need to do this so that the replay checking doesn't
1578 * complain
1579 */
1580 status = srtp_create(&srtp_recv, &policy);
1581 if (status) {
1582 return status;
1583 }
Jonathan Lennox80c4c832010-05-17 19:30:28 +00001584
jfigus67b9c732014-11-20 10:17:21 -05001585 /*
1586 * unprotect ciphertext, then compare with plaintext
1587 */
1588 status = srtp_unprotect(srtp_recv, srtp_ciphertext, &len);
1589 if (status || (len != 28)) {
1590 return status;
1591 }
1592
1593 if (octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len)) {
1594 return srtp_err_status_fail;
1595 }
1596
Pascal Bühler941cf122016-06-10 09:30:52 +02001597 /*
1598 * unprotect srtcp ciphertext, then compare with rtcp plaintext
1599 */
1600 len = 38;
1601 status = srtp_unprotect_rtcp(srtp_recv, srtcp_ciphertext, &len);
1602 if (status || (len != 24)) {
1603 return status;
1604 }
1605
1606 if (octet_string_is_eq(srtcp_ciphertext, rtcp_plaintext_ref, len)) {
1607 return srtp_err_status_fail;
1608 }
1609
jfigus67b9c732014-11-20 10:17:21 -05001610 status = srtp_dealloc(srtp_snd);
1611 if (status) {
1612 return status;
1613 }
1614
1615 status = srtp_dealloc(srtp_recv);
1616 if (status) {
1617 return status;
1618 }
1619
1620 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +00001621}
1622
Paul E. Jonese2ab5f22016-05-29 16:18:24 -04001623#ifdef OPENSSL
1624/*
1625 * srtp_validate_gcm() verifies the correctness of libsrtp by comparing
1626 * an computed packet against the known ciphertext for the plaintext.
1627 */
1628srtp_err_status_t
1629srtp_validate_gcm ()
1630{
1631 unsigned char test_key_gcm[28] = {
1632 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1633 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
1634 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
1635 0xa8, 0xa9, 0xaa, 0xab
1636 };
Pascal Bühler45019ae2016-06-10 08:35:12 +02001637 uint8_t rtp_plaintext_ref[28] = {
Paul E. Jonese2ab5f22016-05-29 16:18:24 -04001638 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1639 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
1640 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1641 0xab, 0xab, 0xab, 0xab
1642 };
Pascal Bühler45019ae2016-06-10 08:35:12 +02001643 uint8_t rtp_plaintext[44] = {
Paul E. Jonese2ab5f22016-05-29 16:18:24 -04001644 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1645 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
1646 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1647 0xab, 0xab, 0xab, 0xab, 0x00, 0x00, 0x00, 0x00,
1648 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1649 0x00, 0x00, 0x00, 0x00
1650 };
1651 uint8_t srtp_ciphertext[44] = {
1652 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1653 0xca, 0xfe, 0xba, 0xbe, 0xc5, 0x00, 0x2e, 0xde,
1654 0x04, 0xcf, 0xdd, 0x2e, 0xb9, 0x11, 0x59, 0xe0,
1655 0x88, 0x0a, 0xa0, 0x6e, 0xd2, 0x97, 0x68, 0x26,
1656 0xf7, 0x96, 0xb2, 0x01, 0xdf, 0x31, 0x31, 0xa1,
1657 0x27, 0xe8, 0xa3, 0x92
1658 };
Pascal Bühler45019ae2016-06-10 08:35:12 +02001659 uint8_t rtcp_plaintext_ref[24] = {
1660 0x81, 0xc8, 0x00, 0x0b, 0xca, 0xfe, 0xba, 0xbe,
1661 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1662 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1663 };
1664 uint8_t rtcp_plaintext[44] = {
1665 0x81, 0xc8, 0x00, 0x0b, 0xca, 0xfe, 0xba, 0xbe,
1666 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1667 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1668 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1669 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1670 0x00, 0x00, 0x00, 0x00
1671 };
1672 uint8_t srtcp_ciphertext[44] = {
1673 0x81, 0xc8, 0x00, 0x0b, 0xca, 0xfe, 0xba, 0xbe,
1674 0xc9, 0x8b, 0x8b, 0x5d, 0xf0, 0x39, 0x2a, 0x55,
1675 0x85, 0x2b, 0x6c, 0x21, 0xac, 0x8e, 0x70, 0x25,
1676 0xc5, 0x2c, 0x6f, 0xbe, 0xa2, 0xb3, 0xb4, 0x46,
1677 0xea, 0x31, 0x12, 0x3b, 0xa8, 0x8c, 0xe6, 0x1e,
1678 0x80, 0x00, 0x00, 0x01
1679 };
1680
Paul E. Jonese2ab5f22016-05-29 16:18:24 -04001681 srtp_t srtp_snd, srtp_recv;
1682 srtp_err_status_t status;
1683 int len;
1684 srtp_policy_t policy;
1685
1686 /*
1687 * create a session with a single stream using the default srtp
1688 * policy and with the SSRC value 0xcafebabe
1689 */
1690 memset(&policy, 0, sizeof(policy));
1691 srtp_crypto_policy_set_aes_gcm_128_16_auth(&policy.rtp);
1692 srtp_crypto_policy_set_aes_gcm_128_16_auth(&policy.rtcp);
1693 policy.ssrc.type = ssrc_specific;
1694 policy.ssrc.value = 0xcafebabe;
1695 policy.key = test_key_gcm;
1696 policy.ekt = NULL;
1697 policy.window_size = 128;
1698 policy.allow_repeat_tx = 0;
1699 policy.next = NULL;
1700
1701 status = srtp_create(&srtp_snd, &policy);
1702 if (status) {
1703 return status;
1704 }
1705
1706 /*
Pascal Bühler45019ae2016-06-10 08:35:12 +02001707 * protect plaintext rtp, then compare with srtp ciphertext
Paul E. Jonese2ab5f22016-05-29 16:18:24 -04001708 */
1709 len = 28;
Pascal Bühler45019ae2016-06-10 08:35:12 +02001710 status = srtp_protect(srtp_snd, rtp_plaintext, &len);
Paul E. Jonese2ab5f22016-05-29 16:18:24 -04001711 if (status || (len != 44)) {
1712 return srtp_err_status_fail;
1713 }
1714
Pascal Bühler45019ae2016-06-10 08:35:12 +02001715 debug_print(mod_driver, "srtp ciphertext:\n %s",
1716 octet_string_hex_string(rtp_plaintext, len));
1717 debug_print(mod_driver, "srtp ciphertext reference:\n %s",
Paul E. Jonese2ab5f22016-05-29 16:18:24 -04001718 octet_string_hex_string(srtp_ciphertext, len));
1719
Pascal Bühler45019ae2016-06-10 08:35:12 +02001720 if (octet_string_is_eq(rtp_plaintext, srtp_ciphertext, len)) {
1721 return srtp_err_status_fail;
1722 }
1723
1724 /*
1725 * protect plaintext rtcp, then compare with srtcp ciphertext
1726 */
1727 len = 24;
1728 status = srtp_protect_rtcp(srtp_snd, rtcp_plaintext, &len);
1729 if (status || (len != 44)) {
1730 return srtp_err_status_fail;
1731 }
1732
1733 debug_print(mod_driver, "srtcp ciphertext:\n %s",
1734 octet_string_hex_string(rtcp_plaintext, len));
1735 debug_print(mod_driver, "srtcp ciphertext reference:\n %s",
1736 octet_string_hex_string(srtcp_ciphertext, len));
1737
1738 if (octet_string_is_eq(rtcp_plaintext, srtcp_ciphertext, len)) {
Paul E. Jonese2ab5f22016-05-29 16:18:24 -04001739 return srtp_err_status_fail;
1740 }
1741
1742 /*
1743 * create a receiver session context comparable to the one created
1744 * above - we need to do this so that the replay checking doesn't
1745 * complain
1746 */
1747 status = srtp_create(&srtp_recv, &policy);
1748 if (status) {
1749 return status;
1750 }
1751
1752 /*
Pascal Bühler45019ae2016-06-10 08:35:12 +02001753 * unprotect srtp ciphertext, then compare with rtp plaintext
Paul E. Jonese2ab5f22016-05-29 16:18:24 -04001754 */
Pascal Bühler45019ae2016-06-10 08:35:12 +02001755 len = 44;
Paul E. Jonese2ab5f22016-05-29 16:18:24 -04001756 status = srtp_unprotect(srtp_recv, srtp_ciphertext, &len);
1757 if (status || (len != 28)) {
1758 return status;
1759 }
1760
Pascal Bühler45019ae2016-06-10 08:35:12 +02001761 if (octet_string_is_eq(srtp_ciphertext, rtp_plaintext_ref, len)) {
1762 return srtp_err_status_fail;
1763 }
1764
1765 /*
1766 * unprotect srtcp ciphertext, then compare with rtcp plaintext
1767 */
1768 len = 44;
1769 status = srtp_unprotect_rtcp(srtp_recv, srtcp_ciphertext, &len);
1770 if (status || (len != 24)) {
1771 return status;
1772 }
1773
1774 if (octet_string_is_eq(srtcp_ciphertext, rtcp_plaintext_ref, len)) {
Paul E. Jonese2ab5f22016-05-29 16:18:24 -04001775 return srtp_err_status_fail;
1776 }
1777
1778 status = srtp_dealloc(srtp_snd);
1779 if (status) {
1780 return status;
1781 }
1782
1783 status = srtp_dealloc(srtp_recv);
1784 if (status) {
1785 return status;
1786 }
1787
1788 return srtp_err_status_ok;
1789}
1790#endif
1791
Joachim Bauch99a74822015-11-17 00:08:19 +01001792/*
1793 * Test vectors taken from RFC 6904, Appendix A
1794 */
1795srtp_err_status_t
1796srtp_validate_encrypted_extensions_headers() {
1797 unsigned char test_key_ext_headers[30] = {
1798 0xe1, 0xf9, 0x7a, 0x0d, 0x3e, 0x01, 0x8b, 0xe0,
1799 0xd6, 0x4f, 0xa3, 0x2c, 0x06, 0xde, 0x41, 0x39,
1800 0x0e, 0xc6, 0x75, 0xad, 0x49, 0x8a, 0xfe, 0xeb,
1801 0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6
1802 };
1803 uint8_t srtp_plaintext_ref[56] = {
1804 0x90, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1805 0xca, 0xfe, 0xba, 0xbe, 0xBE, 0xDE, 0x00, 0x06,
1806 0x17, 0x41, 0x42, 0x73, 0xA4, 0x75, 0x26, 0x27,
1807 0x48, 0x22, 0x00, 0x00, 0xC8, 0x30, 0x8E, 0x46,
1808 0x55, 0x99, 0x63, 0x86, 0xB3, 0x95, 0xFB, 0x00,
1809 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1810 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab
1811 };
1812 uint8_t srtp_plaintext[66] = {
1813 0x90, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1814 0xca, 0xfe, 0xba, 0xbe, 0xBE, 0xDE, 0x00, 0x06,
1815 0x17, 0x41, 0x42, 0x73, 0xA4, 0x75, 0x26, 0x27,
1816 0x48, 0x22, 0x00, 0x00, 0xC8, 0x30, 0x8E, 0x46,
1817 0x55, 0x99, 0x63, 0x86, 0xB3, 0x95, 0xFB, 0x00,
1818 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1819 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1820 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1821 0x00, 0x00
1822 };
1823 uint8_t srtp_ciphertext[66] = {
1824 0x90, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1825 0xca, 0xfe, 0xba, 0xbe, 0xBE, 0xDE, 0x00, 0x06,
1826 0x17, 0x58, 0x8A, 0x92, 0x70, 0xF4, 0xE1, 0x5E,
1827 0x1C, 0x22, 0x00, 0x00, 0xC8, 0x30, 0x95, 0x46,
1828 0xA9, 0x94, 0xF0, 0xBC, 0x54, 0x78, 0x97, 0x00,
1829 0x4e, 0x55, 0xdc, 0x4c, 0xe7, 0x99, 0x78, 0xd8,
1830 0x8c, 0xa4, 0xd2, 0x15, 0x94, 0x9d, 0x24, 0x02,
1831 0x5a, 0x46, 0xb3, 0xca, 0x35, 0xc5, 0x35, 0xa8,
1832 0x91, 0xc7
1833 };
1834 srtp_t srtp_snd, srtp_recv;
1835 srtp_err_status_t status;
1836 int len;
1837 srtp_policy_t policy;
1838 int headers[3] = {1, 3, 4};
1839
1840 /*
1841 * create a session with a single stream using the default srtp
1842 * policy and with the SSRC value 0xcafebabe
1843 */
1844 memset(&policy, 0, sizeof(policy));
1845 srtp_crypto_policy_set_rtp_default(&policy.rtp);
1846 srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
1847 policy.ssrc.type = ssrc_specific;
1848 policy.ssrc.value = 0xcafebabe;
1849 policy.key = test_key_ext_headers;
1850 policy.ekt = NULL;
1851 policy.window_size = 128;
1852 policy.allow_repeat_tx = 0;
1853 policy.enc_xtn_hdr = headers;
1854 policy.enc_xtn_hdr_count = sizeof(headers) / sizeof(headers[0]);
1855 policy.next = NULL;
1856
1857 status = srtp_create(&srtp_snd, &policy);
1858 if (status)
1859 return status;
1860
1861 /*
1862 * protect plaintext, then compare with ciphertext
1863 */
1864 len = sizeof(srtp_plaintext_ref);
1865 status = srtp_protect(srtp_snd, srtp_plaintext, &len);
1866 if (status || (len != sizeof(srtp_plaintext)))
1867 return srtp_err_status_fail;
1868
1869 debug_print(mod_driver, "ciphertext:\n %s",
1870 srtp_octet_string_hex_string(srtp_plaintext, len));
1871 debug_print(mod_driver, "ciphertext reference:\n %s",
1872 srtp_octet_string_hex_string(srtp_ciphertext, len));
1873
1874 if (octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len))
1875 return srtp_err_status_fail;
1876
1877 /*
1878 * create a receiver session context comparable to the one created
1879 * above - we need to do this so that the replay checking doesn't
1880 * complain
1881 */
1882 status = srtp_create(&srtp_recv, &policy);
1883 if (status)
1884 return status;
1885
1886 /*
1887 * unprotect ciphertext, then compare with plaintext
1888 */
1889 status = srtp_unprotect(srtp_recv, srtp_ciphertext, &len);
Joachim Baucha9ecefe2015-12-14 21:40:42 +01001890 if (status) {
Joachim Bauch99a74822015-11-17 00:08:19 +01001891 return status;
Joachim Baucha9ecefe2015-12-14 21:40:42 +01001892 } else if (len != sizeof(srtp_plaintext_ref)) {
1893 return srtp_err_status_fail;
1894 }
Joachim Bauch99a74822015-11-17 00:08:19 +01001895
1896 if (octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len))
1897 return srtp_err_status_fail;
1898
1899 status = srtp_dealloc(srtp_snd);
1900 if (status)
1901 return status;
1902
1903 status = srtp_dealloc(srtp_recv);
1904 if (status)
1905 return status;
1906
1907 return srtp_err_status_ok;
1908}
1909
Cullen Jennings235513a2005-09-21 22:51:36 +00001910
Joachim Bauch80a45b52015-12-06 22:57:58 +01001911#ifdef OPENSSL
Joachim Baucha9ecefe2015-12-14 21:40:42 +01001912
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001913/*
Joachim Bauchfa1e8c22015-11-24 23:38:48 +01001914 * Headers of test vectors taken from RFC 6904, Appendix A
1915 */
1916srtp_err_status_t
1917srtp_validate_encrypted_extensions_headers_gcm() {
1918 unsigned char test_key_ext_headers[30] = {
1919 0xe1, 0xf9, 0x7a, 0x0d, 0x3e, 0x01, 0x8b, 0xe0,
1920 0xd6, 0x4f, 0xa3, 0x2c, 0x06, 0xde, 0x41, 0x39,
1921 0x0e, 0xc6, 0x75, 0xad, 0x49, 0x8a, 0xfe, 0xeb,
1922 0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6
1923 };
1924 uint8_t srtp_plaintext_ref[56] = {
1925 0x90, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1926 0xca, 0xfe, 0xba, 0xbe, 0xBE, 0xDE, 0x00, 0x06,
1927 0x17, 0x41, 0x42, 0x73, 0xA4, 0x75, 0x26, 0x27,
1928 0x48, 0x22, 0x00, 0x00, 0xC8, 0x30, 0x8E, 0x46,
1929 0x55, 0x99, 0x63, 0x86, 0xB3, 0x95, 0xFB, 0x00,
1930 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1931 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab
1932 };
1933 uint8_t srtp_plaintext[64] = {
1934 0x90, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1935 0xca, 0xfe, 0xba, 0xbe, 0xBE, 0xDE, 0x00, 0x06,
1936 0x17, 0x41, 0x42, 0x73, 0xA4, 0x75, 0x26, 0x27,
1937 0x48, 0x22, 0x00, 0x00, 0xC8, 0x30, 0x8E, 0x46,
1938 0x55, 0x99, 0x63, 0x86, 0xB3, 0x95, 0xFB, 0x00,
1939 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1940 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1941 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1942 };
1943 uint8_t srtp_ciphertext[64] = {
1944 0x90, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1945 0xca, 0xfe, 0xba, 0xbe, 0xBE, 0xDE, 0x00, 0x06,
1946 0x17, 0x58, 0x8A, 0x92, 0x70, 0xF4, 0xE1, 0x5E,
1947 0x1C, 0x22, 0x00, 0x00, 0xC8, 0x30, 0x95, 0x46,
1948 0xA9, 0x94, 0xF0, 0xBC, 0x54, 0x78, 0x97, 0x00,
1949 0x0e, 0xca, 0x0c, 0xf9, 0x5e, 0xe9, 0x55, 0xb2,
1950 0x6c, 0xd3, 0xd2, 0x88, 0xb4, 0x9f, 0x6c, 0xa9,
1951 0xbb, 0x4e, 0x15, 0xc2, 0xe9, 0xf2, 0x66, 0x78
1952 };
1953 srtp_t srtp_snd, srtp_recv;
1954 srtp_err_status_t status;
1955 int len;
1956 srtp_policy_t policy;
1957 int headers[3] = {1, 3, 4};
1958
1959 /*
1960 * create a session with a single stream using the default srtp
1961 * policy and with the SSRC value 0xcafebabe
1962 */
1963 memset(&policy, 0, sizeof(policy));
1964 srtp_crypto_policy_set_aes_gcm_128_8_auth(&policy.rtp);
1965 srtp_crypto_policy_set_aes_gcm_128_8_auth(&policy.rtcp);
1966 policy.ssrc.type = ssrc_specific;
1967 policy.ssrc.value = 0xcafebabe;
1968 policy.key = test_key_ext_headers;
1969 policy.ekt = NULL;
1970 policy.window_size = 128;
1971 policy.allow_repeat_tx = 0;
1972 policy.enc_xtn_hdr = headers;
1973 policy.enc_xtn_hdr_count = sizeof(headers) / sizeof(headers[0]);
1974 policy.next = NULL;
1975
1976 status = srtp_create(&srtp_snd, &policy);
1977 if (status)
1978 return status;
1979
1980 /*
1981 * protect plaintext, then compare with ciphertext
1982 */
1983 len = sizeof(srtp_plaintext_ref);
1984 status = srtp_protect(srtp_snd, srtp_plaintext, &len);
1985 if (status || (len != sizeof(srtp_plaintext)))
1986 return srtp_err_status_fail;
1987
1988 debug_print(mod_driver, "ciphertext:\n %s",
1989 srtp_octet_string_hex_string(srtp_plaintext, len));
1990 debug_print(mod_driver, "ciphertext reference:\n %s",
1991 srtp_octet_string_hex_string(srtp_ciphertext, len));
1992
1993 if (octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len))
1994 return srtp_err_status_fail;
1995
1996 /*
1997 * create a receiver session context comparable to the one created
1998 * above - we need to do this so that the replay checking doesn't
1999 * complain
2000 */
2001 status = srtp_create(&srtp_recv, &policy);
2002 if (status)
2003 return status;
2004
2005 /*
2006 * unprotect ciphertext, then compare with plaintext
2007 */
2008 status = srtp_unprotect(srtp_recv, srtp_ciphertext, &len);
Joachim Baucha9ecefe2015-12-14 21:40:42 +01002009 if (status) {
Joachim Bauchfa1e8c22015-11-24 23:38:48 +01002010 return status;
Joachim Baucha9ecefe2015-12-14 21:40:42 +01002011 } else if (len != sizeof(srtp_plaintext_ref)) {
2012 return srtp_err_status_fail;
2013 }
Joachim Bauchfa1e8c22015-11-24 23:38:48 +01002014
2015 if (octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len))
2016 return srtp_err_status_fail;
2017
2018 status = srtp_dealloc(srtp_snd);
2019 if (status)
2020 return status;
2021
2022 status = srtp_dealloc(srtp_recv);
2023 if (status)
2024 return status;
2025
2026 return srtp_err_status_ok;
2027}
Joachim Bauch80a45b52015-12-06 22:57:58 +01002028#endif
Cullen Jennings235513a2005-09-21 22:51:36 +00002029
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002030/*
2031 * srtp_validate_aes_256() verifies the correctness of libsrtp by comparing
2032 * some computed packets against some pre-computed reference values.
2033 * These packets were made with the AES-CM-256/HMAC-SHA-1-80 policy.
2034 */
2035
2036
jfigus857009c2014-11-05 11:17:43 -05002037srtp_err_status_t
jfigus67b9c732014-11-20 10:17:21 -05002038srtp_validate_aes_256 ()
2039{
2040 unsigned char aes_256_test_key[46] = {
2041 0xf0, 0xf0, 0x49, 0x14, 0xb5, 0x13, 0xf2, 0x76,
2042 0x3a, 0x1b, 0x1f, 0xa1, 0x30, 0xf1, 0x0e, 0x29,
2043 0x98, 0xf6, 0xf6, 0xe4, 0x3e, 0x43, 0x09, 0xd1,
2044 0xe6, 0x22, 0xa0, 0xe3, 0x32, 0xb9, 0xf1, 0xb6,
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002045
jfigus67b9c732014-11-20 10:17:21 -05002046 0x3b, 0x04, 0x80, 0x3d, 0xe5, 0x1e, 0xe7, 0xc9,
2047 0x64, 0x23, 0xab, 0x5b, 0x78, 0xd2
2048 };
2049 uint8_t srtp_plaintext_ref[28] = {
2050 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
2051 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
2052 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
2053 0xab, 0xab, 0xab, 0xab
2054 };
2055 uint8_t srtp_plaintext[38] = {
2056 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
2057 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
2058 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
2059 0xab, 0xab, 0xab, 0xab, 0x00, 0x00, 0x00, 0x00,
2060 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
2061 };
2062 uint8_t srtp_ciphertext[38] = {
2063 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
2064 0xca, 0xfe, 0xba, 0xbe, 0xf1, 0xd9, 0xde, 0x17,
2065 0xff, 0x25, 0x1f, 0xf1, 0xaa, 0x00, 0x77, 0x74,
2066 0xb0, 0xb4, 0xb4, 0x0d, 0xa0, 0x8d, 0x9d, 0x9a,
2067 0x5b, 0x3a, 0x55, 0xd8, 0x87, 0x3b
2068 };
2069 srtp_t srtp_snd, srtp_recv;
2070 srtp_err_status_t status;
2071 int len;
2072 srtp_policy_t policy;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002073
jfigus67b9c732014-11-20 10:17:21 -05002074 /*
2075 * create a session with a single stream using the default srtp
2076 * policy and with the SSRC value 0xcafebabe
2077 */
Joachim Bauch99a74822015-11-17 00:08:19 +01002078 memset(&policy, 0, sizeof(policy));
jfigus67b9c732014-11-20 10:17:21 -05002079 srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(&policy.rtp);
2080 srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(&policy.rtcp);
2081 policy.ssrc.type = ssrc_specific;
2082 policy.ssrc.value = 0xcafebabe;
2083 policy.key = aes_256_test_key;
2084 policy.ekt = NULL;
2085 policy.window_size = 128;
2086 policy.allow_repeat_tx = 0;
2087 policy.next = NULL;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002088
jfigus67b9c732014-11-20 10:17:21 -05002089 status = srtp_create(&srtp_snd, &policy);
2090 if (status) {
2091 return status;
2092 }
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002093
jfigus67b9c732014-11-20 10:17:21 -05002094 /*
2095 * protect plaintext, then compare with ciphertext
2096 */
2097 len = 28;
2098 status = srtp_protect(srtp_snd, srtp_plaintext, &len);
2099 if (status || (len != 38)) {
2100 return srtp_err_status_fail;
2101 }
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002102
jfigus67b9c732014-11-20 10:17:21 -05002103 debug_print(mod_driver, "ciphertext:\n %s",
2104 octet_string_hex_string(srtp_plaintext, len));
2105 debug_print(mod_driver, "ciphertext reference:\n %s",
2106 octet_string_hex_string(srtp_ciphertext, len));
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002107
jfigus67b9c732014-11-20 10:17:21 -05002108 if (octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len)) {
2109 return srtp_err_status_fail;
2110 }
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002111
jfigus67b9c732014-11-20 10:17:21 -05002112 /*
2113 * create a receiver session context comparable to the one created
2114 * above - we need to do this so that the replay checking doesn't
2115 * complain
2116 */
2117 status = srtp_create(&srtp_recv, &policy);
2118 if (status) {
2119 return status;
2120 }
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002121
jfigus67b9c732014-11-20 10:17:21 -05002122 /*
2123 * unprotect ciphertext, then compare with plaintext
2124 */
2125 status = srtp_unprotect(srtp_recv, srtp_ciphertext, &len);
2126 if (status || (len != 28)) {
2127 return status;
2128 }
2129
2130 if (octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len)) {
2131 return srtp_err_status_fail;
2132 }
2133
2134 status = srtp_dealloc(srtp_snd);
2135 if (status) {
2136 return status;
2137 }
2138
2139 status = srtp_dealloc(srtp_recv);
2140 if (status) {
2141 return status;
2142 }
2143
2144 return srtp_err_status_ok;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002145}
2146
2147
jfigus857009c2014-11-05 11:17:43 -05002148srtp_err_status_t
jfigus67b9c732014-11-20 10:17:21 -05002149srtp_create_big_policy (srtp_policy_t **list)
2150{
2151 extern const srtp_policy_t *policy_array[];
2152 srtp_policy_t *p, *tmp;
2153 int i = 0;
2154 uint32_t ssrc = 0;
Cullen Jennings235513a2005-09-21 22:51:36 +00002155
jfigus67b9c732014-11-20 10:17:21 -05002156 /* sanity checking */
2157 if ((list == NULL) || (policy_array[0] == NULL)) {
2158 return srtp_err_status_bad_param;
2159 }
Cullen Jennings235513a2005-09-21 22:51:36 +00002160
jfigus67b9c732014-11-20 10:17:21 -05002161 /*
2162 * loop over policy list, mallocing a new list and copying values
2163 * into it (and incrementing the SSRC value as we go along)
2164 */
2165 tmp = NULL;
2166 while (policy_array[i] != NULL) {
2167 p = (srtp_policy_t*)malloc(sizeof(srtp_policy_t));
2168 if (p == NULL) {
2169 return srtp_err_status_bad_param;
2170 }
2171 memcpy(p, policy_array[i], sizeof(srtp_policy_t));
2172 p->ssrc.type = ssrc_specific;
2173 p->ssrc.value = ssrc++;
2174 p->next = tmp;
2175 tmp = p;
2176 i++;
2177 }
2178 *list = p;
2179
2180 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +00002181}
2182
jfigus857009c2014-11-05 11:17:43 -05002183srtp_err_status_t
jfigus67b9c732014-11-20 10:17:21 -05002184srtp_dealloc_big_policy (srtp_policy_t *list)
2185{
2186 srtp_policy_t *p, *next;
Jonathan Lennox80c4c832010-05-17 19:30:28 +00002187
jfigus67b9c732014-11-20 10:17:21 -05002188 for (p = list; p != NULL; p = next) {
2189 next = p->next;
2190 free(p);
2191 }
Jonathan Lennox80c4c832010-05-17 19:30:28 +00002192
jfigus67b9c732014-11-20 10:17:21 -05002193 return srtp_err_status_ok;
Jonathan Lennox80c4c832010-05-17 19:30:28 +00002194}
2195
Joachim Bauchc8a19ae2015-12-14 22:50:36 +01002196srtp_err_status_t
2197srtp_test_empty_payload()
2198{
2199 srtp_t srtp_snd, srtp_recv;
2200 srtp_err_status_t status;
2201 int len;
2202 srtp_policy_t policy;
2203 srtp_hdr_t *mesg;
2204
2205 /*
2206 * create a session with a single stream using the default srtp
2207 * policy and with the SSRC value 0xcafebabe
2208 */
2209 memset(&policy, 0, sizeof(policy));
2210 srtp_crypto_policy_set_rtp_default(&policy.rtp);
2211 srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
2212 policy.ssrc.type = ssrc_specific;
2213 policy.ssrc.value = 0xcafebabe;
2214 policy.key = test_key;
2215 policy.ekt = NULL;
2216 policy.window_size = 128;
2217 policy.allow_repeat_tx = 0;
2218 policy.next = NULL;
2219
2220 status = srtp_create(&srtp_snd, &policy);
2221 if (status) {
2222 return status;
2223 }
2224
2225 mesg = srtp_create_test_packet(0, policy.ssrc.value);
2226 if (mesg == NULL) {
2227 return srtp_err_status_fail;
2228 }
2229
2230 len = 12; /* only the header */
2231 status = srtp_protect(srtp_snd, mesg, &len);
2232 if (status) {
2233 return status;
2234 } else if (len != 12 + 10) {
2235 return srtp_err_status_fail;
2236 }
2237
2238 /*
2239 * create a receiver session context comparable to the one created
2240 * above - we need to do this so that the replay checking doesn't
2241 * complain
2242 */
2243 status = srtp_create(&srtp_recv, &policy);
2244 if (status) {
2245 return status;
2246 }
2247
2248 /*
2249 * unprotect ciphertext, then compare with plaintext
2250 */
2251 status = srtp_unprotect(srtp_recv, mesg, &len);
2252 if (status) {
2253 return status;
2254 } else if (len != 12) {
2255 return srtp_err_status_fail;
2256 }
2257
2258 status = srtp_dealloc(srtp_snd);
2259 if (status) {
2260 return status;
2261 }
2262
2263 status = srtp_dealloc(srtp_recv);
2264 if (status) {
2265 return status;
2266 }
2267
2268 free(mesg);
2269
2270 return srtp_err_status_ok;
2271}
2272
2273#ifdef OPENSSL
2274srtp_err_status_t
2275srtp_test_empty_payload_gcm()
2276{
2277 srtp_t srtp_snd, srtp_recv;
2278 srtp_err_status_t status;
2279 int len;
2280 srtp_policy_t policy;
2281 srtp_hdr_t *mesg;
2282
2283 /*
2284 * create a session with a single stream using the default srtp
2285 * policy and with the SSRC value 0xcafebabe
2286 */
2287 memset(&policy, 0, sizeof(policy));
2288 srtp_crypto_policy_set_aes_gcm_128_8_auth(&policy.rtp);
2289 srtp_crypto_policy_set_aes_gcm_128_8_auth(&policy.rtcp);
2290 policy.ssrc.type = ssrc_specific;
2291 policy.ssrc.value = 0xcafebabe;
2292 policy.key = test_key;
2293 policy.ekt = NULL;
2294 policy.window_size = 128;
2295 policy.allow_repeat_tx = 0;
2296 policy.next = NULL;
2297
2298 status = srtp_create(&srtp_snd, &policy);
2299 if (status) {
2300 return status;
2301 }
2302
2303 mesg = srtp_create_test_packet(0, policy.ssrc.value);
2304 if (mesg == NULL) {
2305 return srtp_err_status_fail;
2306 }
2307
2308 len = 12; /* only the header */
2309 status = srtp_protect(srtp_snd, mesg, &len);
2310 if (status) {
2311 return status;
2312 } else if (len != 12 + 8) {
2313 return srtp_err_status_fail;
2314 }
2315
2316 /*
2317 * create a receiver session context comparable to the one created
2318 * above - we need to do this so that the replay checking doesn't
2319 * complain
2320 */
2321 status = srtp_create(&srtp_recv, &policy);
2322 if (status) {
2323 return status;
2324 }
2325
2326 /*
2327 * unprotect ciphertext, then compare with plaintext
2328 */
2329 status = srtp_unprotect(srtp_recv, mesg, &len);
2330 if (status) {
2331 return status;
2332 } else if (len != 12) {
2333 return srtp_err_status_fail;
2334 }
2335
2336 status = srtp_dealloc(srtp_snd);
2337 if (status) {
2338 return status;
2339 }
2340
2341 status = srtp_dealloc(srtp_recv);
2342 if (status) {
2343 return status;
2344 }
2345
2346 free(mesg);
2347
2348 return srtp_err_status_ok;
2349}
2350#endif // OPENSSL
Jonathan Lennox80c4c832010-05-17 19:30:28 +00002351
jfigus857009c2014-11-05 11:17:43 -05002352srtp_err_status_t
jfigus67b9c732014-11-20 10:17:21 -05002353srtp_test_remove_stream ()
2354{
2355 srtp_err_status_t status;
2356 srtp_policy_t *policy_list, policy;
2357 srtp_t session;
2358 srtp_stream_t stream;
Cullen Jennings235513a2005-09-21 22:51:36 +00002359
jfigus67b9c732014-11-20 10:17:21 -05002360 /*
2361 * srtp_get_stream() is a libSRTP internal function that we declare
2362 * here so that we can use it to verify the correct operation of the
2363 * library
2364 */
2365 extern srtp_stream_t srtp_get_stream(srtp_t srtp, uint32_t ssrc);
Cullen Jennings235513a2005-09-21 22:51:36 +00002366
Cullen Jennings235513a2005-09-21 22:51:36 +00002367
jfigus67b9c732014-11-20 10:17:21 -05002368 status = srtp_create_big_policy(&policy_list);
2369 if (status) {
2370 return status;
2371 }
Cullen Jennings235513a2005-09-21 22:51:36 +00002372
jfigus67b9c732014-11-20 10:17:21 -05002373 status = srtp_create(&session, policy_list);
2374 if (status) {
2375 return status;
2376 }
Jonathan Lennox80c4c832010-05-17 19:30:28 +00002377
jfigus67b9c732014-11-20 10:17:21 -05002378 /*
2379 * check for false positives by trying to remove a stream that's not
2380 * in the session
2381 */
2382 status = srtp_remove_stream(session, htonl(0xaaaaaaaa));
2383 if (status != srtp_err_status_no_ctx) {
2384 return srtp_err_status_fail;
2385 }
Jonathan Lennox80c4c832010-05-17 19:30:28 +00002386
jfigus67b9c732014-11-20 10:17:21 -05002387 /*
2388 * check for false negatives by removing stream 0x1, then
2389 * searching for streams 0x0 and 0x2
2390 */
2391 status = srtp_remove_stream(session, htonl(0x1));
2392 if (status != srtp_err_status_ok) {
2393 return srtp_err_status_fail;
2394 }
2395 stream = srtp_get_stream(session, htonl(0x0));
2396 if (stream == NULL) {
2397 return srtp_err_status_fail;
2398 }
2399 stream = srtp_get_stream(session, htonl(0x2));
2400 if (stream == NULL) {
2401 return srtp_err_status_fail;
2402 }
Jonathan Lennoxad741b22010-05-27 19:23:05 +00002403
jfigus67b9c732014-11-20 10:17:21 -05002404 status = srtp_dealloc(session);
2405 if (status != srtp_err_status_ok) {
2406 return status;
2407 }
Jonathan Lennoxad741b22010-05-27 19:23:05 +00002408
jfigus67b9c732014-11-20 10:17:21 -05002409 status = srtp_dealloc_big_policy(policy_list);
2410 if (status != srtp_err_status_ok) {
2411 return status;
2412 }
Jonathan Lennoxad741b22010-05-27 19:23:05 +00002413
jfigus67b9c732014-11-20 10:17:21 -05002414 /* Now test adding and removing a single stream */
Joachim Bauch99a74822015-11-17 00:08:19 +01002415 memset(&policy, 0, sizeof(policy));
jfigus67b9c732014-11-20 10:17:21 -05002416 srtp_crypto_policy_set_rtp_default(&policy.rtp);
2417 srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
2418 policy.ssrc.type = ssrc_specific;
2419 policy.ssrc.value = 0xcafebabe;
2420 policy.key = test_key;
2421 policy.ekt = NULL;
2422 policy.window_size = 128;
2423 policy.allow_repeat_tx = 0;
2424 policy.next = NULL;
Jonathan Lennoxad741b22010-05-27 19:23:05 +00002425
jfigus67b9c732014-11-20 10:17:21 -05002426 status = srtp_create(&session, NULL);
2427 if (status != srtp_err_status_ok) {
2428 return status;
2429 }
2430
2431 status = srtp_add_stream(session, &policy);
2432 if (status != srtp_err_status_ok) {
2433 return status;
2434 }
2435
2436 status = srtp_remove_stream(session, htonl(0xcafebabe));
2437 if (status != srtp_err_status_ok) {
2438 return status;
2439 }
2440
2441 status = srtp_dealloc(session);
2442 if (status != srtp_err_status_ok) {
2443 return status;
2444 }
2445
2446 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +00002447}
2448
Pascal Bühlerbd3112a2015-11-06 20:29:15 +01002449
2450unsigned char test_alt_key[46] = {
2451 0xe5, 0x19, 0x6f, 0x01, 0x5e, 0xf1, 0x9b, 0xe1,
2452 0xd7, 0x47, 0xa7, 0x27, 0x07, 0xd7, 0x47, 0x33,
2453 0x01, 0xc2, 0x35, 0x4d, 0x59, 0x6a, 0xf7, 0x84,
2454 0x96, 0x98, 0xeb, 0xaa, 0xac, 0xf6, 0xa1, 0x45,
2455 0xc7, 0x15, 0xe2, 0xea, 0xfe, 0x55, 0x67, 0x96,
2456 0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6
2457};
2458
2459/*
2460 * srtp_test_update() verifies updating/rekeying exsisting streams.
2461 * As stated in https://tools.ietf.org/html/rfc3711#section-3.3.1
2462 * the value of the ROC must not be reset after a rekey, this test
2463 * atempts to prove that srtp_update does not reset the ROC.
2464 */
2465
2466srtp_err_status_t
2467srtp_test_update() {
2468
2469 srtp_err_status_t status;
2470 uint32_t ssrc = 0x12121212;
2471 int msg_len_octets = 32;
2472 int protected_msg_len_octets;
2473 srtp_hdr_t * msg;
2474 srtp_t srtp_snd, srtp_recv;
2475 srtp_policy_t policy;
2476
Joachim Bauch1b793352015-12-14 21:30:44 +01002477 memset(&policy, 0, sizeof(policy));
Pascal Bühlerbd3112a2015-11-06 20:29:15 +01002478 srtp_crypto_policy_set_rtp_default(&policy.rtp);
2479 srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
2480 policy.ekt = NULL;
2481 policy.window_size = 128;
2482 policy.allow_repeat_tx = 0;
2483 policy.next = NULL;
2484 policy.ssrc.type = ssrc_any_outbound;
2485 policy.key = test_key;
2486
2487 /* create a send and recive ctx with defualt profile and test_key */
2488 status = srtp_create(&srtp_recv, &policy);
2489 if (status)
2490 return status;
2491
2492 policy.ssrc.type = ssrc_any_inbound;
2493 status = srtp_create(&srtp_snd, &policy);
2494 if (status)
2495 return status;
2496
2497 /* protect and unprotect two msg's that will cause the ROC to be equal to 1 */
2498 msg = srtp_create_test_packet(msg_len_octets, ssrc);
2499 if (msg == NULL)
2500 return srtp_err_status_alloc_fail;
2501 msg->seq = htons(65535);
2502
2503 protected_msg_len_octets = msg_len_octets;
2504 status = srtp_protect(srtp_snd, msg, &protected_msg_len_octets);
2505 if (status)
2506 return srtp_err_status_fail;
2507
2508 status = srtp_unprotect(srtp_recv, msg, &protected_msg_len_octets);
2509 if (status)
2510 return status;
2511
2512 free(msg);
2513
2514 msg = srtp_create_test_packet(msg_len_octets, ssrc);
2515 if (msg == NULL)
2516 return srtp_err_status_alloc_fail;
2517 msg->seq = htons(1);
2518
2519 protected_msg_len_octets = msg_len_octets;
2520 status = srtp_protect(srtp_snd, msg, &protected_msg_len_octets);
2521 if (status)
2522 return srtp_err_status_fail;
2523
2524 status = srtp_unprotect(srtp_recv, msg, &protected_msg_len_octets);
2525 if (status)
2526 return status;
2527
2528 free(msg);
2529
Pascal Bühlerb095e7e2016-06-09 13:46:28 +02002530 /* update send ctx with same test_key t verify update works*/
2531 policy.ssrc.type = ssrc_any_outbound;
2532 policy.key = test_key;
2533 status = srtp_update(srtp_snd, &policy);
2534 if (status)
2535 return status;
2536
2537 msg = srtp_create_test_packet(msg_len_octets, ssrc);
2538 if (msg == NULL)
2539 return srtp_err_status_alloc_fail;
2540 msg->seq = htons(2);
2541
2542 protected_msg_len_octets = msg_len_octets;
2543 status = srtp_protect(srtp_snd, msg, &protected_msg_len_octets);
2544 if (status)
2545 return srtp_err_status_fail;
2546
2547 status = srtp_unprotect(srtp_recv, msg, &protected_msg_len_octets);
2548 if (status)
2549 return status;
2550
2551 free(msg);
2552
2553
Pascal Bühlerbd3112a2015-11-06 20:29:15 +01002554 /* update send ctx to use test_alt_key */
2555 policy.ssrc.type = ssrc_any_outbound;
2556 policy.key = test_alt_key;
2557 status = srtp_update(srtp_snd, &policy);
2558 if (status)
2559 return status;
2560
2561 /* create and protect msg with new key and ROC still equal to 1 */
2562 msg = srtp_create_test_packet(msg_len_octets, ssrc);
2563 if (msg == NULL)
2564 return srtp_err_status_alloc_fail;
Pascal Bühlerb095e7e2016-06-09 13:46:28 +02002565 msg->seq = htons(3);
Pascal Bühlerbd3112a2015-11-06 20:29:15 +01002566
2567 protected_msg_len_octets = msg_len_octets;
2568 status = srtp_protect(srtp_snd, msg, &protected_msg_len_octets);
2569 if (status)
2570 return srtp_err_status_fail;
2571
2572 /* verify that recive ctx will fail to unprotect as it still uses test_key */
2573 status = srtp_unprotect(srtp_recv, msg, &protected_msg_len_octets);
2574 if (status == srtp_err_status_ok)
2575 return srtp_err_status_fail;
2576
2577 /* create a new recvieve ctx with test_alt_key but since it is new it will have ROC equal to 1
2578 * and therefore should fail to unprotected */
2579 {
2580 srtp_t srtp_recv_roc_0;
2581
2582 policy.ssrc.type = ssrc_any_inbound;
2583 policy.key = test_alt_key;
2584 status = srtp_create(&srtp_recv_roc_0, &policy);
2585 if (status)
2586 return status;
2587
2588 status = srtp_unprotect(srtp_recv_roc_0, msg, &protected_msg_len_octets);
2589 if (status == srtp_err_status_ok)
2590 return srtp_err_status_fail;
2591
2592 status = srtp_dealloc(srtp_recv_roc_0);
2593 if (status)
2594 return status;
2595 }
2596
2597 /* update recive ctx to use test_alt_key */
2598 policy.ssrc.type = ssrc_any_inbound;
2599 policy.key = test_alt_key;
2600 status = srtp_update(srtp_recv, &policy);
2601 if (status)
2602 return status;
2603
2604 /* verify that can still unprotect, therfore key is updated and ROC value is preserved */
2605 status = srtp_unprotect(srtp_recv, msg, &protected_msg_len_octets);
2606 if (status)
2607 return status;
2608
2609 free(msg);
2610
2611 status = srtp_dealloc(srtp_snd);
2612 if (status)
2613 return status;
2614
2615 status = srtp_dealloc(srtp_recv);
2616 if (status)
2617 return status;
2618
2619 return srtp_err_status_ok;
2620}
2621
Cullen Jennings235513a2005-09-21 22:51:36 +00002622/*
2623 * srtp policy definitions - these definitions are used above
2624 */
2625
jfigus8c36da22013-10-01 16:41:19 -04002626unsigned char test_key[46] = {
Cullen Jennings235513a2005-09-21 22:51:36 +00002627 0xe1, 0xf9, 0x7a, 0x0d, 0x3e, 0x01, 0x8b, 0xe0,
2628 0xd6, 0x4f, 0xa3, 0x2c, 0x06, 0xde, 0x41, 0x39,
2629 0x0e, 0xc6, 0x75, 0xad, 0x49, 0x8a, 0xfe, 0xeb,
jfigus8c36da22013-10-01 16:41:19 -04002630 0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6, 0xc1, 0x73,
2631 0xc3, 0x17, 0xf2, 0xda, 0xbe, 0x35, 0x77, 0x93,
Cullen Jennings235513a2005-09-21 22:51:36 +00002632 0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6
2633};
2634
2635
2636const srtp_policy_t default_policy = {
jfigus67b9c732014-11-20 10:17:21 -05002637 { ssrc_any_outbound, 0 }, /* SSRC */
2638 { /* SRTP policy */
2639 SRTP_AES_128_ICM, /* cipher type */
2640 30, /* cipher key length in octets */
2641 SRTP_HMAC_SHA1, /* authentication func type */
2642 16, /* auth key length in octets */
2643 10, /* auth tag length in octets */
2644 sec_serv_conf_and_auth /* security services flag */
2645 },
2646 { /* SRTCP policy */
2647 SRTP_AES_128_ICM, /* cipher type */
2648 30, /* cipher key length in octets */
2649 SRTP_HMAC_SHA1, /* authentication func type */
2650 16, /* auth key length in octets */
2651 10, /* auth tag length in octets */
2652 sec_serv_conf_and_auth /* security services flag */
2653 },
2654 test_key,
2655 NULL, /* indicates that EKT is not in use */
2656 128, /* replay window size */
2657 0, /* retransmission not allowed */
Joachim Bauch99a74822015-11-17 00:08:19 +01002658 NULL, /* no encrypted extension headers */
2659 0, /* list of encrypted extension headers is empty */
jfigus67b9c732014-11-20 10:17:21 -05002660 NULL
Cullen Jennings235513a2005-09-21 22:51:36 +00002661};
2662
2663const srtp_policy_t aes_only_policy = {
jfigus67b9c732014-11-20 10:17:21 -05002664 { ssrc_any_outbound, 0 }, /* SSRC */
2665 {
2666 SRTP_AES_128_ICM, /* cipher type */
2667 30, /* cipher key length in octets */
2668 SRTP_NULL_AUTH, /* authentication func type */
2669 0, /* auth key length in octets */
2670 0, /* auth tag length in octets */
2671 sec_serv_conf /* security services flag */
2672 },
2673 {
2674 SRTP_AES_128_ICM, /* cipher type */
2675 30, /* cipher key length in octets */
2676 SRTP_NULL_AUTH, /* authentication func type */
2677 0, /* auth key length in octets */
2678 0, /* auth tag length in octets */
2679 sec_serv_conf /* security services flag */
2680 },
2681 test_key,
2682 NULL, /* indicates that EKT is not in use */
2683 128, /* replay window size */
2684 0, /* retransmission not allowed */
Joachim Bauch99a74822015-11-17 00:08:19 +01002685 NULL, /* no encrypted extension headers */
2686 0, /* list of encrypted extension headers is empty */
jfigus67b9c732014-11-20 10:17:21 -05002687 NULL
Cullen Jennings235513a2005-09-21 22:51:36 +00002688};
2689
2690const srtp_policy_t hmac_only_policy = {
jfigus67b9c732014-11-20 10:17:21 -05002691 { ssrc_any_outbound, 0 }, /* SSRC */
2692 {
2693 SRTP_NULL_CIPHER, /* cipher type */
2694 0, /* cipher key length in octets */
2695 SRTP_HMAC_SHA1, /* authentication func type */
2696 20, /* auth key length in octets */
2697 4, /* auth tag length in octets */
2698 sec_serv_auth /* security services flag */
2699 },
2700 {
2701 SRTP_NULL_CIPHER, /* cipher type */
2702 0, /* cipher key length in octets */
2703 SRTP_HMAC_SHA1, /* authentication func type */
2704 20, /* auth key length in octets */
2705 4, /* auth tag length in octets */
2706 sec_serv_auth /* security services flag */
2707 },
2708 test_key,
2709 NULL, /* indicates that EKT is not in use */
2710 128, /* replay window size */
2711 0, /* retransmission not allowed */
Joachim Bauch99a74822015-11-17 00:08:19 +01002712 NULL, /* no encrypted extension headers */
2713 0, /* list of encrypted extension headers is empty */
jfigus67b9c732014-11-20 10:17:21 -05002714 NULL
Cullen Jennings235513a2005-09-21 22:51:36 +00002715};
2716
jfigus8c36da22013-10-01 16:41:19 -04002717#ifdef OPENSSL
2718const srtp_policy_t aes128_gcm_8_policy = {
jfigus67b9c732014-11-20 10:17:21 -05002719 { ssrc_any_outbound, 0 }, /* SSRC */
2720 { /* SRTP policy */
2721 SRTP_AES_128_GCM, /* cipher type */
2722 SRTP_AES_128_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
2723 SRTP_NULL_AUTH, /* authentication func type */
2724 0, /* auth key length in octets */
2725 8, /* auth tag length in octets */
2726 sec_serv_conf_and_auth /* security services flag */
jfigus8c36da22013-10-01 16:41:19 -04002727 },
jfigus67b9c732014-11-20 10:17:21 -05002728 { /* SRTCP policy */
2729 SRTP_AES_128_GCM, /* cipher type */
2730 SRTP_AES_128_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
2731 SRTP_NULL_AUTH, /* authentication func type */
2732 0, /* auth key length in octets */
2733 8, /* auth tag length in octets */
2734 sec_serv_conf_and_auth /* security services flag */
jfigus8c36da22013-10-01 16:41:19 -04002735 },
2736 test_key,
2737 NULL, /* indicates that EKT is not in use */
2738 128, /* replay window size */
2739 0, /* retransmission not allowed */
Joachim Bauch99a74822015-11-17 00:08:19 +01002740 NULL, /* no encrypted extension headers */
2741 0, /* list of encrypted extension headers is empty */
jfigus8c36da22013-10-01 16:41:19 -04002742 NULL
2743};
2744
2745const srtp_policy_t aes128_gcm_8_cauth_policy = {
jfigus67b9c732014-11-20 10:17:21 -05002746 { ssrc_any_outbound, 0 }, /* SSRC */
2747 { /* SRTP policy */
2748 SRTP_AES_128_GCM, /* cipher type */
2749 SRTP_AES_128_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
2750 SRTP_NULL_AUTH, /* authentication func type */
2751 0, /* auth key length in octets */
2752 8, /* auth tag length in octets */
2753 sec_serv_conf_and_auth /* security services flag */
jfigus8c36da22013-10-01 16:41:19 -04002754 },
jfigus67b9c732014-11-20 10:17:21 -05002755 { /* SRTCP policy */
2756 SRTP_AES_128_GCM, /* cipher type */
2757 SRTP_AES_128_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
2758 SRTP_NULL_AUTH, /* authentication func type */
2759 0, /* auth key length in octets */
2760 8, /* auth tag length in octets */
2761 sec_serv_auth /* security services flag */
jfigus8c36da22013-10-01 16:41:19 -04002762 },
2763 test_key,
2764 NULL, /* indicates that EKT is not in use */
2765 128, /* replay window size */
2766 0, /* retransmission not allowed */
Joachim Bauch99a74822015-11-17 00:08:19 +01002767 NULL, /* no encrypted extension headers */
2768 0, /* list of encrypted extension headers is empty */
jfigus8c36da22013-10-01 16:41:19 -04002769 NULL
2770};
jfigus67b9c732014-11-20 10:17:21 -05002771
jfigus8c36da22013-10-01 16:41:19 -04002772const srtp_policy_t aes256_gcm_8_policy = {
jfigus67b9c732014-11-20 10:17:21 -05002773 { ssrc_any_outbound, 0 }, /* SSRC */
2774 { /* SRTP policy */
2775 SRTP_AES_256_GCM, /* cipher type */
2776 SRTP_AES_256_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
2777 SRTP_NULL_AUTH, /* authentication func type */
2778 0, /* auth key length in octets */
2779 8, /* auth tag length in octets */
2780 sec_serv_conf_and_auth /* security services flag */
jfigus8c36da22013-10-01 16:41:19 -04002781 },
jfigus67b9c732014-11-20 10:17:21 -05002782 { /* SRTCP policy */
2783 SRTP_AES_256_GCM, /* cipher type */
2784 SRTP_AES_256_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
2785 SRTP_NULL_AUTH, /* authentication func type */
2786 0, /* auth key length in octets */
2787 8, /* auth tag length in octets */
2788 sec_serv_conf_and_auth /* security services flag */
jfigus8c36da22013-10-01 16:41:19 -04002789 },
2790 test_key,
2791 NULL, /* indicates that EKT is not in use */
2792 128, /* replay window size */
2793 0, /* retransmission not allowed */
Joachim Bauch99a74822015-11-17 00:08:19 +01002794 NULL, /* no encrypted extension headers */
2795 0, /* list of encrypted extension headers is empty */
jfigus8c36da22013-10-01 16:41:19 -04002796 NULL
2797};
jfigus67b9c732014-11-20 10:17:21 -05002798
jfigus8c36da22013-10-01 16:41:19 -04002799const srtp_policy_t aes256_gcm_8_cauth_policy = {
jfigus67b9c732014-11-20 10:17:21 -05002800 { ssrc_any_outbound, 0 }, /* SSRC */
2801 { /* SRTP policy */
2802 SRTP_AES_256_GCM, /* cipher type */
2803 SRTP_AES_256_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
2804 SRTP_NULL_AUTH, /* authentication func type */
2805 0, /* auth key length in octets */
2806 8, /* auth tag length in octets */
2807 sec_serv_conf_and_auth /* security services flag */
jfigus8c36da22013-10-01 16:41:19 -04002808 },
jfigus67b9c732014-11-20 10:17:21 -05002809 { /* SRTCP policy */
2810 SRTP_AES_256_GCM, /* cipher type */
2811 SRTP_AES_256_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
2812 SRTP_NULL_AUTH, /* authentication func type */
2813 0, /* auth key length in octets */
2814 8, /* auth tag length in octets */
2815 sec_serv_auth /* security services flag */
jfigus8c36da22013-10-01 16:41:19 -04002816 },
2817 test_key,
2818 NULL, /* indicates that EKT is not in use */
2819 128, /* replay window size */
2820 0, /* retransmission not allowed */
Joachim Bauch99a74822015-11-17 00:08:19 +01002821 NULL, /* no encrypted extension headers */
2822 0, /* list of encrypted extension headers is empty */
jfigus8c36da22013-10-01 16:41:19 -04002823 NULL
2824};
2825#endif
2826
Cullen Jennings235513a2005-09-21 22:51:36 +00002827const srtp_policy_t null_policy = {
jfigus67b9c732014-11-20 10:17:21 -05002828 { ssrc_any_outbound, 0 }, /* SSRC */
2829 {
2830 SRTP_NULL_CIPHER, /* cipher type */
2831 0, /* cipher key length in octets */
2832 SRTP_NULL_AUTH, /* authentication func type */
2833 0, /* auth key length in octets */
2834 0, /* auth tag length in octets */
2835 sec_serv_none /* security services flag */
2836 },
2837 {
2838 SRTP_NULL_CIPHER, /* cipher type */
2839 0, /* cipher key length in octets */
2840 SRTP_NULL_AUTH, /* authentication func type */
2841 0, /* auth key length in octets */
2842 0, /* auth tag length in octets */
2843 sec_serv_none /* security services flag */
2844 },
2845 test_key,
2846 NULL, /* indicates that EKT is not in use */
2847 128, /* replay window size */
2848 0, /* retransmission not allowed */
Joachim Bauch99a74822015-11-17 00:08:19 +01002849 NULL, /* no encrypted extension headers */
2850 0, /* list of encrypted extension headers is empty */
jfigus67b9c732014-11-20 10:17:21 -05002851 NULL
David McGrew79870d62007-06-15 18:17:39 +00002852};
2853
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002854unsigned char test_256_key[46] = {
jfigus67b9c732014-11-20 10:17:21 -05002855 0xf0, 0xf0, 0x49, 0x14, 0xb5, 0x13, 0xf2, 0x76,
2856 0x3a, 0x1b, 0x1f, 0xa1, 0x30, 0xf1, 0x0e, 0x29,
2857 0x98, 0xf6, 0xf6, 0xe4, 0x3e, 0x43, 0x09, 0xd1,
2858 0xe6, 0x22, 0xa0, 0xe3, 0x32, 0xb9, 0xf1, 0xb6,
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002859
jfigus67b9c732014-11-20 10:17:21 -05002860 0x3b, 0x04, 0x80, 0x3d, 0xe5, 0x1e, 0xe7, 0xc9,
2861 0x64, 0x23, 0xab, 0x5b, 0x78, 0xd2
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002862};
2863
2864const srtp_policy_t aes_256_hmac_policy = {
jfigus67b9c732014-11-20 10:17:21 -05002865 { ssrc_any_outbound, 0 }, /* SSRC */
2866 { /* SRTP policy */
2867 SRTP_AES_ICM, /* cipher type */
2868 46, /* cipher key length in octets */
2869 SRTP_HMAC_SHA1, /* authentication func type */
2870 20, /* auth key length in octets */
2871 10, /* auth tag length in octets */
2872 sec_serv_conf_and_auth /* security services flag */
2873 },
2874 { /* SRTCP policy */
2875 SRTP_AES_ICM, /* cipher type */
2876 46, /* cipher key length in octets */
2877 SRTP_HMAC_SHA1, /* authentication func type */
2878 20, /* auth key length in octets */
2879 10, /* auth tag length in octets */
2880 sec_serv_conf_and_auth /* security services flag */
2881 },
2882 test_256_key,
2883 NULL, /* indicates that EKT is not in use */
2884 128, /* replay window size */
2885 0, /* retransmission not allowed */
Joachim Bauch99a74822015-11-17 00:08:19 +01002886 NULL, /* no encrypted extension headers */
2887 0, /* list of encrypted extension headers is empty */
jfigus67b9c732014-11-20 10:17:21 -05002888 NULL
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002889};
2890
David McGrew79870d62007-06-15 18:17:39 +00002891uint8_t ekt_test_key[16] = {
jfigus67b9c732014-11-20 10:17:21 -05002892 0x77, 0x26, 0x9d, 0xac, 0x16, 0xa3, 0x28, 0xca,
2893 0x8e, 0xc9, 0x68, 0x4b, 0xcc, 0xc4, 0xd2, 0x1b
David McGrew79870d62007-06-15 18:17:39 +00002894};
2895
2896#include "ekt.h"
2897
jfigusc5887e72014-11-06 09:46:18 -05002898srtp_ekt_policy_ctx_t ekt_test_policy = {
jfigus67b9c732014-11-20 10:17:21 -05002899 0xa5a5, /* SPI */
2900 SRTP_EKT_CIPHER_AES_128_ECB,
2901 ekt_test_key,
2902 NULL
David McGrew79870d62007-06-15 18:17:39 +00002903};
2904
2905const srtp_policy_t hmac_only_with_ekt_policy = {
jfigus67b9c732014-11-20 10:17:21 -05002906 { ssrc_any_outbound, 0 }, /* SSRC */
2907 {
2908 SRTP_NULL_CIPHER, /* cipher type */
2909 0, /* cipher key length in octets */
2910 SRTP_HMAC_SHA1, /* authentication func type */
2911 20, /* auth key length in octets */
2912 4, /* auth tag length in octets */
2913 sec_serv_auth /* security services flag */
2914 },
2915 {
2916 SRTP_NULL_CIPHER, /* cipher type */
2917 0, /* cipher key length in octets */
2918 SRTP_HMAC_SHA1, /* authentication func type */
2919 20, /* auth key length in octets */
2920 4, /* auth tag length in octets */
2921 sec_serv_auth /* security services flag */
2922 },
2923 test_key,
2924 &ekt_test_policy, /* indicates that EKT is not in use */
2925 128, /* replay window size */
2926 0, /* retransmission not allowed */
Joachim Bauch99a74822015-11-17 00:08:19 +01002927 NULL, /* no encrypted extension headers */
2928 0, /* list of encrypted extension headers is empty */
jfigus67b9c732014-11-20 10:17:21 -05002929 NULL
Cullen Jennings235513a2005-09-21 22:51:36 +00002930};
2931
2932
2933/*
2934 * an array of pointers to the policies listed above
2935 *
2936 * This array is used to test various aspects of libSRTP for
2937 * different cryptographic policies. The order of the elements
2938 * matters - the timing test generates output that can be used
jfigus67b9c732014-11-20 10:17:21 -05002939 * in a plot (see the gnuplot script file 'timing'). If you
Cullen Jennings235513a2005-09-21 22:51:36 +00002940 * add to this list, you should do it at the end.
2941 */
2942
Cullen Jennings235513a2005-09-21 22:51:36 +00002943const srtp_policy_t *
2944policy_array[] = {
jfigus67b9c732014-11-20 10:17:21 -05002945 &hmac_only_policy,
2946 &aes_only_policy,
2947 &default_policy,
jfigus8c36da22013-10-01 16:41:19 -04002948#ifdef OPENSSL
jfigus67b9c732014-11-20 10:17:21 -05002949 &aes128_gcm_8_policy,
2950 &aes128_gcm_8_cauth_policy,
2951 &aes256_gcm_8_policy,
2952 &aes256_gcm_8_cauth_policy,
jfigus8c36da22013-10-01 16:41:19 -04002953#endif
jfigus67b9c732014-11-20 10:17:21 -05002954 &null_policy,
2955 &aes_256_hmac_policy,
2956 &hmac_only_with_ekt_policy,
2957 NULL
Cullen Jennings235513a2005-09-21 22:51:36 +00002958};
2959
2960const srtp_policy_t wildcard_policy = {
jfigus67b9c732014-11-20 10:17:21 -05002961 { ssrc_any_outbound, 0 }, /* SSRC */
2962 { /* SRTP policy */
2963 SRTP_AES_128_ICM, /* cipher type */
2964 30, /* cipher key length in octets */
2965 SRTP_HMAC_SHA1, /* authentication func type */
2966 16, /* auth key length in octets */
2967 10, /* auth tag length in octets */
2968 sec_serv_conf_and_auth /* security services flag */
2969 },
2970 { /* SRTCP policy */
2971 SRTP_AES_128_ICM, /* cipher type */
2972 30, /* cipher key length in octets */
2973 SRTP_HMAC_SHA1, /* authentication func type */
2974 16, /* auth key length in octets */
2975 10, /* auth tag length in octets */
2976 sec_serv_conf_and_auth /* security services flag */
2977 },
2978 test_key,
2979 NULL,
2980 128, /* replay window size */
2981 0, /* retransmission not allowed */
Joachim Bauch99a74822015-11-17 00:08:19 +01002982 NULL, /* no encrypted extension headers */
2983 0, /* list of encrypted extension headers is empty */
jfigus67b9c732014-11-20 10:17:21 -05002984 NULL
Cullen Jennings235513a2005-09-21 22:51:36 +00002985};