summaryrefslogtreecommitdiff
path: root/third_party/srtp/test
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/srtp/test')
-rw-r--r--third_party/srtp/test/dtls_srtp_driver.c22
-rw-r--r--third_party/srtp/test/lfsr.c35
-rw-r--r--third_party/srtp/test/rdbx_driver.c106
-rw-r--r--third_party/srtp/test/replay_driver.c58
-rw-r--r--third_party/srtp/test/roc_driver.c10
-rw-r--r--third_party/srtp/test/rtp.c76
-rw-r--r--third_party/srtp/test/rtp_decoder.c515
-rw-r--r--third_party/srtp/test/rtp_decoder.h119
-rw-r--r--third_party/srtp/test/rtpw.c243
-rw-r--r--third_party/srtp/test/rtpw_test.sh95
-rw-r--r--third_party/srtp/test/rtpw_test_gcm.sh237
-rw-r--r--third_party/srtp/test/srtp_driver.c479
12 files changed, 1907 insertions, 88 deletions
diff --git a/third_party/srtp/test/dtls_srtp_driver.c b/third_party/srtp/test/dtls_srtp_driver.c
index a8eddc08..48e72fbf 100644
--- a/third_party/srtp/test/dtls_srtp_driver.c
+++ b/third_party/srtp/test/dtls_srtp_driver.c
@@ -47,7 +47,7 @@
#include "srtp_priv.h"
err_status_t
-test_dtls_srtp();
+test_dtls_srtp(void);
srtp_hdr_t *
srtp_create_test_packet(int pkt_octet_len, uint32_t ssrc);
@@ -63,7 +63,7 @@ usage(char *prog_name) {
int
main(int argc, char *argv[]) {
unsigned do_list_mods = 0;
- char q;
+ int q;
err_status_t err;
printf("dtls_srtp_driver\n");
@@ -112,12 +112,19 @@ main(int argc, char *argv[]) {
}
printf("passed\n");
+ /* shut down srtp library */
+ err = srtp_shutdown();
+ if (err) {
+ printf("error: srtp shutdown failed with error code %d\n", err);
+ exit(1);
+ }
+
return 0;
}
err_status_t
-test_dtls_srtp() {
+test_dtls_srtp(void) {
srtp_hdr_t *test_packet;
int test_packet_len = 80;
srtp_t s;
@@ -183,12 +190,21 @@ test_dtls_srtp() {
err = crypto_policy_set_from_profile_for_rtcp(&policy.rtcp, profile);
if (err) return err;
policy.ssrc.type = ssrc_any_inbound;
+ policy.ekt = NULL;
+ policy.window_size = 128;
+ policy.allow_repeat_tx = 0;
policy.next = NULL;
err = srtp_add_stream(s, &policy);
if (err)
return err;
+ err = srtp_dealloc(s);
+ if (err)
+ return err;
+
+ free(test_packet);
+
return err_status_ok;
}
diff --git a/third_party/srtp/test/lfsr.c b/third_party/srtp/test/lfsr.c
index 28ea02eb..240590c5 100644
--- a/third_party/srtp/test/lfsr.c
+++ b/third_party/srtp/test/lfsr.c
@@ -3,6 +3,41 @@
*
*/
+/*
+ *
+ * Copyright (c) 2001-2006, Cisco Systems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * Neither the name of the Cisco Systems, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
#include <stdio.h>
#include "datatypes.h"
diff --git a/third_party/srtp/test/rdbx_driver.c b/third_party/srtp/test/rdbx_driver.c
index 7db67a2b..90bd72e7 100644
--- a/third_party/srtp/test/rdbx_driver.c
+++ b/third_party/srtp/test/rdbx_driver.c
@@ -43,6 +43,10 @@
*
*/
+#ifdef HAVE_CONFIG_H
+ #include <config.h>
+#endif
+
#include <stdio.h> /* for printf() */
#include "getopt_s.h" /* for local getopt() */
@@ -55,10 +59,10 @@
#include "ut_sim.h"
err_status_t
-test_replay_dbx(int num_trials);
+test_replay_dbx(int num_trials, unsigned long ws);
double
-rdbx_check_adds_per_second(int num_trials);
+rdbx_check_adds_per_second(int num_trials, unsigned long ws);
void
usage(char *prog_name) {
@@ -70,7 +74,7 @@ int
main (int argc, char *argv[]) {
double rate;
err_status_t status;
- char q;
+ int q;
unsigned do_timing_test = 0;
unsigned do_validation = 0;
@@ -99,9 +103,18 @@ main (int argc, char *argv[]) {
usage(argv[0]);
if (do_validation) {
- printf("testing rdbx_t...\n");
+ printf("testing rdbx_t (ws=128)...\n");
+
+ status = test_replay_dbx(1 << 12, 128);
+ if (status) {
+ printf("failed\n");
+ exit(1);
+ }
+ printf("passed\n");
- status = test_replay_dbx(1 << 12);
+ printf("testing rdbx_t (ws=1024)...\n");
+
+ status = test_replay_dbx(1 << 12, 1024);
if (status) {
printf("failed\n");
exit(1);
@@ -110,8 +123,10 @@ main (int argc, char *argv[]) {
}
if (do_timing_test) {
- rate = rdbx_check_adds_per_second(1 << 18);
- printf("rdbx_check/replay_adds per second: %e\n", rate);
+ rate = rdbx_check_adds_per_second(1 << 18, 128);
+ printf("rdbx_check/replay_adds per second (ws=128): %e\n", rate);
+ rate = rdbx_check_adds_per_second(1 << 18, 1024);
+ printf("rdbx_check/replay_adds per second (ws=1024): %e\n", rate);
}
return 0;
@@ -119,8 +134,11 @@ main (int argc, char *argv[]) {
void
print_rdbx(rdbx_t *rdbx) {
+ char buf[2048];
printf("rdbx: {%llu, %s}\n",
- (unsigned long long)(rdbx->index), v128_bit_string(&rdbx->bitmask));
+ (unsigned long long)(rdbx->index),
+ bitvector_bit_string(&rdbx->bitmask, buf, sizeof(buf))
+);
}
@@ -183,28 +201,38 @@ rdbx_check_expect_failure(rdbx_t *rdbx, uint32_t idx) {
}
err_status_t
-rdbx_check_unordered(rdbx_t *rdbx, uint32_t idx) {
+rdbx_check_add_unordered(rdbx_t *rdbx, uint32_t idx) {
+ int delta;
+ xtd_seq_num_t est;
err_status_t rstat;
- rstat = rdbx_check(rdbx, idx);
+ delta = index_guess(&rdbx->index, &est, idx);
+
+ rstat = rdbx_check(rdbx, delta);
if ((rstat != err_status_ok) && (rstat != err_status_replay_old)) {
- printf("replay_check_unordered failed at index %u\n", idx);
+ printf("replay_check_add_unordered failed at index %u\n", idx);
return err_status_algo_fail;
}
+ if (rstat == err_status_replay_old) {
+ return err_status_ok;
+ }
+ if (rdbx_add_index(rdbx, delta) != err_status_ok) {
+ printf("rdbx_add_index failed at index %u\n", idx);
+ return err_status_algo_fail;
+ }
+
return err_status_ok;
}
-#define MAX_IDX 160
-
err_status_t
-test_replay_dbx(int num_trials) {
+test_replay_dbx(int num_trials, unsigned long ws) {
rdbx_t rdbx;
uint32_t idx, ircvd;
ut_connection utc;
err_status_t status;
int num_fp_trials;
- status = rdbx_init(&rdbx);
+ status = rdbx_init(&rdbx, ws);
if (status) {
printf("replay_init failed with error code %d\n", status);
exit(1);
@@ -214,7 +242,7 @@ test_replay_dbx(int num_trials) {
* test sequential insertion
*/
printf("\ttesting sequential insertion...");
- for (idx=0; idx < num_trials; idx++) {
+ for (idx=0; (int) idx < num_trials; idx++) {
status = rdbx_check_add(&rdbx, idx);
if (status)
return status;
@@ -233,7 +261,7 @@ test_replay_dbx(int num_trials) {
printf("warning: no false positive tests performed\n");
}
printf("\ttesting for false positives...");
- for (idx=0; idx < num_fp_trials; idx++) {
+ for (idx=0; (int) idx < num_fp_trials; idx++) {
status = rdbx_check_expect_failure(&rdbx, idx);
if (status)
return status;
@@ -241,7 +269,9 @@ test_replay_dbx(int num_trials) {
printf("passed\n");
/* re-initialize */
- if (rdbx_init(&rdbx) != err_status_ok) {
+ rdbx_dealloc(&rdbx);
+
+ if (rdbx_init(&rdbx, ws) != err_status_ok) {
printf("replay_init failed\n");
return err_status_init_fail;
}
@@ -255,14 +285,42 @@ test_replay_dbx(int num_trials) {
ut_init(&utc);
printf("\ttesting non-sequential insertion...");
- for (idx=0; idx < num_trials; idx++) {
+ for (idx=0; (int) idx < num_trials; idx++) {
ircvd = ut_next_index(&utc);
- status = rdbx_check_unordered(&rdbx, ircvd);
+ status = rdbx_check_add_unordered(&rdbx, ircvd);
if (status)
return status;
+ status = rdbx_check_expect_failure(&rdbx, ircvd);
+ if (status)
+ return status;
}
printf("passed\n");
+ /* re-initialize */
+ rdbx_dealloc(&rdbx);
+
+ if (rdbx_init(&rdbx, ws) != err_status_ok) {
+ printf("replay_init failed\n");
+ return err_status_init_fail;
+ }
+
+ /*
+ * test insertion with large gaps.
+ * check for false positives for each insertion.
+ */
+ printf("\ttesting insertion with large gaps...");
+ for (idx=0, ircvd=0; (int) idx < num_trials; idx++, ircvd += (1 << (rand() % 12))) {
+ status = rdbx_check_add(&rdbx, ircvd);
+ if (status)
+ return status;
+ status = rdbx_check_expect_failure(&rdbx, ircvd);
+ if (status)
+ return status;
+ }
+ printf("passed\n");
+
+ rdbx_dealloc(&rdbx);
+
return err_status_ok;
}
@@ -272,7 +330,7 @@ test_replay_dbx(int num_trials) {
#include <stdlib.h> /* for random() */
double
-rdbx_check_adds_per_second(int num_trials) {
+rdbx_check_adds_per_second(int num_trials, unsigned long ws) {
uint32_t i;
int delta;
rdbx_t rdbx;
@@ -280,14 +338,14 @@ rdbx_check_adds_per_second(int num_trials) {
clock_t timer;
int failures; /* count number of failures */
- if (rdbx_init(&rdbx) != err_status_ok) {
+ if (rdbx_init(&rdbx, ws) != err_status_ok) {
printf("replay_init failed\n");
exit(1);
}
failures = 0;
timer = clock();
- for(i=0; i < num_trials; i++) {
+ for(i=0; (int) i < num_trials; i++) {
delta = index_guess(&rdbx.index, &est, i);
@@ -301,6 +359,8 @@ rdbx_check_adds_per_second(int num_trials) {
printf("number of failures: %d \n", failures);
+ rdbx_dealloc(&rdbx);
+
return (double) CLOCKS_PER_SEC * num_trials / timer;
}
diff --git a/third_party/srtp/test/replay_driver.c b/third_party/srtp/test/replay_driver.c
index 369a77a4..e4d17015 100644
--- a/third_party/srtp/test/replay_driver.c
+++ b/third_party/srtp/test/replay_driver.c
@@ -43,6 +43,10 @@
*
*/
+#ifdef HAVE_CONFIG_H
+ #include <config.h>
+#endif
+
#include <stdio.h>
#include "rdb.h"
@@ -114,15 +118,23 @@ rdb_check_expect_failure(rdb_t *rdb, uint32_t idx) {
}
err_status_t
-rdb_check_unordered(rdb_t *rdb, uint32_t idx) {
+rdb_check_add_unordered(rdb_t *rdb, uint32_t idx) {
err_status_t rstat;
/* printf("index: %u\n", idx); */
rstat = rdb_check(rdb, idx);
if ((rstat != err_status_ok) && (rstat != err_status_replay_old)) {
- printf("rdb_check_unordered failed at index %u\n", idx);
+ printf("rdb_check_add_unordered failed at index %u\n", idx);
return rstat;
}
+ if (rstat == err_status_replay_old) {
+ return err_status_ok;
+ }
+ if (rdb_add_index(rdb, idx) != err_status_ok) {
+ printf("rdb_add_index failed at index %u\n", idx);
+ return err_status_fail;
+ }
+
return err_status_ok;
}
@@ -163,11 +175,51 @@ test_rdb_db() {
for (idx=0; idx < num_trials; idx++) {
ircvd = ut_next_index(&utc);
- err = rdb_check_unordered(&rdb, ircvd);
+ err = rdb_check_add_unordered(&rdb, ircvd);
if (err)
return err;
+ err = rdb_check_expect_failure(&rdb, ircvd);
+ if (err)
+ return err;
+ }
+
+ /* re-initialize */
+ if (rdb_init(&rdb) != err_status_ok) {
+ printf("rdb_init failed\n");
+ return err_status_fail;
+ }
+
+ /* test insertion with large gaps */
+ for (idx=0, ircvd=0; idx < num_trials; idx++, ircvd += (1 << (rand() % 10))) {
+ err = rdb_check_add(&rdb, ircvd);
+ if (err)
+ return err;
+ err = rdb_check_expect_failure(&rdb, ircvd);
+ if (err)
+ return err;
}
+ /* re-initialize */
+ if (rdb_init(&rdb) != err_status_ok) {
+ printf("rdb_init failed\n");
+ return err_status_fail;
+ }
+
+ /* test loss of first 513 packets */
+ for (idx=0; idx < num_trials; idx++) {
+ err = rdb_check_add(&rdb, idx + 513);
+ if (err)
+ return err;
+ }
+
+ /* test for false positives */
+ for (idx=0; idx < num_trials + 513; idx++) {
+ err = rdb_check_expect_failure(&rdb, idx);
+ if (err)
+ return err;
+ }
+
+
return err_status_ok;
}
diff --git a/third_party/srtp/test/roc_driver.c b/third_party/srtp/test/roc_driver.c
index 396c9a79..6fdc6f19 100644
--- a/third_party/srtp/test/roc_driver.c
+++ b/third_party/srtp/test/roc_driver.c
@@ -44,6 +44,10 @@
*/
+#ifdef HAVE_CONFIG_H
+ #include <config.h>
+#endif
+
#include <stdio.h>
/*
@@ -138,6 +142,12 @@ roc_test(int num_trials) {
ref, local, est, ircvd, delta);
#endif
+ if (local + delta != est) {
+ printf(" *bad delta*: local %llu + delta %d != est %llu\n",
+ (unsigned long long)local, delta, (unsigned long long)est);
+ return err_status_algo_fail;
+ }
+
/* now update local xtd_seq_num_t as necessary */
if (delta > 0)
index_advance(&local, delta);
diff --git a/third_party/srtp/test/rtp.c b/third_party/srtp/test/rtp.c
index 69968f3f..20c50f46 100644
--- a/third_party/srtp/test/rtp.c
+++ b/third_party/srtp/test/rtp.c
@@ -7,6 +7,41 @@
* Cisco Systems, Inc.
*/
+/*
+ *
+ * Copyright (c) 2001-2006, Cisco Systems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * Neither the name of the Cisco Systems, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
#include "rtp_priv.h"
@@ -21,7 +56,7 @@
#define PRINT_DEBUG 0 /* set to 1 to print out debugging data */
#define VERBOSE_DEBUG 0 /* set to 1 to print out more data */
-unsigned int
+int
rtp_sendto(rtp_sender_t sender, const void* msg, int len) {
int octets_sent;
err_status_t stat;
@@ -61,7 +96,7 @@ rtp_sendto(rtp_sender_t sender, const void* msg, int len) {
return octets_sent;
}
-unsigned int
+int
rtp_recvfrom(rtp_receiver_t receiver, void *msg, int *len) {
int octets_recvd;
err_status_t stat;
@@ -69,6 +104,11 @@ rtp_recvfrom(rtp_receiver_t receiver, void *msg, int *len) {
octets_recvd = recvfrom(receiver->socket, (void *)&receiver->message,
*len, 0, (struct sockaddr *) NULL, 0);
+ if (octets_recvd == -1) {
+ *len = 0;
+ return -1;
+ }
+
/* verify rtp header */
if (receiver->message.header.version != 2) {
*len = 0;
@@ -100,7 +140,7 @@ rtp_recvfrom(rtp_receiver_t receiver, void *msg, int *len) {
int
rtp_sender_init(rtp_sender_t sender,
- int socket,
+ int sock,
struct sockaddr_in addr,
unsigned int ssrc) {
@@ -116,7 +156,7 @@ rtp_sender_init(rtp_sender_t sender,
sender->message.header.cc = 0;
/* set other stuff */
- sender->socket = socket;
+ sender->socket = sock;
sender->addr = addr;
return 0;
@@ -124,7 +164,7 @@ rtp_sender_init(rtp_sender_t sender,
int
rtp_receiver_init(rtp_receiver_t rcvr,
- int socket,
+ int sock,
struct sockaddr_in addr,
unsigned int ssrc) {
@@ -140,7 +180,7 @@ rtp_receiver_init(rtp_receiver_t rcvr,
rcvr->message.header.cc = 0;
/* set other stuff */
- rcvr->socket = socket;
+ rcvr->socket = sock;
rcvr->addr = addr;
return 0;
@@ -152,16 +192,36 @@ rtp_sender_init_srtp(rtp_sender_t sender, const srtp_policy_t *policy) {
}
int
+rtp_sender_deinit_srtp(rtp_sender_t sender) {
+ return srtp_dealloc(sender->srtp_ctx);
+}
+
+int
rtp_receiver_init_srtp(rtp_receiver_t sender, const srtp_policy_t *policy) {
return srtp_create(&sender->srtp_ctx, policy);
}
+int
+rtp_receiver_deinit_srtp(rtp_receiver_t sender) {
+ return srtp_dealloc(sender->srtp_ctx);
+}
+
rtp_sender_t
-rtp_sender_alloc() {
+rtp_sender_alloc(void) {
return (rtp_sender_t)malloc(sizeof(rtp_sender_ctx_t));
}
+void
+rtp_sender_dealloc(rtp_sender_t rtp_ctx) {
+ free(rtp_ctx);
+}
+
rtp_receiver_t
-rtp_receiver_alloc() {
+rtp_receiver_alloc(void) {
return (rtp_receiver_t)malloc(sizeof(rtp_receiver_ctx_t));
}
+
+void
+rtp_receiver_dealloc(rtp_receiver_t rtp_ctx) {
+ free(rtp_ctx);
+}
diff --git a/third_party/srtp/test/rtp_decoder.c b/third_party/srtp/test/rtp_decoder.c
new file mode 100644
index 00000000..57e2d331
--- /dev/null
+++ b/third_party/srtp/test/rtp_decoder.c
@@ -0,0 +1,515 @@
+/*
+ * rtp_decoder.c
+ *
+ * decoder structures and functions for SRTP pcap decoder
+ *
+ * Example:
+ * $ wget --no-check-certificate https://raw.githubusercontent.com/gteissier/srtp-decrypt/master/marseillaise-srtp.pcap
+ * $ ./test/rtp_decoder -a -t 0 -e 128 -b aSBrbm93IGFsbCB5b3VyIGxpdHRsZSBzZWNyZXRz \
+ * < ~/marseillaise-srtp.pcap | text2pcap -t "%M:%S." -u 10000,10000 - - > ./marseillaise-rtp.pcap
+ *
+ * Bernardo Torres <bernardo@torresautomacao.com.br>
+ *
+ * Some structure and code from https://github.com/gteissier/srtp-decrypt
+ */
+/*
+ *
+ * Copyright (c) 2001-2006 Cisco Systems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * Neither the name of the Cisco Systems, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "getopt_s.h" /* for local getopt() */
+#include <assert.h> /* for assert() */
+
+#include <pcap.h>
+#include "rtp_decoder.h"
+
+#define MAX_KEY_LEN 96
+#define MAX_FILTER 256
+
+int
+main (int argc, char *argv[]) {
+ char errbuf[PCAP_ERRBUF_SIZE];
+ bpf_u_int32 pcap_net = 0;
+ pcap_t *pcap_handle;
+#if BEW
+ struct sockaddr_in local;
+#endif
+ sec_serv_t sec_servs = sec_serv_none;
+ int c;
+ int key_size = 128;
+ int tag_size = 8;
+ int gcm_on = 0;
+ char *input_key = NULL;
+ int b64_input = 0;
+ char key[MAX_KEY_LEN];
+ struct bpf_program fp;
+ char filter_exp[MAX_FILTER] = "";
+ rtp_decoder_t dec;
+ srtp_policy_t policy;
+ err_status_t status;
+ int len;
+ int expected_len;
+ int do_list_mods = 0;
+
+ fprintf(stderr, "Using %s [0x%x]\n", srtp_get_version_string(), srtp_get_version());
+
+ /* initialize srtp library */
+ status = srtp_init();
+ if (status) {
+ fprintf(stderr, "error: srtp initialization failed with error code %d\n", status);
+ exit(1);
+ }
+
+ /* check args */
+ while (1) {
+ c = getopt_s(argc, argv, "b:k:gt:ae:ld:f:");
+ 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) {
+ fprintf(stderr, "error: encryption key size must be 128 or 256 (%d)\n", key_size);
+ exit(1);
+ }
+ input_key = malloc(key_size);
+ sec_servs |= sec_serv_conf;
+ break;
+ case 't':
+ tag_size = atoi(optarg_s);
+ if (tag_size != 8 && tag_size != 16) {
+ fprintf(stderr, "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 'd':
+ status = crypto_kernel_set_debug_module(optarg_s, 1);
+ if (status) {
+ fprintf(stderr, "error: set debug module (%s) failed\n", optarg_s);
+ exit(1);
+ }
+ break;
+ case 'f':
+ if(strlen(optarg_s) > MAX_FILTER){
+ fprintf(stderr, "error: filter bigger than %d characters\n", MAX_FILTER);
+ exit(1);
+ }
+ fprintf(stderr, "Setting filter as %s\n", optarg_s);
+ strcpy(filter_exp, optarg_s);
+ break;
+ case 'l':
+ do_list_mods = 1;
+ break;
+ default:
+ usage(argv[0]);
+ }
+ }
+
+ if (do_list_mods) {
+ status = crypto_kernel_list_debug_modules();
+ if (status) {
+ fprintf(stderr, "error: list of debug modules failed\n");
+ exit(1);
+ }
+ return 0;
+ }
+
+ if ((sec_servs && !input_key) || (!sec_servs && input_key)) {
+ /*
+ * a key must be provided if and only if security services have
+ * been requested
+ */
+ if(input_key == NULL){
+ fprintf(stderr, "key not provided\n");
+ }
+ if(!sec_servs){
+ fprintf(stderr, "no secservs\n");
+ }
+ fprintf(stderr, "provided\n");
+ usage(argv[0]);
+ }
+
+
+
+ /* report security services selected on the command line */
+ fprintf(stderr, "security services: ");
+ if (sec_servs & sec_serv_conf)
+ fprintf(stderr, "confidentiality ");
+ if (sec_servs & sec_serv_auth)
+ fprintf(stderr, "message authentication");
+ if (sec_servs == sec_serv_none)
+ fprintf(stderr, "none");
+ fprintf(stderr, "\n");
+
+ /* set up the srtp policy and master key */
+ if (sec_servs) {
+ /*
+ * create policy structure, using the default mechanisms but
+ * with only the security services requested on the command line,
+ * using the right SSRC value
+ */
+ switch (sec_servs) {
+ case sec_serv_conf_and_auth:
+ 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
+ fprintf(stderr, "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:
+ if (gcm_on) {
+ fprintf(stderr, "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:
+ 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:
+ fprintf(stderr, "error: unknown security service requested\n");
+ return -1;
+ }
+
+ policy.key = (uint8_t *) key;
+ policy.ekt = NULL;
+ policy.next = NULL;
+ policy.window_size = 128;
+ policy.allow_repeat_tx = 0;
+ policy.rtp.sec_serv = sec_servs;
+ policy.rtcp.sec_serv = sec_servs; //sec_serv_none; /* we don't do RTCP anyway */
+ fprintf(stderr, "setting tag len %d\n", tag_size);
+policy.rtp.auth_tag_len = tag_size;
+
+ if (gcm_on && tag_size != 8) {
+ fprintf(stderr, "setted tag len %d\n", tag_size);
+ policy.rtp.auth_tag_len = tag_size;
+ }
+
+ /*
+ * read key from hexadecimal or base64 on command line into an octet string
+ */
+ 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 < expected_len) {
+ fprintf(stderr,
+ "error: too few digits in key/salt "
+ "(should be %d digits, found %d)\n",
+ expected_len, len);
+ exit(1);
+ }
+ 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",
+ policy.rtp.cipher_key_len*2, (unsigned)strlen(input_key));
+ exit(1);
+ }
+
+ fprintf(stderr, "set master key/salt to %s/", octet_string_hex_string(key, 16));
+ fprintf(stderr, "%s\n", octet_string_hex_string(key+16, 14));
+
+ } else {
+ /*
+ * we're not providing security services, so set the policy to the
+ * null policy
+ *
+ * Note that this policy does not conform to the SRTP
+ * specification, since RTCP authentication is required. However,
+ * the effect of this policy is to turn off SRTP, so that this
+ * application is now a vanilla-flavored RTP application.
+ */
+ policy.key = (uint8_t *)key;
+ policy.ssrc.type = ssrc_specific;
+ policy.rtp.cipher_type = NULL_CIPHER;
+ policy.rtp.cipher_key_len = 0;
+ policy.rtp.auth_type = NULL_AUTH;
+ policy.rtp.auth_key_len = 0;
+ policy.rtp.auth_tag_len = 0;
+ policy.rtp.sec_serv = sec_serv_none;
+ policy.rtcp.cipher_type = NULL_CIPHER;
+ policy.rtcp.cipher_key_len = 0;
+ policy.rtcp.auth_type = NULL_AUTH;
+ policy.rtcp.auth_key_len = 0;
+ policy.rtcp.auth_tag_len = 0;
+ policy.rtcp.sec_serv = sec_serv_none;
+ policy.window_size = 0;
+ policy.allow_repeat_tx = 0;
+ policy.ekt = NULL;
+ policy.next = NULL;
+ }
+
+ pcap_handle = pcap_open_offline("-", errbuf);
+
+ if (!pcap_handle) {
+ fprintf(stderr, "libpcap failed to open file '%s'\n", errbuf);
+ exit(1);
+ }
+ assert(pcap_handle != NULL);
+ if ((pcap_compile(pcap_handle, &fp, filter_exp, 1, pcap_net)) == -1){
+ fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp,
+ pcap_geterr(pcap_handle));
+ return (2);
+ }
+ if (pcap_setfilter(pcap_handle, &fp) == -1){
+ fprintf(stderr, "couldn't install filter %s: %s\n", filter_exp,
+ pcap_geterr(pcap_handle));
+ return (2);
+ }
+ dec = rtp_decoder_alloc();
+ if (dec == NULL) {
+ fprintf(stderr, "error: malloc() failed\n");
+ exit(1);
+ }
+ fprintf(stderr, "Starting decoder\n");
+ rtp_decoder_init(dec, policy);
+
+ pcap_loop(pcap_handle, 0, rtp_decoder_handle_pkt, (u_char *)dec);
+
+ rtp_decoder_deinit_srtp(dec);
+ rtp_decoder_dealloc(dec);
+
+ status = srtp_shutdown();
+ if (status) {
+ fprintf(stderr, "error: srtp shutdown failed with error code %d\n", status);
+ exit(1);
+ }
+
+ return 0;
+}
+
+
+void
+usage(char *string) {
+
+ fprintf(stderr, "usage: %s [-d <debug>]* [[-k][-b] <key> [-a][-e]]\n"
+ "or %s -l\n"
+ "where -a use message authentication\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"
+ " -l list debug modules\n"
+ " -f \"<pcap filter>\" to filter only the desired SRTP packets\n"
+ " -d <debug> turn on debugging for module <debug>\n",
+ string, string);
+ exit(1);
+
+}
+
+rtp_decoder_t
+rtp_decoder_alloc(void) {
+ return (rtp_decoder_t)malloc(sizeof(rtp_decoder_ctx_t));
+}
+
+void
+rtp_decoder_dealloc(rtp_decoder_t rtp_ctx) {
+ free(rtp_ctx);
+}
+
+err_status_t
+rtp_decoder_init_srtp(rtp_decoder_t decoder, unsigned int ssrc) {
+ decoder->policy.ssrc.value = htonl(ssrc);
+ return srtp_create(&decoder->srtp_ctx, &decoder->policy);
+}
+
+int
+rtp_decoder_deinit_srtp(rtp_decoder_t decoder) {
+ return srtp_dealloc(decoder->srtp_ctx);
+}
+
+int
+rtp_decoder_init(rtp_decoder_t dcdr, srtp_policy_t policy){
+ dcdr->rtp_offset = DEFAULT_RTP_OFFSET;
+ dcdr->srtp_ctx = NULL;
+ dcdr->start_tv.tv_usec = 0;
+ dcdr->start_tv.tv_sec = 0;
+ dcdr->frame_nr = -1;
+ dcdr->policy = policy;
+ dcdr->policy.ssrc.type = ssrc_specific;
+ return 0;
+}
+
+/*
+ * decodes key as base64
+ */
+
+void hexdump(const void *ptr, size_t size) {
+ int i, j;
+ const unsigned char *cptr = ptr;
+
+ for (i = 0; i < size; i += 16) {
+ fprintf(stdout, "%04x ", i);
+ for (j = 0; j < 16 && i+j < size; j++) {
+ fprintf(stdout, "%02x ", cptr[i+j]);
+ }
+ fprintf(stdout, "\n");
+ }
+}
+
+void
+rtp_decoder_handle_pkt(u_char *arg, const struct pcap_pkthdr *hdr,
+ const u_char *bytes){
+ rtp_decoder_t dcdr = (rtp_decoder_t)arg;
+ int pktsize;
+ struct timeval delta;
+ int octets_recvd;
+ err_status_t status;
+ dcdr->frame_nr++;
+
+ if (dcdr->start_tv.tv_sec == 0 && dcdr->start_tv.tv_sec == 0) {
+ dcdr->start_tv = hdr->ts;
+ }
+
+ if (hdr->caplen < dcdr->rtp_offset) {
+ return;
+ }
+ const void *rtp_packet = bytes + dcdr->rtp_offset;
+
+ memcpy((void *)&dcdr->message, rtp_packet, hdr->caplen - dcdr->rtp_offset);
+ pktsize = hdr->caplen - dcdr->rtp_offset;
+ octets_recvd = pktsize;
+
+ if (octets_recvd == -1) {
+ return;
+ }
+
+ /* verify rtp header */
+ if (dcdr->message.header.version != 2) {
+ return; //return -1;
+ }
+ if(dcdr->srtp_ctx == NULL){
+ status = rtp_decoder_init_srtp(dcdr, dcdr->message.header.ssrc);
+ if (status) {
+ exit(1);
+ }
+ }
+ if(dcdr->srtp_ctx != NULL){
+ }
+ status = srtp_unprotect(dcdr->srtp_ctx, &dcdr->message, &octets_recvd);
+ if (status){
+ return;
+ }
+ timersub(&hdr->ts, &dcdr->start_tv, &delta);
+ fprintf(stdout, "%02ld:%02ld.%06lu\n", delta.tv_sec/60, delta.tv_sec%60, delta.tv_usec);
+ hexdump(&dcdr->message, pktsize);
+}
+
+void rtp_print_error(err_status_t status, char *message){
+ fprintf(stderr,
+ "error: %s %d%s\n", message, status,
+ status == err_status_replay_fail ? " (replay check failed)" :
+ status == err_status_bad_param ? " (bad param)" :
+ status == err_status_no_ctx ? " (no context)" :
+ status == err_status_cipher_fail ? " (cipher failed)" :
+ status == err_status_key_expired ? " (key expired)" :
+ status == err_status_auth_fail ? " (auth check failed)" : "");
+}
diff --git a/third_party/srtp/test/rtp_decoder.h b/third_party/srtp/test/rtp_decoder.h
new file mode 100644
index 00000000..3a92d8aa
--- /dev/null
+++ b/third_party/srtp/test/rtp_decoder.h
@@ -0,0 +1,119 @@
+/*
+ * rtp_decoder.h
+ *
+ * decoder structures and functions for SRTP pcap decoder
+ *
+ * Bernardo Torres <bernardo@torresautomacao.com.br>
+ *
+ * Some structure and code from https://github.com/gteissier/srtp-decrypt
+ *
+ */
+/*
+ *
+ * Copyright (c) 2001-2006 Cisco Systems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * Neither the name of the Cisco Systems, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+
+#ifndef RTP_DECODER_H
+#define RTP_DECODER_H
+
+#include "srtp_priv.h"
+#include "rtp_priv.h"
+#include "rtp.h"
+#include "datatypes.h"
+
+#define DEFAULT_RTP_OFFSET 42
+
+typedef struct rtp_decoder_ctx_t {
+ srtp_policy_t policy;
+ srtp_ctx_t *srtp_ctx;
+ int rtp_offset;
+ struct timeval start_tv;
+ int frame_nr;
+ rtp_msg_t message;
+} rtp_decoder_ctx_t;
+
+typedef struct rtp_decoder_ctx_t *rtp_decoder_t;
+
+/*
+ * error to string
+ */
+
+void rtp_print_error(err_status_t status, char *message);
+
+/*
+ * prints the output of a random buffer in hexadecimal
+ */
+
+void
+hexdump(const void *ptr, size_t size);
+
+/*
+ * the function usage() prints an error message describing how this
+ * program should be called, then calls exit()
+ */
+
+void
+usage(char *prog_name);
+
+/*
+ * transforms base64 key into octet
+ */
+
+char *decode_sdes(char *in, char *out);
+
+/*
+ * pcap handling
+ */
+
+void
+rtp_decoder_handle_pkt(u_char *arg, const struct pcap_pkthdr *hdr,
+ const u_char *bytes);
+
+rtp_decoder_t
+rtp_decoder_alloc(void);
+
+void
+rtp_decoder_dealloc(rtp_decoder_t rtp_ctx);
+
+int
+rtp_decoder_init(rtp_decoder_t dcdr, srtp_policy_t policy);
+
+err_status_t
+rtp_decoder_init_srtp(rtp_decoder_t decoder, unsigned int ssrc);
+
+int
+rtp_decoder_deinit_srtp(rtp_decoder_t decoder);
+
+#endif /* RTP_DECODER_H */
diff --git a/third_party/srtp/test/rtpw.c b/third_party/srtp/test/rtpw.c
index e477a779..9d560b6d 100644
--- a/third_party/srtp/test/rtpw.c
+++ b/third_party/srtp/test/rtpw.c
@@ -51,16 +51,27 @@
*/
+#ifdef HAVE_CONFIG_H
+ #include <config.h>
+#endif
+
#include "datatypes.h"
#include "getopt_s.h" /* for local getopt() */
#include <stdio.h> /* for printf, fprintf */
#include <stdlib.h> /* for atoi() */
#include <errno.h>
-#include <unistd.h> /* for close() */
+#include <signal.h> /* for signal() */
#include <string.h> /* for strncpy() */
#include <time.h> /* for usleep() */
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h> /* for close() */
+#elif defined(_MSC_VER)
+#include <io.h> /* for _close() */
+#define close _close
+#endif
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
@@ -77,6 +88,7 @@
#include "srtp.h"
#include "rtp.h"
+#include "crypto_kernel.h"
#ifdef RTPW_USE_WINSOCK2
# define DICT_FILE "words.txt"
@@ -86,8 +98,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
@@ -116,6 +127,18 @@ leave_group(int sock, struct ip_mreq mreq, char *name);
/*
+ * setup_signal_handler() sets up a signal handler to trigger
+ * cleanups after an interrupt
+ */
+int setup_signal_handler(char* name);
+
+/*
+ * handle_signal(...) handles interrupt signal to trigger cleanups
+ */
+
+volatile int interrupted = 0;
+
+/*
* program_type distinguishes the [s]rtp sender and receiver cases
*/
@@ -137,7 +160,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;
@@ -145,6 +172,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
@@ -158,6 +186,12 @@ 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);
+ }
+
/* initialize srtp library */
status = srtp_init();
if (status) {
@@ -167,20 +201,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;
@@ -263,7 +316,7 @@ main (int argc, char *argv[]) {
err = errno;
#endif
fprintf(stderr, "%s: couldn't open socket: %d\n", argv[0], err);
- exit(1);
+ exit(1);
}
name.sin_addr = rcvr_addr;
@@ -311,16 +364,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");
@@ -329,28 +439,45 @@ main (int argc, char *argv[]) {
policy.ssrc.type = ssrc_specific;
policy.ssrc.value = ssrc;
policy.key = (uint8_t *) key;
+ policy.ekt = NULL;
policy.next = NULL;
+ policy.window_size = 128;
+ policy.allow_repeat_tx = 0;
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 ((int) 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);
}
@@ -382,6 +509,9 @@ main (int argc, char *argv[]) {
policy.rtcp.auth_key_len = 0;
policy.rtcp.auth_tag_len = 0;
policy.rtcp.sec_serv = sec_serv_none;
+ policy.window_size = 0;
+ policy.allow_repeat_tx = 0;
+ policy.ekt = NULL;
policy.next = NULL;
}
@@ -426,7 +556,7 @@ main (int argc, char *argv[]) {
}
/* read words from dictionary, then send them off */
- while (fgets(word, MAX_WORD_LEN, dict) != NULL) {
+ while (!interrupted && fgets(word, MAX_WORD_LEN, dict) != NULL) {
len = strlen(word) + 1; /* plus one for null */
if (len > MAX_WORD_LEN)
@@ -437,7 +567,11 @@ main (int argc, char *argv[]) {
}
usleep(USEC_RATE);
}
-
+
+ rtp_sender_deinit_srtp(snd);
+ rtp_sender_dealloc(snd);
+
+ fclose(dict);
} else { /* prog_type == receiver */
rtp_receiver_t rcvr;
@@ -466,12 +600,14 @@ main (int argc, char *argv[]) {
}
/* get next word and loop */
- while (1) {
+ while (!interrupted) {
len = MAX_WORD_LEN;
if (rtp_recvfrom(rcvr, word, &len) > -1)
- printf("\tword: %s", word);
+ printf("\tword: %s\n", word);
}
+ rtp_receiver_deinit_srtp(rcvr);
+ rtp_receiver_dealloc(rcvr);
}
if (ADDR_IS_MULTICAST(rcvr_addr.s_addr)) {
@@ -479,6 +615,22 @@ main (int argc, char *argv[]) {
}
#ifdef RTPW_USE_WINSOCK2
+ ret = closesocket(sock);
+#else
+ ret = close(sock);
+#endif
+ if (ret < 0) {
+ fprintf(stderr, "%s: Failed to close socket", argv[0]);
+ perror("");
+ }
+
+ status = srtp_shutdown();
+ if (status) {
+ printf("error: srtp shutdown failed with error code %d\n", status);
+ exit(1);
+ }
+
+#ifdef RTPW_USE_WINSOCK2
WSACleanup();
#endif
@@ -493,8 +645,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"
@@ -517,3 +672,41 @@ leave_group(int sock, struct ip_mreq mreq, char *name) {
}
}
+void handle_signal(int signum)
+{
+ interrupted = 1;
+ /* Reset handler explicitly, in case we don't have sigaction() (and signal()
+ has BSD semantics), or we don't have SA_RESETHAND */
+ signal(signum, SIG_DFL);
+}
+
+int setup_signal_handler(char* name)
+{
+#if HAVE_SIGACTION
+ struct sigaction act;
+ memset(&act, 0, sizeof(act));
+
+ act.sa_handler = handle_signal;
+ sigemptyset(&act.sa_mask);
+#if defined(SA_RESETHAND)
+ act.sa_flags = SA_RESETHAND;
+#else
+ act.sa_flags = 0;
+#endif
+ /* Note that we're not setting SA_RESTART; we want recvfrom to return
+ * EINTR when we signal the receiver. */
+
+ if (sigaction(SIGTERM, &act, NULL) != 0) {
+ fprintf(stderr, "%s: error setting up signal handler", name);
+ perror("");
+ return -1;
+ }
+#else
+ if (signal(SIGTERM, handle_signal) == SIG_ERR) {
+ fprintf(stderr, "%s: error setting up signal handler", name);
+ perror("");
+ return -1;
+ }
+#endif
+ return 0;
+}
diff --git a/third_party/srtp/test/rtpw_test.sh b/third_party/srtp/test/rtpw_test.sh
index f82e9370..d5808aba 100644
--- a/third_party/srtp/test/rtpw_test.sh
+++ b/third_party/srtp/test/rtpw_test.sh
@@ -3,14 +3,47 @@
# usage: rtpw_test <rtpw_commands>
#
# tests the rtpw sender and receiver functions
-
-RTPW=rtpw
+#
+# Copyright (c) 2001-2006, Cisco Systems, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following
+# disclaimer in the documentation and/or other materials provided
+# with the distribution.
+#
+# Neither the name of the Cisco Systems, Inc. nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+# OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+RTPW=./rtpw
DEST_PORT=9999
DURATION=3
-key=2b2edc5034f61a72345ca5986d7bfd0189aa6dc2ecab32fd9af74df6dfc6
+key=Ky7cUDT2GnI0XKWYbXv9AYmqbcLsqzL9mvdN9t/G
-ARGS="-k $key -ae"
+ARGS="-b $key -a -e 128"
# First, we run "killall" to get rid of all existing rtpw processes.
# This step also enables this script to clean up after itself; if this
@@ -18,7 +51,7 @@ ARGS="-k $key -ae"
# they are killed, those processes will linger. Re-running the script
# will get rid of them.
-killall rtpw 2&>/dev/null
+killall rtpw 2>/dev/null
if test -x $RTPW; then
@@ -63,6 +96,58 @@ sleep $DURATION
kill $receiver_pid
kill $sender_pid
+wait $receiver_pid
+wait $sender_pid
+
+
+key=033490ba9e82994fc21013395739038992b2edc5034f61a72345ca598d7bfd0189aa6dc2ecab32fd9af74df6dfc6
+
+ARGS="-k $key -a -e 256"
+
+echo $0 ": starting rtpw receiver process... "
+
+$RTPW $* $ARGS -r 0.0.0.0 $DEST_PORT &
+
+receiver_pid=$!
+
+echo $0 ": receiver PID = $receiver_pid"
+
+sleep 1
+
+# verify that the background job is running
+ps | grep -q $receiver_pid
+retval=$?
+echo $retval
+if [ $retval != 0 ]; then
+ echo $0 ": error"
+ exit 254
+fi
+
+echo $0 ": starting rtpw sender process..."
+
+$RTPW $* $ARGS -s 127.0.0.1 $DEST_PORT &
+
+sender_pid=$!
+
+echo $0 ": sender PID = $sender_pid"
+
+# verify that the background job is running
+ps | grep -q $sender_pid
+retval=$?
+echo $retval
+if [ $retval != 0 ]; then
+ echo $0 ": error"
+ exit 255
+fi
+
+sleep $DURATION
+
+kill $receiver_pid
+kill $sender_pid
+
+wait $receiver_pid
+wait $sender_pid
+
echo $0 ": done (test passed)"
else
diff --git a/third_party/srtp/test/rtpw_test_gcm.sh b/third_party/srtp/test/rtpw_test_gcm.sh
new file mode 100644
index 00000000..6e58b6c8
--- /dev/null
+++ b/third_party/srtp/test/rtpw_test_gcm.sh
@@ -0,0 +1,237 @@
+#!/bin/sh
+#
+# usage: rtpw_test <rtpw_commands>
+#
+# tests the rtpw sender and receiver functions
+#
+# Copyright (c) 2001-2006, Cisco Systems, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following
+# disclaimer in the documentation and/or other materials provided
+# with the distribution.
+#
+# Neither the name of the Cisco Systems, Inc. nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+# OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+RTPW=./rtpw
+DEST_PORT=9999
+DURATION=3
+
+# First, we run "killall" to get rid of all existing rtpw processes.
+# This step also enables this script to clean up after itself; if this
+# script is interrupted after the rtpw processes are started but before
+# they are killed, those processes will linger. Re-running the script
+# will get rid of them.
+
+killall rtpw 2>/dev/null
+
+if test -x $RTPW; then
+
+GCMARGS128="-k 01234567890123456789012345678901234567890123456789012345 -g -e 128"
+echo $0 ": starting GCM mode 128-bit rtpw receiver process... "
+
+exec $RTPW $* $GCMARGS128 -r 127.0.0.1 $DEST_PORT &
+
+receiver_pid=$!
+
+echo $0 ": receiver PID = $receiver_pid"
+
+sleep 1
+
+# verify that the background job is running
+ps | grep -q $receiver_pid
+retval=$?
+echo $retval
+if [ $retval != 0 ]; then
+ echo $0 ": error"
+ exit 254
+fi
+
+echo $0 ": starting GCM 128-bit rtpw sender process..."
+
+exec $RTPW $* $GCMARGS128 -s 127.0.0.1 $DEST_PORT &
+
+sender_pid=$!
+
+echo $0 ": sender PID = $sender_pid"
+
+# verify that the background job is running
+ps | grep -q $sender_pid
+retval=$?
+echo $retval
+if [ $retval != 0 ]; then
+ echo $0 ": error"
+ exit 255
+fi
+
+sleep $DURATION
+
+kill $receiver_pid
+kill $sender_pid
+
+GCMARGS128="-k 01234567890123456789012345678901234567890123456789012345 -g -t 16 -e 128"
+echo $0 ": starting GCM mode 128-bit (16 byte tag) rtpw receiver process... "
+
+exec $RTPW $* $GCMARGS128 -r 127.0.0.1 $DEST_PORT &
+
+receiver_pid=$!
+
+echo $0 ": receiver PID = $receiver_pid"
+
+sleep 1
+
+# verify that the background job is running
+ps | grep -q $receiver_pid
+retval=$?
+echo $retval
+if [ $retval != 0 ]; then
+ echo $0 ": error"
+ exit 254
+fi
+
+echo $0 ": starting GCM 128-bit (16 byte tag) rtpw sender process..."
+
+exec $RTPW $* $GCMARGS128 -s 127.0.0.1 $DEST_PORT &
+
+sender_pid=$!
+
+echo $0 ": sender PID = $sender_pid"
+
+# verify that the background job is running
+ps | grep -q $sender_pid
+retval=$?
+echo $retval
+if [ $retval != 0 ]; then
+ echo $0 ": error"
+ exit 255
+fi
+
+sleep $DURATION
+
+kill $receiver_pid
+kill $sender_pid
+
+
+
+GCMARGS256="-k 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567 -g -e 256"
+echo $0 ": starting GCM mode 256-bit rtpw receiver process... "
+
+exec $RTPW $* $GCMARGS256 -r 127.0.0.1 $DEST_PORT &
+
+receiver_pid=$!
+
+echo $0 ": receiver PID = $receiver_pid"
+
+sleep 1
+
+# verify that the background job is running
+ps | grep -q $receiver_pid
+retval=$?
+echo $retval
+if [ $retval != 0 ]; then
+ echo $0 ": error"
+ exit 254
+fi
+
+echo $0 ": starting GCM 256-bit rtpw sender process..."
+
+exec $RTPW $* $GCMARGS256 -s 127.0.0.1 $DEST_PORT &
+
+sender_pid=$!
+
+echo $0 ": sender PID = $sender_pid"
+
+# verify that the background job is running
+ps | grep -q $sender_pid
+retval=$?
+echo $retval
+if [ $retval != 0 ]; then
+ echo $0 ": error"
+ exit 255
+fi
+
+sleep $DURATION
+
+kill $receiver_pid
+kill $sender_pid
+
+
+GCMARGS256="-k a123456789012345678901234567890123456789012345678901234567890123456789012345678901234567 -g -t 16 -e 256"
+echo $0 ": starting GCM mode 256-bit (16 byte tag) rtpw receiver process... "
+
+exec $RTPW $* $GCMARGS256 -r 127.0.0.1 $DEST_PORT &
+
+receiver_pid=$!
+
+echo $0 ": receiver PID = $receiver_pid"
+
+sleep 1
+
+# verify that the background job is running
+ps | grep -q $receiver_pid
+retval=$?
+echo $retval
+if [ $retval != 0 ]; then
+ echo $0 ": error"
+ exit 254
+fi
+
+echo $0 ": starting GCM 256-bit (16 byte tag) rtpw sender process..."
+
+exec $RTPW $* $GCMARGS256 -s 127.0.0.1 $DEST_PORT &
+
+sender_pid=$!
+
+echo $0 ": sender PID = $sender_pid"
+
+# verify that the background job is running
+ps | grep -q $sender_pid
+retval=$?
+echo $retval
+if [ $retval != 0 ]; then
+ echo $0 ": error"
+ exit 255
+fi
+
+sleep $DURATION
+
+kill $receiver_pid
+kill $sender_pid
+
+
+echo $0 ": done (test passed)"
+
+else
+
+echo "error: can't find executable" $RTPW
+exit 1
+
+fi
+
+# EOF
+
+
diff --git a/third_party/srtp/test/srtp_driver.c b/third_party/srtp/test/srtp_driver.c
index 12d1c8c2..88729717 100644
--- a/third_party/srtp/test/srtp_driver.c
+++ b/third_party/srtp/test/srtp_driver.c
@@ -63,9 +63,15 @@ err_status_t
srtp_validate(void);
err_status_t
+srtp_validate_aes_256(void);
+
+err_status_t
srtp_create_big_policy(srtp_policy_t **list);
err_status_t
+srtp_dealloc_big_policy(srtp_policy_t *list);
+
+err_status_t
srtp_test_remove_stream(void);
double
@@ -98,7 +104,7 @@ srtp_packet_to_string(srtp_hdr_t *hdr, int packet_len);
double
mips_estimate(int num_trials, int *ignore);
-extern uint8_t test_key[30];
+extern uint8_t test_key[46];
void
usage(char *prog_name) {
@@ -138,7 +144,7 @@ debug_module_t mod_driver = {
int
main (int argc, char *argv[]) {
- char q;
+ int q;
unsigned do_timing_test = 0;
unsigned do_rejection_test = 0;
unsigned do_codec_timing = 0;
@@ -153,7 +159,7 @@ main (int argc, char *argv[]) {
if (sizeof(srtp_hdr_t) != 12) {
printf("error: srtp_hdr_t has incorrect size"
"(size is %ld bytes, expected 12)\n",
- sizeof(srtp_hdr_t));
+ (long)sizeof(srtp_hdr_t));
exit(1);
}
@@ -253,6 +259,11 @@ main (int argc, char *argv[]) {
printf("failed\n");
exit(1);
}
+ status = srtp_dealloc_big_policy(big_policy);
+ if (status) {
+ printf("unexpected failure with error code %d\n", status);
+ exit(1);
+ }
/* run test on wildcard policy */
printf("testing srtp_protect and srtp_unprotect on "
@@ -277,6 +288,22 @@ main (int argc, char *argv[]) {
exit(1);
}
+//FIXME: need to get this working with the OpenSSL AES module
+#ifndef OPENSSL
+ /*
+ * run validation test against the reference packets for
+ * AES-256
+ */
+ printf("testing srtp_protect and srtp_unprotect against "
+ "reference packets (AES-256)\n");
+ if (srtp_validate_aes_256() == err_status_ok)
+ printf("passed\n\n");
+ else {
+ printf("failed\n");
+ exit(1);
+ }
+#endif
+
/*
* test the function srtp_remove_stream()
*/
@@ -321,6 +348,9 @@ main (int argc, char *argv[]) {
policy.ssrc.type = ssrc_specific;
policy.ssrc.value = 0xdecafbad;
policy.key = test_key;
+ policy.ekt = NULL;
+ policy.window_size = 128;
+ policy.allow_repeat_tx = 0;
policy.next = NULL;
printf("mips estimate: %e\n", mips);
@@ -353,6 +383,12 @@ main (int argc, char *argv[]) {
srtp_bits_per_second(640, &policy) / .02 );
}
+ status = srtp_shutdown();
+ if (status) {
+ printf("error: srtp shutdown failed with error code %d\n", status);
+ exit(1);
+ }
+
return 0;
}
@@ -492,7 +528,6 @@ srtp_bits_per_second(int msg_len_octets, const srtp_policy_t *policy) {
timer = clock();
for (i=0; i < num_trials; i++) {
- err_status_t status;
len = msg_len_octets + 12; /* add in rtp header length */
/* srtp protect message */
@@ -503,12 +538,21 @@ srtp_bits_per_second(int msg_len_octets, const srtp_policy_t *policy) {
}
/* increment message number */
- mesg->seq = htons(ntohs(mesg->seq) + 1);
-
+ {
+ /* hack sequence to avoid problems with macros for htons/ntohs on some systems */
+ short new_seq = ntohs(mesg->seq) + 1;
+ mesg->seq = htons(new_seq);
+ }
}
timer = clock() - timer;
free(mesg);
+
+ status = srtp_dealloc(srtp);
+ if (status) {
+ printf("error: srtp_dealloc() failed with error code %d\n", status);
+ exit(1);
+ }
return (double) (msg_len_octets) * 8 *
num_trials * CLOCKS_PER_SEC / timer;
@@ -549,7 +593,13 @@ srtp_rejections_per_second(int msg_len_octets, const srtp_policy_t *policy) {
timer = clock() - timer;
free(mesg);
-
+
+ status = srtp_dealloc(srtp);
+ if (status) {
+ printf("error: srtp_dealloc() failed with error code %d\n", status);
+ exit(1);
+ }
+
return (double) num_trials * CLOCKS_PER_SEC / timer;
}
@@ -678,8 +728,11 @@ srtp_test(const srtp_policy_t *policy) {
* the compiler would fret about the constness of the policy
*/
rcvr_policy = (srtp_policy_t*) malloc(sizeof(srtp_policy_t));
- if (rcvr_policy == NULL)
+ if (rcvr_policy == NULL) {
+ free(hdr);
+ free(hdr2);
return err_status_alloc_fail;
+ }
memcpy(rcvr_policy, policy, sizeof(srtp_policy_t));
if (policy->ssrc.type == ssrc_any_outbound) {
rcvr_policy->ssrc.type = ssrc_any_inbound;
@@ -701,6 +754,7 @@ srtp_test(const srtp_policy_t *policy) {
if (status) {
free(hdr);
free(hdr2);
+ free(rcvr_policy);
return status;
}
@@ -721,6 +775,7 @@ srtp_test(const srtp_policy_t *policy) {
printf("failed with error code %d\n", status);
free(hdr);
free(hdr2);
+ free(rcvr_policy);
return status;
} else {
printf("passed\n");
@@ -746,6 +801,7 @@ srtp_test(const srtp_policy_t *policy) {
printf("failed\n");
free(hdr);
free(hdr2);
+ free(rcvr_policy);
return status;
} else {
printf("passed\n");
@@ -758,6 +814,7 @@ srtp_test(const srtp_policy_t *policy) {
free(hdr);
free(hdr2);
+ free(rcvr_policy);
return err_status_ok;
}
@@ -900,6 +957,7 @@ srtcp_test(const srtp_policy_t *policy) {
if (status) {
free(hdr);
free(hdr2);
+ free(rcvr_policy);
return status;
}
@@ -920,6 +978,7 @@ srtcp_test(const srtp_policy_t *policy) {
printf("failed with error code %d\n", status);
free(hdr);
free(hdr2);
+ free(rcvr_policy);
return status;
} else {
printf("passed\n");
@@ -945,6 +1004,7 @@ srtcp_test(const srtp_policy_t *policy) {
printf("failed\n");
free(hdr);
free(hdr2);
+ free(rcvr_policy);
return status;
} else {
printf("passed\n");
@@ -957,6 +1017,7 @@ srtcp_test(const srtp_policy_t *policy) {
free(hdr);
free(hdr2);
+ free(rcvr_policy);
return err_status_ok;
}
@@ -989,14 +1050,18 @@ srtp_session_print_policy(srtp_t srtp) {
"# rtp services: %s\r\n"
"# rtcp cipher: %s\r\n"
"# rtcp auth: %s\r\n"
- "# rtcp services: %s\r\n",
+ "# rtcp services: %s\r\n"
+ "# window size: %lu\r\n"
+ "# tx rtx allowed:%s\r\n",
direction[stream->direction],
stream->rtp_cipher->type->description,
stream->rtp_auth->type->description,
serv_descr[stream->rtp_services],
stream->rtcp_cipher->type->description,
stream->rtcp_auth->type->description,
- serv_descr[stream->rtcp_services]);
+ serv_descr[stream->rtcp_services],
+ rdbx_get_window_size(&stream->rtp_rdbx),
+ stream->allow_repeat_tx ? "true" : "false");
}
/* loop over streams in session, printing the policy of each */
@@ -1011,14 +1076,18 @@ srtp_session_print_policy(srtp_t srtp) {
"# rtp services: %s\r\n"
"# rtcp cipher: %s\r\n"
"# rtcp auth: %s\r\n"
- "# rtcp services: %s\r\n",
+ "# rtcp services: %s\r\n"
+ "# window size: %lu\r\n"
+ "# tx rtx allowed:%s\r\n",
stream->ssrc,
stream->rtp_cipher->type->description,
stream->rtp_auth->type->description,
serv_descr[stream->rtp_services],
stream->rtcp_cipher->type->description,
stream->rtcp_auth->type->description,
- serv_descr[stream->rtcp_services]);
+ serv_descr[stream->rtcp_services],
+ rdbx_get_window_size(&stream->rtp_rdbx),
+ stream->allow_repeat_tx ? "true" : "false");
/* advance to next stream in the list */
stream = stream->next;
@@ -1108,7 +1177,7 @@ srtp_packet_to_string(srtp_hdr_t *hdr, int pkt_octet_len) {
double
mips_estimate(int num_trials, int *ignore) {
clock_t t;
- int i, sum;
+ volatile int i, sum;
sum = 0;
t = clock();
@@ -1132,12 +1201,6 @@ mips_estimate(int num_trials, int *ignore) {
err_status_t
srtp_validate() {
- unsigned char test_key[30] = {
- 0xe1, 0xf9, 0x7a, 0x0d, 0x3e, 0x01, 0x8b, 0xe0,
- 0xd6, 0x4f, 0xa3, 0x2c, 0x06, 0xde, 0x41, 0x39,
- 0x0e, 0xc6, 0x75, 0xad, 0x49, 0x8a, 0xfe, 0xeb,
- 0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6
- };
uint8_t srtp_plaintext_ref[28] = {
0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
@@ -1172,6 +1235,9 @@ srtp_validate() {
policy.ssrc.type = ssrc_specific;
policy.ssrc.value = 0xcafebabe;
policy.key = test_key;
+ policy.ekt = NULL;
+ policy.window_size = 128;
+ policy.allow_repeat_tx = 0;
policy.next = NULL;
status = srtp_create(&srtp_snd, &policy);
@@ -1213,6 +1279,122 @@ srtp_validate() {
if (octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len))
return err_status_fail;
+ status = srtp_dealloc(srtp_snd);
+ if (status)
+ return status;
+
+ status = srtp_dealloc(srtp_recv);
+ if (status)
+ return status;
+
+ return err_status_ok;
+}
+
+
+/*
+ * srtp_validate_aes_256() verifies the correctness of libsrtp by comparing
+ * some computed packets against some pre-computed reference values.
+ * These packets were made with the AES-CM-256/HMAC-SHA-1-80 policy.
+ */
+
+
+err_status_t
+srtp_validate_aes_256() {
+ unsigned char aes_256_test_key[46] = {
+ 0xf0, 0xf0, 0x49, 0x14, 0xb5, 0x13, 0xf2, 0x76,
+ 0x3a, 0x1b, 0x1f, 0xa1, 0x30, 0xf1, 0x0e, 0x29,
+ 0x98, 0xf6, 0xf6, 0xe4, 0x3e, 0x43, 0x09, 0xd1,
+ 0xe6, 0x22, 0xa0, 0xe3, 0x32, 0xb9, 0xf1, 0xb6,
+
+ 0x3b, 0x04, 0x80, 0x3d, 0xe5, 0x1e, 0xe7, 0xc9,
+ 0x64, 0x23, 0xab, 0x5b, 0x78, 0xd2
+ };
+ uint8_t srtp_plaintext_ref[28] = {
+ 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
+ 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
+ 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
+ 0xab, 0xab, 0xab, 0xab
+ };
+ uint8_t srtp_plaintext[38] = {
+ 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
+ 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
+ 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
+ 0xab, 0xab, 0xab, 0xab, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+ uint8_t srtp_ciphertext[38] = {
+ 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
+ 0xca, 0xfe, 0xba, 0xbe, 0xf1, 0xd9, 0xde, 0x17,
+ 0xff, 0x25, 0x1f, 0xf1, 0xaa, 0x00, 0x77, 0x74,
+ 0xb0, 0xb4, 0xb4, 0x0d, 0xa0, 0x8d, 0x9d, 0x9a,
+ 0x5b, 0x3a, 0x55, 0xd8, 0x87, 0x3b
+ };
+ srtp_t srtp_snd, srtp_recv;
+ err_status_t status;
+ int len;
+ srtp_policy_t policy;
+
+ /*
+ * create a session with a single stream using the default srtp
+ * policy and with the SSRC value 0xcafebabe
+ */
+ crypto_policy_set_aes_cm_256_hmac_sha1_80(&policy.rtp);
+ crypto_policy_set_aes_cm_256_hmac_sha1_80(&policy.rtcp);
+ policy.ssrc.type = ssrc_specific;
+ policy.ssrc.value = 0xcafebabe;
+ policy.key = aes_256_test_key;
+ policy.ekt = NULL;
+ policy.window_size = 128;
+ policy.allow_repeat_tx = 0;
+ policy.next = NULL;
+
+ status = srtp_create(&srtp_snd, &policy);
+ if (status)
+ return status;
+
+ /*
+ * protect plaintext, then compare with ciphertext
+ */
+ len = 28;
+ status = srtp_protect(srtp_snd, srtp_plaintext, &len);
+ if (status || (len != 38))
+ return err_status_fail;
+
+ debug_print(mod_driver, "ciphertext:\n %s",
+ octet_string_hex_string(srtp_plaintext, len));
+ debug_print(mod_driver, "ciphertext reference:\n %s",
+ octet_string_hex_string(srtp_ciphertext, len));
+
+ if (octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len))
+ return err_status_fail;
+
+ /*
+ * create a receiver session context comparable to the one created
+ * above - we need to do this so that the replay checking doesn't
+ * complain
+ */
+ status = srtp_create(&srtp_recv, &policy);
+ if (status)
+ return status;
+
+ /*
+ * unprotect ciphertext, then compare with plaintext
+ */
+ status = srtp_unprotect(srtp_recv, srtp_ciphertext, &len);
+ if (status || (len != 28))
+ return status;
+
+ if (octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len))
+ return err_status_fail;
+
+ status = srtp_dealloc(srtp_snd);
+ if (status)
+ return status;
+
+ status = srtp_dealloc(srtp_recv);
+ if (status)
+ return status;
+
return err_status_ok;
}
@@ -1250,9 +1432,22 @@ srtp_create_big_policy(srtp_policy_t **list) {
}
err_status_t
+srtp_dealloc_big_policy(srtp_policy_t *list) {
+ srtp_policy_t *p, *next;
+
+ for (p = list; p != NULL; p = next) {
+ next = p->next;
+ free(p);
+ }
+
+ return err_status_ok;
+}
+
+
+err_status_t
srtp_test_remove_stream() {
err_status_t status;
- srtp_policy_t *policy_list;
+ srtp_policy_t *policy_list, policy;
srtp_t session;
srtp_stream_t stream;
/*
@@ -1293,6 +1488,41 @@ srtp_test_remove_stream() {
if (stream == NULL)
return err_status_fail;
+ status = srtp_dealloc(session);
+ if (status != err_status_ok)
+ return status;
+
+ status = srtp_dealloc_big_policy(policy_list);
+ if (status != err_status_ok)
+ return status;
+
+ /* Now test adding and removing a single stream */
+ crypto_policy_set_rtp_default(&policy.rtp);
+ crypto_policy_set_rtcp_default(&policy.rtcp);
+ policy.ssrc.type = ssrc_specific;
+ policy.ssrc.value = 0xcafebabe;
+ policy.key = test_key;
+ policy.ekt = NULL;
+ policy.window_size = 128;
+ policy.allow_repeat_tx = 0;
+ policy.next = NULL;
+
+ status = srtp_create(&session, NULL);
+ if (status != err_status_ok)
+ return status;
+
+ status = srtp_add_stream(session, &policy);
+ if (status != err_status_ok)
+ return status;
+
+ status = srtp_remove_stream(session, htonl(0xcafebabe));
+ if (status != err_status_ok)
+ return status;
+
+ status = srtp_dealloc(session);
+ if (status != err_status_ok)
+ return status;
+
return err_status_ok;
}
@@ -1300,10 +1530,12 @@ srtp_test_remove_stream() {
* srtp policy definitions - these definitions are used above
*/
-unsigned char test_key[30] = {
+unsigned char test_key[46] = {
0xe1, 0xf9, 0x7a, 0x0d, 0x3e, 0x01, 0x8b, 0xe0,
0xd6, 0x4f, 0xa3, 0x2c, 0x06, 0xde, 0x41, 0x39,
0x0e, 0xc6, 0x75, 0xad, 0x49, 0x8a, 0xfe, 0xeb,
+ 0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6, 0xc1, 0x73,
+ 0xc3, 0x17, 0xf2, 0xda, 0xbe, 0x35, 0x77, 0x93,
0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6
};
@@ -1327,6 +1559,9 @@ const srtp_policy_t default_policy = {
sec_serv_conf_and_auth /* security services flag */
},
test_key,
+ NULL, /* indicates that EKT is not in use */
+ 128, /* replay window size */
+ 0, /* retransmission not allowed */
NULL
};
@@ -1349,6 +1584,9 @@ const srtp_policy_t aes_tmmh_policy = {
sec_serv_conf_and_auth /* security services flag */
},
test_key,
+ NULL, /* indicates that EKT is not in use */
+ 128, /* replay window size */
+ 0, /* retransmission not allowed */
NULL
};
@@ -1371,6 +1609,9 @@ const srtp_policy_t tmmh_only_policy = {
sec_serv_auth /* security services flag */
},
test_key,
+ NULL, /* indicates that EKT is not in use */
+ 128, /* replay window size */
+ 0, /* retransmission not allowed */
NULL
};
@@ -1393,6 +1634,9 @@ const srtp_policy_t aes_only_policy = {
sec_serv_conf /* security services flag */
},
test_key,
+ NULL, /* indicates that EKT is not in use */
+ 128, /* replay window size */
+ 0, /* retransmission not allowed */
NULL
};
@@ -1415,9 +1659,114 @@ const srtp_policy_t hmac_only_policy = {
sec_serv_auth /* security services flag */
},
test_key,
+ NULL, /* indicates that EKT is not in use */
+ 128, /* replay window size */
+ 0, /* retransmission not allowed */
NULL
};
+#ifdef OPENSSL
+const srtp_policy_t aes128_gcm_8_policy = {
+ { ssrc_any_outbound, 0 }, /* SSRC */
+ { /* SRTP policy */
+ AES_128_GCM, /* cipher type */
+ AES_128_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
+ NULL_AUTH, /* authentication func type */
+ 0, /* auth key length in octets */
+ 8, /* auth tag length in octets */
+ sec_serv_conf_and_auth /* security services flag */
+ },
+ { /* SRTCP policy */
+ AES_128_GCM, /* cipher type */
+ AES_128_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
+ NULL_AUTH, /* authentication func type */
+ 0, /* auth key length in octets */
+ 8, /* auth tag length in octets */
+ sec_serv_conf_and_auth /* security services flag */
+ },
+ test_key,
+ NULL, /* indicates that EKT is not in use */
+ 128, /* replay window size */
+ 0, /* retransmission not allowed */
+ NULL
+};
+
+const srtp_policy_t aes128_gcm_8_cauth_policy = {
+ { ssrc_any_outbound, 0 }, /* SSRC */
+ { /* SRTP policy */
+ AES_128_GCM, /* cipher type */
+ AES_128_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
+ NULL_AUTH, /* authentication func type */
+ 0, /* auth key length in octets */
+ 8, /* auth tag length in octets */
+ sec_serv_conf_and_auth /* security services flag */
+ },
+ { /* SRTCP policy */
+ AES_128_GCM, /* cipher type */
+ AES_128_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
+ NULL_AUTH, /* authentication func type */
+ 0, /* auth key length in octets */
+ 8, /* auth tag length in octets */
+ sec_serv_auth /* security services flag */
+ },
+ test_key,
+ NULL, /* indicates that EKT is not in use */
+ 128, /* replay window size */
+ 0, /* retransmission not allowed */
+ NULL
+};
+
+const srtp_policy_t aes256_gcm_8_policy = {
+ { ssrc_any_outbound, 0 }, /* SSRC */
+ { /* SRTP policy */
+ AES_256_GCM, /* cipher type */
+ AES_256_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
+ NULL_AUTH, /* authentication func type */
+ 0, /* auth key length in octets */
+ 8, /* auth tag length in octets */
+ sec_serv_conf_and_auth /* security services flag */
+ },
+ { /* SRTCP policy */
+ AES_256_GCM, /* cipher type */
+ AES_256_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
+ NULL_AUTH, /* authentication func type */
+ 0, /* auth key length in octets */
+ 8, /* auth tag length in octets */
+ sec_serv_conf_and_auth /* security services flag */
+ },
+ test_key,
+ NULL, /* indicates that EKT is not in use */
+ 128, /* replay window size */
+ 0, /* retransmission not allowed */
+ NULL
+};
+
+const srtp_policy_t aes256_gcm_8_cauth_policy = {
+ { ssrc_any_outbound, 0 }, /* SSRC */
+ { /* SRTP policy */
+ AES_256_GCM, /* cipher type */
+ AES_256_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
+ NULL_AUTH, /* authentication func type */
+ 0, /* auth key length in octets */
+ 8, /* auth tag length in octets */
+ sec_serv_conf_and_auth /* security services flag */
+ },
+ { /* SRTCP policy */
+ AES_256_GCM, /* cipher type */
+ AES_256_GCM_KEYSIZE_WSALT, /* cipher key length in octets */
+ NULL_AUTH, /* authentication func type */
+ 0, /* auth key length in octets */
+ 8, /* auth tag length in octets */
+ sec_serv_auth /* security services flag */
+ },
+ test_key,
+ NULL, /* indicates that EKT is not in use */
+ 128, /* replay window size */
+ 0, /* retransmission not allowed */
+ NULL
+};
+#endif
+
const srtp_policy_t null_policy = {
{ ssrc_any_outbound, 0 }, /* SSRC */
{
@@ -1437,6 +1786,83 @@ const srtp_policy_t null_policy = {
sec_serv_none /* security services flag */
},
test_key,
+ NULL, /* indicates that EKT is not in use */
+ 128, /* replay window size */
+ 0, /* retransmission not allowed */
+ NULL
+};
+
+unsigned char test_256_key[46] = {
+ 0xf0, 0xf0, 0x49, 0x14, 0xb5, 0x13, 0xf2, 0x76,
+ 0x3a, 0x1b, 0x1f, 0xa1, 0x30, 0xf1, 0x0e, 0x29,
+ 0x98, 0xf6, 0xf6, 0xe4, 0x3e, 0x43, 0x09, 0xd1,
+ 0xe6, 0x22, 0xa0, 0xe3, 0x32, 0xb9, 0xf1, 0xb6,
+
+ 0x3b, 0x04, 0x80, 0x3d, 0xe5, 0x1e, 0xe7, 0xc9,
+ 0x64, 0x23, 0xab, 0x5b, 0x78, 0xd2
+};
+
+const srtp_policy_t aes_256_hmac_policy = {
+ { ssrc_any_outbound, 0 }, /* SSRC */
+ { /* SRTP policy */
+ AES_ICM, /* cipher type */
+ 46, /* cipher key length in octets */
+ HMAC_SHA1, /* authentication func type */
+ 20, /* auth key length in octets */
+ 10, /* auth tag length in octets */
+ sec_serv_conf_and_auth /* security services flag */
+ },
+ { /* SRTCP policy */
+ AES_ICM, /* cipher type */
+ 46, /* cipher key length in octets */
+ HMAC_SHA1, /* authentication func type */
+ 20, /* auth key length in octets */
+ 10, /* auth tag length in octets */
+ sec_serv_conf_and_auth /* security services flag */
+ },
+ test_256_key,
+ NULL, /* indicates that EKT is not in use */
+ 128, /* replay window size */
+ 0, /* retransmission not allowed */
+ NULL
+};
+
+uint8_t ekt_test_key[16] = {
+ 0x77, 0x26, 0x9d, 0xac, 0x16, 0xa3, 0x28, 0xca,
+ 0x8e, 0xc9, 0x68, 0x4b, 0xcc, 0xc4, 0xd2, 0x1b
+};
+
+#include "ekt.h"
+
+ekt_policy_ctx_t ekt_test_policy = {
+ 0xa5a5, /* SPI */
+ EKT_CIPHER_AES_128_ECB,
+ ekt_test_key,
+ NULL
+};
+
+const srtp_policy_t hmac_only_with_ekt_policy = {
+ { ssrc_any_outbound, 0 }, /* SSRC */
+ {
+ NULL_CIPHER, /* cipher type */
+ 0, /* cipher key length in octets */
+ HMAC_SHA1, /* authentication func type */
+ 20, /* auth key length in octets */
+ 4, /* auth tag length in octets */
+ sec_serv_auth /* security services flag */
+ },
+ {
+ NULL_CIPHER, /* cipher type */
+ 0, /* cipher key length in octets */
+ HMAC_SHA1, /* authentication func type */
+ 20, /* auth key length in octets */
+ 4, /* auth tag length in octets */
+ sec_serv_auth /* security services flag */
+ },
+ test_key,
+ &ekt_test_policy, /* indicates that EKT is not in use */
+ 128, /* replay window size */
+ 0, /* retransmission not allowed */
NULL
};
@@ -1464,7 +1890,15 @@ policy_array[] = {
&aes_tmmh_policy,
#endif
&default_policy,
+#ifdef OPENSSL
+ &aes128_gcm_8_policy,
+ &aes128_gcm_8_cauth_policy,
+ &aes256_gcm_8_policy,
+ &aes256_gcm_8_cauth_policy,
+#endif
&null_policy,
+ &aes_256_hmac_policy,
+ &hmac_only_with_ekt_policy,
NULL
};
@@ -1487,5 +1921,8 @@ const srtp_policy_t wildcard_policy = {
sec_serv_conf_and_auth /* security services flag */
},
test_key,
+ NULL,
+ 128, /* replay window size */
+ 0, /* retransmission not allowed */
NULL
};