replay_driver.c (7636B)
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 #include "cipher_priv.h" 56 57 /* 58 * num_trials defines the number of trials that are used in the 59 * validation functions below 60 */ 61 62 unsigned num_trials = 1 << 16; 63 64 srtp_err_status_t test_rdb_db(void); 65 66 double rdb_check_adds_per_second(void); 67 68 int main(void) 69 { 70 srtp_err_status_t err; 71 72 printf("testing anti-replay database (srtp_rdb_t)...\n"); 73 err = test_rdb_db(); 74 if (err) { 75 printf("failed\n"); 76 exit(1); 77 } 78 printf("done\n"); 79 80 printf("rdb_check/rdb_adds per second: %e\n", rdb_check_adds_per_second()); 81 82 return 0; 83 } 84 85 srtp_err_status_t rdb_check_add(srtp_rdb_t *rdb, uint32_t idx) 86 { 87 if (srtp_rdb_check(rdb, idx) != srtp_err_status_ok) { 88 printf("rdb_check failed at index %u\n", idx); 89 return srtp_err_status_fail; 90 } 91 if (srtp_rdb_add_index(rdb, idx) != srtp_err_status_ok) { 92 printf("rdb_add_index failed at index %u\n", idx); 93 return srtp_err_status_fail; 94 } 95 96 return srtp_err_status_ok; 97 } 98 99 srtp_err_status_t rdb_check_expect_failure(srtp_rdb_t *rdb, uint32_t idx) 100 { 101 srtp_err_status_t err; 102 103 err = srtp_rdb_check(rdb, idx); 104 if ((err != srtp_err_status_replay_old) && 105 (err != srtp_err_status_replay_fail)) { 106 printf("rdb_check failed at index %u (false positive)\n", idx); 107 return srtp_err_status_fail; 108 } 109 110 return srtp_err_status_ok; 111 } 112 113 srtp_err_status_t rdb_check_add_unordered(srtp_rdb_t *rdb, uint32_t idx) 114 { 115 srtp_err_status_t rstat; 116 117 /* printf("index: %u\n", idx); */ 118 rstat = srtp_rdb_check(rdb, idx); 119 if ((rstat != srtp_err_status_ok) && 120 (rstat != srtp_err_status_replay_old)) { 121 printf("rdb_check_add_unordered failed at index %u\n", idx); 122 return rstat; 123 } 124 if (rstat == srtp_err_status_replay_old) { 125 return srtp_err_status_ok; 126 } 127 if (srtp_rdb_add_index(rdb, idx) != srtp_err_status_ok) { 128 printf("rdb_add_index failed at index %u\n", idx); 129 return srtp_err_status_fail; 130 } 131 132 return srtp_err_status_ok; 133 } 134 135 srtp_err_status_t test_rdb_db(void) 136 { 137 srtp_rdb_t rdb; 138 uint32_t idx, ircvd; 139 ut_connection utc; 140 srtp_err_status_t err; 141 142 if (srtp_rdb_init(&rdb) != srtp_err_status_ok) { 143 printf("rdb_init failed\n"); 144 return srtp_err_status_init_fail; 145 } 146 147 /* test sequential insertion */ 148 for (idx = 0; idx < num_trials; idx++) { 149 err = rdb_check_add(&rdb, idx); 150 if (err) 151 return err; 152 } 153 154 /* test for false positives */ 155 for (idx = 0; idx < num_trials; idx++) { 156 err = rdb_check_expect_failure(&rdb, idx); 157 if (err) 158 return err; 159 } 160 161 /* re-initialize */ 162 if (srtp_rdb_init(&rdb) != srtp_err_status_ok) { 163 printf("rdb_init failed\n"); 164 return srtp_err_status_fail; 165 } 166 167 /* test non-sequential insertion */ 168 ut_init(&utc); 169 170 for (idx = 0; idx < num_trials; idx++) { 171 ircvd = ut_next_index(&utc); 172 err = rdb_check_add_unordered(&rdb, ircvd); 173 if (err) 174 return err; 175 err = rdb_check_expect_failure(&rdb, ircvd); 176 if (err) 177 return err; 178 } 179 180 /* re-initialize */ 181 if (srtp_rdb_init(&rdb) != srtp_err_status_ok) { 182 printf("rdb_init failed\n"); 183 return srtp_err_status_fail; 184 } 185 186 /* test insertion with large gaps */ 187 for (idx = 0, ircvd = 0; idx < num_trials; 188 idx++, ircvd += (1 << (srtp_cipher_rand_u32_for_tests() % 10))) { 189 err = rdb_check_add(&rdb, ircvd); 190 if (err) 191 return err; 192 err = rdb_check_expect_failure(&rdb, ircvd); 193 if (err) 194 return err; 195 } 196 197 /* re-initialize */ 198 if (srtp_rdb_init(&rdb) != srtp_err_status_ok) { 199 printf("rdb_init failed\n"); 200 return srtp_err_status_fail; 201 } 202 203 /* test loss of first 513 packets */ 204 for (idx = 0; idx < num_trials; idx++) { 205 err = rdb_check_add(&rdb, idx + 513); 206 if (err) 207 return err; 208 } 209 210 /* test for false positives */ 211 for (idx = 0; idx < num_trials + 513; idx++) { 212 err = rdb_check_expect_failure(&rdb, idx); 213 if (err) 214 return err; 215 } 216 217 /* test for key expired */ 218 if (srtp_rdb_init(&rdb) != srtp_err_status_ok) { 219 printf("rdb_init failed\n"); 220 return srtp_err_status_fail; 221 } 222 rdb.window_start = 0x7ffffffe; 223 if (srtp_rdb_increment(&rdb) != srtp_err_status_ok) { 224 printf("srtp_rdb_increment of 0x7ffffffe failed\n"); 225 return srtp_err_status_fail; 226 } 227 if (srtp_rdb_get_value(&rdb) != 0x7fffffff) { 228 printf("rdb valiue was not 0x7fffffff\n"); 229 return srtp_err_status_fail; 230 } 231 if (srtp_rdb_increment(&rdb) != srtp_err_status_key_expired) { 232 printf("srtp_rdb_increment of 0x7fffffff did not return " 233 "srtp_err_status_key_expired\n"); 234 return srtp_err_status_fail; 235 } 236 if (srtp_rdb_get_value(&rdb) != 0x7fffffff) { 237 printf("rdb valiue was not 0x7fffffff\n"); 238 return srtp_err_status_fail; 239 } 240 241 return srtp_err_status_ok; 242 } 243 244 #include <time.h> /* for clock() */ 245 #include <stdlib.h> /* for random() */ 246 247 #define REPLAY_NUM_TRIALS 10000000 248 249 double rdb_check_adds_per_second(void) 250 { 251 uint32_t i; 252 srtp_rdb_t rdb; 253 clock_t timer; 254 255 if (srtp_rdb_init(&rdb) != srtp_err_status_ok) { 256 printf("rdb_init failed\n"); 257 exit(1); 258 } 259 260 timer = clock(); 261 for (i = 0; i < REPLAY_NUM_TRIALS; i += 3) { 262 srtp_rdb_check(&rdb, i + 2); 263 srtp_rdb_add_index(&rdb, i + 2); 264 srtp_rdb_check(&rdb, i + 1); 265 srtp_rdb_add_index(&rdb, i + 1); 266 srtp_rdb_check(&rdb, i); 267 srtp_rdb_add_index(&rdb, i); 268 } 269 timer = clock() - timer; 270 271 return (double)CLOCKS_PER_SEC * REPLAY_NUM_TRIALS / timer; 272 }