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