| Index: srtp/test/rtpw.c
|
| diff --git a/srtp/test/rtpw.c b/srtp/test/rtpw.c
|
| index f18d42045e0e4eac7c1d17afb6acbb773b9d80fc..17f27f278136bfb72c451b182878f75a6f8c9421 100644
|
| --- a/srtp/test/rtpw.c
|
| +++ b/srtp/test/rtpw.c
|
| @@ -51,6 +51,10 @@
|
| */
|
|
|
|
|
| +#ifdef HAVE_CONFIG_H
|
| + #include <config.h>
|
| +#endif
|
| +
|
| #include "datatypes.h"
|
| #include "getopt_s.h" /* for local getopt() */
|
|
|
| @@ -81,6 +85,7 @@
|
|
|
| #include "srtp.h"
|
| #include "rtp.h"
|
| +#include "crypto_kernel.h"
|
|
|
| #ifdef RTPW_USE_WINSOCK2
|
| # define DICT_FILE "words.txt"
|
| @@ -90,8 +95,7 @@
|
| #define USEC_RATE (5e5)
|
| #define MAX_WORD_LEN 128
|
| #define ADDR_IS_MULTICAST(a) IN_MULTICAST(htonl(a))
|
| -#define MAX_KEY_LEN 64
|
| -#define MASTER_KEY_LEN 30
|
| +#define MAX_KEY_LEN 96
|
|
|
|
|
| #ifndef HAVE_USLEEP
|
| @@ -153,7 +157,11 @@ main (int argc, char *argv[]) {
|
| sec_serv_t sec_servs = sec_serv_none;
|
| unsigned char ttl = 5;
|
| int c;
|
| + int key_size = 128;
|
| + int tag_size = 8;
|
| + int gcm_on = 0;
|
| char *input_key = NULL;
|
| + int b64_input = 0;
|
| char *address = NULL;
|
| char key[MAX_KEY_LEN];
|
| unsigned short port = 0;
|
| @@ -161,6 +169,7 @@ main (int argc, char *argv[]) {
|
| srtp_policy_t policy;
|
| err_status_t status;
|
| int len;
|
| + int expected_len;
|
| int do_list_mods = 0;
|
| uint32_t ssrc = 0xdeadbeef; /* ssrc value hardcoded for now */
|
| #ifdef RTPW_USE_WINSOCK2
|
| @@ -174,6 +183,8 @@ main (int argc, char *argv[]) {
|
| }
|
| #endif
|
|
|
| + printf("Using %s [0x%x]\n", srtp_get_version_string(), srtp_get_version());
|
| +
|
| if (setup_signal_handler(argv[0]) != 0) {
|
| exit(1);
|
| }
|
| @@ -187,20 +198,39 @@ main (int argc, char *argv[]) {
|
|
|
| /* check args */
|
| while (1) {
|
| - c = getopt_s(argc, argv, "k:rsaeld:");
|
| + c = getopt_s(argc, argv, "b:k:rsgt:ae:ld:");
|
| if (c == -1) {
|
| break;
|
| }
|
| switch (c) {
|
| + case 'b':
|
| + b64_input = 1;
|
| + /* fall thru */
|
| case 'k':
|
| input_key = optarg_s;
|
| break;
|
| case 'e':
|
| + key_size = atoi(optarg_s);
|
| + if (key_size != 128 && key_size != 256) {
|
| + printf("error: encryption key size must be 128 or 256 (%d)\n", key_size);
|
| + exit(1);
|
| + }
|
| sec_servs |= sec_serv_conf;
|
| break;
|
| + case 't':
|
| + tag_size = atoi(optarg_s);
|
| + if (tag_size != 8 && tag_size != 16) {
|
| + printf("error: GCM tag size must be 8 or 16 (%d)\n", tag_size);
|
| + exit(1);
|
| + }
|
| + break;
|
| case 'a':
|
| sec_servs |= sec_serv_auth;
|
| break;
|
| + case 'g':
|
| + gcm_on = 1;
|
| + sec_servs |= sec_serv_auth;
|
| + break;
|
| case 'r':
|
| prog_type = receiver;
|
| break;
|
| @@ -331,16 +361,73 @@ main (int argc, char *argv[]) {
|
| */
|
| switch (sec_servs) {
|
| case sec_serv_conf_and_auth:
|
| - crypto_policy_set_rtp_default(&policy.rtp);
|
| - crypto_policy_set_rtcp_default(&policy.rtcp);
|
| + if (gcm_on) {
|
| +#ifdef OPENSSL
|
| + switch (key_size) {
|
| + case 128:
|
| + crypto_policy_set_aes_gcm_128_8_auth(&policy.rtp);
|
| + crypto_policy_set_aes_gcm_128_8_auth(&policy.rtcp);
|
| + break;
|
| + case 256:
|
| + crypto_policy_set_aes_gcm_256_8_auth(&policy.rtp);
|
| + crypto_policy_set_aes_gcm_256_8_auth(&policy.rtcp);
|
| + break;
|
| + }
|
| +#else
|
| + printf("error: GCM mode only supported when using the OpenSSL crypto engine.\n");
|
| + return 0;
|
| +#endif
|
| + } else {
|
| + switch (key_size) {
|
| + case 128:
|
| + crypto_policy_set_rtp_default(&policy.rtp);
|
| + crypto_policy_set_rtcp_default(&policy.rtcp);
|
| + break;
|
| + case 256:
|
| + crypto_policy_set_aes_cm_256_hmac_sha1_80(&policy.rtp);
|
| + crypto_policy_set_rtcp_default(&policy.rtcp);
|
| + break;
|
| + }
|
| + }
|
| break;
|
| case sec_serv_conf:
|
| - crypto_policy_set_aes_cm_128_null_auth(&policy.rtp);
|
| - crypto_policy_set_rtcp_default(&policy.rtcp);
|
| + if (gcm_on) {
|
| + printf("error: GCM mode must always be used with auth enabled\n");
|
| + return -1;
|
| + } else {
|
| + switch (key_size) {
|
| + case 128:
|
| + crypto_policy_set_aes_cm_128_null_auth(&policy.rtp);
|
| + crypto_policy_set_rtcp_default(&policy.rtcp);
|
| + break;
|
| + case 256:
|
| + crypto_policy_set_aes_cm_256_null_auth(&policy.rtp);
|
| + crypto_policy_set_rtcp_default(&policy.rtcp);
|
| + break;
|
| + }
|
| + }
|
| break;
|
| case sec_serv_auth:
|
| - crypto_policy_set_null_cipher_hmac_sha1_80(&policy.rtp);
|
| - crypto_policy_set_rtcp_default(&policy.rtcp);
|
| + if (gcm_on) {
|
| +#ifdef OPENSSL
|
| + switch (key_size) {
|
| + case 128:
|
| + crypto_policy_set_aes_gcm_128_8_only_auth(&policy.rtp);
|
| + crypto_policy_set_aes_gcm_128_8_only_auth(&policy.rtcp);
|
| + break;
|
| + case 256:
|
| + crypto_policy_set_aes_gcm_256_8_only_auth(&policy.rtp);
|
| + crypto_policy_set_aes_gcm_256_8_only_auth(&policy.rtcp);
|
| + break;
|
| + }
|
| +#else
|
| + printf("error: GCM mode only supported when using the OpenSSL crypto engine.\n");
|
| + return 0;
|
| +#endif
|
| + } else {
|
| + crypto_policy_set_null_cipher_hmac_sha1_80(&policy.rtp);
|
| + crypto_policy_set_rtcp_default(&policy.rtcp);
|
| + }
|
| break;
|
| default:
|
| printf("error: unknown security service requested\n");
|
| @@ -356,24 +443,38 @@ main (int argc, char *argv[]) {
|
| policy.rtp.sec_serv = sec_servs;
|
| policy.rtcp.sec_serv = sec_serv_none; /* we don't do RTCP anyway */
|
|
|
| + if (gcm_on && tag_size != 8) {
|
| + policy.rtp.auth_tag_len = tag_size;
|
| + }
|
| +
|
| /*
|
| - * read key from hexadecimal on command line into an octet string
|
| + * read key from hexadecimal or base64 on command line into an octet string
|
| */
|
| - len = hex_string_to_octet_string(key, input_key, MASTER_KEY_LEN*2);
|
| -
|
| + if (b64_input) {
|
| + int pad;
|
| + expected_len = (policy.rtp.cipher_key_len*4)/3;
|
| + len = base64_string_to_octet_string(key, &pad, input_key, expected_len);
|
| + if (pad != 0) {
|
| + fprintf(stderr, "error: padding in base64 unexpected\n");
|
| + exit(1);
|
| + }
|
| + } else {
|
| + expected_len = policy.rtp.cipher_key_len*2;
|
| + len = hex_string_to_octet_string(key, input_key, expected_len);
|
| + }
|
| /* check that hex string is the right length */
|
| - if (len < MASTER_KEY_LEN*2) {
|
| + if (len < expected_len) {
|
| fprintf(stderr,
|
| "error: too few digits in key/salt "
|
| - "(should be %d hexadecimal digits, found %d)\n",
|
| - MASTER_KEY_LEN*2, len);
|
| + "(should be %d digits, found %d)\n",
|
| + expected_len, len);
|
| exit(1);
|
| }
|
| - if (strlen(input_key) > MASTER_KEY_LEN*2) {
|
| + if (strlen(input_key) > policy.rtp.cipher_key_len*2) {
|
| fprintf(stderr,
|
| "error: too many digits in key/salt "
|
| "(should be %d hexadecimal digits, found %u)\n",
|
| - MASTER_KEY_LEN*2, (unsigned)strlen(input_key));
|
| + policy.rtp.cipher_key_len*2, (unsigned)strlen(input_key));
|
| exit(1);
|
| }
|
|
|
| @@ -541,8 +642,11 @@ usage(char *string) {
|
| "[-s | -r] dest_ip dest_port\n"
|
| "or %s -l\n"
|
| "where -a use message authentication\n"
|
| - " -e use encryption\n"
|
| - " -k <key> sets the srtp master key\n"
|
| + " -e <key size> use encryption (use 128 or 256 for key size)\n"
|
| + " -g Use AES-GCM mode (must be used with -e)\n"
|
| + " -t <tag size> Tag size to use in GCM mode (use 8 or 16)\n"
|
| + " -k <key> sets the srtp master key given in hexadecimal\n"
|
| + " -b <key> sets the srtp master key given in base64\n"
|
| " -s act as rtp sender\n"
|
| " -r act as rtp receiver\n"
|
| " -l list debug modules\n"
|
|
|