1 /* 2 * rdbx.h 3 * 4 * replay database with extended packet indices, using a rollover counter 5 * 6 * David A. McGrew 7 * Cisco Systems, Inc. 8 * 9 */ 10 11 /* 12 * 13 * Copyright (c) 2001-2017, Cisco Systems, Inc. 14 * All rights reserved. 15 * 16 * Redistribution and use in source and binary forms, with or without 17 * modification, are permitted provided that the following conditions 18 * are met: 19 * 20 * Redistributions of source code must retain the above copyright 21 * notice, this list of conditions and the following disclaimer. 22 * 23 * Redistributions in binary form must reproduce the above 24 * copyright notice, this list of conditions and the following 25 * disclaimer in the documentation and/or other materials provided 26 * with the distribution. 27 * 28 * Neither the name of the Cisco Systems, Inc. nor the names of its 29 * contributors may be used to endorse or promote products derived 30 * from this software without specific prior written permission. 31 * 32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 35 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 36 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 37 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 38 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 39 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 40 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 41 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 42 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 43 * OF THE POSSIBILITY OF SUCH DAMAGE. 44 * 45 */ 46 47 #ifndef RDBX_H 48 #define RDBX_H 49 50 #include "datatypes.h" 51 #include "err.h" 52 53 #ifdef __cplusplus 54 extern "C" { 55 #endif 56 57 /* #define ROC_TEST */ 58 59 #ifndef ROC_TEST 60 61 typedef uint16_t srtp_sequence_number_t; /* 16 bit sequence number */ 62 typedef uint32_t srtp_rollover_counter_t; /* 32 bit rollover counter */ 63 64 #else /* use small seq_num and roc datatypes for testing purposes */ 65 66 typedef unsigned char srtp_sequence_number_t; /* 8 bit sequence number */ 67 typedef uint16_t srtp_rollover_counter_t; /* 16 bit rollover counter */ 68 69 #endif 70 71 #define seq_num_median (1 << (8 * sizeof(srtp_sequence_number_t) - 1)) 72 #define seq_num_max (1 << (8 * sizeof(srtp_sequence_number_t))) 73 74 /* 75 * An rtp_xtd_seq_num_t is a 64-bit unsigned integer used as an 'extended' 76 * sequence number. 77 */ 78 typedef uint64_t srtp_xtd_seq_num_t; 79 80 /* 81 * An srtp_rdbx_t is a replay database with extended range; it uses an 82 * xtd_seq_num_t and a bitmask of recently received indices. 83 */ 84 typedef struct { 85 srtp_xtd_seq_num_t index; 86 bitvector_t bitmask; 87 } srtp_rdbx_t; 88 89 /* 90 * srtp_rdbx_init(rdbx_ptr, ws) 91 * 92 * initializes the rdbx pointed to by its argument with the window size ws, 93 * setting the rollover counter and sequence number to zero 94 */ 95 srtp_err_status_t srtp_rdbx_init(srtp_rdbx_t *rdbx, unsigned long ws); 96 97 /* 98 * srtp_rdbx_dealloc(rdbx_ptr) 99 * 100 * frees memory associated with the rdbx 101 */ 102 srtp_err_status_t srtp_rdbx_dealloc(srtp_rdbx_t *rdbx); 103 104 /* 105 * srtp_rdbx_estimate_index(rdbx, guess, s) 106 * 107 * given an rdbx and a sequence number s (from a newly arrived packet), 108 * sets the contents of *guess to contain the best guess of the packet 109 * index to which s corresponds, and returns the difference between 110 * *guess and the locally stored synch info 111 */ 112 int32_t srtp_rdbx_estimate_index(const srtp_rdbx_t *rdbx, 113 srtp_xtd_seq_num_t *guess, 114 srtp_sequence_number_t s); 115 116 /* 117 * srtp_rdbx_check(rdbx, delta); 118 * 119 * srtp_rdbx_check(&r, delta) checks to see if the xtd_seq_num_t 120 * which is at rdbx->window_start + delta is in the rdb 121 * 122 */ 123 srtp_err_status_t srtp_rdbx_check(const srtp_rdbx_t *rdbx, int difference); 124 125 /* 126 * srtp_replay_add_index(rdbx, delta) 127 * 128 * adds the srtp_xtd_seq_num_t at rdbx->window_start + delta to replay_db 129 * (and does *not* check if that xtd_seq_num_t appears in db) 130 * 131 * this function should be called *only* after replay_check has 132 * indicated that the index does not appear in the rdbx, and a mutex 133 * should protect the rdbx between these calls if necessary. 134 */ 135 srtp_err_status_t srtp_rdbx_add_index(srtp_rdbx_t *rdbx, int delta); 136 137 /* 138 * srtp_rdbx_set_roc(rdbx, roc) initalizes the srtp_rdbx_t at the location rdbx 139 * to have the rollover counter value roc. If that value is less than 140 * the current rollover counter value, then the function returns 141 * srtp_err_status_replay_old; otherwise, srtp_err_status_ok is returned. 142 * 143 */ 144 srtp_err_status_t srtp_rdbx_set_roc(srtp_rdbx_t *rdbx, uint32_t roc); 145 146 /* 147 * srtp_rdbx_get_packet_index(rdbx) returns the value of the rollover counter 148 * for 149 * the srtp_rdbx_t pointed to by rdbx 150 * 151 */ 152 srtp_xtd_seq_num_t srtp_rdbx_get_packet_index(const srtp_rdbx_t *rdbx); 153 154 /* 155 * srtp_xtd_seq_num_t functions - these are *internal* functions of rdbx, and 156 * shouldn't be used to manipulate rdbx internal values. use the rdbx 157 * api instead! 158 */ 159 160 /* 161 * srtp_rdbx_get_ws(rdbx_ptr) 162 * 163 * gets the window size which was used to initialize the rdbx 164 */ 165 unsigned long srtp_rdbx_get_window_size(const srtp_rdbx_t *rdbx); 166 167 /* index_init(&pi) initializes a packet index pi (sets it to zero) */ 168 void srtp_index_init(srtp_xtd_seq_num_t *pi); 169 170 /* index_advance(&pi, s) advances a xtd_seq_num_t forward by s */ 171 void srtp_index_advance(srtp_xtd_seq_num_t *pi, srtp_sequence_number_t s); 172 173 /* 174 * srtp_index_guess(local, guess, s) 175 * 176 * given a srtp_xtd_seq_num_t local (which represents the highest 177 * known-to-be-good index) and a sequence number s (from a newly 178 * arrived packet), sets the contents of *guess to contain the best 179 * guess of the packet index to which s corresponds, and returns the 180 * difference between *guess and *local 181 */ 182 int32_t srtp_index_guess(const srtp_xtd_seq_num_t *local, 183 srtp_xtd_seq_num_t *guess, 184 srtp_sequence_number_t s); 185 186 /* 187 * srtp_rdbx_get_roc(rdbx) 188 * 189 * Get the current rollover counter 190 * 191 */ 192 uint32_t srtp_rdbx_get_roc(const srtp_rdbx_t *rdbx); 193 194 /* 195 * srtp_rdbx_set_roc_seq(rdbx, roc, seq) initalizes the srtp_rdbx_t at the 196 * location rdbx to have the rollover counter value roc and packet sequence 197 * number seq. If the new rollover counter value is less than the current 198 * rollover counter value, then the function returns 199 * srtp_err_status_replay_old, otherwise, srtp_err_status_ok is returned. 200 */ 201 srtp_err_status_t srtp_rdbx_set_roc_seq(srtp_rdbx_t *rdbx, 202 uint32_t roc, 203 uint16_t seq); 204 205 #ifdef __cplusplus 206 } 207 #endif 208 209 #endif /* RDBX_H */ 210