OLD | NEW |
| (Empty) |
1 /* | |
2 * rdb.c | |
3 * | |
4 * Implements a replay database for packet security | |
5 * | |
6 * David A. McGrew | |
7 * Cisco Systems, Inc. | |
8 */ | |
9 | |
10 /* | |
11 * | |
12 * Copyright (c) 2001-2006, 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 | |
47 #ifdef HAVE_CONFIG_H | |
48 #include <config.h> | |
49 #endif | |
50 | |
51 #include "rdb.h" | |
52 | |
53 | |
54 /* | |
55 * this implementation of a replay database works as follows: | |
56 * | |
57 * window_start is the index of the first packet in the window | |
58 * bitmask a bit-buffer, containing the most recently entered | |
59 * index as the leftmost bit | |
60 * | |
61 */ | |
62 | |
63 /* rdb_init initalizes rdb */ | |
64 | |
65 err_status_t | |
66 rdb_init(rdb_t *rdb) { | |
67 v128_set_to_zero(&rdb->bitmask); | |
68 rdb->window_start = 0; | |
69 return err_status_ok; | |
70 } | |
71 | |
72 /* | |
73 * rdb_check checks to see if index appears in rdb | |
74 */ | |
75 | |
76 err_status_t | |
77 rdb_check(const rdb_t *rdb, uint32_t p_index) { | |
78 | |
79 /* if the index appears after (or at very end of) the window, its good */ | |
80 if (p_index >= rdb->window_start + rdb_bits_in_bitmask) | |
81 return err_status_ok; | |
82 | |
83 /* if the index appears before the window, its bad */ | |
84 if (p_index < rdb->window_start) | |
85 return err_status_replay_old; | |
86 | |
87 /* otherwise, the index appears within the window, so check the bitmask */ | |
88 if (v128_get_bit(&rdb->bitmask, (p_index - rdb->window_start)) == 1) | |
89 return err_status_replay_fail; | |
90 | |
91 /* otherwise, the index is okay */ | |
92 return err_status_ok; | |
93 } | |
94 | |
95 /* | |
96 * rdb_add_index adds index to rdb_t (and does *not* check if | |
97 * index appears in db) | |
98 * | |
99 * this function should be called only after rdb_check has | |
100 * indicated that the index does not appear in the rdb, e.g., a mutex | |
101 * should protect the rdb between these calls | |
102 */ | |
103 | |
104 err_status_t | |
105 rdb_add_index(rdb_t *rdb, uint32_t p_index) { | |
106 int delta; | |
107 | |
108 /* here we *assume* that p_index > rdb->window_start */ | |
109 | |
110 delta = (p_index - rdb->window_start); | |
111 if (delta < rdb_bits_in_bitmask) { | |
112 | |
113 /* if the p_index is within the window, set the appropriate bit */ | |
114 v128_set_bit(&rdb->bitmask, delta); | |
115 | |
116 } else { | |
117 | |
118 delta -= rdb_bits_in_bitmask - 1; | |
119 | |
120 /* shift the window forward by delta bits*/ | |
121 v128_left_shift(&rdb->bitmask, delta); | |
122 v128_set_bit(&rdb->bitmask, rdb_bits_in_bitmask-1); | |
123 rdb->window_start += delta; | |
124 | |
125 } | |
126 | |
127 return err_status_ok; | |
128 } | |
129 | |
130 err_status_t | |
131 rdb_increment(rdb_t *rdb) { | |
132 | |
133 if (rdb->window_start++ > 0x7fffffff) | |
134 return err_status_key_expired; | |
135 return err_status_ok; | |
136 } | |
137 | |
138 uint32_t | |
139 rdb_get_value(const rdb_t *rdb) { | |
140 return rdb->window_start; | |
141 } | |
OLD | NEW |