| OLD | NEW |
| 1 /* | 1 /* |
| 2 * rtpw.c | 2 * rtpw.c |
| 3 * | 3 * |
| 4 * rtp word sender/receiver | 4 * rtp word sender/receiver |
| 5 * | 5 * |
| 6 * David A. McGrew | 6 * David A. McGrew |
| 7 * Cisco Systems, Inc. | 7 * Cisco Systems, Inc. |
| 8 * | 8 * |
| 9 * This app is a simple RTP application intended only for testing | 9 * This app is a simple RTP application intended only for testing |
| 10 * libsrtp. It reads one word at a time from /usr/dict/words (or | 10 * libsrtp. It reads one word at a time from /usr/dict/words (or |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 44 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | 44 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
| 45 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 45 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| 46 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | 46 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
| 47 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 47 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| 48 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | 48 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED |
| 49 * OF THE POSSIBILITY OF SUCH DAMAGE. | 49 * OF THE POSSIBILITY OF SUCH DAMAGE. |
| 50 * | 50 * |
| 51 */ | 51 */ |
| 52 | 52 |
| 53 | 53 |
| 54 #ifdef HAVE_CONFIG_H |
| 55 #include <config.h> |
| 56 #endif |
| 57 |
| 54 #include "datatypes.h" | 58 #include "datatypes.h" |
| 55 #include "getopt_s.h" /* for local getopt() */ | 59 #include "getopt_s.h" /* for local getopt() */ |
| 56 | 60 |
| 57 #include <stdio.h> /* for printf, fprintf */ | 61 #include <stdio.h> /* for printf, fprintf */ |
| 58 #include <stdlib.h> /* for atoi() */ | 62 #include <stdlib.h> /* for atoi() */ |
| 59 #include <errno.h> | 63 #include <errno.h> |
| 60 #include <signal.h> /* for signal() */ | 64 #include <signal.h> /* for signal() */ |
| 61 | 65 |
| 62 #include <string.h> /* for strncpy() */ | 66 #include <string.h> /* for strncpy() */ |
| 63 #include <time.h> /* for usleep() */ | 67 #include <time.h> /* for usleep() */ |
| (...skipping 10 matching lines...) Expand all Loading... |
| 74 # include <winsock2.h> | 78 # include <winsock2.h> |
| 75 # include <ws2tcpip.h> | 79 # include <ws2tcpip.h> |
| 76 # define RTPW_USE_WINSOCK2 1 | 80 # define RTPW_USE_WINSOCK2 1 |
| 77 #endif | 81 #endif |
| 78 #ifdef HAVE_ARPA_INET_H | 82 #ifdef HAVE_ARPA_INET_H |
| 79 # include <arpa/inet.h> | 83 # include <arpa/inet.h> |
| 80 #endif | 84 #endif |
| 81 | 85 |
| 82 #include "srtp.h" | 86 #include "srtp.h" |
| 83 #include "rtp.h" | 87 #include "rtp.h" |
| 88 #include "crypto_kernel.h" |
| 84 | 89 |
| 85 #ifdef RTPW_USE_WINSOCK2 | 90 #ifdef RTPW_USE_WINSOCK2 |
| 86 # define DICT_FILE "words.txt" | 91 # define DICT_FILE "words.txt" |
| 87 #else | 92 #else |
| 88 # define DICT_FILE "/usr/share/dict/words" | 93 # define DICT_FILE "/usr/share/dict/words" |
| 89 #endif | 94 #endif |
| 90 #define USEC_RATE (5e5) | 95 #define USEC_RATE (5e5) |
| 91 #define MAX_WORD_LEN 128 | 96 #define MAX_WORD_LEN 128 |
| 92 #define ADDR_IS_MULTICAST(a) IN_MULTICAST(htonl(a)) | 97 #define ADDR_IS_MULTICAST(a) IN_MULTICAST(htonl(a)) |
| 93 #define MAX_KEY_LEN 64 | 98 #define MAX_KEY_LEN 96 |
| 94 #define MASTER_KEY_LEN 30 | |
| 95 | 99 |
| 96 | 100 |
| 97 #ifndef HAVE_USLEEP | 101 #ifndef HAVE_USLEEP |
| 98 # ifdef HAVE_WINDOWS_H | 102 # ifdef HAVE_WINDOWS_H |
| 99 # define usleep(us) Sleep((us)/1000) | 103 # define usleep(us) Sleep((us)/1000) |
| 100 # else | 104 # else |
| 101 # define usleep(us) sleep((us)/1000000) | 105 # define usleep(us) sleep((us)/1000000) |
| 102 # endif | 106 # endif |
| 103 #endif | 107 #endif |
| 104 | 108 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 146 struct in_addr rcvr_addr; | 150 struct in_addr rcvr_addr; |
| 147 struct sockaddr_in name; | 151 struct sockaddr_in name; |
| 148 struct ip_mreq mreq; | 152 struct ip_mreq mreq; |
| 149 #if BEW | 153 #if BEW |
| 150 struct sockaddr_in local; | 154 struct sockaddr_in local; |
| 151 #endif | 155 #endif |
| 152 program_type prog_type = unknown; | 156 program_type prog_type = unknown; |
| 153 sec_serv_t sec_servs = sec_serv_none; | 157 sec_serv_t sec_servs = sec_serv_none; |
| 154 unsigned char ttl = 5; | 158 unsigned char ttl = 5; |
| 155 int c; | 159 int c; |
| 160 int key_size = 128; |
| 161 int tag_size = 8; |
| 162 int gcm_on = 0; |
| 156 char *input_key = NULL; | 163 char *input_key = NULL; |
| 157 char *address = NULL; | 164 char *address = NULL; |
| 158 char key[MAX_KEY_LEN]; | 165 char key[MAX_KEY_LEN]; |
| 159 unsigned short port = 0; | 166 unsigned short port = 0; |
| 160 rtp_sender_t snd; | 167 rtp_sender_t snd; |
| 161 srtp_policy_t policy; | 168 srtp_policy_t policy; |
| 162 err_status_t status; | 169 err_status_t status; |
| 163 int len; | 170 int len; |
| 164 int do_list_mods = 0; | 171 int do_list_mods = 0; |
| 165 uint32_t ssrc = 0xdeadbeef; /* ssrc value hardcoded for now */ | 172 uint32_t ssrc = 0xdeadbeef; /* ssrc value hardcoded for now */ |
| 166 #ifdef RTPW_USE_WINSOCK2 | 173 #ifdef RTPW_USE_WINSOCK2 |
| 167 WORD wVersionRequested = MAKEWORD(2, 0); | 174 WORD wVersionRequested = MAKEWORD(2, 0); |
| 168 WSADATA wsaData; | 175 WSADATA wsaData; |
| 169 | 176 |
| 170 ret = WSAStartup(wVersionRequested, &wsaData); | 177 ret = WSAStartup(wVersionRequested, &wsaData); |
| 171 if (ret != 0) { | 178 if (ret != 0) { |
| 172 fprintf(stderr, "error: WSAStartup() failed: %d\n", ret); | 179 fprintf(stderr, "error: WSAStartup() failed: %d\n", ret); |
| 173 exit(1); | 180 exit(1); |
| 174 } | 181 } |
| 175 #endif | 182 #endif |
| 176 | 183 |
| 184 printf("Using %s [0x%x]\n", srtp_get_version_string(), srtp_get_version()); |
| 185 |
| 177 if (setup_signal_handler(argv[0]) != 0) { | 186 if (setup_signal_handler(argv[0]) != 0) { |
| 178 exit(1); | 187 exit(1); |
| 179 } | 188 } |
| 180 | 189 |
| 181 /* initialize srtp library */ | 190 /* initialize srtp library */ |
| 182 status = srtp_init(); | 191 status = srtp_init(); |
| 183 if (status) { | 192 if (status) { |
| 184 printf("error: srtp initialization failed with error code %d\n", status); | 193 printf("error: srtp initialization failed with error code %d\n", status); |
| 185 exit(1); | 194 exit(1); |
| 186 } | 195 } |
| 187 | 196 |
| 188 /* check args */ | 197 /* check args */ |
| 189 while (1) { | 198 while (1) { |
| 190 c = getopt_s(argc, argv, "k:rsaeld:"); | 199 c = getopt_s(argc, argv, "k:rsgt:ae:ld:"); |
| 191 if (c == -1) { | 200 if (c == -1) { |
| 192 break; | 201 break; |
| 193 } | 202 } |
| 194 switch (c) { | 203 switch (c) { |
| 195 case 'k': | 204 case 'k': |
| 196 input_key = optarg_s; | 205 input_key = optarg_s; |
| 197 break; | 206 break; |
| 198 case 'e': | 207 case 'e': |
| 208 key_size = atoi(optarg_s); |
| 209 if (key_size != 128 && key_size != 256) { |
| 210 printf("error: encryption key size must be 128 or 256 (%d)\n", key_size)
; |
| 211 exit(1); |
| 212 } |
| 199 sec_servs |= sec_serv_conf; | 213 sec_servs |= sec_serv_conf; |
| 200 break; | 214 break; |
| 215 case 't': |
| 216 tag_size = atoi(optarg_s); |
| 217 if (tag_size != 8 && tag_size != 16) { |
| 218 printf("error: GCM tag size must be 8 or 16 (%d)\n", tag_size); |
| 219 exit(1); |
| 220 } |
| 221 break; |
| 201 case 'a': | 222 case 'a': |
| 202 sec_servs |= sec_serv_auth; | 223 sec_servs |= sec_serv_auth; |
| 203 break; | 224 break; |
| 225 case 'g': |
| 226 gcm_on = 1; |
| 227 sec_servs |= sec_serv_auth; |
| 228 break; |
| 204 case 'r': | 229 case 'r': |
| 205 prog_type = receiver; | 230 prog_type = receiver; |
| 206 break; | 231 break; |
| 207 case 's': | 232 case 's': |
| 208 prog_type = sender; | 233 prog_type = sender; |
| 209 break; | 234 break; |
| 210 case 'd': | 235 case 'd': |
| 211 status = crypto_kernel_set_debug_module(optarg_s, 1); | 236 status = crypto_kernel_set_debug_module(optarg_s, 1); |
| 212 if (status) { | 237 if (status) { |
| 213 printf("error: set debug module (%s) failed\n", optarg_s); | 238 printf("error: set debug module (%s) failed\n", optarg_s); |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 324 | 349 |
| 325 /* set up the srtp policy and master key */ | 350 /* set up the srtp policy and master key */ |
| 326 if (sec_servs) { | 351 if (sec_servs) { |
| 327 /* | 352 /* |
| 328 * create policy structure, using the default mechanisms but | 353 * create policy structure, using the default mechanisms but |
| 329 * with only the security services requested on the command line, | 354 * with only the security services requested on the command line, |
| 330 * using the right SSRC value | 355 * using the right SSRC value |
| 331 */ | 356 */ |
| 332 switch (sec_servs) { | 357 switch (sec_servs) { |
| 333 case sec_serv_conf_and_auth: | 358 case sec_serv_conf_and_auth: |
| 334 crypto_policy_set_rtp_default(&policy.rtp); | 359 if (gcm_on) { |
| 335 crypto_policy_set_rtcp_default(&policy.rtcp); | 360 #ifdef OPENSSL |
| 361 » switch (key_size) { |
| 362 » case 128: |
| 363 » crypto_policy_set_aes_gcm_128_8_auth(&policy.rtp); |
| 364 » crypto_policy_set_aes_gcm_128_8_auth(&policy.rtcp); |
| 365 » break; |
| 366 » case 256: |
| 367 » crypto_policy_set_aes_gcm_256_8_auth(&policy.rtp); |
| 368 » crypto_policy_set_aes_gcm_256_8_auth(&policy.rtcp); |
| 369 » break; |
| 370 » } |
| 371 #else |
| 372 » printf("error: GCM mode only supported when using the OpenSSL crypto eng
ine.\n"); |
| 373 » return 0; |
| 374 #endif |
| 375 } else { |
| 376 » switch (key_size) { |
| 377 » case 128: |
| 378 crypto_policy_set_rtp_default(&policy.rtp); |
| 379 crypto_policy_set_rtcp_default(&policy.rtcp); |
| 380 » break; |
| 381 » case 256: |
| 382 crypto_policy_set_aes_cm_256_hmac_sha1_80(&policy.rtp); |
| 383 crypto_policy_set_rtcp_default(&policy.rtcp); |
| 384 » break; |
| 385 » } |
| 386 } |
| 336 break; | 387 break; |
| 337 case sec_serv_conf: | 388 case sec_serv_conf: |
| 338 crypto_policy_set_aes_cm_128_null_auth(&policy.rtp); | 389 if (gcm_on) { |
| 339 crypto_policy_set_rtcp_default(&policy.rtcp); | 390 » printf("error: GCM mode must always be used with auth enabled\n"); |
| 391 » return -1; |
| 392 } else { |
| 393 » switch (key_size) { |
| 394 » case 128: |
| 395 crypto_policy_set_aes_cm_128_null_auth(&policy.rtp); |
| 396 crypto_policy_set_rtcp_default(&policy.rtcp); |
| 397 » break; |
| 398 » case 256: |
| 399 crypto_policy_set_aes_cm_256_null_auth(&policy.rtp); |
| 400 crypto_policy_set_rtcp_default(&policy.rtcp); |
| 401 » break; |
| 402 » } |
| 403 } |
| 340 break; | 404 break; |
| 341 case sec_serv_auth: | 405 case sec_serv_auth: |
| 342 crypto_policy_set_null_cipher_hmac_sha1_80(&policy.rtp); | 406 if (gcm_on) { |
| 343 crypto_policy_set_rtcp_default(&policy.rtcp); | 407 #ifdef OPENSSL |
| 408 » switch (key_size) { |
| 409 » case 128: |
| 410 » crypto_policy_set_aes_gcm_128_8_only_auth(&policy.rtp); |
| 411 » crypto_policy_set_aes_gcm_128_8_only_auth(&policy.rtcp); |
| 412 » break; |
| 413 » case 256: |
| 414 » crypto_policy_set_aes_gcm_256_8_only_auth(&policy.rtp); |
| 415 » crypto_policy_set_aes_gcm_256_8_only_auth(&policy.rtcp); |
| 416 » break; |
| 417 » } |
| 418 #else |
| 419 » printf("error: GCM mode only supported when using the OpenSSL crypto eng
ine.\n"); |
| 420 » return 0; |
| 421 #endif |
| 422 } else { |
| 423 crypto_policy_set_null_cipher_hmac_sha1_80(&policy.rtp); |
| 424 crypto_policy_set_rtcp_default(&policy.rtcp); |
| 425 } |
| 344 break; | 426 break; |
| 345 default: | 427 default: |
| 346 printf("error: unknown security service requested\n"); | 428 printf("error: unknown security service requested\n"); |
| 347 return -1; | 429 return -1; |
| 348 } | 430 } |
| 349 policy.ssrc.type = ssrc_specific; | 431 policy.ssrc.type = ssrc_specific; |
| 350 policy.ssrc.value = ssrc; | 432 policy.ssrc.value = ssrc; |
| 351 policy.key = (uint8_t *) key; | 433 policy.key = (uint8_t *) key; |
| 352 policy.ekt = NULL; | 434 policy.ekt = NULL; |
| 353 policy.next = NULL; | 435 policy.next = NULL; |
| 354 policy.window_size = 128; | 436 policy.window_size = 128; |
| 355 policy.allow_repeat_tx = 0; | 437 policy.allow_repeat_tx = 0; |
| 356 policy.rtp.sec_serv = sec_servs; | 438 policy.rtp.sec_serv = sec_servs; |
| 357 policy.rtcp.sec_serv = sec_serv_none; /* we don't do RTCP anyway */ | 439 policy.rtcp.sec_serv = sec_serv_none; /* we don't do RTCP anyway */ |
| 358 | 440 |
| 441 if (gcm_on && tag_size != 8) { |
| 442 policy.rtp.auth_tag_len = tag_size; |
| 443 } |
| 444 |
| 359 /* | 445 /* |
| 360 * read key from hexadecimal on command line into an octet string | 446 * read key from hexadecimal on command line into an octet string |
| 361 */ | 447 */ |
| 362 len = hex_string_to_octet_string(key, input_key, MASTER_KEY_LEN*2); | 448 len = hex_string_to_octet_string(key, input_key, policy.rtp.cipher_key_len*2
); |
| 363 | 449 |
| 364 /* check that hex string is the right length */ | 450 /* check that hex string is the right length */ |
| 365 if (len < MASTER_KEY_LEN*2) { | 451 if (len < policy.rtp.cipher_key_len*2) { |
| 366 fprintf(stderr, | 452 fprintf(stderr, |
| 367 "error: too few digits in key/salt " | 453 "error: too few digits in key/salt " |
| 368 "(should be %d hexadecimal digits, found %d)\n", | 454 "(should be %d hexadecimal digits, found %d)\n", |
| 369 » MASTER_KEY_LEN*2, len); | 455 » policy.rtp.cipher_key_len*2, len); |
| 370 exit(1); | 456 exit(1); |
| 371 } | 457 } |
| 372 if (strlen(input_key) > MASTER_KEY_LEN*2) { | 458 if (strlen(input_key) > policy.rtp.cipher_key_len*2) { |
| 373 fprintf(stderr, | 459 fprintf(stderr, |
| 374 "error: too many digits in key/salt " | 460 "error: too many digits in key/salt " |
| 375 "(should be %d hexadecimal digits, found %u)\n", | 461 "(should be %d hexadecimal digits, found %u)\n", |
| 376 » MASTER_KEY_LEN*2, (unsigned)strlen(input_key)); | 462 » policy.rtp.cipher_key_len*2, (unsigned)strlen(input_key)); |
| 377 exit(1); | 463 exit(1); |
| 378 } | 464 } |
| 379 | 465 |
| 380 printf("set master key/salt to %s/", octet_string_hex_string(key, 16)); | 466 printf("set master key/salt to %s/", octet_string_hex_string(key, 16)); |
| 381 printf("%s\n", octet_string_hex_string(key+16, 14)); | 467 printf("%s\n", octet_string_hex_string(key+16, 14)); |
| 382 | 468 |
| 383 } else { | 469 } else { |
| 384 /* | 470 /* |
| 385 * we're not providing security services, so set the policy to the | 471 * we're not providing security services, so set the policy to the |
| 386 * null policy | 472 * null policy |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 534 } | 620 } |
| 535 | 621 |
| 536 | 622 |
| 537 void | 623 void |
| 538 usage(char *string) { | 624 usage(char *string) { |
| 539 | 625 |
| 540 printf("usage: %s [-d <debug>]* [-k <key> [-a][-e]] " | 626 printf("usage: %s [-d <debug>]* [-k <key> [-a][-e]] " |
| 541 "[-s | -r] dest_ip dest_port\n" | 627 "[-s | -r] dest_ip dest_port\n" |
| 542 "or %s -l\n" | 628 "or %s -l\n" |
| 543 "where -a use message authentication\n" | 629 "where -a use message authentication\n" |
| 544 » " -e use encryption\n" | 630 » " -e <key size> use encryption (use 128 or 256 for key size)\n" |
| 631 » " -g Use AES-GCM mode (must be used with -e)\n" |
| 632 » " -t <tag size> Tag size to use in GCM mode (use 8 or 16)\n" |
| 545 " -k <key> sets the srtp master key\n" | 633 " -k <key> sets the srtp master key\n" |
| 546 " -s act as rtp sender\n" | 634 " -s act as rtp sender\n" |
| 547 " -r act as rtp receiver\n" | 635 " -r act as rtp receiver\n" |
| 548 " -l list debug modules\n" | 636 " -l list debug modules\n" |
| 549 " -d <debug> turn on debugging for module <debug>\n", | 637 " -d <debug> turn on debugging for module <debug>\n", |
| 550 string, string); | 638 string, string); |
| 551 exit(1); | 639 exit(1); |
| 552 | 640 |
| 553 } | 641 } |
| 554 | 642 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 596 } | 684 } |
| 597 #else | 685 #else |
| 598 if (signal(SIGTERM, handle_signal) == SIG_ERR) { | 686 if (signal(SIGTERM, handle_signal) == SIG_ERR) { |
| 599 fprintf(stderr, "%s: error setting up signal handler", name); | 687 fprintf(stderr, "%s: error setting up signal handler", name); |
| 600 perror(""); | 688 perror(""); |
| 601 return -1; | 689 return -1; |
| 602 } | 690 } |
| 603 #endif | 691 #endif |
| 604 return 0; | 692 return 0; |
| 605 } | 693 } |
| OLD | NEW |