diff options
Diffstat (limited to 'third_party/srtp/crypto/replay/rdbx.c')
-rw-r--r-- | third_party/srtp/crypto/replay/rdbx.c | 107 |
1 files changed, 87 insertions, 20 deletions
diff --git a/third_party/srtp/crypto/replay/rdbx.c b/third_party/srtp/crypto/replay/rdbx.c index 12e4e8f8..153676f3 100644 --- a/third_party/srtp/crypto/replay/rdbx.c +++ b/third_party/srtp/crypto/replay/rdbx.c @@ -43,20 +43,23 @@ * */ +#ifdef HAVE_CONFIG_H + #include <config.h> +#endif + #include "rdbx.h" -#define rdbx_high_bit_in_bitmask 127 /* - * from draft-ietf-avt-srtp-00.txt: + * from RFC 3711: * * A receiver reconstructs the index i of a packet with sequence - * number s using the estimate + * number SEQ using the estimate * - * i = 65,536 * t + s, + * i = 2^16 * v + SEQ, * - * where t is chosen from the set { r-1, r, r+1 } such that i is - * closest to the value 65,536 * r + s_l. If the value r+1 is used, + * where v is chosen from the set { ROC-1, ROC, ROC+1 } such that i is + * closest to the value 2^16 * ROC + s_l. If the value r+1 is used, * then the rollover counter r in the cryptographic context is * incremented by one (if the packet containing s is authentic). */ @@ -146,18 +149,18 @@ index_guess(const xtd_seq_num_t *local, if (local_seq < seq_num_median) { if (s - local_seq > seq_num_median) { guess_roc = local_roc - 1; - difference = seq_num_max - s + local_seq; + difference = s - local_seq - seq_num_max; } else { guess_roc = local_roc; difference = s - local_seq; } } else { if (local_seq - seq_num_median > s) { - guess_roc = local_roc+1; - difference = seq_num_max - local_seq + s; + guess_roc = local_roc + 1; + difference = s - local_seq + seq_num_max; } else { - difference = s - local_seq; guess_roc = local_roc; + difference = s - local_seq; } } guess_seq = s; @@ -180,17 +183,81 @@ index_guess(const xtd_seq_num_t *local, /* - * 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 + * to have the rollover counter value roc. If that value is less than + * the current rollover counter value, then the function returns + * err_status_replay_old; otherwise, err_status_ok is returned. + * + */ + +err_status_t +rdbx_set_roc(rdbx_t *rdbx, uint32_t roc) { + bitvector_set_to_zero(&rdbx->bitmask); + +#ifdef NO_64BIT_MATH + #error not yet implemented +#else + + /* make sure that we're not moving backwards */ + if (roc < (rdbx->index >> 16)) + return err_status_replay_old; + + rdbx->index &= 0xffff; /* retain lowest 16 bits */ + rdbx->index |= ((uint64_t)roc) << 16; /* set ROC */ +#endif + + return err_status_ok; +} + +/* + * rdbx_get_packet_index(rdbx) returns the value of the packet index + * for the rdbx_t pointed to by rdbx + * + */ + +xtd_seq_num_t +rdbx_get_packet_index(const rdbx_t *rdbx) { + return rdbx->index; +} + +/* + * 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 @@ -202,11 +269,11 @@ rdbx_check(const rdbx_t *rdbx, int delta) { 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; } @@ -230,11 +297,11 @@ rdbx_add_index(rdbx_t *rdbx, int delta) { 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, so flip bit in bitmask */ - v128_set_bit(&rdbx->bitmask, -delta); + /* delta is in window */ + bitvector_set_bit(&rdbx->bitmask, bitvector_get_length(&rdbx->bitmask) -1 + delta); } /* note that we need not consider the case that delta == 0 */ |