| 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 |