OLD | NEW |
| (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_encrypted_extensions_headers(void); | |
67 | |
68 #ifdef OPENSSL | |
69 err_status_t | |
70 srtp_validate_encrypted_extensions_headers_gcm(void); | |
71 #endif | |
72 | |
73 err_status_t | |
74 srtp_validate_aes_256(void); | |
75 | |
76 err_status_t | |
77 srtp_create_big_policy(srtp_policy_t **list); | |
78 | |
79 err_status_t | |
80 srtp_dealloc_big_policy(srtp_policy_t *list); | |
81 | |
82 err_status_t | |
83 srtp_test_remove_stream(void); | |
84 | |
85 double | |
86 srtp_bits_per_second(int msg_len_octets, const srtp_policy_t *policy); | |
87 | |
88 double | |
89 srtp_rejections_per_second(int msg_len_octets, const srtp_policy_t *policy); | |
90 | |
91 void | |
92 srtp_do_timing(const srtp_policy_t *policy); | |
93 | |
94 void | |
95 srtp_do_rejection_timing(const srtp_policy_t *policy); | |
96 | |
97 err_status_t | |
98 srtp_test(const srtp_policy_t *policy, int extension_header); | |
99 | |
100 err_status_t | |
101 srtcp_test(const srtp_policy_t *policy); | |
102 | |
103 err_status_t | |
104 srtp_session_print_policy(srtp_t srtp); | |
105 | |
106 err_status_t | |
107 srtp_print_policy(const srtp_policy_t *policy); | |
108 | |
109 char * | |
110 srtp_packet_to_string(srtp_hdr_t *hdr, int packet_len); | |
111 | |
112 double | |
113 mips_estimate(int num_trials, int *ignore); | |
114 | |
115 extern uint8_t test_key[46]; | |
116 | |
117 void | |
118 usage(char *prog_name) { | |
119 printf("usage: %s [ -t ][ -c ][ -v ][-d <debug_module> ]* [ -l ]\n" | |
120 " -t run timing test\n" | |
121 " -r run rejection timing test\n" | |
122 " -c run codec timing test\n" | |
123 " -v run validation tests\n" | |
124 " -d <mod> turn on debugging module <mod>\n" | |
125 " -l list debugging modules\n", prog_name); | |
126 exit(1); | |
127 } | |
128 | |
129 /* | |
130 * The policy_array is a null-terminated array of policy structs. it | |
131 * is declared at the end of this file | |
132 */ | |
133 | |
134 extern const srtp_policy_t *policy_array[]; | |
135 | |
136 | |
137 /* the wildcard_policy is declared below; it has a wildcard ssrc */ | |
138 | |
139 extern const srtp_policy_t wildcard_policy; | |
140 | |
141 /* | |
142 * mod_driver debug module - debugging module for this test driver | |
143 * | |
144 * we use the crypto_kernel debugging system in this driver, which | |
145 * makes the interface uniform and increases portability | |
146 */ | |
147 | |
148 debug_module_t mod_driver = { | |
149 0, /* debugging is off by default */ | |
150 "driver" /* printable name for module */ | |
151 }; | |
152 | |
153 int | |
154 main (int argc, char *argv[]) { | |
155 int q; | |
156 unsigned do_timing_test = 0; | |
157 unsigned do_rejection_test = 0; | |
158 unsigned do_codec_timing = 0; | |
159 unsigned do_validation = 0; | |
160 unsigned do_list_mods = 0; | |
161 err_status_t status; | |
162 | |
163 /* | |
164 * verify that the compiler has interpreted the header data | |
165 * structure srtp_hdr_t correctly | |
166 */ | |
167 if (sizeof(srtp_hdr_t) != 12) { | |
168 printf("error: srtp_hdr_t has incorrect size" | |
169 "(size is %ld bytes, expected 12)\n", | |
170 (long)sizeof(srtp_hdr_t)); | |
171 exit(1); | |
172 } | |
173 | |
174 /* initialize srtp library */ | |
175 status = srtp_init(); | |
176 if (status) { | |
177 printf("error: srtp init failed with error code %d\n", status); | |
178 exit(1); | |
179 } | |
180 | |
181 /* load srtp_driver debug module */ | |
182 status = crypto_kernel_load_debug_module(&mod_driver); | |
183 if (status) { | |
184 printf("error: load of srtp_driver debug module failed " | |
185 "with error code %d\n", status); | |
186 exit(1); | |
187 } | |
188 | |
189 /* process input arguments */ | |
190 while (1) { | |
191 q = getopt_s(argc, argv, "trcvld:"); | |
192 if (q == -1) | |
193 break; | |
194 switch (q) { | |
195 case 't': | |
196 do_timing_test = 1; | |
197 break; | |
198 case 'r': | |
199 do_rejection_test = 1; | |
200 break; | |
201 case 'c': | |
202 do_codec_timing = 1; | |
203 break; | |
204 case 'v': | |
205 do_validation = 1; | |
206 break; | |
207 case 'l': | |
208 do_list_mods = 1; | |
209 break; | |
210 case 'd': | |
211 status = crypto_kernel_set_debug_module(optarg_s, 1); | |
212 if (status) { | |
213 printf("error: set debug module (%s) failed\n", optarg_s); | |
214 exit(1); | |
215 } | |
216 break; | |
217 default: | |
218 usage(argv[0]); | |
219 } | |
220 } | |
221 | |
222 if (!do_validation && !do_timing_test && !do_codec_timing | |
223 && !do_list_mods && !do_rejection_test) | |
224 usage(argv[0]); | |
225 | |
226 if (do_list_mods) { | |
227 status = crypto_kernel_list_debug_modules(); | |
228 if (status) { | |
229 printf("error: list of debug modules failed\n"); | |
230 exit(1); | |
231 } | |
232 } | |
233 | |
234 if (do_validation) { | |
235 const srtp_policy_t **policy = policy_array; | |
236 srtp_policy_t *big_policy; | |
237 | |
238 /* loop over policy array, testing srtp and srtcp for each policy */ | |
239 while (*policy != NULL) { | |
240 printf("testing srtp_protect and srtp_unprotect\n"); | |
241 if (srtp_test(*policy, 0) == err_status_ok) | |
242 printf("passed\n\n"); | |
243 else { | |
244 printf("failed\n"); | |
245 exit(1); | |
246 } | |
247 printf("testing srtp_protect and srtp_unprotect with encrypted extensions
headers\n"); | |
248 if (srtp_test(*policy, 1) == err_status_ok) | |
249 printf("passed\n\n"); | |
250 else { | |
251 printf("failed\n"); | |
252 exit(1); | |
253 } | |
254 printf("testing srtp_protect_rtcp and srtp_unprotect_rtcp\n"); | |
255 if (srtcp_test(*policy) == err_status_ok) | |
256 printf("passed\n\n"); | |
257 else { | |
258 printf("failed\n"); | |
259 exit(1); | |
260 } | |
261 policy++; | |
262 } | |
263 | |
264 /* create a big policy list and run tests on it */ | |
265 status = srtp_create_big_policy(&big_policy); | |
266 if (status) { | |
267 printf("unexpected failure with error code %d\n", status); | |
268 exit(1); | |
269 } | |
270 printf("testing srtp_protect and srtp_unprotect with big policy\n"); | |
271 if (srtp_test(big_policy, 0) == err_status_ok) | |
272 printf("passed\n\n"); | |
273 else { | |
274 printf("failed\n"); | |
275 exit(1); | |
276 } | |
277 printf("testing srtp_protect and srtp_unprotect with big policy and encrypte
d extensions headers\n"); | |
278 if (srtp_test(big_policy, 1) == err_status_ok) | |
279 printf("passed\n\n"); | |
280 else { | |
281 printf("failed\n"); | |
282 exit(1); | |
283 } | |
284 status = srtp_dealloc_big_policy(big_policy); | |
285 if (status) { | |
286 printf("unexpected failure with error code %d\n", status); | |
287 exit(1); | |
288 } | |
289 | |
290 /* run test on wildcard policy */ | |
291 printf("testing srtp_protect and srtp_unprotect on " | |
292 "wildcard ssrc policy\n"); | |
293 if (srtp_test(&wildcard_policy, 0) == err_status_ok) | |
294 printf("passed\n\n"); | |
295 else { | |
296 printf("failed\n"); | |
297 exit(1); | |
298 } | |
299 printf("testing srtp_protect and srtp_unprotect on " | |
300 "wildcard ssrc policy and encrypted extensions headers\n"); | |
301 if (srtp_test(&wildcard_policy, 1) == err_status_ok) | |
302 printf("passed\n\n"); | |
303 else { | |
304 printf("failed\n"); | |
305 exit(1); | |
306 } | |
307 | |
308 /* | |
309 * run validation test against the reference packets - note | |
310 * that this test only covers the default policy | |
311 */ | |
312 printf("testing srtp_protect and srtp_unprotect against " | |
313 "reference packets\n"); | |
314 if (srtp_validate() == err_status_ok) | |
315 printf("passed\n\n"); | |
316 else { | |
317 printf("failed\n"); | |
318 exit(1); | |
319 } | |
320 | |
321 printf("testing srtp_protect and srtp_unprotect against " | |
322 "reference packets with encrypted extensions headers\n"); | |
323 if (srtp_validate_encrypted_extensions_headers() == err_status_ok) | |
324 printf("passed\n\n"); | |
325 else { | |
326 printf("failed\n"); | |
327 exit(1); | |
328 } | |
329 | |
330 #ifdef OPENSSL | |
331 printf("testing srtp_protect and srtp_unprotect against " | |
332 "reference packets with encrypted extension headers (GCM)\n"); | |
333 if (srtp_validate_encrypted_extensions_headers_gcm() == err_status_ok) { | |
334 printf("passed\n\n"); | |
335 } else{ | |
336 printf("failed\n"); | |
337 exit(1); | |
338 } | |
339 #endif | |
340 | |
341 /* | |
342 * run validation test against the reference packets for | |
343 * AES-256 | |
344 */ | |
345 printf("testing srtp_protect and srtp_unprotect against " | |
346 "reference packets (AES-256)\n"); | |
347 if (srtp_validate_aes_256() == err_status_ok) | |
348 printf("passed\n\n"); | |
349 else { | |
350 printf("failed\n"); | |
351 exit(1); | |
352 } | |
353 | |
354 /* | |
355 * test the function srtp_remove_stream() | |
356 */ | |
357 printf("testing srtp_remove_stream()..."); | |
358 if (srtp_test_remove_stream() == err_status_ok) | |
359 printf("passed\n"); | |
360 else { | |
361 printf("failed\n"); | |
362 exit(1); | |
363 } | |
364 } | |
365 | |
366 if (do_timing_test) { | |
367 const srtp_policy_t **policy = policy_array; | |
368 | |
369 /* loop over policies, run timing test for each */ | |
370 while (*policy != NULL) { | |
371 srtp_print_policy(*policy); | |
372 srtp_do_timing(*policy); | |
373 policy++; | |
374 } | |
375 } | |
376 | |
377 if (do_rejection_test) { | |
378 const srtp_policy_t **policy = policy_array; | |
379 | |
380 /* loop over policies, run rejection timing test for each */ | |
381 while (*policy != NULL) { | |
382 srtp_print_policy(*policy); | |
383 srtp_do_rejection_timing(*policy); | |
384 policy++; | |
385 } | |
386 } | |
387 | |
388 if (do_codec_timing) { | |
389 srtp_policy_t policy; | |
390 int ignore; | |
391 double mips_value = mips_estimate(1000000000, &ignore); | |
392 | |
393 memset(&policy, 0, sizeof(policy)); | |
394 crypto_policy_set_rtp_default(&policy.rtp); | |
395 crypto_policy_set_rtcp_default(&policy.rtcp); | |
396 policy.ssrc.type = ssrc_specific; | |
397 policy.ssrc.value = 0xdecafbad; | |
398 policy.key = test_key; | |
399 policy.ekt = NULL; | |
400 policy.window_size = 128; | |
401 policy.allow_repeat_tx = 0; | |
402 policy.next = NULL; | |
403 | |
404 printf("mips estimate: %e\n", mips_value); | |
405 | |
406 printf("testing srtp processing time for voice codecs:\n"); | |
407 printf("codec\t\tlength (octets)\t\tsrtp instructions/second\n"); | |
408 printf("G.711\t\t%d\t\t\t%e\n", 80, | |
409 (double) mips_value * (80 * 8) / | |
410 srtp_bits_per_second(80, &policy) / .01 ); | |
411 printf("G.711\t\t%d\t\t\t%e\n", 160, | |
412 (double) mips_value * (160 * 8) / | |
413 srtp_bits_per_second(160, &policy) / .02); | |
414 printf("G.726-32\t%d\t\t\t%e\n", 40, | |
415 (double) mips_value * (40 * 8) / | |
416 srtp_bits_per_second(40, &policy) / .01 ); | |
417 printf("G.726-32\t%d\t\t\t%e\n", 80, | |
418 (double) mips_value * (80 * 8) / | |
419 srtp_bits_per_second(80, &policy) / .02); | |
420 printf("G.729\t\t%d\t\t\t%e\n", 10, | |
421 (double) mips_value * (10 * 8) / | |
422 srtp_bits_per_second(10, &policy) / .01 ); | |
423 printf("G.729\t\t%d\t\t\t%e\n", 20, | |
424 (double) mips_value * (20 * 8) / | |
425 srtp_bits_per_second(20, &policy) / .02 ); | |
426 printf("Wideband\t%d\t\t\t%e\n", 320, | |
427 (double) mips_value * (320 * 8) / | |
428 srtp_bits_per_second(320, &policy) / .01 ); | |
429 printf("Wideband\t%d\t\t\t%e\n", 640, | |
430 (double) mips_value * (640 * 8) / | |
431 srtp_bits_per_second(640, &policy) / .02 ); | |
432 } | |
433 | |
434 status = srtp_shutdown(); | |
435 if (status) { | |
436 printf("error: srtp shutdown failed with error code %d\n", status); | |
437 exit(1); | |
438 } | |
439 | |
440 return 0; | |
441 } | |
442 | |
443 | |
444 | |
445 /* | |
446 * srtp_create_test_packet(len, ssrc) returns a pointer to a | |
447 * (malloced) example RTP packet whose data field has the length given | |
448 * by pkt_octet_len and the SSRC value ssrc. The total length of the | |
449 * packet is twelve octets longer, since the header is at the | |
450 * beginning. There is room at the end of the packet for a trailer, | |
451 * and the four octets following the packet are filled with 0xff | |
452 * values to enable testing for overwrites. | |
453 * | |
454 * note that the location of the test packet can (and should) be | |
455 * deallocated with the free() call once it is no longer needed. | |
456 */ | |
457 | |
458 srtp_hdr_t * | |
459 srtp_create_test_packet(int pkt_octet_len, uint32_t ssrc) { | |
460 int i; | |
461 uint8_t *buffer; | |
462 srtp_hdr_t *hdr; | |
463 int bytes_in_hdr = 12; | |
464 | |
465 /* allocate memory for test packet */ | |
466 hdr = (srtp_hdr_t*) malloc(pkt_octet_len + bytes_in_hdr | |
467 + SRTP_MAX_TRAILER_LEN + 4); | |
468 if (!hdr) | |
469 return NULL; | |
470 | |
471 hdr->version = 2; /* RTP version two */ | |
472 hdr->p = 0; /* no padding needed */ | |
473 hdr->x = 0; /* no header extension */ | |
474 hdr->cc = 0; /* no CSRCs */ | |
475 hdr->m = 0; /* marker bit */ | |
476 hdr->pt = 0xf; /* payload type */ | |
477 hdr->seq = htons(0x1234); /* sequence number */ | |
478 hdr->ts = htonl(0xdecafbad); /* timestamp */ | |
479 hdr->ssrc = htonl(ssrc); /* synch. source */ | |
480 | |
481 buffer = (uint8_t *)hdr; | |
482 buffer += bytes_in_hdr; | |
483 | |
484 /* set RTP data to 0xab */ | |
485 for (i=0; i < pkt_octet_len; i++) | |
486 *buffer++ = 0xab; | |
487 | |
488 /* set post-data value to 0xffff to enable overrun checking */ | |
489 for (i=0; i < SRTP_MAX_TRAILER_LEN+4; i++) | |
490 *buffer++ = 0xff; | |
491 | |
492 return hdr; | |
493 } | |
494 | |
495 srtp_hdr_t * | |
496 srtp_create_test_packet_ext_hdr(int pkt_octet_len, uint32_t ssrc) { | |
497 int i; | |
498 uint8_t *buffer; | |
499 srtp_hdr_t *hdr; | |
500 int bytes_in_hdr = 12; | |
501 uint8_t extension_header[12] = { | |
502 /* one-byte header */ | |
503 0xbe, 0xde, | |
504 /* size */ | |
505 0x00, 0x02, | |
506 /* id 1, length 1 (i.e. 2 bytes) */ | |
507 0x11, | |
508 /* payload */ | |
509 0xca, | |
510 0xfe, | |
511 /* padding */ | |
512 0x00, | |
513 /* id 2, length 0 (i.e. 1 byte) */ | |
514 0x20, | |
515 /* payload */ | |
516 0xba, | |
517 /* padding */ | |
518 0x00, | |
519 0x00 | |
520 }; | |
521 | |
522 /* allocate memory for test packet */ | |
523 hdr = (srtp_hdr_t*) malloc(pkt_octet_len + bytes_in_hdr | |
524 + sizeof(extension_header) + SRTP_MAX_TRAILER_LEN + 4); | |
525 if (!hdr) | |
526 return NULL; | |
527 | |
528 hdr->version = 2; /* RTP version two */ | |
529 hdr->p = 0; /* no padding needed */ | |
530 hdr->x = 1; /* no header extension */ | |
531 hdr->cc = 0; /* no CSRCs */ | |
532 hdr->m = 0; /* marker bit */ | |
533 hdr->pt = 0xf; /* payload type */ | |
534 hdr->seq = htons(0x1234); /* sequence number */ | |
535 hdr->ts = htonl(0xdecafbad); /* timestamp */ | |
536 hdr->ssrc = htonl(ssrc); /* synch. source */ | |
537 | |
538 buffer = (uint8_t *)hdr; | |
539 buffer += bytes_in_hdr; | |
540 | |
541 memcpy(buffer, extension_header, sizeof(extension_header)); | |
542 buffer += sizeof(extension_header); | |
543 | |
544 /* set RTP data to 0xab */ | |
545 for (i=0; i < pkt_octet_len; i++) | |
546 *buffer++ = 0xab; | |
547 | |
548 /* set post-data value to 0xffff to enable overrun checking */ | |
549 for (i=0; i < SRTP_MAX_TRAILER_LEN+4; i++) | |
550 *buffer++ = 0xff; | |
551 | |
552 return hdr; | |
553 } | |
554 | |
555 void | |
556 srtp_do_timing(const srtp_policy_t *policy) { | |
557 int len; | |
558 | |
559 /* | |
560 * note: the output of this function is formatted so that it | |
561 * can be used in gnuplot. '#' indicates a comment, and "\r\n" | |
562 * terminates a record | |
563 */ | |
564 | |
565 printf("# testing srtp throughput:\r\n"); | |
566 printf("# mesg length (octets)\tthroughput (megabits per second)\r\n"); | |
567 | |
568 for (len=16; len <= 2048; len *= 2) | |
569 printf("%d\t\t\t%f\r\n", len, | |
570 srtp_bits_per_second(len, policy) / 1.0E6); | |
571 | |
572 /* these extra linefeeds let gnuplot know that a dataset is done */ | |
573 printf("\r\n\r\n"); | |
574 | |
575 } | |
576 | |
577 void | |
578 srtp_do_rejection_timing(const srtp_policy_t *policy) { | |
579 int len; | |
580 | |
581 /* | |
582 * note: the output of this function is formatted so that it | |
583 * can be used in gnuplot. '#' indicates a comment, and "\r\n" | |
584 * terminates a record | |
585 */ | |
586 | |
587 printf("# testing srtp rejection throughput:\r\n"); | |
588 printf("# mesg length (octets)\trejections per second\r\n"); | |
589 | |
590 for (len=8; len <= 2048; len *= 2) | |
591 printf("%d\t\t\t%e\r\n", len, srtp_rejections_per_second(len, policy)); | |
592 | |
593 /* these extra linefeeds let gnuplot know that a dataset is done */ | |
594 printf("\r\n\r\n"); | |
595 | |
596 } | |
597 | |
598 | |
599 #define MAX_MSG_LEN 1024 | |
600 | |
601 double | |
602 srtp_bits_per_second(int msg_len_octets, const srtp_policy_t *policy) { | |
603 srtp_t srtp; | |
604 srtp_hdr_t *mesg; | |
605 int i; | |
606 clock_t timer; | |
607 int num_trials = 100000; | |
608 int len; | |
609 uint32_t ssrc; | |
610 err_status_t status; | |
611 | |
612 /* | |
613 * allocate and initialize an srtp session | |
614 */ | |
615 status = srtp_create(&srtp, policy); | |
616 if (status) { | |
617 printf("error: srtp_create() failed with error code %d\n", status); | |
618 exit(1); | |
619 } | |
620 | |
621 /* | |
622 * if the ssrc is unspecified, use a predetermined one | |
623 */ | |
624 if (policy->ssrc.type != ssrc_specific) { | |
625 ssrc = 0xdeadbeef; | |
626 } else { | |
627 ssrc = policy->ssrc.value; | |
628 } | |
629 | |
630 /* | |
631 * create a test packet | |
632 */ | |
633 mesg = srtp_create_test_packet(msg_len_octets, ssrc); | |
634 if (mesg == NULL) | |
635 return 0.0; /* indicate failure by returning zero */ | |
636 | |
637 timer = clock(); | |
638 for (i=0; i < num_trials; i++) { | |
639 len = msg_len_octets + 12; /* add in rtp header length */ | |
640 | |
641 /* srtp protect message */ | |
642 status = srtp_protect(srtp, mesg, &len); | |
643 if (status) { | |
644 printf("error: srtp_protect() failed with error code %d\n", status); | |
645 exit(1); | |
646 } | |
647 | |
648 /* increment message number */ | |
649 { | |
650 /* hack sequence to avoid problems with macros for htons/ntohs on some sys
tems */ | |
651 short new_seq = ntohs(mesg->seq) + 1; | |
652 mesg->seq = htons(new_seq); | |
653 } | |
654 } | |
655 timer = clock() - timer; | |
656 | |
657 free(mesg); | |
658 | |
659 status = srtp_dealloc(srtp); | |
660 if (status) { | |
661 printf("error: srtp_dealloc() failed with error code %d\n", status); | |
662 exit(1); | |
663 } | |
664 | |
665 return (double) (msg_len_octets) * 8 * | |
666 num_trials * CLOCKS_PER_SEC / timer; | |
667 } | |
668 | |
669 double | |
670 srtp_rejections_per_second(int msg_len_octets, const srtp_policy_t *policy) { | |
671 srtp_ctx_t *srtp; | |
672 srtp_hdr_t *mesg; | |
673 int i; | |
674 int len; | |
675 clock_t timer; | |
676 int num_trials = 1000000; | |
677 uint32_t ssrc = policy->ssrc.value; | |
678 err_status_t status; | |
679 | |
680 /* | |
681 * allocate and initialize an srtp session | |
682 */ | |
683 status = srtp_create(&srtp, policy); | |
684 if (status) { | |
685 printf("error: srtp_create() failed with error code %d\n", status); | |
686 exit(1); | |
687 } | |
688 | |
689 mesg = srtp_create_test_packet(msg_len_octets, ssrc); | |
690 if (mesg == NULL) | |
691 return 0.0; /* indicate failure by returning zero */ | |
692 | |
693 len = msg_len_octets; | |
694 srtp_protect(srtp, (srtp_hdr_t *)mesg, &len); | |
695 | |
696 timer = clock(); | |
697 for (i=0; i < num_trials; i++) { | |
698 len = msg_len_octets; | |
699 srtp_unprotect(srtp, (srtp_hdr_t *)mesg, &len); | |
700 } | |
701 timer = clock() - timer; | |
702 | |
703 free(mesg); | |
704 | |
705 status = srtp_dealloc(srtp); | |
706 if (status) { | |
707 printf("error: srtp_dealloc() failed with error code %d\n", status); | |
708 exit(1); | |
709 } | |
710 | |
711 return (double) num_trials * CLOCKS_PER_SEC / timer; | |
712 } | |
713 | |
714 | |
715 void | |
716 err_check(err_status_t s) { | |
717 if (s == err_status_ok) | |
718 return; | |
719 else | |
720 fprintf(stderr, "error: unexpected srtp failure (code %d)\n", s); | |
721 exit (1); | |
722 } | |
723 | |
724 err_status_t | |
725 srtp_test(const srtp_policy_t *policy, int extension_header) { | |
726 int i; | |
727 srtp_t srtp_sender; | |
728 srtp_t srtp_rcvr; | |
729 err_status_t status = err_status_ok; | |
730 srtp_hdr_t *hdr, *hdr2; | |
731 uint8_t hdr_enc[64]; | |
732 uint8_t *pkt_end; | |
733 int msg_len_octets, msg_len_enc; | |
734 int len; | |
735 int tag_length = policy->rtp.auth_tag_len; | |
736 uint32_t ssrc; | |
737 srtp_policy_t *rcvr_policy; | |
738 srtp_policy_t tmp_policy; | |
739 int header = 1; | |
740 | |
741 if (extension_header) { | |
742 memcpy(&tmp_policy, policy, sizeof(srtp_policy_t)); | |
743 tmp_policy.enc_xtn_hdr = &header; | |
744 tmp_policy.enc_xtn_hdr_count = 1; | |
745 err_check(srtp_create(&srtp_sender, &tmp_policy)); | |
746 } else { | |
747 err_check(srtp_create(&srtp_sender, policy)); | |
748 } | |
749 | |
750 /* print out policy */ | |
751 err_check(srtp_session_print_policy(srtp_sender)); | |
752 | |
753 /* | |
754 * initialize data buffer, using the ssrc in the policy unless that | |
755 * value is a wildcard, in which case we'll just use an arbitrary | |
756 * one | |
757 */ | |
758 if (policy->ssrc.type != ssrc_specific) | |
759 ssrc = 0xdecafbad; | |
760 else | |
761 ssrc = policy->ssrc.value; | |
762 msg_len_octets = 28; | |
763 if (extension_header) { | |
764 hdr = srtp_create_test_packet_ext_hdr(msg_len_octets, ssrc); | |
765 hdr2 = srtp_create_test_packet_ext_hdr(msg_len_octets, ssrc); | |
766 } else { | |
767 hdr = srtp_create_test_packet(msg_len_octets, ssrc); | |
768 hdr2 = srtp_create_test_packet(msg_len_octets, ssrc); | |
769 } | |
770 if (hdr == NULL) { | |
771 free(hdr2); | |
772 return err_status_alloc_fail; | |
773 } | |
774 if (hdr2 == NULL) { | |
775 free(hdr); | |
776 return err_status_alloc_fail; | |
777 } | |
778 | |
779 /* set message length */ | |
780 len = msg_len_octets; | |
781 if (extension_header) { | |
782 len += 12; | |
783 } | |
784 | |
785 debug_print(mod_driver, "before protection:\n%s", | |
786 srtp_packet_to_string(hdr, len)); | |
787 | |
788 #if PRINT_REFERENCE_PACKET | |
789 debug_print(mod_driver, "reference packet before protection:\n%s", | |
790 octet_string_hex_string((uint8_t *)hdr, len)); | |
791 #endif | |
792 err_check(srtp_protect(srtp_sender, hdr, &len)); | |
793 | |
794 debug_print(mod_driver, "after protection:\n%s", | |
795 srtp_packet_to_string(hdr, len)); | |
796 #if PRINT_REFERENCE_PACKET | |
797 debug_print(mod_driver, "after protection:\n%s", | |
798 octet_string_hex_string((uint8_t *)hdr, len)); | |
799 #endif | |
800 | |
801 /* save protected message and length */ | |
802 memcpy(hdr_enc, hdr, len); | |
803 msg_len_enc = len; | |
804 | |
805 /* | |
806 * check for overrun of the srtp_protect() function | |
807 * | |
808 * The packet is followed by a value of 0xfffff; if the value of the | |
809 * data following the packet is different, then we know that the | |
810 * protect function is overwriting the end of the packet. | |
811 */ | |
812 pkt_end = (uint8_t *)hdr + sizeof(srtp_hdr_t) | |
813 + msg_len_octets + tag_length; | |
814 if (extension_header) { | |
815 pkt_end += 12; | |
816 } | |
817 for (i = 0; i < 4; i++) | |
818 if (pkt_end[i] != 0xff) { | |
819 fprintf(stdout, "overwrite in srtp_protect() function " | |
820 "(expected %x, found %x in trailing octet %d)\n", | |
821 0xff, ((uint8_t *)hdr)[i], i); | |
822 free(hdr); | |
823 free(hdr2); | |
824 return err_status_algo_fail; | |
825 } | |
826 | |
827 /* | |
828 * if the policy includes confidentiality, check that ciphertext is | |
829 * different than plaintext | |
830 * | |
831 * Note that this check will give false negatives, with some small | |
832 * probability, especially if the packets are short. For that | |
833 * reason, we skip this check if the plaintext is less than four | |
834 * octets long. | |
835 */ | |
836 if ((policy->rtp.sec_serv & sec_serv_conf) && (msg_len_octets >= 4)) { | |
837 printf("testing that ciphertext is distinct from plaintext..."); | |
838 status = err_status_algo_fail; | |
839 for (i=12; i < msg_len_octets+12; i++) | |
840 if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) { | |
841 status = err_status_ok; | |
842 } | |
843 if (status) { | |
844 printf("failed\n"); | |
845 free(hdr); | |
846 free(hdr2); | |
847 return status; | |
848 } | |
849 printf("passed\n"); | |
850 } | |
851 | |
852 /* | |
853 * if the policy uses a 'wildcard' ssrc, then we need to make a copy | |
854 * of the policy that changes the direction to inbound | |
855 * | |
856 * we always copy the policy into the rcvr_policy, since otherwise | |
857 * the compiler would fret about the constness of the policy | |
858 */ | |
859 rcvr_policy = (srtp_policy_t*) malloc(sizeof(srtp_policy_t)); | |
860 if (rcvr_policy == NULL) { | |
861 free(hdr); | |
862 free(hdr2); | |
863 return err_status_alloc_fail; | |
864 } | |
865 if (extension_header) { | |
866 memcpy(rcvr_policy, &tmp_policy, sizeof(srtp_policy_t)); | |
867 if (tmp_policy.ssrc.type == ssrc_any_outbound) { | |
868 rcvr_policy->ssrc.type = ssrc_any_inbound; | |
869 } | |
870 } else { | |
871 memcpy(rcvr_policy, policy, sizeof(srtp_policy_t)); | |
872 if (policy->ssrc.type == ssrc_any_outbound) { | |
873 rcvr_policy->ssrc.type = ssrc_any_inbound; | |
874 } | |
875 } | |
876 | |
877 err_check(srtp_create(&srtp_rcvr, rcvr_policy)); | |
878 | |
879 err_check(srtp_unprotect(srtp_rcvr, hdr, &len)); | |
880 | |
881 debug_print(mod_driver, "after unprotection:\n%s", | |
882 srtp_packet_to_string(hdr, len)); | |
883 | |
884 /* verify that the unprotected packet matches the origial one */ | |
885 for (i=0; i < msg_len_octets; i++) | |
886 if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) { | |
887 fprintf(stdout, "mismatch at octet %d\n", i); | |
888 status = err_status_algo_fail; | |
889 } | |
890 if (status) { | |
891 free(hdr); | |
892 free(hdr2); | |
893 free(rcvr_policy); | |
894 return status; | |
895 } | |
896 | |
897 /* | |
898 * if the policy includes authentication, then test for false positives | |
899 */ | |
900 if (policy->rtp.sec_serv & sec_serv_auth) { | |
901 char *data = ((char *)hdr) + 12; | |
902 | |
903 printf("testing for false positives in replay check..."); | |
904 | |
905 /* set message length */ | |
906 len = msg_len_enc; | |
907 if (extension_header) { | |
908 len += 12; | |
909 } | |
910 | |
911 /* unprotect a second time - should fail with a replay error */ | |
912 status = srtp_unprotect(srtp_rcvr, hdr_enc, &len); | |
913 if (status != err_status_replay_fail) { | |
914 printf("failed with error code %d\n", status); | |
915 free(hdr); | |
916 free(hdr2); | |
917 free(rcvr_policy); | |
918 return status; | |
919 } else { | |
920 printf("passed\n"); | |
921 } | |
922 | |
923 printf("testing for false positives in auth check..."); | |
924 | |
925 /* increment sequence number in header */ | |
926 hdr->seq++; | |
927 | |
928 /* set message length */ | |
929 len = msg_len_octets; | |
930 | |
931 /* apply protection */ | |
932 err_check(srtp_protect(srtp_sender, hdr, &len)); | |
933 | |
934 /* flip bits in packet */ | |
935 data[extension_header ? 12 : 0] ^= 0xff; | |
936 | |
937 /* unprotect, and check for authentication failure */ | |
938 status = srtp_unprotect(srtp_rcvr, hdr, &len); | |
939 if (status != err_status_auth_fail) { | |
940 printf("failed\n"); | |
941 free(hdr); | |
942 free(hdr2); | |
943 free(rcvr_policy); | |
944 return status; | |
945 } else { | |
946 printf("passed\n"); | |
947 } | |
948 | |
949 } | |
950 | |
951 err_check(srtp_dealloc(srtp_sender)); | |
952 err_check(srtp_dealloc(srtp_rcvr)); | |
953 | |
954 free(hdr); | |
955 free(hdr2); | |
956 free(rcvr_policy); | |
957 return err_status_ok; | |
958 } | |
959 | |
960 | |
961 err_status_t | |
962 srtcp_test(const srtp_policy_t *policy) { | |
963 int i; | |
964 srtp_t srtcp_sender; | |
965 srtp_t srtcp_rcvr; | |
966 err_status_t status = err_status_ok; | |
967 srtp_hdr_t *hdr, *hdr2; | |
968 uint8_t hdr_enc[64]; | |
969 uint8_t *pkt_end; | |
970 int msg_len_octets, msg_len_enc; | |
971 int len; | |
972 int tag_length = policy->rtp.auth_tag_len; | |
973 uint32_t ssrc; | |
974 srtp_policy_t *rcvr_policy; | |
975 | |
976 err_check(srtp_create(&srtcp_sender, policy)); | |
977 | |
978 /* print out policy */ | |
979 err_check(srtp_session_print_policy(srtcp_sender)); | |
980 | |
981 /* | |
982 * initialize data buffer, using the ssrc in the policy unless that | |
983 * value is a wildcard, in which case we'll just use an arbitrary | |
984 * one | |
985 */ | |
986 if (policy->ssrc.type != ssrc_specific) | |
987 ssrc = 0xdecafbad; | |
988 else | |
989 ssrc = policy->ssrc.value; | |
990 msg_len_octets = 28; | |
991 hdr = srtp_create_test_packet(msg_len_octets, ssrc); | |
992 | |
993 if (hdr == NULL) | |
994 return err_status_alloc_fail; | |
995 hdr2 = srtp_create_test_packet(msg_len_octets, ssrc); | |
996 if (hdr2 == NULL) { | |
997 free(hdr); | |
998 return err_status_alloc_fail; | |
999 } | |
1000 | |
1001 /* set message length */ | |
1002 len = msg_len_octets; | |
1003 | |
1004 debug_print(mod_driver, "before protection:\n%s", | |
1005 srtp_packet_to_string(hdr, len)); | |
1006 | |
1007 #if PRINT_REFERENCE_PACKET | |
1008 debug_print(mod_driver, "reference packet before protection:\n%s", | |
1009 octet_string_hex_string((uint8_t *)hdr, len)); | |
1010 #endif | |
1011 err_check(srtp_protect_rtcp(srtcp_sender, hdr, &len)); | |
1012 | |
1013 debug_print(mod_driver, "after protection:\n%s", | |
1014 srtp_packet_to_string(hdr, len)); | |
1015 #if PRINT_REFERENCE_PACKET | |
1016 debug_print(mod_driver, "after protection:\n%s", | |
1017 octet_string_hex_string((uint8_t *)hdr, len)); | |
1018 #endif | |
1019 | |
1020 /* save protected message and length */ | |
1021 memcpy(hdr_enc, hdr, len); | |
1022 msg_len_enc = len; | |
1023 | |
1024 /* | |
1025 * check for overrun of the srtp_protect() function | |
1026 * | |
1027 * The packet is followed by a value of 0xfffff; if the value of the | |
1028 * data following the packet is different, then we know that the | |
1029 * protect function is overwriting the end of the packet. | |
1030 */ | |
1031 pkt_end = (uint8_t *)hdr + sizeof(srtp_hdr_t) | |
1032 + msg_len_octets + tag_length; | |
1033 for (i = 0; i < 4; i++) | |
1034 if (pkt_end[i] != 0xff) { | |
1035 fprintf(stdout, "overwrite in srtp_protect_rtcp() function " | |
1036 "(expected %x, found %x in trailing octet %d)\n", | |
1037 0xff, ((uint8_t *)hdr)[i], i); | |
1038 free(hdr); | |
1039 free(hdr2); | |
1040 return err_status_algo_fail; | |
1041 } | |
1042 | |
1043 /* | |
1044 * if the policy includes confidentiality, check that ciphertext is | |
1045 * different than plaintext | |
1046 * | |
1047 * Note that this check will give false negatives, with some small | |
1048 * probability, especially if the packets are short. For that | |
1049 * reason, we skip this check if the plaintext is less than four | |
1050 * octets long. | |
1051 */ | |
1052 if ((policy->rtp.sec_serv & sec_serv_conf) && (msg_len_octets >= 4)) { | |
1053 printf("testing that ciphertext is distinct from plaintext..."); | |
1054 status = err_status_algo_fail; | |
1055 for (i=12; i < msg_len_octets+12; i++) | |
1056 if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) { | |
1057 status = err_status_ok; | |
1058 } | |
1059 if (status) { | |
1060 printf("failed\n"); | |
1061 free(hdr); | |
1062 free(hdr2); | |
1063 return status; | |
1064 } | |
1065 printf("passed\n"); | |
1066 } | |
1067 | |
1068 /* | |
1069 * if the policy uses a 'wildcard' ssrc, then we need to make a copy | |
1070 * of the policy that changes the direction to inbound | |
1071 * | |
1072 * we always copy the policy into the rcvr_policy, since otherwise | |
1073 * the compiler would fret about the constness of the policy | |
1074 */ | |
1075 rcvr_policy = (srtp_policy_t*) malloc(sizeof(srtp_policy_t)); | |
1076 if (rcvr_policy == NULL) | |
1077 return err_status_alloc_fail; | |
1078 memcpy(rcvr_policy, policy, sizeof(srtp_policy_t)); | |
1079 if (policy->ssrc.type == ssrc_any_outbound) { | |
1080 rcvr_policy->ssrc.type = ssrc_any_inbound; | |
1081 } | |
1082 | |
1083 err_check(srtp_create(&srtcp_rcvr, rcvr_policy)); | |
1084 | |
1085 err_check(srtp_unprotect_rtcp(srtcp_rcvr, hdr, &len)); | |
1086 | |
1087 debug_print(mod_driver, "after unprotection:\n%s", | |
1088 srtp_packet_to_string(hdr, len)); | |
1089 | |
1090 /* verify that the unprotected packet matches the origial one */ | |
1091 for (i=0; i < msg_len_octets; i++) | |
1092 if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) { | |
1093 fprintf(stdout, "mismatch at octet %d\n", i); | |
1094 status = err_status_algo_fail; | |
1095 } | |
1096 if (status) { | |
1097 free(hdr); | |
1098 free(hdr2); | |
1099 free(rcvr_policy); | |
1100 return status; | |
1101 } | |
1102 | |
1103 /* | |
1104 * if the policy includes authentication, then test for false positives | |
1105 */ | |
1106 if (policy->rtp.sec_serv & sec_serv_auth) { | |
1107 char *data = ((char *)hdr) + 12; | |
1108 | |
1109 printf("testing for false positives in replay check..."); | |
1110 | |
1111 /* set message length */ | |
1112 len = msg_len_enc; | |
1113 | |
1114 /* unprotect a second time - should fail with a replay error */ | |
1115 status = srtp_unprotect_rtcp(srtcp_rcvr, hdr_enc, &len); | |
1116 if (status != err_status_replay_fail) { | |
1117 printf("failed with error code %d\n", status); | |
1118 free(hdr); | |
1119 free(hdr2); | |
1120 free(rcvr_policy); | |
1121 return status; | |
1122 } else { | |
1123 printf("passed\n"); | |
1124 } | |
1125 | |
1126 printf("testing for false positives in auth check..."); | |
1127 | |
1128 /* increment sequence number in header */ | |
1129 hdr->seq++; | |
1130 | |
1131 /* set message length */ | |
1132 len = msg_len_octets; | |
1133 | |
1134 /* apply protection */ | |
1135 err_check(srtp_protect_rtcp(srtcp_sender, hdr, &len)); | |
1136 | |
1137 /* flip bits in packet */ | |
1138 data[0] ^= 0xff; | |
1139 | |
1140 /* unprotect, and check for authentication failure */ | |
1141 status = srtp_unprotect_rtcp(srtcp_rcvr, hdr, &len); | |
1142 if (status != err_status_auth_fail) { | |
1143 printf("failed\n"); | |
1144 free(hdr); | |
1145 free(hdr2); | |
1146 free(rcvr_policy); | |
1147 return status; | |
1148 } else { | |
1149 printf("passed\n"); | |
1150 } | |
1151 | |
1152 } | |
1153 | |
1154 err_check(srtp_dealloc(srtcp_sender)); | |
1155 err_check(srtp_dealloc(srtcp_rcvr)); | |
1156 | |
1157 free(hdr); | |
1158 free(hdr2); | |
1159 free(rcvr_policy); | |
1160 return err_status_ok; | |
1161 } | |
1162 | |
1163 | |
1164 err_status_t | |
1165 srtp_session_print_policy(srtp_t srtp) { | |
1166 char *serv_descr[4] = { | |
1167 "none", | |
1168 "confidentiality", | |
1169 "authentication", | |
1170 "confidentiality and authentication" | |
1171 }; | |
1172 char *direction[3] = { | |
1173 "unknown", | |
1174 "outbound", | |
1175 "inbound" | |
1176 }; | |
1177 srtp_stream_t stream; | |
1178 | |
1179 /* sanity checking */ | |
1180 if (srtp == NULL) | |
1181 return err_status_fail; | |
1182 | |
1183 /* if there's a template stream, print it out */ | |
1184 if (srtp->stream_template != NULL) { | |
1185 stream = srtp->stream_template; | |
1186 printf("# SSRC: any %s\r\n" | |
1187 "# rtp cipher: %s\r\n" | |
1188 "# rtp auth: %s\r\n" | |
1189 "# rtp services: %s\r\n" | |
1190 "# rtcp cipher: %s\r\n" | |
1191 "# rtcp auth: %s\r\n" | |
1192 "# rtcp services: %s\r\n" | |
1193 "# window size: %lu\r\n" | |
1194 "# tx rtx allowed:%s\r\n", | |
1195 direction[stream->direction], | |
1196 stream->rtp_cipher->type->description, | |
1197 stream->rtp_auth->type->description, | |
1198 serv_descr[stream->rtp_services], | |
1199 stream->rtcp_cipher->type->description, | |
1200 stream->rtcp_auth->type->description, | |
1201 serv_descr[stream->rtcp_services], | |
1202 rdbx_get_window_size(&stream->rtp_rdbx), | |
1203 stream->allow_repeat_tx ? "true" : "false"); | |
1204 | |
1205 printf("# Encrypted extension headers: "); | |
1206 if (stream->enc_xtn_hdr && stream->enc_xtn_hdr_count > 0) { | |
1207 int* enc_xtn_hdr = stream->enc_xtn_hdr; | |
1208 int count = stream->enc_xtn_hdr_count; | |
1209 while (count > 0) { | |
1210 printf("%d ", *enc_xtn_hdr); | |
1211 enc_xtn_hdr++; | |
1212 count--; | |
1213 } | |
1214 printf("\n"); | |
1215 } else { | |
1216 printf("none\n"); | |
1217 } | |
1218 } | |
1219 | |
1220 /* loop over streams in session, printing the policy of each */ | |
1221 stream = srtp->stream_list; | |
1222 while (stream != NULL) { | |
1223 if (stream->rtp_services > sec_serv_conf_and_auth) | |
1224 return err_status_bad_param; | |
1225 | |
1226 printf("# SSRC: 0x%08x\r\n" | |
1227 "# rtp cipher: %s\r\n" | |
1228 "# rtp auth: %s\r\n" | |
1229 "# rtp services: %s\r\n" | |
1230 "# rtcp cipher: %s\r\n" | |
1231 "# rtcp auth: %s\r\n" | |
1232 "# rtcp services: %s\r\n" | |
1233 "# window size: %lu\r\n" | |
1234 "# tx rtx allowed:%s\r\n", | |
1235 stream->ssrc, | |
1236 stream->rtp_cipher->type->description, | |
1237 stream->rtp_auth->type->description, | |
1238 serv_descr[stream->rtp_services], | |
1239 stream->rtcp_cipher->type->description, | |
1240 stream->rtcp_auth->type->description, | |
1241 serv_descr[stream->rtcp_services], | |
1242 rdbx_get_window_size(&stream->rtp_rdbx), | |
1243 stream->allow_repeat_tx ? "true" : "false"); | |
1244 | |
1245 printf("# Encrypted extension headers: "); | |
1246 if (stream->enc_xtn_hdr && stream->enc_xtn_hdr_count > 0) { | |
1247 int* enc_xtn_hdr = stream->enc_xtn_hdr; | |
1248 int count = stream->enc_xtn_hdr_count; | |
1249 while (count > 0) { | |
1250 printf("%d ", *enc_xtn_hdr); | |
1251 enc_xtn_hdr++; | |
1252 count--; | |
1253 } | |
1254 printf("\n"); | |
1255 } else { | |
1256 printf("none\n"); | |
1257 } | |
1258 | |
1259 /* advance to next stream in the list */ | |
1260 stream = stream->next; | |
1261 } | |
1262 return err_status_ok; | |
1263 } | |
1264 | |
1265 err_status_t | |
1266 srtp_print_policy(const srtp_policy_t *policy) { | |
1267 err_status_t status; | |
1268 srtp_t session; | |
1269 | |
1270 status = srtp_create(&session, policy); | |
1271 if (status) | |
1272 return status; | |
1273 status = srtp_session_print_policy(session); | |
1274 if (status) | |
1275 return status; | |
1276 status = srtp_dealloc(session); | |
1277 if (status) | |
1278 return status; | |
1279 return err_status_ok; | |
1280 } | |
1281 | |
1282 /* | |
1283 * srtp_print_packet(...) is for debugging only | |
1284 * it prints an RTP packet to the stdout | |
1285 * | |
1286 * note that this function is *not* threadsafe | |
1287 */ | |
1288 | |
1289 #include <stdio.h> | |
1290 | |
1291 #define MTU 2048 | |
1292 | |
1293 char packet_string[MTU]; | |
1294 | |
1295 char * | |
1296 srtp_packet_to_string(srtp_hdr_t *hdr, int pkt_octet_len) { | |
1297 int octets_in_rtp_header = 12; | |
1298 uint8_t *data = ((uint8_t *)hdr)+octets_in_rtp_header; | |
1299 int hex_len = pkt_octet_len-octets_in_rtp_header; | |
1300 | |
1301 /* sanity checking */ | |
1302 if ((hdr == NULL) || (pkt_octet_len > MTU)) | |
1303 return NULL; | |
1304 | |
1305 /* write packet into string */ | |
1306 sprintf(packet_string, | |
1307 "(s)rtp packet: {\n" | |
1308 " version:\t%d\n" | |
1309 " p:\t\t%d\n" | |
1310 " x:\t\t%d\n" | |
1311 " cc:\t\t%d\n" | |
1312 " m:\t\t%d\n" | |
1313 " pt:\t\t%x\n" | |
1314 " seq:\t\t%x\n" | |
1315 " ts:\t\t%x\n" | |
1316 " ssrc:\t%x\n" | |
1317 " data:\t%s\n" | |
1318 "} (%d octets in total)\n", | |
1319 hdr->version, | |
1320 hdr->p, | |
1321 hdr->x, | |
1322 hdr->cc, | |
1323 hdr->m, | |
1324 hdr->pt, | |
1325 hdr->seq, | |
1326 hdr->ts, | |
1327 hdr->ssrc, | |
1328 octet_string_hex_string(data, hex_len), | |
1329 pkt_octet_len); | |
1330 | |
1331 return packet_string; | |
1332 } | |
1333 | |
1334 /* | |
1335 * mips_estimate() is a simple function to estimate the number of | |
1336 * instructions per second that the host can perform. note that this | |
1337 * function can be grossly wrong; you may want to have a manual sanity | |
1338 * check of its output! | |
1339 * | |
1340 * the 'ignore' pointer is there to convince the compiler to not just | |
1341 * optimize away the function | |
1342 */ | |
1343 | |
1344 double | |
1345 mips_estimate(int num_trials, int *ignore) { | |
1346 clock_t t; | |
1347 volatile int i, sum; | |
1348 | |
1349 sum = 0; | |
1350 t = clock(); | |
1351 for (i=0; i<num_trials; i++) | |
1352 sum += i; | |
1353 t = clock() - t; | |
1354 | |
1355 /* printf("%d\n", sum); */ | |
1356 *ignore = sum; | |
1357 | |
1358 return (double) num_trials * CLOCKS_PER_SEC / t; | |
1359 } | |
1360 | |
1361 | |
1362 /* | |
1363 * srtp_validate() verifies the correctness of libsrtp by comparing | |
1364 * some computed packets against some pre-computed reference values. | |
1365 * These packets were made with the default SRTP policy. | |
1366 */ | |
1367 | |
1368 | |
1369 err_status_t | |
1370 srtp_validate() { | |
1371 uint8_t srtp_plaintext_ref[28] = { | |
1372 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad, | |
1373 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab, | |
1374 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, | |
1375 0xab, 0xab, 0xab, 0xab | |
1376 }; | |
1377 uint8_t srtp_plaintext[38] = { | |
1378 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad, | |
1379 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab, | |
1380 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, | |
1381 0xab, 0xab, 0xab, 0xab, 0x00, 0x00, 0x00, 0x00, | |
1382 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | |
1383 }; | |
1384 uint8_t srtp_ciphertext[38] = { | |
1385 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad, | |
1386 0xca, 0xfe, 0xba, 0xbe, 0x4e, 0x55, 0xdc, 0x4c, | |
1387 0xe7, 0x99, 0x78, 0xd8, 0x8c, 0xa4, 0xd2, 0x15, | |
1388 0x94, 0x9d, 0x24, 0x02, 0xb7, 0x8d, 0x6a, 0xcc, | |
1389 0x99, 0xea, 0x17, 0x9b, 0x8d, 0xbb | |
1390 }; | |
1391 srtp_t srtp_snd, srtp_recv; | |
1392 err_status_t status; | |
1393 int len; | |
1394 srtp_policy_t policy; | |
1395 | |
1396 /* | |
1397 * create a session with a single stream using the default srtp | |
1398 * policy and with the SSRC value 0xcafebabe | |
1399 */ | |
1400 memset(&policy, 0, sizeof(policy)); | |
1401 crypto_policy_set_rtp_default(&policy.rtp); | |
1402 crypto_policy_set_rtcp_default(&policy.rtcp); | |
1403 policy.ssrc.type = ssrc_specific; | |
1404 policy.ssrc.value = 0xcafebabe; | |
1405 policy.key = test_key; | |
1406 policy.ekt = NULL; | |
1407 policy.window_size = 128; | |
1408 policy.allow_repeat_tx = 0; | |
1409 policy.next = NULL; | |
1410 | |
1411 status = srtp_create(&srtp_snd, &policy); | |
1412 if (status) | |
1413 return status; | |
1414 | |
1415 /* | |
1416 * protect plaintext, then compare with ciphertext | |
1417 */ | |
1418 len = 28; | |
1419 status = srtp_protect(srtp_snd, srtp_plaintext, &len); | |
1420 if (status || (len != 38)) | |
1421 return err_status_fail; | |
1422 | |
1423 debug_print(mod_driver, "ciphertext:\n %s", | |
1424 octet_string_hex_string(srtp_plaintext, len)); | |
1425 debug_print(mod_driver, "ciphertext reference:\n %s", | |
1426 octet_string_hex_string(srtp_ciphertext, len)); | |
1427 | |
1428 if (octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len)) | |
1429 return err_status_fail; | |
1430 | |
1431 /* | |
1432 * create a receiver session context comparable to the one created | |
1433 * above - we need to do this so that the replay checking doesn't | |
1434 * complain | |
1435 */ | |
1436 status = srtp_create(&srtp_recv, &policy); | |
1437 if (status) | |
1438 return status; | |
1439 | |
1440 /* | |
1441 * unprotect ciphertext, then compare with plaintext | |
1442 */ | |
1443 status = srtp_unprotect(srtp_recv, srtp_ciphertext, &len); | |
1444 if (status || (len != 28)) | |
1445 return status; | |
1446 | |
1447 if (octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len)) | |
1448 return err_status_fail; | |
1449 | |
1450 status = srtp_dealloc(srtp_snd); | |
1451 if (status) | |
1452 return status; | |
1453 | |
1454 status = srtp_dealloc(srtp_recv); | |
1455 if (status) | |
1456 return status; | |
1457 | |
1458 return err_status_ok; | |
1459 } | |
1460 | |
1461 | |
1462 /* | |
1463 * Test vectors taken from RFC 6904, Appendix A | |
1464 */ | |
1465 err_status_t | |
1466 srtp_validate_encrypted_extensions_headers() { | |
1467 unsigned char test_key_ext_headers[30] = { | |
1468 0xe1, 0xf9, 0x7a, 0x0d, 0x3e, 0x01, 0x8b, 0xe0, | |
1469 0xd6, 0x4f, 0xa3, 0x2c, 0x06, 0xde, 0x41, 0x39, | |
1470 0x0e, 0xc6, 0x75, 0xad, 0x49, 0x8a, 0xfe, 0xeb, | |
1471 0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6 | |
1472 }; | |
1473 uint8_t srtp_plaintext_ref[56] = { | |
1474 0x90, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad, | |
1475 0xca, 0xfe, 0xba, 0xbe, 0xBE, 0xDE, 0x00, 0x06, | |
1476 0x17, 0x41, 0x42, 0x73, 0xA4, 0x75, 0x26, 0x27, | |
1477 0x48, 0x22, 0x00, 0x00, 0xC8, 0x30, 0x8E, 0x46, | |
1478 0x55, 0x99, 0x63, 0x86, 0xB3, 0x95, 0xFB, 0x00, | |
1479 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, | |
1480 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab | |
1481 }; | |
1482 uint8_t srtp_plaintext[66] = { | |
1483 0x90, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad, | |
1484 0xca, 0xfe, 0xba, 0xbe, 0xBE, 0xDE, 0x00, 0x06, | |
1485 0x17, 0x41, 0x42, 0x73, 0xA4, 0x75, 0x26, 0x27, | |
1486 0x48, 0x22, 0x00, 0x00, 0xC8, 0x30, 0x8E, 0x46, | |
1487 0x55, 0x99, 0x63, 0x86, 0xB3, 0x95, 0xFB, 0x00, | |
1488 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, | |
1489 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, | |
1490 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
1491 0x00, 0x00 | |
1492 }; | |
1493 uint8_t srtp_ciphertext[66] = { | |
1494 0x90, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad, | |
1495 0xca, 0xfe, 0xba, 0xbe, 0xBE, 0xDE, 0x00, 0x06, | |
1496 0x17, 0x58, 0x8A, 0x92, 0x70, 0xF4, 0xE1, 0x5E, | |
1497 0x1C, 0x22, 0x00, 0x00, 0xC8, 0x30, 0x95, 0x46, | |
1498 0xA9, 0x94, 0xF0, 0xBC, 0x54, 0x78, 0x97, 0x00, | |
1499 0x4e, 0x55, 0xdc, 0x4c, 0xe7, 0x99, 0x78, 0xd8, | |
1500 0x8c, 0xa4, 0xd2, 0x15, 0x94, 0x9d, 0x24, 0x02, | |
1501 0x5a, 0x46, 0xb3, 0xca, 0x35, 0xc5, 0x35, 0xa8, | |
1502 0x91, 0xc7 | |
1503 }; | |
1504 srtp_t srtp_snd, srtp_recv; | |
1505 err_status_t status; | |
1506 int len; | |
1507 srtp_policy_t policy; | |
1508 int headers[3] = {1, 3, 4}; | |
1509 | |
1510 /* | |
1511 * create a session with a single stream using the default srtp | |
1512 * policy and with the SSRC value 0xcafebabe | |
1513 */ | |
1514 memset(&policy, 0, sizeof(policy)); | |
1515 crypto_policy_set_rtp_default(&policy.rtp); | |
1516 crypto_policy_set_rtcp_default(&policy.rtcp); | |
1517 policy.ssrc.type = ssrc_specific; | |
1518 policy.ssrc.value = 0xcafebabe; | |
1519 policy.key = test_key_ext_headers; | |
1520 policy.ekt = NULL; | |
1521 policy.window_size = 128; | |
1522 policy.allow_repeat_tx = 0; | |
1523 policy.enc_xtn_hdr = headers; | |
1524 policy.enc_xtn_hdr_count = sizeof(headers) / sizeof(headers[0]); | |
1525 policy.next = NULL; | |
1526 | |
1527 status = srtp_create(&srtp_snd, &policy); | |
1528 if (status) | |
1529 return status; | |
1530 | |
1531 /* | |
1532 * protect plaintext, then compare with ciphertext | |
1533 */ | |
1534 len = sizeof(srtp_plaintext_ref); | |
1535 status = srtp_protect(srtp_snd, srtp_plaintext, &len); | |
1536 if (status || (len != sizeof(srtp_plaintext))) | |
1537 return err_status_fail; | |
1538 | |
1539 debug_print(mod_driver, "ciphertext:\n %s", | |
1540 octet_string_hex_string(srtp_plaintext, len)); | |
1541 debug_print(mod_driver, "ciphertext reference:\n %s", | |
1542 octet_string_hex_string(srtp_ciphertext, len)); | |
1543 | |
1544 if (octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len)) | |
1545 return err_status_fail; | |
1546 | |
1547 /* | |
1548 * create a receiver session context comparable to the one created | |
1549 * above - we need to do this so that the replay checking doesn't | |
1550 * complain | |
1551 */ | |
1552 status = srtp_create(&srtp_recv, &policy); | |
1553 if (status) | |
1554 return status; | |
1555 | |
1556 /* | |
1557 * unprotect ciphertext, then compare with plaintext | |
1558 */ | |
1559 status = srtp_unprotect(srtp_recv, srtp_ciphertext, &len); | |
1560 if (status) { | |
1561 return status; | |
1562 } else if (len != sizeof(srtp_plaintext_ref)) { | |
1563 return err_status_fail; | |
1564 } | |
1565 | |
1566 if (octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len)) | |
1567 return err_status_fail; | |
1568 | |
1569 status = srtp_dealloc(srtp_snd); | |
1570 if (status) | |
1571 return status; | |
1572 | |
1573 status = srtp_dealloc(srtp_recv); | |
1574 if (status) | |
1575 return status; | |
1576 | |
1577 return err_status_ok; | |
1578 } | |
1579 | |
1580 | |
1581 #ifdef OPENSSL | |
1582 /* | |
1583 * Headers of test vectors taken from RFC 6904, Appendix A | |
1584 */ | |
1585 err_status_t | |
1586 srtp_validate_encrypted_extensions_headers_gcm() { | |
1587 unsigned char test_key_ext_headers[30] = { | |
1588 0xe1, 0xf9, 0x7a, 0x0d, 0x3e, 0x01, 0x8b, 0xe0, | |
1589 0xd6, 0x4f, 0xa3, 0x2c, 0x06, 0xde, 0x41, 0x39, | |
1590 0x0e, 0xc6, 0x75, 0xad, 0x49, 0x8a, 0xfe, 0xeb, | |
1591 0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6 | |
1592 }; | |
1593 uint8_t srtp_plaintext_ref[56] = { | |
1594 0x90, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad, | |
1595 0xca, 0xfe, 0xba, 0xbe, 0xBE, 0xDE, 0x00, 0x06, | |
1596 0x17, 0x41, 0x42, 0x73, 0xA4, 0x75, 0x26, 0x27, | |
1597 0x48, 0x22, 0x00, 0x00, 0xC8, 0x30, 0x8E, 0x46, | |
1598 0x55, 0x99, 0x63, 0x86, 0xB3, 0x95, 0xFB, 0x00, | |
1599 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, | |
1600 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab | |
1601 }; | |
1602 uint8_t srtp_plaintext[64] = { | |
1603 0x90, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad, | |
1604 0xca, 0xfe, 0xba, 0xbe, 0xBE, 0xDE, 0x00, 0x06, | |
1605 0x17, 0x41, 0x42, 0x73, 0xA4, 0x75, 0x26, 0x27, | |
1606 0x48, 0x22, 0x00, 0x00, 0xC8, 0x30, 0x8E, 0x46, | |
1607 0x55, 0x99, 0x63, 0x86, 0xB3, 0x95, 0xFB, 0x00, | |
1608 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, | |
1609 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, | |
1610 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | |
1611 }; | |
1612 uint8_t srtp_ciphertext[64] = { | |
1613 0x90, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad, | |
1614 0xca, 0xfe, 0xba, 0xbe, 0xBE, 0xDE, 0x00, 0x06, | |
1615 0x17, 0x58, 0x8A, 0x92, 0x70, 0xF4, 0xE1, 0x5E, | |
1616 0x1C, 0x22, 0x00, 0x00, 0xC8, 0x30, 0x95, 0x46, | |
1617 0xA9, 0x94, 0xF0, 0xBC, 0x54, 0x78, 0x97, 0x00, | |
1618 0x0e, 0xca, 0x0c, 0xf9, 0x5e, 0xe9, 0x55, 0xb2, | |
1619 0x6c, 0xd3, 0xd2, 0x88, 0xb4, 0x9f, 0x6c, 0xa9, | |
1620 0xbb, 0x4e, 0x15, 0xc2, 0xe9, 0xf2, 0x66, 0x78 | |
1621 }; | |
1622 srtp_t srtp_snd, srtp_recv; | |
1623 err_status_t status; | |
1624 int len; | |
1625 srtp_policy_t policy; | |
1626 int headers[3] = {1, 3, 4}; | |
1627 | |
1628 /* | |
1629 * create a session with a single stream using the default srtp | |
1630 * policy and with the SSRC value 0xcafebabe | |
1631 */ | |
1632 memset(&policy, 0, sizeof(policy)); | |
1633 crypto_policy_set_aes_gcm_128_8_auth(&policy.rtp); | |
1634 crypto_policy_set_aes_gcm_128_8_auth(&policy.rtcp); | |
1635 policy.ssrc.type = ssrc_specific; | |
1636 policy.ssrc.value = 0xcafebabe; | |
1637 policy.key = test_key_ext_headers; | |
1638 policy.ekt = NULL; | |
1639 policy.window_size = 128; | |
1640 policy.allow_repeat_tx = 0; | |
1641 policy.enc_xtn_hdr = headers; | |
1642 policy.enc_xtn_hdr_count = sizeof(headers) / sizeof(headers[0]); | |
1643 policy.next = NULL; | |
1644 | |
1645 status = srtp_create(&srtp_snd, &policy); | |
1646 if (status) | |
1647 return status; | |
1648 | |
1649 /* | |
1650 * protect plaintext, then compare with ciphertext | |
1651 */ | |
1652 len = sizeof(srtp_plaintext_ref); | |
1653 status = srtp_protect(srtp_snd, srtp_plaintext, &len); | |
1654 if (status || (len != sizeof(srtp_plaintext))) | |
1655 return err_status_fail; | |
1656 | |
1657 debug_print(mod_driver, "ciphertext:\n %s", | |
1658 octet_string_hex_string(srtp_plaintext, len)); | |
1659 debug_print(mod_driver, "ciphertext reference:\n %s", | |
1660 octet_string_hex_string(srtp_ciphertext, len)); | |
1661 | |
1662 if (octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len)) | |
1663 return err_status_fail; | |
1664 | |
1665 /* | |
1666 * create a receiver session context comparable to the one created | |
1667 * above - we need to do this so that the replay checking doesn't | |
1668 * complain | |
1669 */ | |
1670 status = srtp_create(&srtp_recv, &policy); | |
1671 if (status) | |
1672 return status; | |
1673 | |
1674 /* | |
1675 * unprotect ciphertext, then compare with plaintext | |
1676 */ | |
1677 status = srtp_unprotect(srtp_recv, srtp_ciphertext, &len); | |
1678 if (status) { | |
1679 return status; | |
1680 } else if (len != sizeof(srtp_plaintext_ref)) { | |
1681 return err_status_fail; | |
1682 } | |
1683 | |
1684 if (octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len)) | |
1685 return err_status_fail; | |
1686 | |
1687 status = srtp_dealloc(srtp_snd); | |
1688 if (status) | |
1689 return status; | |
1690 | |
1691 status = srtp_dealloc(srtp_recv); | |
1692 if (status) | |
1693 return status; | |
1694 | |
1695 return err_status_ok; | |
1696 } | |
1697 #endif | |
1698 | |
1699 | |
1700 /* | |
1701 * srtp_validate_aes_256() verifies the correctness of libsrtp by comparing | |
1702 * some computed packets against some pre-computed reference values. | |
1703 * These packets were made with the AES-CM-256/HMAC-SHA-1-80 policy. | |
1704 */ | |
1705 | |
1706 | |
1707 err_status_t | |
1708 srtp_validate_aes_256() { | |
1709 unsigned char aes_256_test_key[46] = { | |
1710 0xf0, 0xf0, 0x49, 0x14, 0xb5, 0x13, 0xf2, 0x76, | |
1711 0x3a, 0x1b, 0x1f, 0xa1, 0x30, 0xf1, 0x0e, 0x29, | |
1712 0x98, 0xf6, 0xf6, 0xe4, 0x3e, 0x43, 0x09, 0xd1, | |
1713 0xe6, 0x22, 0xa0, 0xe3, 0x32, 0xb9, 0xf1, 0xb6, | |
1714 | |
1715 0x3b, 0x04, 0x80, 0x3d, 0xe5, 0x1e, 0xe7, 0xc9, | |
1716 0x64, 0x23, 0xab, 0x5b, 0x78, 0xd2 | |
1717 }; | |
1718 uint8_t srtp_plaintext_ref[28] = { | |
1719 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad, | |
1720 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab, | |
1721 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, | |
1722 0xab, 0xab, 0xab, 0xab | |
1723 }; | |
1724 uint8_t srtp_plaintext[38] = { | |
1725 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad, | |
1726 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab, | |
1727 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, | |
1728 0xab, 0xab, 0xab, 0xab, 0x00, 0x00, 0x00, 0x00, | |
1729 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | |
1730 }; | |
1731 uint8_t srtp_ciphertext[38] = { | |
1732 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad, | |
1733 0xca, 0xfe, 0xba, 0xbe, 0xf1, 0xd9, 0xde, 0x17, | |
1734 0xff, 0x25, 0x1f, 0xf1, 0xaa, 0x00, 0x77, 0x74, | |
1735 0xb0, 0xb4, 0xb4, 0x0d, 0xa0, 0x8d, 0x9d, 0x9a, | |
1736 0x5b, 0x3a, 0x55, 0xd8, 0x87, 0x3b | |
1737 }; | |
1738 srtp_t srtp_snd, srtp_recv; | |
1739 err_status_t status; | |
1740 int len; | |
1741 srtp_policy_t policy; | |
1742 | |
1743 /* | |
1744 * create a session with a single stream using the default srtp | |
1745 * policy and with the SSRC value 0xcafebabe | |
1746 */ | |
1747 memset(&policy, 0, sizeof(policy)); | |
1748 crypto_policy_set_aes_cm_256_hmac_sha1_80(&policy.rtp); | |
1749 crypto_policy_set_aes_cm_256_hmac_sha1_80(&policy.rtcp); | |
1750 policy.ssrc.type = ssrc_specific; | |
1751 policy.ssrc.value = 0xcafebabe; | |
1752 policy.key = aes_256_test_key; | |
1753 policy.ekt = NULL; | |
1754 policy.window_size = 128; | |
1755 policy.allow_repeat_tx = 0; | |
1756 policy.next = NULL; | |
1757 | |
1758 status = srtp_create(&srtp_snd, &policy); | |
1759 if (status) | |
1760 return status; | |
1761 | |
1762 /* | |
1763 * protect plaintext, then compare with ciphertext | |
1764 */ | |
1765 len = 28; | |
1766 status = srtp_protect(srtp_snd, srtp_plaintext, &len); | |
1767 if (status || (len != 38)) | |
1768 return err_status_fail; | |
1769 | |
1770 debug_print(mod_driver, "ciphertext:\n %s", | |
1771 octet_string_hex_string(srtp_plaintext, len)); | |
1772 debug_print(mod_driver, "ciphertext reference:\n %s", | |
1773 octet_string_hex_string(srtp_ciphertext, len)); | |
1774 | |
1775 if (octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len)) | |
1776 return err_status_fail; | |
1777 | |
1778 /* | |
1779 * create a receiver session context comparable to the one created | |
1780 * above - we need to do this so that the replay checking doesn't | |
1781 * complain | |
1782 */ | |
1783 status = srtp_create(&srtp_recv, &policy); | |
1784 if (status) | |
1785 return status; | |
1786 | |
1787 /* | |
1788 * unprotect ciphertext, then compare with plaintext | |
1789 */ | |
1790 status = srtp_unprotect(srtp_recv, srtp_ciphertext, &len); | |
1791 if (status || (len != 28)) | |
1792 return status; | |
1793 | |
1794 if (octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len)) | |
1795 return err_status_fail; | |
1796 | |
1797 status = srtp_dealloc(srtp_snd); | |
1798 if (status) | |
1799 return status; | |
1800 | |
1801 status = srtp_dealloc(srtp_recv); | |
1802 if (status) | |
1803 return status; | |
1804 | |
1805 return err_status_ok; | |
1806 } | |
1807 | |
1808 | |
1809 err_status_t | |
1810 srtp_create_big_policy(srtp_policy_t **list) { | |
1811 extern const srtp_policy_t *policy_array[]; | |
1812 srtp_policy_t *p, *tmp; | |
1813 int i = 0; | |
1814 uint32_t ssrc = 0; | |
1815 | |
1816 /* sanity checking */ | |
1817 if ((list == NULL) || (policy_array[0] == NULL)) | |
1818 return err_status_bad_param; | |
1819 | |
1820 /* | |
1821 * loop over policy list, mallocing a new list and copying values | |
1822 * into it (and incrementing the SSRC value as we go along) | |
1823 */ | |
1824 tmp = NULL; | |
1825 while (policy_array[i] != NULL) { | |
1826 p = (srtp_policy_t*) malloc(sizeof(srtp_policy_t)); | |
1827 if (p == NULL) | |
1828 return err_status_bad_param; | |
1829 memcpy(p, policy_array[i], sizeof(srtp_policy_t)); | |
1830 p->ssrc.type = ssrc_specific; | |
1831 p->ssrc.value = ssrc++; | |
1832 p->next = tmp; | |
1833 tmp = p; | |
1834 i++; | |
1835 } | |
1836 *list = p; | |
1837 | |
1838 return err_status_ok; | |
1839 } | |
1840 | |
1841 err_status_t | |
1842 srtp_dealloc_big_policy(srtp_policy_t *list) { | |
1843 srtp_policy_t *p, *next; | |
1844 | |
1845 for (p = list; p != NULL; p = next) { | |
1846 next = p->next; | |
1847 free(p); | |
1848 } | |
1849 | |
1850 return err_status_ok; | |
1851 } | |
1852 | |
1853 | |
1854 err_status_t | |
1855 srtp_test_remove_stream() { | |
1856 err_status_t status; | |
1857 srtp_policy_t *policy_list, policy; | |
1858 srtp_t session; | |
1859 srtp_stream_t stream; | |
1860 /* | |
1861 * srtp_get_stream() is a libSRTP internal function that we declare | |
1862 * here so that we can use it to verify the correct operation of the | |
1863 * library | |
1864 */ | |
1865 extern srtp_stream_t srtp_get_stream(srtp_t srtp, uint32_t ssrc); | |
1866 | |
1867 | |
1868 status = srtp_create_big_policy(&policy_list); | |
1869 if (status) | |
1870 return status; | |
1871 | |
1872 status = srtp_create(&session, policy_list); | |
1873 if (status) | |
1874 return status; | |
1875 | |
1876 /* | |
1877 * check for false positives by trying to remove a stream that's not | |
1878 * in the session | |
1879 */ | |
1880 status = srtp_remove_stream(session, htonl(0xaaaaaaaa)); | |
1881 if (status != err_status_no_ctx) | |
1882 return err_status_fail; | |
1883 | |
1884 /* | |
1885 * check for false negatives by removing stream 0x1, then | |
1886 * searching for streams 0x0 and 0x2 | |
1887 */ | |
1888 status = srtp_remove_stream(session, htonl(0x1)); | |
1889 if (status != err_status_ok) | |
1890 return err_status_fail; | |
1891 stream = srtp_get_stream(session, htonl(0x0)); | |
1892 if (stream == NULL) | |
1893 return err_status_fail; | |
1894 stream = srtp_get_stream(session, htonl(0x2)); | |
1895 if (stream == NULL) | |
1896 return err_status_fail; | |
1897 | |
1898 status = srtp_dealloc(session); | |
1899 if (status != err_status_ok) | |
1900 return status; | |
1901 | |
1902 status = srtp_dealloc_big_policy(policy_list); | |
1903 if (status != err_status_ok) | |
1904 return status; | |
1905 | |
1906 /* Now test adding and removing a single stream */ | |
1907 memset(&policy, 0, sizeof(policy)); | |
1908 crypto_policy_set_rtp_default(&policy.rtp); | |
1909 crypto_policy_set_rtcp_default(&policy.rtcp); | |
1910 policy.ssrc.type = ssrc_specific; | |
1911 policy.ssrc.value = 0xcafebabe; | |
1912 policy.key = test_key; | |
1913 policy.ekt = NULL; | |
1914 policy.window_size = 128; | |
1915 policy.allow_repeat_tx = 0; | |
1916 policy.next = NULL; | |
1917 | |
1918 status = srtp_create(&session, NULL); | |
1919 if (status != err_status_ok) | |
1920 return status; | |
1921 | |
1922 status = srtp_add_stream(session, &policy); | |
1923 if (status != err_status_ok) | |
1924 return status; | |
1925 | |
1926 status = srtp_remove_stream(session, htonl(0xcafebabe)); | |
1927 if (status != err_status_ok) | |
1928 return status; | |
1929 | |
1930 status = srtp_dealloc(session); | |
1931 if (status != err_status_ok) | |
1932 return status; | |
1933 | |
1934 return err_status_ok; | |
1935 } | |
1936 | |
1937 /* | |
1938 * srtp policy definitions - these definitions are used above | |
1939 */ | |
1940 | |
1941 unsigned char test_key[46] = { | |
1942 0xe1, 0xf9, 0x7a, 0x0d, 0x3e, 0x01, 0x8b, 0xe0, | |
1943 0xd6, 0x4f, 0xa3, 0x2c, 0x06, 0xde, 0x41, 0x39, | |
1944 0x0e, 0xc6, 0x75, 0xad, 0x49, 0x8a, 0xfe, 0xeb, | |
1945 0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6, 0xc1, 0x73, | |
1946 0xc3, 0x17, 0xf2, 0xda, 0xbe, 0x35, 0x77, 0x93, | |
1947 0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6 | |
1948 }; | |
1949 | |
1950 | |
1951 const srtp_policy_t default_policy = { | |
1952 { ssrc_any_outbound, 0 }, /* SSRC */ | |
1953 { /* SRTP policy */ | |
1954 AES_128_ICM, /* cipher type */ | |
1955 30, /* cipher key length in octets */ | |
1956 HMAC_SHA1, /* authentication func type */ | |
1957 16, /* auth key length in octets */ | |
1958 10, /* auth tag length in octets */ | |
1959 sec_serv_conf_and_auth /* security services flag */ | |
1960 }, | |
1961 { /* SRTCP policy */ | |
1962 AES_128_ICM, /* cipher type */ | |
1963 30, /* cipher key length in octets */ | |
1964 HMAC_SHA1, /* authentication func type */ | |
1965 16, /* auth key length in octets */ | |
1966 10, /* auth tag length in octets */ | |
1967 sec_serv_conf_and_auth /* security services flag */ | |
1968 }, | |
1969 test_key, | |
1970 NULL, /* indicates that EKT is not in use */ | |
1971 128, /* replay window size */ | |
1972 0, /* retransmission not allowed */ | |
1973 NULL, /* no encrypted extension headers */ | |
1974 0, /* list of encrypted extension headers is empty */ | |
1975 NULL | |
1976 }; | |
1977 | |
1978 const srtp_policy_t aes_tmmh_policy = { | |
1979 { ssrc_any_outbound, 0 }, /* SSRC */ | |
1980 { | |
1981 AES_128_ICM, /* cipher type */ | |
1982 30, /* cipher key length in octets */ | |
1983 UST_TMMHv2, /* authentication func type */ | |
1984 94, /* auth key length in octets */ | |
1985 4, /* auth tag length in octets */ | |
1986 sec_serv_conf_and_auth /* security services flag */ | |
1987 }, | |
1988 { | |
1989 AES_128_ICM, /* cipher type */ | |
1990 30, /* cipher key length in octets */ | |
1991 UST_TMMHv2, /* authentication func type */ | |
1992 94, /* auth key length in octets */ | |
1993 4, /* auth tag length in octets */ | |
1994 sec_serv_conf_and_auth /* security services flag */ | |
1995 }, | |
1996 test_key, | |
1997 NULL, /* indicates that EKT is not in use */ | |
1998 128, /* replay window size */ | |
1999 0, /* retransmission not allowed */ | |
2000 NULL, /* no encrypted extension headers */ | |
2001 0, /* list of encrypted extension headers is empty */ | |
2002 NULL | |
2003 }; | |
2004 | |
2005 const srtp_policy_t tmmh_only_policy = { | |
2006 { ssrc_any_outbound, 0 }, /* SSRC */ | |
2007 { | |
2008 AES_128_ICM, /* cipher type */ | |
2009 30, /* cipher key length in octets */ | |
2010 UST_TMMHv2, /* authentication func type */ | |
2011 94, /* auth key length in octets */ | |
2012 4, /* auth tag length in octets */ | |
2013 sec_serv_auth /* security services flag */ | |
2014 }, | |
2015 { | |
2016 AES_128_ICM, /* cipher type */ | |
2017 30, /* cipher key length in octets */ | |
2018 UST_TMMHv2, /* authentication func type */ | |
2019 94, /* auth key length in octets */ | |
2020 4, /* auth tag length in octets */ | |
2021 sec_serv_auth /* security services flag */ | |
2022 }, | |
2023 test_key, | |
2024 NULL, /* indicates that EKT is not in use */ | |
2025 128, /* replay window size */ | |
2026 0, /* retransmission not allowed */ | |
2027 NULL, /* no encrypted extension headers */ | |
2028 0, /* list of encrypted extension headers is empty */ | |
2029 NULL | |
2030 }; | |
2031 | |
2032 const srtp_policy_t aes_only_policy = { | |
2033 { ssrc_any_outbound, 0 }, /* SSRC */ | |
2034 { | |
2035 AES_128_ICM, /* cipher type */ | |
2036 30, /* cipher key length in octets */ | |
2037 NULL_AUTH, /* authentication func type */ | |
2038 0, /* auth key length in octets */ | |
2039 0, /* auth tag length in octets */ | |
2040 sec_serv_conf /* security services flag */ | |
2041 }, | |
2042 { | |
2043 AES_128_ICM, /* cipher type */ | |
2044 30, /* cipher key length in octets */ | |
2045 NULL_AUTH, /* authentication func type */ | |
2046 0, /* auth key length in octets */ | |
2047 0, /* auth tag length in octets */ | |
2048 sec_serv_conf /* security services flag */ | |
2049 }, | |
2050 test_key, | |
2051 NULL, /* indicates that EKT is not in use */ | |
2052 128, /* replay window size */ | |
2053 0, /* retransmission not allowed */ | |
2054 NULL, /* no encrypted extension headers */ | |
2055 0, /* list of encrypted extension headers is empty */ | |
2056 NULL | |
2057 }; | |
2058 | |
2059 const srtp_policy_t hmac_only_policy = { | |
2060 { ssrc_any_outbound, 0 }, /* SSRC */ | |
2061 { | |
2062 NULL_CIPHER, /* cipher type */ | |
2063 0, /* cipher key length in octets */ | |
2064 HMAC_SHA1, /* authentication func type */ | |
2065 20, /* auth key length in octets */ | |
2066 4, /* auth tag length in octets */ | |
2067 sec_serv_auth /* security services flag */ | |
2068 }, | |
2069 { | |
2070 NULL_CIPHER, /* cipher type */ | |
2071 0, /* cipher key length in octets */ | |
2072 HMAC_SHA1, /* authentication func type */ | |
2073 20, /* auth key length in octets */ | |
2074 4, /* auth tag length in octets */ | |
2075 sec_serv_auth /* security services flag */ | |
2076 }, | |
2077 test_key, | |
2078 NULL, /* indicates that EKT is not in use */ | |
2079 128, /* replay window size */ | |
2080 0, /* retransmission not allowed */ | |
2081 NULL, /* no encrypted extension headers */ | |
2082 0, /* list of encrypted extension headers is empty */ | |
2083 NULL | |
2084 }; | |
2085 | |
2086 #ifdef OPENSSL | |
2087 const srtp_policy_t aes128_gcm_8_policy = { | |
2088 { ssrc_any_outbound, 0 }, /* SSRC */ | |
2089 { /* SRTP policy */
| |
2090 AES_128_GCM, /* cipher type */ | |
2091 AES_128_GCM_KEYSIZE_WSALT, /* cipher key length in octets */ | |
2092 NULL_AUTH, /* authentication func type */ | |
2093 0, /* auth key length in octets */ | |
2094 8, /* auth tag length in octets */ | |
2095 sec_serv_conf_and_auth /* security services flag */ | |
2096 }, | |
2097 { /* SRTCP policy */ | |
2098 AES_128_GCM, /* cipher type */ | |
2099 AES_128_GCM_KEYSIZE_WSALT, /* cipher key length in octets */ | |
2100 NULL_AUTH, /* authentication func type */ | |
2101 0, /* auth key length in octets */ | |
2102 8, /* auth tag length in octets */ | |
2103 sec_serv_conf_and_auth /* security services flag */ | |
2104 }, | |
2105 test_key, | |
2106 NULL, /* indicates that EKT is not in use */ | |
2107 128, /* replay window size */ | |
2108 0, /* retransmission not allowed */ | |
2109 NULL, /* no encrypted extension headers */ | |
2110 0, /* list of encrypted extension headers is empty */ | |
2111 NULL | |
2112 }; | |
2113 | |
2114 const srtp_policy_t aes128_gcm_8_cauth_policy = { | |
2115 { ssrc_any_outbound, 0 }, /* SSRC */ | |
2116 { /* SRTP policy */
| |
2117 AES_128_GCM, /* cipher type */ | |
2118 AES_128_GCM_KEYSIZE_WSALT, /* cipher key length in octets */ | |
2119 NULL_AUTH, /* authentication func type */ | |
2120 0, /* auth key length in octets */ | |
2121 8, /* auth tag length in octets */ | |
2122 sec_serv_conf_and_auth /* security services flag */ | |
2123 }, | |
2124 { /* SRTCP policy */ | |
2125 AES_128_GCM, /* cipher type */ | |
2126 AES_128_GCM_KEYSIZE_WSALT, /* cipher key length in octets */ | |
2127 NULL_AUTH, /* authentication func type */ | |
2128 0, /* auth key length in octets */ | |
2129 8, /* auth tag length in octets */ | |
2130 sec_serv_auth /* security services flag */ | |
2131 }, | |
2132 test_key, | |
2133 NULL, /* indicates that EKT is not in use */ | |
2134 128, /* replay window size */ | |
2135 0, /* retransmission not allowed */ | |
2136 NULL, /* no encrypted extension headers */ | |
2137 0, /* list of encrypted extension headers is empty */ | |
2138 NULL | |
2139 }; | |
2140 | |
2141 const srtp_policy_t aes256_gcm_8_policy = { | |
2142 { ssrc_any_outbound, 0 }, /* SSRC */ | |
2143 { /* SRTP policy */
| |
2144 AES_256_GCM, /* cipher type */ | |
2145 AES_256_GCM_KEYSIZE_WSALT, /* cipher key length in octets */ | |
2146 NULL_AUTH, /* authentication func type */ | |
2147 0, /* auth key length in octets */ | |
2148 8, /* auth tag length in octets */ | |
2149 sec_serv_conf_and_auth /* security services flag */ | |
2150 }, | |
2151 { /* SRTCP policy */ | |
2152 AES_256_GCM, /* cipher type */ | |
2153 AES_256_GCM_KEYSIZE_WSALT, /* cipher key length in octets */ | |
2154 NULL_AUTH, /* authentication func type */ | |
2155 0, /* auth key length in octets */ | |
2156 8, /* auth tag length in octets */ | |
2157 sec_serv_conf_and_auth /* security services flag */ | |
2158 }, | |
2159 test_key, | |
2160 NULL, /* indicates that EKT is not in use */ | |
2161 128, /* replay window size */ | |
2162 0, /* retransmission not allowed */ | |
2163 NULL, /* no encrypted extension headers */ | |
2164 0, /* list of encrypted extension headers is empty */ | |
2165 NULL | |
2166 }; | |
2167 | |
2168 const srtp_policy_t aes256_gcm_8_cauth_policy = { | |
2169 { ssrc_any_outbound, 0 }, /* SSRC */ | |
2170 { /* SRTP policy */
| |
2171 AES_256_GCM, /* cipher type */ | |
2172 AES_256_GCM_KEYSIZE_WSALT, /* cipher key length in octets */ | |
2173 NULL_AUTH, /* authentication func type */ | |
2174 0, /* auth key length in octets */ | |
2175 8, /* auth tag length in octets */ | |
2176 sec_serv_conf_and_auth /* security services flag */ | |
2177 }, | |
2178 { /* SRTCP policy */ | |
2179 AES_256_GCM, /* cipher type */ | |
2180 AES_256_GCM_KEYSIZE_WSALT, /* cipher key length in octets */ | |
2181 NULL_AUTH, /* authentication func type */ | |
2182 0, /* auth key length in octets */ | |
2183 8, /* auth tag length in octets */ | |
2184 sec_serv_auth /* security services flag */ | |
2185 }, | |
2186 test_key, | |
2187 NULL, /* indicates that EKT is not in use */ | |
2188 128, /* replay window size */ | |
2189 0, /* retransmission not allowed */ | |
2190 NULL, /* no encrypted extension headers */ | |
2191 0, /* list of encrypted extension headers is empty */ | |
2192 NULL | |
2193 }; | |
2194 #endif | |
2195 | |
2196 const srtp_policy_t null_policy = { | |
2197 { ssrc_any_outbound, 0 }, /* SSRC */ | |
2198 { | |
2199 NULL_CIPHER, /* cipher type */ | |
2200 0, /* cipher key length in octets */ | |
2201 NULL_AUTH, /* authentication func type */ | |
2202 0, /* auth key length in octets */ | |
2203 0, /* auth tag length in octets */ | |
2204 sec_serv_none /* security services flag */ | |
2205 }, | |
2206 { | |
2207 NULL_CIPHER, /* cipher type */ | |
2208 0, /* cipher key length in octets */ | |
2209 NULL_AUTH, /* authentication func type */ | |
2210 0, /* auth key length in octets */ | |
2211 0, /* auth tag length in octets */ | |
2212 sec_serv_none /* security services flag */ | |
2213 }, | |
2214 test_key, | |
2215 NULL, /* indicates that EKT is not in use */ | |
2216 128, /* replay window size */ | |
2217 0, /* retransmission not allowed */ | |
2218 NULL, /* no encrypted extension headers */ | |
2219 0, /* list of encrypted extension headers is empty */ | |
2220 NULL | |
2221 }; | |
2222 | |
2223 unsigned char test_256_key[46] = { | |
2224 0xf0, 0xf0, 0x49, 0x14, 0xb5, 0x13, 0xf2, 0x76, | |
2225 0x3a, 0x1b, 0x1f, 0xa1, 0x30, 0xf1, 0x0e, 0x29, | |
2226 0x98, 0xf6, 0xf6, 0xe4, 0x3e, 0x43, 0x09, 0xd1, | |
2227 0xe6, 0x22, 0xa0, 0xe3, 0x32, 0xb9, 0xf1, 0xb6, | |
2228 | |
2229 0x3b, 0x04, 0x80, 0x3d, 0xe5, 0x1e, 0xe7, 0xc9, | |
2230 0x64, 0x23, 0xab, 0x5b, 0x78, 0xd2 | |
2231 }; | |
2232 | |
2233 const srtp_policy_t aes_256_hmac_policy = { | |
2234 { ssrc_any_outbound, 0 }, /* SSRC */ | |
2235 { /* SRTP policy */ | |
2236 AES_ICM, /* cipher type */ | |
2237 46, /* cipher key length in octets */ | |
2238 HMAC_SHA1, /* authentication func type */ | |
2239 20, /* auth key length in octets */ | |
2240 10, /* auth tag length in octets */ | |
2241 sec_serv_conf_and_auth /* security services flag */ | |
2242 }, | |
2243 { /* SRTCP policy */ | |
2244 AES_ICM, /* cipher type */ | |
2245 46, /* cipher key length in octets */ | |
2246 HMAC_SHA1, /* authentication func type */ | |
2247 20, /* auth key length in octets */ | |
2248 10, /* auth tag length in octets */ | |
2249 sec_serv_conf_and_auth /* security services flag */ | |
2250 }, | |
2251 test_256_key, | |
2252 NULL, /* indicates that EKT is not in use */ | |
2253 128, /* replay window size */ | |
2254 0, /* retransmission not allowed */ | |
2255 NULL, /* no encrypted extension headers */ | |
2256 0, /* list of encrypted extension headers is empty */ | |
2257 NULL | |
2258 }; | |
2259 | |
2260 uint8_t ekt_test_key[16] = { | |
2261 0x77, 0x26, 0x9d, 0xac, 0x16, 0xa3, 0x28, 0xca, | |
2262 0x8e, 0xc9, 0x68, 0x4b, 0xcc, 0xc4, 0xd2, 0x1b | |
2263 }; | |
2264 | |
2265 #include "ekt.h" | |
2266 | |
2267 ekt_policy_ctx_t ekt_test_policy = { | |
2268 0xa5a5, /* SPI */ | |
2269 EKT_CIPHER_AES_128_ECB, | |
2270 ekt_test_key, | |
2271 NULL | |
2272 }; | |
2273 | |
2274 const srtp_policy_t hmac_only_with_ekt_policy = { | |
2275 { ssrc_any_outbound, 0 }, /* SSRC */ | |
2276 { | |
2277 NULL_CIPHER, /* cipher type */ | |
2278 0, /* cipher key length in octets */ | |
2279 HMAC_SHA1, /* authentication func type */ | |
2280 20, /* auth key length in octets */ | |
2281 4, /* auth tag length in octets */ | |
2282 sec_serv_auth /* security services flag */ | |
2283 }, | |
2284 { | |
2285 NULL_CIPHER, /* cipher type */ | |
2286 0, /* cipher key length in octets */ | |
2287 HMAC_SHA1, /* authentication func type */ | |
2288 20, /* auth key length in octets */ | |
2289 4, /* auth tag length in octets */ | |
2290 sec_serv_auth /* security services flag */ | |
2291 }, | |
2292 test_key, | |
2293 &ekt_test_policy, /* indicates that EKT is not in use */ | |
2294 128, /* replay window size */ | |
2295 0, /* retransmission not allowed */ | |
2296 NULL, /* no encrypted extension headers */ | |
2297 0, /* list of encrypted extension headers is empty */ | |
2298 NULL | |
2299 }; | |
2300 | |
2301 | |
2302 /* | |
2303 * an array of pointers to the policies listed above | |
2304 * | |
2305 * This array is used to test various aspects of libSRTP for | |
2306 * different cryptographic policies. The order of the elements | |
2307 * matters - the timing test generates output that can be used | |
2308 * in a plot (see the gnuplot script file 'timing'). If you | |
2309 * add to this list, you should do it at the end. | |
2310 */ | |
2311 | |
2312 #define USE_TMMH 0 | |
2313 | |
2314 const srtp_policy_t * | |
2315 policy_array[] = { | |
2316 &hmac_only_policy, | |
2317 #if USE_TMMH | |
2318 &tmmh_only_policy, | |
2319 #endif | |
2320 &aes_only_policy, | |
2321 #if USE_TMMH | |
2322 &aes_tmmh_policy, | |
2323 #endif | |
2324 &default_policy, | |
2325 #ifdef OPENSSL | |
2326 &aes128_gcm_8_policy, | |
2327 &aes128_gcm_8_cauth_policy, | |
2328 &aes256_gcm_8_policy, | |
2329 &aes256_gcm_8_cauth_policy, | |
2330 #endif | |
2331 &null_policy, | |
2332 &aes_256_hmac_policy, | |
2333 &hmac_only_with_ekt_policy, | |
2334 NULL | |
2335 }; | |
2336 | |
2337 const srtp_policy_t wildcard_policy = { | |
2338 { ssrc_any_outbound, 0 }, /* SSRC */ | |
2339 { /* SRTP policy */ | |
2340 AES_128_ICM, /* cipher type */ | |
2341 30, /* cipher key length in octets */ | |
2342 HMAC_SHA1, /* authentication func type */ | |
2343 16, /* auth key length in octets */ | |
2344 10, /* auth tag length in octets */ | |
2345 sec_serv_conf_and_auth /* security services flag */ | |
2346 }, | |
2347 { /* SRTCP policy */ | |
2348 AES_128_ICM, /* cipher type */ | |
2349 30, /* cipher key length in octets */ | |
2350 HMAC_SHA1, /* authentication func type */ | |
2351 16, /* auth key length in octets */ | |
2352 10, /* auth tag length in octets */ | |
2353 sec_serv_conf_and_auth /* security services flag */ | |
2354 }, | |
2355 test_key, | |
2356 NULL, | |
2357 128, /* replay window size */ | |
2358 0, /* retransmission not allowed */ | |
2359 NULL, /* no encrypted extension headers */ | |
2360 0, /* list of encrypted extension headers is empty */ | |
2361 NULL | |
2362 }; | |
OLD | NEW |