1 /*
2 * replay_driver.c
3 *
4 * A driver for the replay_database implementation
5 *
6 * David A. McGrew
7 * Cisco Systems, Inc.
8 */
9
10 /*
11 *
12 * Copyright (c) 2001-2017, Cisco Systems, Inc.
13 * All rights reserved.
14 *
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
17 * are met:
18 *
19 * Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer.
21 *
22 * Redistributions in binary form must reproduce the above
23 * copyright notice, this list of conditions and the following
24 * disclaimer in the documentation and/or other materials provided
25 * with the distribution.
26 *
27 * Neither the name of the Cisco Systems, Inc. nor the names of its
28 * contributors may be used to endorse or promote products derived
29 * from this software without specific prior written permission.
30 *
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
34 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
35 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
36 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
37 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
38 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
41 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
42 * OF THE POSSIBILITY OF SUCH DAMAGE.
43 *
44 */
45
46 #ifdef HAVE_CONFIG_H
47 #include <config.h>
48 #endif
49
50 #include <stdio.h>
51
52 #include "rdb.h"
53 #include "ut_sim.h"
54
55 /*
56 * num_trials defines the number of trials that are used in the
57 * validation functions below
58 */
59
60 unsigned num_trials = 1 << 16;
61
62 srtp_err_status_t test_rdb_db(void);
63
64 double rdb_check_adds_per_second(void);
65
main(void)66 int main(void)
67 {
68 srtp_err_status_t err;
69
70 printf("testing anti-replay database (srtp_rdb_t)...\n");
71 err = test_rdb_db();
72 if (err) {
73 printf("failed\n");
74 exit(1);
75 }
76 printf("done\n");
77
78 printf("rdb_check/rdb_adds per second: %e\n", rdb_check_adds_per_second());
79
80 return 0;
81 }
82
print_rdb(srtp_rdb_t * rdb)83 void print_rdb(srtp_rdb_t *rdb)
84 {
85 printf("rdb: {%u, %s}\n", rdb->window_start,
86 v128_bit_string(&rdb->bitmask));
87 }
88
rdb_check_add(srtp_rdb_t * rdb,uint32_t idx)89 srtp_err_status_t rdb_check_add(srtp_rdb_t *rdb, uint32_t idx)
90 {
91 if (srtp_rdb_check(rdb, idx) != srtp_err_status_ok) {
92 printf("rdb_check failed at index %u\n", idx);
93 return srtp_err_status_fail;
94 }
95 if (srtp_rdb_add_index(rdb, idx) != srtp_err_status_ok) {
96 printf("rdb_add_index failed at index %u\n", idx);
97 return srtp_err_status_fail;
98 }
99
100 return srtp_err_status_ok;
101 }
102
rdb_check_expect_failure(srtp_rdb_t * rdb,uint32_t idx)103 srtp_err_status_t rdb_check_expect_failure(srtp_rdb_t *rdb, uint32_t idx)
104 {
105 srtp_err_status_t err;
106
107 err = srtp_rdb_check(rdb, idx);
108 if ((err != srtp_err_status_replay_old) &&
109 (err != srtp_err_status_replay_fail)) {
110 printf("rdb_check failed at index %u (false positive)\n", idx);
111 return srtp_err_status_fail;
112 }
113
114 return srtp_err_status_ok;
115 }
116
rdb_check_add_unordered(srtp_rdb_t * rdb,uint32_t idx)117 srtp_err_status_t rdb_check_add_unordered(srtp_rdb_t *rdb, uint32_t idx)
118 {
119 srtp_err_status_t rstat;
120
121 /* printf("index: %u\n", idx); */
122 rstat = srtp_rdb_check(rdb, idx);
123 if ((rstat != srtp_err_status_ok) &&
124 (rstat != srtp_err_status_replay_old)) {
125 printf("rdb_check_add_unordered failed at index %u\n", idx);
126 return rstat;
127 }
128 if (rstat == srtp_err_status_replay_old) {
129 return srtp_err_status_ok;
130 }
131 if (srtp_rdb_add_index(rdb, idx) != srtp_err_status_ok) {
132 printf("rdb_add_index failed at index %u\n", idx);
133 return srtp_err_status_fail;
134 }
135
136 return srtp_err_status_ok;
137 }
138
test_rdb_db()139 srtp_err_status_t test_rdb_db()
140 {
141 srtp_rdb_t rdb;
142 uint32_t idx, ircvd;
143 ut_connection utc;
144 srtp_err_status_t err;
145
146 if (srtp_rdb_init(&rdb) != srtp_err_status_ok) {
147 printf("rdb_init failed\n");
148 return srtp_err_status_init_fail;
149 }
150
151 /* test sequential insertion */
152 for (idx = 0; idx < num_trials; idx++) {
153 err = rdb_check_add(&rdb, idx);
154 if (err)
155 return err;
156 }
157
158 /* test for false positives */
159 for (idx = 0; idx < num_trials; idx++) {
160 err = rdb_check_expect_failure(&rdb, idx);
161 if (err)
162 return err;
163 }
164
165 /* re-initialize */
166 if (srtp_rdb_init(&rdb) != srtp_err_status_ok) {
167 printf("rdb_init failed\n");
168 return srtp_err_status_fail;
169 }
170
171 /* test non-sequential insertion */
172 ut_init(&utc);
173
174 for (idx = 0; idx < num_trials; idx++) {
175 ircvd = ut_next_index(&utc);
176 err = rdb_check_add_unordered(&rdb, ircvd);
177 if (err)
178 return err;
179 err = rdb_check_expect_failure(&rdb, ircvd);
180 if (err)
181 return err;
182 }
183
184 /* re-initialize */
185 if (srtp_rdb_init(&rdb) != srtp_err_status_ok) {
186 printf("rdb_init failed\n");
187 return srtp_err_status_fail;
188 }
189
190 /* test insertion with large gaps */
191 for (idx = 0, ircvd = 0; idx < num_trials;
192 idx++, ircvd += (1 << (rand() % 10))) {
193 err = rdb_check_add(&rdb, ircvd);
194 if (err)
195 return err;
196 err = rdb_check_expect_failure(&rdb, ircvd);
197 if (err)
198 return err;
199 }
200
201 /* re-initialize */
202 if (srtp_rdb_init(&rdb) != srtp_err_status_ok) {
203 printf("rdb_init failed\n");
204 return srtp_err_status_fail;
205 }
206
207 /* test loss of first 513 packets */
208 for (idx = 0; idx < num_trials; idx++) {
209 err = rdb_check_add(&rdb, idx + 513);
210 if (err)
211 return err;
212 }
213
214 /* test for false positives */
215 for (idx = 0; idx < num_trials + 513; idx++) {
216 err = rdb_check_expect_failure(&rdb, idx);
217 if (err)
218 return err;
219 }
220
221 /* test for key expired */
222 if (srtp_rdb_init(&rdb) != srtp_err_status_ok) {
223 printf("rdb_init failed\n");
224 return srtp_err_status_fail;
225 }
226 rdb.window_start = 0x7ffffffe;
227 if (srtp_rdb_increment(&rdb) != srtp_err_status_ok) {
228 printf("srtp_rdb_increment of 0x7ffffffe failed\n");
229 return srtp_err_status_fail;
230 }
231 if (srtp_rdb_get_value(&rdb) != 0x7fffffff) {
232 printf("rdb valiue was not 0x7fffffff\n");
233 return srtp_err_status_fail;
234 }
235 if (srtp_rdb_increment(&rdb) != srtp_err_status_key_expired) {
236 printf("srtp_rdb_increment of 0x7fffffff did not return "
237 "srtp_err_status_key_expired\n");
238 return srtp_err_status_fail;
239 }
240 if (srtp_rdb_get_value(&rdb) != 0x7fffffff) {
241 printf("rdb valiue was not 0x7fffffff\n");
242 return srtp_err_status_fail;
243 }
244
245 return srtp_err_status_ok;
246 }
247
248 #include <time.h> /* for clock() */
249 #include <stdlib.h> /* for random() */
250
251 #define REPLAY_NUM_TRIALS 10000000
252
rdb_check_adds_per_second(void)253 double rdb_check_adds_per_second(void)
254 {
255 uint32_t i;
256 srtp_rdb_t rdb;
257 clock_t timer;
258 int failures = 0; /* count number of failures */
259
260 if (srtp_rdb_init(&rdb) != srtp_err_status_ok) {
261 printf("rdb_init failed\n");
262 exit(1);
263 }
264
265 timer = clock();
266 for (i = 0; i < REPLAY_NUM_TRIALS; i += 3) {
267 if (srtp_rdb_check(&rdb, i + 2) != srtp_err_status_ok)
268 ++failures;
269 if (srtp_rdb_add_index(&rdb, i + 2) != srtp_err_status_ok)
270 ++failures;
271 if (srtp_rdb_check(&rdb, i + 1) != srtp_err_status_ok)
272 ++failures;
273 if (srtp_rdb_add_index(&rdb, i + 1) != srtp_err_status_ok)
274 ++failures;
275 if (srtp_rdb_check(&rdb, i) != srtp_err_status_ok)
276 ++failures;
277 if (srtp_rdb_add_index(&rdb, i) != srtp_err_status_ok)
278 ++failures;
279 }
280 timer = clock() - timer;
281
282 return (double)CLOCKS_PER_SEC * REPLAY_NUM_TRIALS / timer;
283 }
284