Add support for user-selectable srtp window size, as a parameter in srtp_policy_t.
diff --git a/crypto/include/rdbx.h b/crypto/include/rdbx.h
index 00a9e2e..146fb42 100644
--- a/crypto/include/rdbx.h
+++ b/crypto/include/rdbx.h
@@ -46,19 +46,29 @@
typedef struct {
xtd_seq_num_t index;
- v128_t bitmask;
+ bitvector_t bitmask;
} rdbx_t;
/*
- * rdbx_init(rdbx_ptr)
+ * rdbx_init(rdbx_ptr, ws)
*
- * initializes the rdbx pointed to by its argument, setting the
- * rollover counter and sequence number to zero
+ * initializes the rdbx pointed to by its argument with the window size ws,
+ * setting the rollover counter and sequence number to zero
*/
err_status_t
-rdbx_init(rdbx_t *rdbx);
+rdbx_init(rdbx_t *rdbx, unsigned long ws);
+
+
+/*
+ * rdbx_dealloc(rdbx_ptr)
+ *
+ * frees memory associated with the rdbx
+ */
+
+err_status_t
+rdbx_dealloc(rdbx_t *rdbx);
/*
@@ -127,6 +137,15 @@
* api instead!
*/
+/*
+ * rdbx_get_ws(rdbx_ptr)
+ *
+ * gets the window size which was used to initialize the rdbx
+ */
+
+unsigned long
+rdbx_get_window_size(const rdbx_t *rdbx);
+
/* index_init(&pi) initializes a packet index pi (sets it to zero) */
diff --git a/crypto/replay/rdbx.c b/crypto/replay/rdbx.c
index ce713bb..15d52b5 100644
--- a/crypto/replay/rdbx.c
+++ b/crypto/replay/rdbx.c
@@ -45,7 +45,6 @@
#include "rdbx.h"
-#define rdbx_high_bit_in_bitmask 127
/*
* from RFC 3711:
@@ -180,17 +179,32 @@
/*
- * rdbx_init(&r) initalizes the rdbx_t pointed to by r
+ * rdbx_init(&r, ws) initializes the rdbx_t pointed to by r with window size ws
*/
err_status_t
-rdbx_init(rdbx_t *rdbx) {
- v128_set_to_zero(&rdbx->bitmask);
+rdbx_init(rdbx_t *rdbx, unsigned long ws) {
+ if (ws == 0)
+ return err_status_bad_param;
+
+ if (bitvector_alloc(&rdbx->bitmask, ws) != 0)
+ return err_status_alloc_fail;
+
index_init(&rdbx->index);
return err_status_ok;
}
+/*
+ * rdbx_dealloc(&r) frees memory for the rdbx_t pointed to by r
+ */
+
+err_status_t
+rdbx_dealloc(rdbx_t *rdbx) {
+ bitvector_dealloc(&rdbx->bitmask);
+
+ return err_status_ok;
+}
/*
* rdbx_set_roc(rdbx, roc) initalizes the rdbx_t at the location rdbx
@@ -202,7 +216,7 @@
err_status_t
rdbx_set_roc(rdbx_t *rdbx, uint32_t roc) {
- v128_set_to_zero(&rdbx->bitmask);
+ bitvector_set_to_zero(&rdbx->bitmask);
#ifdef NO_64BIT_MATH
#error not yet implemented
@@ -231,6 +245,17 @@
}
/*
+ * rdbx_get_window_size(rdbx) returns the value of the window size
+ * for the rdbx_t pointed to by rdbx
+ *
+ */
+
+unsigned long
+rdbx_get_window_size(const rdbx_t *rdbx) {
+ return bitvector_get_length(&rdbx->bitmask);
+}
+
+/*
* rdbx_check(&r, delta) checks to see if the xtd_seq_num_t
* which is at rdbx->index + delta is in the rdb
*/
@@ -240,11 +265,11 @@
if (delta > 0) { /* if delta is positive, it's good */
return err_status_ok;
- } else if (rdbx_high_bit_in_bitmask + delta < 0) {
+ } else if ((int)(bitvector_get_length(&rdbx->bitmask) - 1) + delta < 0) {
/* if delta is lower than the bitmask, it's bad */
return err_status_replay_old;
- } else if (v128_get_bit(&rdbx->bitmask,
- rdbx_high_bit_in_bitmask + delta) == 1) {
+ } else if (bitvector_get_bit(&rdbx->bitmask,
+ (int)(bitvector_get_length(&rdbx->bitmask) - 1) + delta) == 1) {
/* delta is within the window, so check the bitmask */
return err_status_replay_fail;
}
@@ -268,11 +293,11 @@
if (delta > 0) {
/* shift forward by delta */
index_advance(&rdbx->index, delta);
- v128_left_shift(&rdbx->bitmask, delta);
- v128_set_bit(&rdbx->bitmask, 127);
+ bitvector_left_shift(&rdbx->bitmask, delta);
+ bitvector_set_bit(&rdbx->bitmask, bitvector_get_length(&rdbx->bitmask) - 1);
} else {
/* delta is in window */
- v128_set_bit(&rdbx->bitmask, rdbx_high_bit_in_bitmask + delta);
+ bitvector_set_bit(&rdbx->bitmask, bitvector_get_length(&rdbx->bitmask) -1 + delta);
}
/* note that we need not consider the case that delta == 0 */
diff --git a/include/srtp.h b/include/srtp.h
index 81cd617..68073e5 100644
--- a/include/srtp.h
+++ b/include/srtp.h
@@ -223,6 +223,8 @@
* this stream. */
ekt_policy_t ekt; /**< Pointer to the EKT policy structure
* for this stream (if any) */
+ unsigned long window_size; /**< The window size to use for replay
+ * protection. */
struct srtp_policy_t *next; /**< Pointer to next stream policy. */
} srtp_policy_t;
diff --git a/srtp/srtp.c b/srtp/srtp.c
index 2877e8e..04a917a 100644
--- a/srtp/srtp.c
+++ b/srtp/srtp.c
@@ -231,6 +231,10 @@
return status;
}
+ status = rdbx_dealloc(&stream->rtp_rdbx);
+ if (status)
+ return status;
+
/* DAM - need to deallocate EKT here */
/* deallocate srtp stream context */
@@ -275,7 +279,10 @@
return status;
/* initialize replay databases */
- rdbx_init(&str->rtp_rdbx);
+ status = rdbx_init(&str->rtp_rdbx,
+ rdbx_get_window_size(&stream_template->rtp_rdbx));
+ if (status)
+ return status;
rdb_init(&str->rtcp_rdb);
/* set ssrc to that provided */
@@ -491,7 +498,18 @@
p->ssrc.value);
/* initialize replay database */
- rdbx_init(&srtp->rtp_rdbx);
+ /* window size MUST be at least 64. MAY be larger. Values more than
+ * 2^15 aren't meaningful due to how extended sequence numbers are
+ * calculated. Let a window size of 0 imply the default value. */
+
+ if (p->window_size != 0 && (p->window_size < 64 || p->window_size >= 0x8000))
+ return err_status_bad_param;
+
+ if (p->window_size != 0)
+ err = rdbx_init(&srtp->rtp_rdbx, p->window_size);
+ else
+ err = rdbx_init(&srtp->rtp_rdbx, 128);
+ if (err) return err;
/* initialize key limit to maximum value */
#ifdef NO_64BIT_MATH
@@ -525,14 +543,20 @@
/* initialize keys */
err = srtp_stream_init_keys(srtp, p->key);
- if (err) return err;
+ if (err) {
+ rdbx_dealloc(&srtp->rtp_rdbx);
+ return err;
+ }
/*
* if EKT is in use, then initialize the EKT data associated with
* the stream
*/
err = ekt_stream_init_from_policy(srtp->ekt, p->ekt);
- if (err) return err;
+ if (err) {
+ rdbx_dealloc(&srtp->rtp_rdbx);
+ return err;
+ }
return err_status_ok;
}
@@ -1220,6 +1244,9 @@
status = auth_dealloc(session->stream_template->rtp_auth);
if (status)
return status;
+ status = rdbx_dealloc(&session->stream_template->rtp_rdbx);
+ if (status)
+ return status;
crypto_free(session->stream_template);
}
diff --git a/test/dtls_srtp_driver.c b/test/dtls_srtp_driver.c
index 2f3cade..6980305 100644
--- a/test/dtls_srtp_driver.c
+++ b/test/dtls_srtp_driver.c
@@ -191,6 +191,7 @@
if (err) return err;
policy.ssrc.type = ssrc_any_inbound;
policy.ekt = NULL;
+ policy.window_size = 128;
policy.next = NULL;
err = srtp_add_stream(s, &policy);
diff --git a/test/rdbx_driver.c b/test/rdbx_driver.c
index cb4e4fe..838cc43 100644
--- a/test/rdbx_driver.c
+++ b/test/rdbx_driver.c
@@ -55,10 +55,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) {
@@ -99,9 +99,18 @@
usage(argv[0]);
if (do_validation) {
- printf("testing rdbx_t...\n");
+ printf("testing rdbx_t (ws=128)...\n");
- status = test_replay_dbx(1 << 12);
+ status = test_replay_dbx(1 << 12, 128);
+ if (status) {
+ printf("failed\n");
+ exit(1);
+ }
+ printf("passed\n");
+
+ printf("testing rdbx_t (ws=1024)...\n");
+
+ status = test_replay_dbx(1 << 12, 1024);
if (status) {
printf("failed\n");
exit(1);
@@ -110,8 +119,10 @@
}
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 +130,11 @@
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))
+);
}
@@ -206,17 +220,15 @@
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);
@@ -253,7 +265,9 @@
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;
}
@@ -279,7 +293,9 @@
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;
}
@@ -299,6 +315,8 @@
}
printf("passed\n");
+ rdbx_dealloc(&rdbx);
+
return err_status_ok;
}
@@ -308,7 +326,7 @@
#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;
@@ -316,7 +334,7 @@
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);
}
@@ -337,6 +355,8 @@
printf("number of failures: %d \n", failures);
+ rdbx_dealloc(&rdbx);
+
return (double) CLOCKS_PER_SEC * num_trials / timer;
}
diff --git a/test/rtpw.c b/test/rtpw.c
index ccfdc31..b95ecfd 100644
--- a/test/rtpw.c
+++ b/test/rtpw.c
@@ -350,6 +350,7 @@
policy.ssrc.value = ssrc;
policy.key = (uint8_t *) key;
policy.next = NULL;
+ policy.window_size = 128;
policy.rtp.sec_serv = sec_servs;
policy.rtcp.sec_serv = sec_serv_none; /* we don't do RTCP anyway */
@@ -402,6 +403,7 @@
policy.rtcp.auth_key_len = 0;
policy.rtcp.auth_tag_len = 0;
policy.rtcp.sec_serv = sec_serv_none;
+ policy.window_size = 0;
policy.next = NULL;
}
diff --git a/test/srtp_driver.c b/test/srtp_driver.c
index 7b62147..db0bc4f 100644
--- a/test/srtp_driver.c
+++ b/test/srtp_driver.c
@@ -329,6 +329,8 @@
policy.ssrc.type = ssrc_specific;
policy.ssrc.value = 0xdecafbad;
policy.key = test_key;
+ policy.ekt = NULL;
+ policy.window_size = 128;
policy.next = NULL;
printf("mips estimate: %e\n", mips);
@@ -1026,14 +1028,16 @@
"# 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",
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));
}
/* loop over streams in session, printing the policy of each */
@@ -1048,14 +1052,16 @@
"# 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",
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));
/* advance to next stream in the list */
stream = stream->next;
@@ -1209,6 +1215,8 @@
policy.ssrc.type = ssrc_specific;
policy.ssrc.value = 0xcafebabe;
policy.key = test_key;
+ policy.ekt = NULL;
+ policy.window_size = 128;
policy.next = NULL;
status = srtp_create(&srtp_snd, &policy);
@@ -1394,6 +1402,7 @@
},
test_key,
NULL, /* indicates that EKT is not in use */
+ 128, /* replay window size */
NULL
};
@@ -1417,6 +1426,7 @@
},
test_key,
NULL, /* indicates that EKT is not in use */
+ 128, /* replay window size */
NULL
};
@@ -1440,6 +1450,7 @@
},
test_key,
NULL, /* indicates that EKT is not in use */
+ 128, /* replay window size */
NULL
};
@@ -1463,6 +1474,7 @@
},
test_key,
NULL, /* indicates that EKT is not in use */
+ 128, /* replay window size */
NULL
};
@@ -1486,6 +1498,7 @@
},
test_key,
NULL, /* indicates that EKT is not in use */
+ 128, /* replay window size */
NULL
};
@@ -1509,6 +1522,7 @@
},
test_key,
NULL, /* indicates that EKT is not in use */
+ 128, /* replay window size */
NULL
};
@@ -1546,6 +1560,7 @@
},
test_key,
&ekt_test_policy, /* indicates that EKT is not in use */
+ 128, /* replay window size */
NULL
};
@@ -1598,5 +1613,6 @@
},
test_key,
NULL,
+ 128, /* replay window size */
NULL
};