Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(195)

Side by Side Diff: libsrtp/test/srtp_driver.c

Issue 3423016: Add current version of libSRTP from CVS. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/third_party/
Patch Set: '' Created 10 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « libsrtp/test/rtpw_test.sh ('k') | libsrtp/timing » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 /*
2 * srtp_driver.c
3 *
4 * a test driver for libSRTP
5 *
6 * David A. McGrew
7 * Cisco Systems, Inc.
8 */
9 /*
10 *
11 * Copyright (c) 2001-2006, Cisco Systems, Inc.
12 * All rights reserved.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
16 * are met:
17 *
18 * Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 *
21 * 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.
25 *
26 * 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.
29 *
30 * 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() */
50 #include "getopt_s.h" /* for local getopt() */
51
52 #include "srtp_priv.h"
53
54 #ifdef HAVE_NETINET_IN_H
55 # include <netinet/in.h>
56 #elif defined HAVE_WINSOCK2_H
57 # include <winsock2.h>
58 #endif
59
60 #define PRINT_REFERENCE_PACKET 1
61
62 err_status_t
63 srtp_validate(void);
64
65 err_status_t
66 srtp_validate_aes_256(void);
67
68 err_status_t
69 srtp_create_big_policy(srtp_policy_t **list);
70
71 err_status_t
72 srtp_dealloc_big_policy(srtp_policy_t *list);
73
74 err_status_t
75 srtp_test_remove_stream(void);
76
77 double
78 srtp_bits_per_second(int msg_len_octets, const srtp_policy_t *policy);
79
80 double
81 srtp_rejections_per_second(int msg_len_octets, const srtp_policy_t *policy);
82
83 void
84 srtp_do_timing(const srtp_policy_t *policy);
85
86 void
87 srtp_do_rejection_timing(const srtp_policy_t *policy);
88
89 err_status_t
90 srtp_test(const srtp_policy_t *policy);
91
92 err_status_t
93 srtcp_test(const srtp_policy_t *policy);
94
95 err_status_t
96 srtp_session_print_policy(srtp_t srtp);
97
98 err_status_t
99 srtp_print_policy(const srtp_policy_t *policy);
100
101 char *
102 srtp_packet_to_string(srtp_hdr_t *hdr, int packet_len);
103
104 double
105 mips_estimate(int num_trials, int *ignore);
106
107 extern uint8_t test_key[30];
108
109 void
110 usage(char *prog_name) {
111 printf("usage: %s [ -t ][ -c ][ -v ][-d <debug_module> ]* [ -l ]\n"
112 " -t run timing test\n"
113 " -r run rejection timing test\n"
114 " -c run codec timing test\n"
115 " -v run validation tests\n"
116 " -d <mod> turn on debugging module <mod>\n"
117 " -l list debugging modules\n", prog_name);
118 exit(1);
119 }
120
121 /*
122 * The policy_array is a null-terminated array of policy structs. it
123 * is declared at the end of this file
124 */
125
126 extern const srtp_policy_t *policy_array[];
127
128
129 /* the wildcard_policy is declared below; it has a wildcard ssrc */
130
131 extern const srtp_policy_t wildcard_policy;
132
133 /*
134 * mod_driver debug module - debugging module for this test driver
135 *
136 * we use the crypto_kernel debugging system in this driver, which
137 * makes the interface uniform and increases portability
138 */
139
140 debug_module_t mod_driver = {
141 0, /* debugging is off by default */
142 "driver" /* printable name for module */
143 };
144
145 int
146 main (int argc, char *argv[]) {
147 int q;
148 unsigned do_timing_test = 0;
149 unsigned do_rejection_test = 0;
150 unsigned do_codec_timing = 0;
151 unsigned do_validation = 0;
152 unsigned do_list_mods = 0;
153 err_status_t status;
154
155 /*
156 * verify that the compiler has interpreted the header data
157 * structure srtp_hdr_t correctly
158 */
159 if (sizeof(srtp_hdr_t) != 12) {
160 printf("error: srtp_hdr_t has incorrect size"
161 "(size is %ld bytes, expected 12)\n",
162 (long)sizeof(srtp_hdr_t));
163 exit(1);
164 }
165
166 /* initialize srtp library */
167 status = srtp_init();
168 if (status) {
169 printf("error: srtp init failed with error code %d\n", status);
170 exit(1);
171 }
172
173 /* load srtp_driver debug module */
174 status = crypto_kernel_load_debug_module(&mod_driver);
175 if (status) {
176 printf("error: load of srtp_driver debug module failed "
177 "with error code %d\n", status);
178 exit(1);
179 }
180
181 /* process input arguments */
182 while (1) {
183 q = getopt_s(argc, argv, "trcvld:");
184 if (q == -1)
185 break;
186 switch (q) {
187 case 't':
188 do_timing_test = 1;
189 break;
190 case 'r':
191 do_rejection_test = 1;
192 break;
193 case 'c':
194 do_codec_timing = 1;
195 break;
196 case 'v':
197 do_validation = 1;
198 break;
199 case 'l':
200 do_list_mods = 1;
201 break;
202 case 'd':
203 status = crypto_kernel_set_debug_module(optarg_s, 1);
204 if (status) {
205 printf("error: set debug module (%s) failed\n", optarg_s);
206 exit(1);
207 }
208 break;
209 default:
210 usage(argv[0]);
211 }
212 }
213
214 if (!do_validation && !do_timing_test && !do_codec_timing
215 && !do_list_mods && !do_rejection_test)
216 usage(argv[0]);
217
218 if (do_list_mods) {
219 status = crypto_kernel_list_debug_modules();
220 if (status) {
221 printf("error: list of debug modules failed\n");
222 exit(1);
223 }
224 }
225
226 if (do_validation) {
227 const srtp_policy_t **policy = policy_array;
228 srtp_policy_t *big_policy;
229
230 /* loop over policy array, testing srtp and srtcp for each policy */
231 while (*policy != NULL) {
232 printf("testing srtp_protect and srtp_unprotect\n");
233 if (srtp_test(*policy) == err_status_ok)
234 printf("passed\n\n");
235 else {
236 printf("failed\n");
237 exit(1);
238 }
239 printf("testing srtp_protect_rtcp and srtp_unprotect_rtcp\n");
240 if (srtcp_test(*policy) == err_status_ok)
241 printf("passed\n\n");
242 else {
243 printf("failed\n");
244 exit(1);
245 }
246 policy++;
247 }
248
249 /* create a big policy list and run tests on it */
250 status = srtp_create_big_policy(&big_policy);
251 if (status) {
252 printf("unexpected failure with error code %d\n", status);
253 exit(1);
254 }
255 printf("testing srtp_protect and srtp_unprotect with big policy\n");
256 if (srtp_test(big_policy) == err_status_ok)
257 printf("passed\n\n");
258 else {
259 printf("failed\n");
260 exit(1);
261 }
262 status = srtp_dealloc_big_policy(big_policy);
263 if (status) {
264 printf("unexpected failure with error code %d\n", status);
265 exit(1);
266 }
267
268 /* run test on wildcard policy */
269 printf("testing srtp_protect and srtp_unprotect on "
270 "wildcard ssrc policy\n");
271 if (srtp_test(&wildcard_policy) == err_status_ok)
272 printf("passed\n\n");
273 else {
274 printf("failed\n");
275 exit(1);
276 }
277
278 /*
279 * run validation test against the reference packets - note
280 * that this test only covers the default policy
281 */
282 printf("testing srtp_protect and srtp_unprotect against "
283 "reference packets\n");
284 if (srtp_validate() == err_status_ok)
285 printf("passed\n\n");
286 else {
287 printf("failed\n");
288 exit(1);
289 }
290
291 /*
292 * run validation test against the reference packets for
293 * AES-256
294 */
295 printf("testing srtp_protect and srtp_unprotect against "
296 "reference packets (AES-256)\n");
297 if (srtp_validate_aes_256() == err_status_ok)
298 printf("passed\n\n");
299 else {
300 printf("failed\n");
301 exit(1);
302 }
303
304 /*
305 * test the function srtp_remove_stream()
306 */
307 printf("testing srtp_remove_stream()...");
308 if (srtp_test_remove_stream() == err_status_ok)
309 printf("passed\n");
310 else {
311 printf("failed\n");
312 exit(1);
313 }
314 }
315
316 if (do_timing_test) {
317 const srtp_policy_t **policy = policy_array;
318
319 /* loop over policies, run timing test for each */
320 while (*policy != NULL) {
321 srtp_print_policy(*policy);
322 srtp_do_timing(*policy);
323 policy++;
324 }
325 }
326
327 if (do_rejection_test) {
328 const srtp_policy_t **policy = policy_array;
329
330 /* loop over policies, run rejection timing test for each */
331 while (*policy != NULL) {
332 srtp_print_policy(*policy);
333 srtp_do_rejection_timing(*policy);
334 policy++;
335 }
336 }
337
338 if (do_codec_timing) {
339 srtp_policy_t policy;
340 int ignore;
341 double mips = mips_estimate(1000000000, &ignore);
342
343 crypto_policy_set_rtp_default(&policy.rtp);
344 crypto_policy_set_rtcp_default(&policy.rtcp);
345 policy.ssrc.type = ssrc_specific;
346 policy.ssrc.value = 0xdecafbad;
347 policy.key = test_key;
348 policy.ekt = NULL;
349 policy.window_size = 128;
350 policy.allow_repeat_tx = 0;
351 policy.next = NULL;
352
353 printf("mips estimate: %e\n", mips);
354
355 printf("testing srtp processing time for voice codecs:\n");
356 printf("codec\t\tlength (octets)\t\tsrtp instructions/second\n");
357 printf("G.711\t\t%d\t\t\t%e\n", 80,
358 (double) mips * (80 * 8) /
359 srtp_bits_per_second(80, &policy) / .01 );
360 printf("G.711\t\t%d\t\t\t%e\n", 160,
361 (double) mips * (160 * 8) /
362 srtp_bits_per_second(160, &policy) / .02);
363 printf("G.726-32\t%d\t\t\t%e\n", 40,
364 (double) mips * (40 * 8) /
365 srtp_bits_per_second(40, &policy) / .01 );
366 printf("G.726-32\t%d\t\t\t%e\n", 80,
367 (double) mips * (80 * 8) /
368 srtp_bits_per_second(80, &policy) / .02);
369 printf("G.729\t\t%d\t\t\t%e\n", 10,
370 (double) mips * (10 * 8) /
371 srtp_bits_per_second(10, &policy) / .01 );
372 printf("G.729\t\t%d\t\t\t%e\n", 20,
373 (double) mips * (20 * 8) /
374 srtp_bits_per_second(20, &policy) / .02 );
375 printf("Wideband\t%d\t\t\t%e\n", 320,
376 (double) mips * (320 * 8) /
377 srtp_bits_per_second(320, &policy) / .01 );
378 printf("Wideband\t%d\t\t\t%e\n", 640,
379 (double) mips * (640 * 8) /
380 srtp_bits_per_second(640, &policy) / .02 );
381 }
382
383 status = srtp_shutdown();
384 if (status) {
385 printf("error: srtp shutdown failed with error code %d\n", status);
386 exit(1);
387 }
388
389 return 0;
390 }
391
392
393
394 /*
395 * srtp_create_test_packet(len, ssrc) returns a pointer to a
396 * (malloced) example RTP packet whose data field has the length given
397 * by pkt_octet_len and the SSRC value ssrc. The total length of the
398 * packet is twelve octets longer, since the header is at the
399 * beginning. There is room at the end of the packet for a trailer,
400 * and the four octets following the packet are filled with 0xff
401 * values to enable testing for overwrites.
402 *
403 * note that the location of the test packet can (and should) be
404 * deallocated with the free() call once it is no longer needed.
405 */
406
407 srtp_hdr_t *
408 srtp_create_test_packet(int pkt_octet_len, uint32_t ssrc) {
409 int i;
410 uint8_t *buffer;
411 srtp_hdr_t *hdr;
412 int bytes_in_hdr = 12;
413
414 /* allocate memory for test packet */
415 hdr = (srtp_hdr_t*) malloc(pkt_octet_len + bytes_in_hdr
416 + SRTP_MAX_TRAILER_LEN + 4);
417 if (!hdr)
418 return NULL;
419
420 hdr->version = 2; /* RTP version two */
421 hdr->p = 0; /* no padding needed */
422 hdr->x = 0; /* no header extension */
423 hdr->cc = 0; /* no CSRCs */
424 hdr->m = 0; /* marker bit */
425 hdr->pt = 0xf; /* payload type */
426 hdr->seq = htons(0x1234); /* sequence number */
427 hdr->ts = htonl(0xdecafbad); /* timestamp */
428 hdr->ssrc = htonl(ssrc); /* synch. source */
429
430 buffer = (uint8_t *)hdr;
431 buffer += bytes_in_hdr;
432
433 /* set RTP data to 0xab */
434 for (i=0; i < pkt_octet_len; i++)
435 *buffer++ = 0xab;
436
437 /* set post-data value to 0xffff to enable overrun checking */
438 for (i=0; i < SRTP_MAX_TRAILER_LEN+4; i++)
439 *buffer++ = 0xff;
440
441 return hdr;
442 }
443
444 void
445 srtp_do_timing(const srtp_policy_t *policy) {
446 int len;
447
448 /*
449 * note: the output of this function is formatted so that it
450 * can be used in gnuplot. '#' indicates a comment, and "\r\n"
451 * terminates a record
452 */
453
454 printf("# testing srtp throughput:\r\n");
455 printf("# mesg length (octets)\tthroughput (megabits per second)\r\n");
456
457 for (len=16; len <= 2048; len *= 2)
458 printf("%d\t\t\t%f\r\n", len,
459 srtp_bits_per_second(len, policy) / 1.0E6);
460
461 /* these extra linefeeds let gnuplot know that a dataset is done */
462 printf("\r\n\r\n");
463
464 }
465
466 void
467 srtp_do_rejection_timing(const srtp_policy_t *policy) {
468 int len;
469
470 /*
471 * note: the output of this function is formatted so that it
472 * can be used in gnuplot. '#' indicates a comment, and "\r\n"
473 * terminates a record
474 */
475
476 printf("# testing srtp rejection throughput:\r\n");
477 printf("# mesg length (octets)\trejections per second\r\n");
478
479 for (len=8; len <= 2048; len *= 2)
480 printf("%d\t\t\t%e\r\n", len, srtp_rejections_per_second(len, policy));
481
482 /* these extra linefeeds let gnuplot know that a dataset is done */
483 printf("\r\n\r\n");
484
485 }
486
487
488 #define MAX_MSG_LEN 1024
489
490 double
491 srtp_bits_per_second(int msg_len_octets, const srtp_policy_t *policy) {
492 srtp_t srtp;
493 srtp_hdr_t *mesg;
494 int i;
495 clock_t timer;
496 int num_trials = 100000;
497 int len;
498 uint32_t ssrc;
499 err_status_t status;
500
501 /*
502 * allocate and initialize an srtp session
503 */
504 status = srtp_create(&srtp, policy);
505 if (status) {
506 printf("error: srtp_create() failed with error code %d\n", status);
507 exit(1);
508 }
509
510 /*
511 * if the ssrc is unspecified, use a predetermined one
512 */
513 if (policy->ssrc.type != ssrc_specific) {
514 ssrc = 0xdeadbeef;
515 } else {
516 ssrc = policy->ssrc.value;
517 }
518
519 /*
520 * create a test packet
521 */
522 mesg = srtp_create_test_packet(msg_len_octets, ssrc);
523 if (mesg == NULL)
524 return 0.0; /* indicate failure by returning zero */
525
526 timer = clock();
527 for (i=0; i < num_trials; i++) {
528 len = msg_len_octets + 12; /* add in rtp header length */
529
530 /* srtp protect message */
531 status = srtp_protect(srtp, mesg, &len);
532 if (status) {
533 printf("error: srtp_protect() failed with error code %d\n", status);
534 exit(1);
535 }
536
537 /* increment message number */
538 {
539 /* hack sequence to avoid problems with macros for htons/ntohs on some sys tems */
540 short new_seq = ntohs(mesg->seq) + 1;
541 mesg->seq = htons(new_seq);
542 }
543 }
544 timer = clock() - timer;
545
546 free(mesg);
547
548 status = srtp_dealloc(srtp);
549 if (status) {
550 printf("error: srtp_dealloc() failed with error code %d\n", status);
551 exit(1);
552 }
553
554 return (double) (msg_len_octets) * 8 *
555 num_trials * CLOCKS_PER_SEC / timer;
556 }
557
558 double
559 srtp_rejections_per_second(int msg_len_octets, const srtp_policy_t *policy) {
560 srtp_ctx_t *srtp;
561 srtp_hdr_t *mesg;
562 int i;
563 int len;
564 clock_t timer;
565 int num_trials = 1000000;
566 uint32_t ssrc = policy->ssrc.value;
567 err_status_t status;
568
569 /*
570 * allocate and initialize an srtp session
571 */
572 status = srtp_create(&srtp, policy);
573 if (status) {
574 printf("error: srtp_create() failed with error code %d\n", status);
575 exit(1);
576 }
577
578 mesg = srtp_create_test_packet(msg_len_octets, ssrc);
579 if (mesg == NULL)
580 return 0.0; /* indicate failure by returning zero */
581
582 len = msg_len_octets;
583 srtp_protect(srtp, (srtp_hdr_t *)mesg, &len);
584
585 timer = clock();
586 for (i=0; i < num_trials; i++) {
587 len = msg_len_octets;
588 srtp_unprotect(srtp, (srtp_hdr_t *)mesg, &len);
589 }
590 timer = clock() - timer;
591
592 free(mesg);
593
594 status = srtp_dealloc(srtp);
595 if (status) {
596 printf("error: srtp_dealloc() failed with error code %d\n", status);
597 exit(1);
598 }
599
600 return (double) num_trials * CLOCKS_PER_SEC / timer;
601 }
602
603
604 void
605 err_check(err_status_t s) {
606 if (s == err_status_ok)
607 return;
608 else
609 fprintf(stderr, "error: unexpected srtp failure (code %d)\n", s);
610 exit (1);
611 }
612
613 err_status_t
614 srtp_test(const srtp_policy_t *policy) {
615 int i;
616 srtp_t srtp_sender;
617 srtp_t srtp_rcvr;
618 err_status_t status = err_status_ok;
619 srtp_hdr_t *hdr, *hdr2;
620 uint8_t hdr_enc[64];
621 uint8_t *pkt_end;
622 int msg_len_octets, msg_len_enc;
623 int len;
624 int tag_length = policy->rtp.auth_tag_len;
625 uint32_t ssrc;
626 srtp_policy_t *rcvr_policy;
627
628 err_check(srtp_create(&srtp_sender, policy));
629
630 /* print out policy */
631 err_check(srtp_session_print_policy(srtp_sender));
632
633 /*
634 * initialize data buffer, using the ssrc in the policy unless that
635 * value is a wildcard, in which case we'll just use an arbitrary
636 * one
637 */
638 if (policy->ssrc.type != ssrc_specific)
639 ssrc = 0xdecafbad;
640 else
641 ssrc = policy->ssrc.value;
642 msg_len_octets = 28;
643 hdr = srtp_create_test_packet(msg_len_octets, ssrc);
644
645 if (hdr == NULL)
646 return err_status_alloc_fail;
647 hdr2 = srtp_create_test_packet(msg_len_octets, ssrc);
648 if (hdr2 == NULL) {
649 free(hdr);
650 return err_status_alloc_fail;
651 }
652
653 /* set message length */
654 len = msg_len_octets;
655
656 debug_print(mod_driver, "before protection:\n%s",
657 srtp_packet_to_string(hdr, len));
658
659 #if PRINT_REFERENCE_PACKET
660 debug_print(mod_driver, "reference packet before protection:\n%s",
661 octet_string_hex_string((uint8_t *)hdr, len));
662 #endif
663 err_check(srtp_protect(srtp_sender, hdr, &len));
664
665 debug_print(mod_driver, "after protection:\n%s",
666 srtp_packet_to_string(hdr, len));
667 #if PRINT_REFERENCE_PACKET
668 debug_print(mod_driver, "after protection:\n%s",
669 octet_string_hex_string((uint8_t *)hdr, len));
670 #endif
671
672 /* save protected message and length */
673 memcpy(hdr_enc, hdr, len);
674 msg_len_enc = len;
675
676 /*
677 * check for overrun of the srtp_protect() function
678 *
679 * The packet is followed by a value of 0xfffff; if the value of the
680 * data following the packet is different, then we know that the
681 * protect function is overwriting the end of the packet.
682 */
683 pkt_end = (uint8_t *)hdr + sizeof(srtp_hdr_t)
684 + msg_len_octets + tag_length;
685 for (i = 0; i < 4; i++)
686 if (pkt_end[i] != 0xff) {
687 fprintf(stdout, "overwrite in srtp_protect() function "
688 "(expected %x, found %x in trailing octet %d)\n",
689 0xff, ((uint8_t *)hdr)[i], i);
690 free(hdr);
691 free(hdr2);
692 return err_status_algo_fail;
693 }
694
695 /*
696 * if the policy includes confidentiality, check that ciphertext is
697 * different than plaintext
698 *
699 * Note that this check will give false negatives, with some small
700 * probability, especially if the packets are short. For that
701 * reason, we skip this check if the plaintext is less than four
702 * octets long.
703 */
704 if ((policy->rtp.sec_serv & sec_serv_conf) && (msg_len_octets >= 4)) {
705 printf("testing that ciphertext is distinct from plaintext...");
706 status = err_status_algo_fail;
707 for (i=12; i < msg_len_octets+12; i++)
708 if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) {
709 status = err_status_ok;
710 }
711 if (status) {
712 printf("failed\n");
713 free(hdr);
714 free(hdr2);
715 return status;
716 }
717 printf("passed\n");
718 }
719
720 /*
721 * if the policy uses a 'wildcard' ssrc, then we need to make a copy
722 * of the policy that changes the direction to inbound
723 *
724 * we always copy the policy into the rcvr_policy, since otherwise
725 * the compiler would fret about the constness of the policy
726 */
727 rcvr_policy = (srtp_policy_t*) malloc(sizeof(srtp_policy_t));
728 if (rcvr_policy == NULL) {
729 free(hdr);
730 free(hdr2);
731 return err_status_alloc_fail;
732 }
733 memcpy(rcvr_policy, policy, sizeof(srtp_policy_t));
734 if (policy->ssrc.type == ssrc_any_outbound) {
735 rcvr_policy->ssrc.type = ssrc_any_inbound;
736 }
737
738 err_check(srtp_create(&srtp_rcvr, rcvr_policy));
739
740 err_check(srtp_unprotect(srtp_rcvr, hdr, &len));
741
742 debug_print(mod_driver, "after unprotection:\n%s",
743 srtp_packet_to_string(hdr, len));
744
745 /* verify that the unprotected packet matches the origial one */
746 for (i=0; i < msg_len_octets; i++)
747 if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) {
748 fprintf(stdout, "mismatch at octet %d\n", i);
749 status = err_status_algo_fail;
750 }
751 if (status) {
752 free(hdr);
753 free(hdr2);
754 free(rcvr_policy);
755 return status;
756 }
757
758 /*
759 * if the policy includes authentication, then test for false positives
760 */
761 if (policy->rtp.sec_serv & sec_serv_auth) {
762 char *data = ((char *)hdr) + 12;
763
764 printf("testing for false positives in replay check...");
765
766 /* set message length */
767 len = msg_len_enc;
768
769 /* unprotect a second time - should fail with a replay error */
770 status = srtp_unprotect(srtp_rcvr, hdr_enc, &len);
771 if (status != err_status_replay_fail) {
772 printf("failed with error code %d\n", status);
773 free(hdr);
774 free(hdr2);
775 free(rcvr_policy);
776 return status;
777 } else {
778 printf("passed\n");
779 }
780
781 printf("testing for false positives in auth check...");
782
783 /* increment sequence number in header */
784 hdr->seq++;
785
786 /* set message length */
787 len = msg_len_octets;
788
789 /* apply protection */
790 err_check(srtp_protect(srtp_sender, hdr, &len));
791
792 /* flip bits in packet */
793 data[0] ^= 0xff;
794
795 /* unprotect, and check for authentication failure */
796 status = srtp_unprotect(srtp_rcvr, hdr, &len);
797 if (status != err_status_auth_fail) {
798 printf("failed\n");
799 free(hdr);
800 free(hdr2);
801 free(rcvr_policy);
802 return status;
803 } else {
804 printf("passed\n");
805 }
806
807 }
808
809 err_check(srtp_dealloc(srtp_sender));
810 err_check(srtp_dealloc(srtp_rcvr));
811
812 free(hdr);
813 free(hdr2);
814 free(rcvr_policy);
815 return err_status_ok;
816 }
817
818
819 err_status_t
820 srtcp_test(const srtp_policy_t *policy) {
821 int i;
822 srtp_t srtcp_sender;
823 srtp_t srtcp_rcvr;
824 err_status_t status = err_status_ok;
825 srtp_hdr_t *hdr, *hdr2;
826 uint8_t hdr_enc[64];
827 uint8_t *pkt_end;
828 int msg_len_octets, msg_len_enc;
829 int len;
830 int tag_length = policy->rtp.auth_tag_len;
831 uint32_t ssrc;
832 srtp_policy_t *rcvr_policy;
833
834 err_check(srtp_create(&srtcp_sender, policy));
835
836 /* print out policy */
837 err_check(srtp_session_print_policy(srtcp_sender));
838
839 /*
840 * initialize data buffer, using the ssrc in the policy unless that
841 * value is a wildcard, in which case we'll just use an arbitrary
842 * one
843 */
844 if (policy->ssrc.type != ssrc_specific)
845 ssrc = 0xdecafbad;
846 else
847 ssrc = policy->ssrc.value;
848 msg_len_octets = 28;
849 hdr = srtp_create_test_packet(msg_len_octets, ssrc);
850
851 if (hdr == NULL)
852 return err_status_alloc_fail;
853 hdr2 = srtp_create_test_packet(msg_len_octets, ssrc);
854 if (hdr2 == NULL) {
855 free(hdr);
856 return err_status_alloc_fail;
857 }
858
859 /* set message length */
860 len = msg_len_octets;
861
862 debug_print(mod_driver, "before protection:\n%s",
863 srtp_packet_to_string(hdr, len));
864
865 #if PRINT_REFERENCE_PACKET
866 debug_print(mod_driver, "reference packet before protection:\n%s",
867 octet_string_hex_string((uint8_t *)hdr, len));
868 #endif
869 err_check(srtp_protect_rtcp(srtcp_sender, hdr, &len));
870
871 debug_print(mod_driver, "after protection:\n%s",
872 srtp_packet_to_string(hdr, len));
873 #if PRINT_REFERENCE_PACKET
874 debug_print(mod_driver, "after protection:\n%s",
875 octet_string_hex_string((uint8_t *)hdr, len));
876 #endif
877
878 /* save protected message and length */
879 memcpy(hdr_enc, hdr, len);
880 msg_len_enc = len;
881
882 /*
883 * check for overrun of the srtp_protect() function
884 *
885 * The packet is followed by a value of 0xfffff; if the value of the
886 * data following the packet is different, then we know that the
887 * protect function is overwriting the end of the packet.
888 */
889 pkt_end = (uint8_t *)hdr + sizeof(srtp_hdr_t)
890 + msg_len_octets + tag_length;
891 for (i = 0; i < 4; i++)
892 if (pkt_end[i] != 0xff) {
893 fprintf(stdout, "overwrite in srtp_protect_rtcp() function "
894 "(expected %x, found %x in trailing octet %d)\n",
895 0xff, ((uint8_t *)hdr)[i], i);
896 free(hdr);
897 free(hdr2);
898 return err_status_algo_fail;
899 }
900
901 /*
902 * if the policy includes confidentiality, check that ciphertext is
903 * different than plaintext
904 *
905 * Note that this check will give false negatives, with some small
906 * probability, especially if the packets are short. For that
907 * reason, we skip this check if the plaintext is less than four
908 * octets long.
909 */
910 if ((policy->rtp.sec_serv & sec_serv_conf) && (msg_len_octets >= 4)) {
911 printf("testing that ciphertext is distinct from plaintext...");
912 status = err_status_algo_fail;
913 for (i=12; i < msg_len_octets+12; i++)
914 if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) {
915 status = err_status_ok;
916 }
917 if (status) {
918 printf("failed\n");
919 free(hdr);
920 free(hdr2);
921 return status;
922 }
923 printf("passed\n");
924 }
925
926 /*
927 * if the policy uses a 'wildcard' ssrc, then we need to make a copy
928 * of the policy that changes the direction to inbound
929 *
930 * we always copy the policy into the rcvr_policy, since otherwise
931 * the compiler would fret about the constness of the policy
932 */
933 rcvr_policy = (srtp_policy_t*) malloc(sizeof(srtp_policy_t));
934 if (rcvr_policy == NULL)
935 return err_status_alloc_fail;
936 memcpy(rcvr_policy, policy, sizeof(srtp_policy_t));
937 if (policy->ssrc.type == ssrc_any_outbound) {
938 rcvr_policy->ssrc.type = ssrc_any_inbound;
939 }
940
941 err_check(srtp_create(&srtcp_rcvr, rcvr_policy));
942
943 err_check(srtp_unprotect_rtcp(srtcp_rcvr, hdr, &len));
944
945 debug_print(mod_driver, "after unprotection:\n%s",
946 srtp_packet_to_string(hdr, len));
947
948 /* verify that the unprotected packet matches the origial one */
949 for (i=0; i < msg_len_octets; i++)
950 if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) {
951 fprintf(stdout, "mismatch at octet %d\n", i);
952 status = err_status_algo_fail;
953 }
954 if (status) {
955 free(hdr);
956 free(hdr2);
957 free(rcvr_policy);
958 return status;
959 }
960
961 /*
962 * if the policy includes authentication, then test for false positives
963 */
964 if (policy->rtp.sec_serv & sec_serv_auth) {
965 char *data = ((char *)hdr) + 12;
966
967 printf("testing for false positives in replay check...");
968
969 /* set message length */
970 len = msg_len_enc;
971
972 /* unprotect a second time - should fail with a replay error */
973 status = srtp_unprotect_rtcp(srtcp_rcvr, hdr_enc, &len);
974 if (status != err_status_replay_fail) {
975 printf("failed with error code %d\n", status);
976 free(hdr);
977 free(hdr2);
978 free(rcvr_policy);
979 return status;
980 } else {
981 printf("passed\n");
982 }
983
984 printf("testing for false positives in auth check...");
985
986 /* increment sequence number in header */
987 hdr->seq++;
988
989 /* set message length */
990 len = msg_len_octets;
991
992 /* apply protection */
993 err_check(srtp_protect_rtcp(srtcp_sender, hdr, &len));
994
995 /* flip bits in packet */
996 data[0] ^= 0xff;
997
998 /* unprotect, and check for authentication failure */
999 status = srtp_unprotect_rtcp(srtcp_rcvr, hdr, &len);
1000 if (status != err_status_auth_fail) {
1001 printf("failed\n");
1002 free(hdr);
1003 free(hdr2);
1004 free(rcvr_policy);
1005 return status;
1006 } else {
1007 printf("passed\n");
1008 }
1009
1010 }
1011
1012 err_check(srtp_dealloc(srtcp_sender));
1013 err_check(srtp_dealloc(srtcp_rcvr));
1014
1015 free(hdr);
1016 free(hdr2);
1017 free(rcvr_policy);
1018 return err_status_ok;
1019 }
1020
1021
1022 err_status_t
1023 srtp_session_print_policy(srtp_t srtp) {
1024 char *serv_descr[4] = {
1025 "none",
1026 "confidentiality",
1027 "authentication",
1028 "confidentiality and authentication"
1029 };
1030 char *direction[3] = {
1031 "unknown",
1032 "outbound",
1033 "inbound"
1034 };
1035 srtp_stream_t stream;
1036
1037 /* sanity checking */
1038 if (srtp == NULL)
1039 return err_status_fail;
1040
1041 /* if there's a template stream, print it out */
1042 if (srtp->stream_template != NULL) {
1043 stream = srtp->stream_template;
1044 printf("# SSRC: any %s\r\n"
1045 "# rtp cipher: %s\r\n"
1046 "# rtp auth: %s\r\n"
1047 "# rtp services: %s\r\n"
1048 "# rtcp cipher: %s\r\n"
1049 "# rtcp auth: %s\r\n"
1050 "# rtcp services: %s\r\n"
1051 "# window size: %lu\r\n"
1052 "# tx rtx allowed:%s\r\n",
1053 direction[stream->direction],
1054 stream->rtp_cipher->type->description,
1055 stream->rtp_auth->type->description,
1056 serv_descr[stream->rtp_services],
1057 stream->rtcp_cipher->type->description,
1058 stream->rtcp_auth->type->description,
1059 serv_descr[stream->rtcp_services],
1060 rdbx_get_window_size(&stream->rtp_rdbx),
1061 stream->allow_repeat_tx ? "true" : "false");
1062 }
1063
1064 /* loop over streams in session, printing the policy of each */
1065 stream = srtp->stream_list;
1066 while (stream != NULL) {
1067 if (stream->rtp_services > sec_serv_conf_and_auth)
1068 return err_status_bad_param;
1069
1070 printf("# SSRC: 0x%08x\r\n"
1071 "# rtp cipher: %s\r\n"
1072 "# rtp auth: %s\r\n"
1073 "# rtp services: %s\r\n"
1074 "# rtcp cipher: %s\r\n"
1075 "# rtcp auth: %s\r\n"
1076 "# rtcp services: %s\r\n"
1077 "# window size: %lu\r\n"
1078 "# tx rtx allowed:%s\r\n",
1079 stream->ssrc,
1080 stream->rtp_cipher->type->description,
1081 stream->rtp_auth->type->description,
1082 serv_descr[stream->rtp_services],
1083 stream->rtcp_cipher->type->description,
1084 stream->rtcp_auth->type->description,
1085 serv_descr[stream->rtcp_services],
1086 rdbx_get_window_size(&stream->rtp_rdbx),
1087 stream->allow_repeat_tx ? "true" : "false");
1088
1089 /* advance to next stream in the list */
1090 stream = stream->next;
1091 }
1092 return err_status_ok;
1093 }
1094
1095 err_status_t
1096 srtp_print_policy(const srtp_policy_t *policy) {
1097 err_status_t status;
1098 srtp_t session;
1099
1100 status = srtp_create(&session, policy);
1101 if (status)
1102 return status;
1103 status = srtp_session_print_policy(session);
1104 if (status)
1105 return status;
1106 status = srtp_dealloc(session);
1107 if (status)
1108 return status;
1109 return err_status_ok;
1110 }
1111
1112 /*
1113 * srtp_print_packet(...) is for debugging only
1114 * it prints an RTP packet to the stdout
1115 *
1116 * note that this function is *not* threadsafe
1117 */
1118
1119 #include <stdio.h>
1120
1121 #define MTU 2048
1122
1123 char packet_string[MTU];
1124
1125 char *
1126 srtp_packet_to_string(srtp_hdr_t *hdr, int pkt_octet_len) {
1127 int octets_in_rtp_header = 12;
1128 uint8_t *data = ((uint8_t *)hdr)+octets_in_rtp_header;
1129 int hex_len = pkt_octet_len-octets_in_rtp_header;
1130
1131 /* sanity checking */
1132 if ((hdr == NULL) || (pkt_octet_len > MTU))
1133 return NULL;
1134
1135 /* write packet into string */
1136 sprintf(packet_string,
1137 "(s)rtp packet: {\n"
1138 " version:\t%d\n"
1139 " p:\t\t%d\n"
1140 " x:\t\t%d\n"
1141 " cc:\t\t%d\n"
1142 " m:\t\t%d\n"
1143 " pt:\t\t%x\n"
1144 " seq:\t\t%x\n"
1145 " ts:\t\t%x\n"
1146 " ssrc:\t%x\n"
1147 " data:\t%s\n"
1148 "} (%d octets in total)\n",
1149 hdr->version,
1150 hdr->p,
1151 hdr->x,
1152 hdr->cc,
1153 hdr->m,
1154 hdr->pt,
1155 hdr->seq,
1156 hdr->ts,
1157 hdr->ssrc,
1158 octet_string_hex_string(data, hex_len),
1159 pkt_octet_len);
1160
1161 return packet_string;
1162 }
1163
1164 /*
1165 * mips_estimate() is a simple function to estimate the number of
1166 * instructions per second that the host can perform. note that this
1167 * function can be grossly wrong; you may want to have a manual sanity
1168 * check of its output!
1169 *
1170 * the 'ignore' pointer is there to convince the compiler to not just
1171 * optimize away the function
1172 */
1173
1174 double
1175 mips_estimate(int num_trials, int *ignore) {
1176 clock_t t;
1177 volatile int i, sum;
1178
1179 sum = 0;
1180 t = clock();
1181 for (i=0; i<num_trials; i++)
1182 sum += i;
1183 t = clock() - t;
1184
1185 /* printf("%d\n", sum); */
1186 *ignore = sum;
1187
1188 return (double) num_trials * CLOCKS_PER_SEC / t;
1189 }
1190
1191
1192 /*
1193 * srtp_validate() verifies the correctness of libsrtp by comparing
1194 * some computed packets against some pre-computed reference values.
1195 * These packets were made with the default SRTP policy.
1196 */
1197
1198
1199 err_status_t
1200 srtp_validate() {
1201 uint8_t srtp_plaintext_ref[28] = {
1202 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1203 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
1204 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1205 0xab, 0xab, 0xab, 0xab
1206 };
1207 uint8_t srtp_plaintext[38] = {
1208 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1209 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
1210 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1211 0xab, 0xab, 0xab, 0xab, 0x00, 0x00, 0x00, 0x00,
1212 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1213 };
1214 uint8_t srtp_ciphertext[38] = {
1215 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1216 0xca, 0xfe, 0xba, 0xbe, 0x4e, 0x55, 0xdc, 0x4c,
1217 0xe7, 0x99, 0x78, 0xd8, 0x8c, 0xa4, 0xd2, 0x15,
1218 0x94, 0x9d, 0x24, 0x02, 0xb7, 0x8d, 0x6a, 0xcc,
1219 0x99, 0xea, 0x17, 0x9b, 0x8d, 0xbb
1220 };
1221 srtp_t srtp_snd, srtp_recv;
1222 err_status_t status;
1223 int len;
1224 srtp_policy_t policy;
1225
1226 /*
1227 * create a session with a single stream using the default srtp
1228 * policy and with the SSRC value 0xcafebabe
1229 */
1230 crypto_policy_set_rtp_default(&policy.rtp);
1231 crypto_policy_set_rtcp_default(&policy.rtcp);
1232 policy.ssrc.type = ssrc_specific;
1233 policy.ssrc.value = 0xcafebabe;
1234 policy.key = test_key;
1235 policy.ekt = NULL;
1236 policy.window_size = 128;
1237 policy.allow_repeat_tx = 0;
1238 policy.next = NULL;
1239
1240 status = srtp_create(&srtp_snd, &policy);
1241 if (status)
1242 return status;
1243
1244 /*
1245 * protect plaintext, then compare with ciphertext
1246 */
1247 len = 28;
1248 status = srtp_protect(srtp_snd, srtp_plaintext, &len);
1249 if (status || (len != 38))
1250 return err_status_fail;
1251
1252 debug_print(mod_driver, "ciphertext:\n %s",
1253 octet_string_hex_string(srtp_plaintext, len));
1254 debug_print(mod_driver, "ciphertext reference:\n %s",
1255 octet_string_hex_string(srtp_ciphertext, len));
1256
1257 if (octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len))
1258 return err_status_fail;
1259
1260 /*
1261 * create a receiver session context comparable to the one created
1262 * above - we need to do this so that the replay checking doesn't
1263 * complain
1264 */
1265 status = srtp_create(&srtp_recv, &policy);
1266 if (status)
1267 return status;
1268
1269 /*
1270 * unprotect ciphertext, then compare with plaintext
1271 */
1272 status = srtp_unprotect(srtp_recv, srtp_ciphertext, &len);
1273 if (status || (len != 28))
1274 return status;
1275
1276 if (octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len))
1277 return err_status_fail;
1278
1279 status = srtp_dealloc(srtp_snd);
1280 if (status)
1281 return status;
1282
1283 status = srtp_dealloc(srtp_recv);
1284 if (status)
1285 return status;
1286
1287 return err_status_ok;
1288 }
1289
1290
1291 /*
1292 * srtp_validate_aes_256() verifies the correctness of libsrtp by comparing
1293 * some computed packets against some pre-computed reference values.
1294 * These packets were made with the AES-CM-256/HMAC-SHA-1-80 policy.
1295 */
1296
1297
1298 err_status_t
1299 srtp_validate_aes_256() {
1300 unsigned char aes_256_test_key[46] = {
1301 0xf0, 0xf0, 0x49, 0x14, 0xb5, 0x13, 0xf2, 0x76,
1302 0x3a, 0x1b, 0x1f, 0xa1, 0x30, 0xf1, 0x0e, 0x29,
1303 0x98, 0xf6, 0xf6, 0xe4, 0x3e, 0x43, 0x09, 0xd1,
1304 0xe6, 0x22, 0xa0, 0xe3, 0x32, 0xb9, 0xf1, 0xb6,
1305
1306 0x3b, 0x04, 0x80, 0x3d, 0xe5, 0x1e, 0xe7, 0xc9,
1307 0x64, 0x23, 0xab, 0x5b, 0x78, 0xd2
1308 };
1309 uint8_t srtp_plaintext_ref[28] = {
1310 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1311 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
1312 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1313 0xab, 0xab, 0xab, 0xab
1314 };
1315 uint8_t srtp_plaintext[38] = {
1316 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1317 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
1318 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
1319 0xab, 0xab, 0xab, 0xab, 0x00, 0x00, 0x00, 0x00,
1320 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1321 };
1322 uint8_t srtp_ciphertext[38] = {
1323 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
1324 0xca, 0xfe, 0xba, 0xbe, 0xf1, 0xd9, 0xde, 0x17,
1325 0xff, 0x25, 0x1f, 0xf1, 0xaa, 0x00, 0x77, 0x74,
1326 0xb0, 0xb4, 0xb4, 0x0d, 0xa0, 0x8d, 0x9d, 0x9a,
1327 0x5b, 0x3a, 0x55, 0xd8, 0x87, 0x3b
1328 };
1329 srtp_t srtp_snd, srtp_recv;
1330 err_status_t status;
1331 int len;
1332 srtp_policy_t policy;
1333
1334 /*
1335 * create a session with a single stream using the default srtp
1336 * policy and with the SSRC value 0xcafebabe
1337 */
1338 crypto_policy_set_aes_cm_256_hmac_sha1_80(&policy.rtp);
1339 crypto_policy_set_aes_cm_256_hmac_sha1_80(&policy.rtcp);
1340 policy.ssrc.type = ssrc_specific;
1341 policy.ssrc.value = 0xcafebabe;
1342 policy.key = aes_256_test_key;
1343 policy.ekt = NULL;
1344 policy.window_size = 128;
1345 policy.allow_repeat_tx = 0;
1346 policy.next = NULL;
1347
1348 status = srtp_create(&srtp_snd, &policy);
1349 if (status)
1350 return status;
1351
1352 /*
1353 * protect plaintext, then compare with ciphertext
1354 */
1355 len = 28;
1356 status = srtp_protect(srtp_snd, srtp_plaintext, &len);
1357 if (status || (len != 38))
1358 return err_status_fail;
1359
1360 debug_print(mod_driver, "ciphertext:\n %s",
1361 octet_string_hex_string(srtp_plaintext, len));
1362 debug_print(mod_driver, "ciphertext reference:\n %s",
1363 octet_string_hex_string(srtp_ciphertext, len));
1364
1365 if (octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len))
1366 return err_status_fail;
1367
1368 /*
1369 * create a receiver session context comparable to the one created
1370 * above - we need to do this so that the replay checking doesn't
1371 * complain
1372 */
1373 status = srtp_create(&srtp_recv, &policy);
1374 if (status)
1375 return status;
1376
1377 /*
1378 * unprotect ciphertext, then compare with plaintext
1379 */
1380 status = srtp_unprotect(srtp_recv, srtp_ciphertext, &len);
1381 if (status || (len != 28))
1382 return status;
1383
1384 if (octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len))
1385 return err_status_fail;
1386
1387 status = srtp_dealloc(srtp_snd);
1388 if (status)
1389 return status;
1390
1391 status = srtp_dealloc(srtp_recv);
1392 if (status)
1393 return status;
1394
1395 return err_status_ok;
1396 }
1397
1398
1399 err_status_t
1400 srtp_create_big_policy(srtp_policy_t **list) {
1401 extern const srtp_policy_t *policy_array[];
1402 srtp_policy_t *p, *tmp;
1403 int i = 0;
1404 uint32_t ssrc = 0;
1405
1406 /* sanity checking */
1407 if ((list == NULL) || (policy_array[0] == NULL))
1408 return err_status_bad_param;
1409
1410 /*
1411 * loop over policy list, mallocing a new list and copying values
1412 * into it (and incrementing the SSRC value as we go along)
1413 */
1414 tmp = NULL;
1415 while (policy_array[i] != NULL) {
1416 p = (srtp_policy_t*) malloc(sizeof(srtp_policy_t));
1417 if (p == NULL)
1418 return err_status_bad_param;
1419 memcpy(p, policy_array[i], sizeof(srtp_policy_t));
1420 p->ssrc.type = ssrc_specific;
1421 p->ssrc.value = ssrc++;
1422 p->next = tmp;
1423 tmp = p;
1424 i++;
1425 }
1426 *list = p;
1427
1428 return err_status_ok;
1429 }
1430
1431 err_status_t
1432 srtp_dealloc_big_policy(srtp_policy_t *list) {
1433 srtp_policy_t *p, *next;
1434
1435 for (p = list; p != NULL; p = next) {
1436 next = p->next;
1437 free(p);
1438 }
1439
1440 return err_status_ok;
1441 }
1442
1443
1444 err_status_t
1445 srtp_test_remove_stream() {
1446 err_status_t status;
1447 srtp_policy_t *policy_list, policy;
1448 srtp_t session;
1449 srtp_stream_t stream;
1450 /*
1451 * srtp_get_stream() is a libSRTP internal function that we declare
1452 * here so that we can use it to verify the correct operation of the
1453 * library
1454 */
1455 extern srtp_stream_t srtp_get_stream(srtp_t srtp, uint32_t ssrc);
1456
1457
1458 status = srtp_create_big_policy(&policy_list);
1459 if (status)
1460 return status;
1461
1462 status = srtp_create(&session, policy_list);
1463 if (status)
1464 return status;
1465
1466 /*
1467 * check for false positives by trying to remove a stream that's not
1468 * in the session
1469 */
1470 status = srtp_remove_stream(session, htonl(0xaaaaaaaa));
1471 if (status != err_status_no_ctx)
1472 return err_status_fail;
1473
1474 /*
1475 * check for false negatives by removing stream 0x1, then
1476 * searching for streams 0x0 and 0x2
1477 */
1478 status = srtp_remove_stream(session, htonl(0x1));
1479 if (status != err_status_ok)
1480 return err_status_fail;
1481 stream = srtp_get_stream(session, htonl(0x0));
1482 if (stream == NULL)
1483 return err_status_fail;
1484 stream = srtp_get_stream(session, htonl(0x2));
1485 if (stream == NULL)
1486 return err_status_fail;
1487
1488 status = srtp_dealloc(session);
1489 if (status != err_status_ok)
1490 return status;
1491
1492 status = srtp_dealloc_big_policy(policy_list);
1493 if (status != err_status_ok)
1494 return status;
1495
1496 /* Now test adding and removing a single stream */
1497 crypto_policy_set_rtp_default(&policy.rtp);
1498 crypto_policy_set_rtcp_default(&policy.rtcp);
1499 policy.ssrc.type = ssrc_specific;
1500 policy.ssrc.value = 0xcafebabe;
1501 policy.key = test_key;
1502 policy.ekt = NULL;
1503 policy.window_size = 128;
1504 policy.allow_repeat_tx = 0;
1505 policy.next = NULL;
1506
1507 status = srtp_create(&session, NULL);
1508 if (status != err_status_ok)
1509 return status;
1510
1511 status = srtp_add_stream(session, &policy);
1512 if (status != err_status_ok)
1513 return status;
1514
1515 status = srtp_remove_stream(session, htonl(0xcafebabe));
1516 if (status != err_status_ok)
1517 return status;
1518
1519 status = srtp_dealloc(session);
1520 if (status != err_status_ok)
1521 return status;
1522
1523 return err_status_ok;
1524 }
1525
1526 /*
1527 * srtp policy definitions - these definitions are used above
1528 */
1529
1530 unsigned char test_key[30] = {
1531 0xe1, 0xf9, 0x7a, 0x0d, 0x3e, 0x01, 0x8b, 0xe0,
1532 0xd6, 0x4f, 0xa3, 0x2c, 0x06, 0xde, 0x41, 0x39,
1533 0x0e, 0xc6, 0x75, 0xad, 0x49, 0x8a, 0xfe, 0xeb,
1534 0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6
1535 };
1536
1537
1538 const srtp_policy_t default_policy = {
1539 { ssrc_any_outbound, 0 }, /* SSRC */
1540 { /* SRTP policy */
1541 AES_128_ICM, /* cipher type */
1542 30, /* cipher key length in octets */
1543 HMAC_SHA1, /* authentication func type */
1544 16, /* auth key length in octets */
1545 10, /* auth tag length in octets */
1546 sec_serv_conf_and_auth /* security services flag */
1547 },
1548 { /* SRTCP policy */
1549 AES_128_ICM, /* cipher type */
1550 30, /* cipher key length in octets */
1551 HMAC_SHA1, /* authentication func type */
1552 16, /* auth key length in octets */
1553 10, /* auth tag length in octets */
1554 sec_serv_conf_and_auth /* security services flag */
1555 },
1556 test_key,
1557 NULL, /* indicates that EKT is not in use */
1558 128, /* replay window size */
1559 0, /* retransmission not allowed */
1560 NULL
1561 };
1562
1563 const srtp_policy_t aes_tmmh_policy = {
1564 { ssrc_any_outbound, 0 }, /* SSRC */
1565 {
1566 AES_128_ICM, /* cipher type */
1567 30, /* cipher key length in octets */
1568 UST_TMMHv2, /* authentication func type */
1569 94, /* auth key length in octets */
1570 4, /* auth tag length in octets */
1571 sec_serv_conf_and_auth /* security services flag */
1572 },
1573 {
1574 AES_128_ICM, /* cipher type */
1575 30, /* cipher key length in octets */
1576 UST_TMMHv2, /* authentication func type */
1577 94, /* auth key length in octets */
1578 4, /* auth tag length in octets */
1579 sec_serv_conf_and_auth /* security services flag */
1580 },
1581 test_key,
1582 NULL, /* indicates that EKT is not in use */
1583 128, /* replay window size */
1584 0, /* retransmission not allowed */
1585 NULL
1586 };
1587
1588 const srtp_policy_t tmmh_only_policy = {
1589 { ssrc_any_outbound, 0 }, /* SSRC */
1590 {
1591 AES_128_ICM, /* cipher type */
1592 30, /* cipher key length in octets */
1593 UST_TMMHv2, /* authentication func type */
1594 94, /* auth key length in octets */
1595 4, /* auth tag length in octets */
1596 sec_serv_auth /* security services flag */
1597 },
1598 {
1599 AES_128_ICM, /* cipher type */
1600 30, /* cipher key length in octets */
1601 UST_TMMHv2, /* authentication func type */
1602 94, /* auth key length in octets */
1603 4, /* auth tag length in octets */
1604 sec_serv_auth /* security services flag */
1605 },
1606 test_key,
1607 NULL, /* indicates that EKT is not in use */
1608 128, /* replay window size */
1609 0, /* retransmission not allowed */
1610 NULL
1611 };
1612
1613 const srtp_policy_t aes_only_policy = {
1614 { ssrc_any_outbound, 0 }, /* SSRC */
1615 {
1616 AES_128_ICM, /* cipher type */
1617 30, /* cipher key length in octets */
1618 NULL_AUTH, /* authentication func type */
1619 0, /* auth key length in octets */
1620 0, /* auth tag length in octets */
1621 sec_serv_conf /* security services flag */
1622 },
1623 {
1624 AES_128_ICM, /* cipher type */
1625 30, /* cipher key length in octets */
1626 NULL_AUTH, /* authentication func type */
1627 0, /* auth key length in octets */
1628 0, /* auth tag length in octets */
1629 sec_serv_conf /* security services flag */
1630 },
1631 test_key,
1632 NULL, /* indicates that EKT is not in use */
1633 128, /* replay window size */
1634 0, /* retransmission not allowed */
1635 NULL
1636 };
1637
1638 const srtp_policy_t hmac_only_policy = {
1639 { ssrc_any_outbound, 0 }, /* SSRC */
1640 {
1641 NULL_CIPHER, /* cipher type */
1642 0, /* cipher key length in octets */
1643 HMAC_SHA1, /* authentication func type */
1644 20, /* auth key length in octets */
1645 4, /* auth tag length in octets */
1646 sec_serv_auth /* security services flag */
1647 },
1648 {
1649 NULL_CIPHER, /* cipher type */
1650 0, /* cipher key length in octets */
1651 HMAC_SHA1, /* authentication func type */
1652 20, /* auth key length in octets */
1653 4, /* auth tag length in octets */
1654 sec_serv_auth /* security services flag */
1655 },
1656 test_key,
1657 NULL, /* indicates that EKT is not in use */
1658 128, /* replay window size */
1659 0, /* retransmission not allowed */
1660 NULL
1661 };
1662
1663 const srtp_policy_t null_policy = {
1664 { ssrc_any_outbound, 0 }, /* SSRC */
1665 {
1666 NULL_CIPHER, /* cipher type */
1667 0, /* cipher key length in octets */
1668 NULL_AUTH, /* authentication func type */
1669 0, /* auth key length in octets */
1670 0, /* auth tag length in octets */
1671 sec_serv_none /* security services flag */
1672 },
1673 {
1674 NULL_CIPHER, /* cipher type */
1675 0, /* cipher key length in octets */
1676 NULL_AUTH, /* authentication func type */
1677 0, /* auth key length in octets */
1678 0, /* auth tag length in octets */
1679 sec_serv_none /* security services flag */
1680 },
1681 test_key,
1682 NULL, /* indicates that EKT is not in use */
1683 128, /* replay window size */
1684 0, /* retransmission not allowed */
1685 NULL
1686 };
1687
1688 unsigned char test_256_key[46] = {
1689 0xf0, 0xf0, 0x49, 0x14, 0xb5, 0x13, 0xf2, 0x76,
1690 0x3a, 0x1b, 0x1f, 0xa1, 0x30, 0xf1, 0x0e, 0x29,
1691 0x98, 0xf6, 0xf6, 0xe4, 0x3e, 0x43, 0x09, 0xd1,
1692 0xe6, 0x22, 0xa0, 0xe3, 0x32, 0xb9, 0xf1, 0xb6,
1693
1694 0x3b, 0x04, 0x80, 0x3d, 0xe5, 0x1e, 0xe7, 0xc9,
1695 0x64, 0x23, 0xab, 0x5b, 0x78, 0xd2
1696 };
1697
1698 const srtp_policy_t aes_256_hmac_policy = {
1699 { ssrc_any_outbound, 0 }, /* SSRC */
1700 { /* SRTP policy */
1701 AES_ICM, /* cipher type */
1702 46, /* cipher key length in octets */
1703 HMAC_SHA1, /* authentication func type */
1704 20, /* auth key length in octets */
1705 10, /* auth tag length in octets */
1706 sec_serv_conf_and_auth /* security services flag */
1707 },
1708 { /* SRTCP policy */
1709 AES_ICM, /* cipher type */
1710 46, /* cipher key length in octets */
1711 HMAC_SHA1, /* authentication func type */
1712 20, /* auth key length in octets */
1713 10, /* auth tag length in octets */
1714 sec_serv_conf_and_auth /* security services flag */
1715 },
1716 test_256_key,
1717 NULL, /* indicates that EKT is not in use */
1718 128, /* replay window size */
1719 0, /* retransmission not allowed */
1720 NULL
1721 };
1722
1723 uint8_t ekt_test_key[16] = {
1724 0x77, 0x26, 0x9d, 0xac, 0x16, 0xa3, 0x28, 0xca,
1725 0x8e, 0xc9, 0x68, 0x4b, 0xcc, 0xc4, 0xd2, 0x1b
1726 };
1727
1728 #include "ekt.h"
1729
1730 ekt_policy_ctx_t ekt_test_policy = {
1731 0xa5a5, /* SPI */
1732 EKT_CIPHER_AES_128_ECB,
1733 ekt_test_key,
1734 NULL
1735 };
1736
1737 const srtp_policy_t hmac_only_with_ekt_policy = {
1738 { ssrc_any_outbound, 0 }, /* SSRC */
1739 {
1740 NULL_CIPHER, /* cipher type */
1741 0, /* cipher key length in octets */
1742 HMAC_SHA1, /* authentication func type */
1743 20, /* auth key length in octets */
1744 4, /* auth tag length in octets */
1745 sec_serv_auth /* security services flag */
1746 },
1747 {
1748 NULL_CIPHER, /* cipher type */
1749 0, /* cipher key length in octets */
1750 HMAC_SHA1, /* authentication func type */
1751 20, /* auth key length in octets */
1752 4, /* auth tag length in octets */
1753 sec_serv_auth /* security services flag */
1754 },
1755 test_key,
1756 &ekt_test_policy, /* indicates that EKT is not in use */
1757 128, /* replay window size */
1758 0, /* retransmission not allowed */
1759 NULL
1760 };
1761
1762
1763 /*
1764 * an array of pointers to the policies listed above
1765 *
1766 * This array is used to test various aspects of libSRTP for
1767 * different cryptographic policies. The order of the elements
1768 * matters - the timing test generates output that can be used
1769 * in a plot (see the gnuplot script file 'timing'). If you
1770 * add to this list, you should do it at the end.
1771 */
1772
1773 #define USE_TMMH 0
1774
1775 const srtp_policy_t *
1776 policy_array[] = {
1777 &hmac_only_policy,
1778 #if USE_TMMH
1779 &tmmh_only_policy,
1780 #endif
1781 &aes_only_policy,
1782 #if USE_TMMH
1783 &aes_tmmh_policy,
1784 #endif
1785 &default_policy,
1786 &null_policy,
1787 &aes_256_hmac_policy,
1788 &hmac_only_with_ekt_policy,
1789 NULL
1790 };
1791
1792 const srtp_policy_t wildcard_policy = {
1793 { ssrc_any_outbound, 0 }, /* SSRC */
1794 { /* SRTP policy */
1795 AES_128_ICM, /* cipher type */
1796 30, /* cipher key length in octets */
1797 HMAC_SHA1, /* authentication func type */
1798 16, /* auth key length in octets */
1799 10, /* auth tag length in octets */
1800 sec_serv_conf_and_auth /* security services flag */
1801 },
1802 { /* SRTCP policy */
1803 AES_128_ICM, /* cipher type */
1804 30, /* cipher key length in octets */
1805 HMAC_SHA1, /* authentication func type */
1806 16, /* auth key length in octets */
1807 10, /* auth tag length in octets */
1808 sec_serv_conf_and_auth /* security services flag */
1809 },
1810 test_key,
1811 NULL,
1812 128, /* replay window size */
1813 0, /* retransmission not allowed */
1814 NULL
1815 };
OLDNEW
« no previous file with comments | « libsrtp/test/rtpw_test.sh ('k') | libsrtp/timing » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698