Index: srtp/test/rtpw.c |
diff --git a/srtp/test/rtpw.c b/srtp/test/rtpw.c |
index f18d42045e0e4eac7c1d17afb6acbb773b9d80fc..48c664948d31ae8a213d5b575fa7779bc99c8b92 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,6 +157,9 @@ 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; |
char *address = NULL; |
char key[MAX_KEY_LEN]; |
@@ -174,6 +181,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,7 +196,7 @@ main (int argc, char *argv[]) { |
/* check args */ |
while (1) { |
- c = getopt_s(argc, argv, "k:rsaeld:"); |
+ c = getopt_s(argc, argv, "k:rsgt:ae:ld:"); |
if (c == -1) { |
break; |
} |
@@ -196,11 +205,27 @@ main (int argc, char *argv[]) { |
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 +356,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 +438,28 @@ 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 |
*/ |
- len = hex_string_to_octet_string(key, input_key, MASTER_KEY_LEN*2); |
+ len = hex_string_to_octet_string(key, input_key, policy.rtp.cipher_key_len*2); |
/* check that hex string is the right length */ |
- if (len < MASTER_KEY_LEN*2) { |
+ if (len < policy.rtp.cipher_key_len*2) { |
fprintf(stderr, |
"error: too few digits in key/salt " |
"(should be %d hexadecimal digits, found %d)\n", |
- MASTER_KEY_LEN*2, len); |
+ policy.rtp.cipher_key_len*2, 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,7 +627,9 @@ usage(char *string) { |
"[-s | -r] dest_ip dest_port\n" |
"or %s -l\n" |
"where -a use message authentication\n" |
- " -e use encryption\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\n" |
" -s act as rtp sender\n" |
" -r act as rtp receiver\n" |