OLD | NEW |
1 /* | 1 /* |
2 * rdb.c | 2 * rdb.c |
3 * | 3 * |
4 * Implements a replay database for packet security | 4 * Implements a replay database for packet security |
5 * | 5 * |
6 * David A. McGrew | 6 * David A. McGrew |
7 * Cisco Systems, Inc. | 7 * Cisco Systems, Inc. |
8 */ | 8 */ |
9 | 9 |
10 /* | 10 /* |
11 *» | 11 * |
12 * Copyright (c) 2001-2006, Cisco Systems, Inc. | 12 * Copyright (c) 2001-2006, Cisco Systems, Inc. |
13 * All rights reserved. | 13 * All rights reserved. |
14 * | 14 * |
15 * Redistribution and use in source and binary forms, with or without | 15 * Redistribution and use in source and binary forms, with or without |
16 * modification, are permitted provided that the following conditions | 16 * modification, are permitted provided that the following conditions |
17 * are met: | 17 * are met: |
18 * | 18 * |
19 * Redistributions of source code must retain the above copyright | 19 * Redistributions of source code must retain the above copyright |
20 * notice, this list of conditions and the following disclaimer. | 20 * notice, this list of conditions and the following disclaimer. |
21 * | 21 * |
22 * Redistributions in binary form must reproduce the above | 22 * Redistributions in binary form must reproduce the above |
23 * copyright notice, this list of conditions and the following | 23 * copyright notice, this list of conditions and the following |
24 * disclaimer in the documentation and/or other materials provided | 24 * disclaimer in the documentation and/or other materials provided |
25 * with the distribution. | 25 * with the distribution. |
26 * | 26 * |
27 * Neither the name of the Cisco Systems, Inc. nor the names of its | 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 | 28 * contributors may be used to endorse or promote products derived |
29 * from this software without specific prior written permission. | 29 * from this software without specific prior written permission. |
30 * | 30 * |
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
34 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | 34 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
35 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, | 35 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
36 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 36 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
37 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | 37 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
38 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 38 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | 39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
41 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | 41 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED |
42 * OF THE POSSIBILITY OF SUCH DAMAGE. | 42 * OF THE POSSIBILITY OF SUCH DAMAGE. |
43 * | 43 * |
44 */ | 44 */ |
45 | 45 |
46 | 46 |
47 #ifdef HAVE_CONFIG_H | 47 #ifdef HAVE_CONFIG_H |
48 #include <config.h> | 48 #include <config.h> |
49 #endif | 49 #endif |
50 | 50 |
51 #include "rdb.h" | 51 #include "rdb.h" |
52 | 52 |
53 | 53 |
54 /* | 54 /* |
55 * this implementation of a replay database works as follows: | 55 * this implementation of a replay database works as follows: |
56 * | 56 * |
57 * window_start is the index of the first packet in the window | 57 * window_start is the index of the first packet in the window |
58 * bitmask a bit-buffer, containing the most recently entered | 58 * bitmask a bit-buffer, containing the most recently entered |
59 * index as the leftmost bit | 59 * index as the leftmost bit |
60 * | 60 * |
61 */ | 61 */ |
62 | 62 |
63 /* rdb_init initalizes rdb */ | 63 /* srtp_rdb_init initalizes rdb */ |
64 | 64 srtp_err_status_t srtp_rdb_init (srtp_rdb_t *rdb) |
65 err_status_t | 65 { |
66 rdb_init(rdb_t *rdb) { | 66 v128_set_to_zero(&rdb->bitmask); |
67 v128_set_to_zero(&rdb->bitmask); | 67 rdb->window_start = 0; |
68 rdb->window_start = 0; | 68 return srtp_err_status_ok; |
69 return err_status_ok; | |
70 } | 69 } |
71 | 70 |
72 /* | 71 /* |
73 * rdb_check checks to see if index appears in rdb | 72 * srtp_rdb_check checks to see if index appears in rdb |
74 */ | 73 */ |
| 74 srtp_err_status_t srtp_rdb_check (const srtp_rdb_t *rdb, uint32_t p_index) |
| 75 { |
75 | 76 |
76 err_status_t | 77 /* if the index appears after (or at very end of) the window, its good */ |
77 rdb_check(const rdb_t *rdb, uint32_t p_index) { | 78 if (p_index >= rdb->window_start + rdb_bits_in_bitmask) { |
78 | 79 return srtp_err_status_ok; |
79 /* if the index appears after (or at very end of) the window, its good */ | 80 } |
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 | 81 |
87 /* otherwise, the index appears within the window, so check the bitmask */ | 82 /* if the index appears before the window, its bad */ |
88 if (v128_get_bit(&rdb->bitmask, (p_index - rdb->window_start)) == 1) | 83 if (p_index < rdb->window_start) { |
89 return err_status_replay_fail; | 84 return srtp_err_status_replay_old; |
90 | 85 } |
91 /* otherwise, the index is okay */ | 86 |
92 return err_status_ok; | 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 srtp_err_status_replay_fail; |
| 90 } |
| 91 |
| 92 /* otherwise, the index is okay */ |
| 93 return srtp_err_status_ok; |
93 } | 94 } |
94 | 95 |
95 /* | 96 /* |
96 * rdb_add_index adds index to rdb_t (and does *not* check if | 97 * srtp_rdb_add_index adds index to srtp_rdb_t (and does *not* check if |
97 * index appears in db) | 98 * index appears in db) |
98 * | 99 * |
99 * this function should be called only after rdb_check has | 100 * this function should be called only after srtp_rdb_check has |
100 * indicated that the index does not appear in the rdb, e.g., a mutex | 101 * indicated that the index does not appear in the rdb, e.g., a mutex |
101 * should protect the rdb between these calls | 102 * should protect the rdb between these calls |
102 */ | 103 */ |
| 104 srtp_err_status_t srtp_rdb_add_index (srtp_rdb_t *rdb, uint32_t p_index) |
| 105 { |
| 106 int delta; |
103 | 107 |
104 err_status_t | 108 /* here we *assume* that p_index > rdb->window_start */ |
105 rdb_add_index(rdb_t *rdb, uint32_t p_index) { | |
106 int delta; | |
107 | 109 |
108 /* here we *assume* that p_index > rdb->window_start */ | 110 delta = (p_index - rdb->window_start); |
| 111 if (delta < rdb_bits_in_bitmask) { |
109 | 112 |
110 delta = (p_index - rdb->window_start); | 113 /* if the p_index is within the window, set the appropriate bit */ |
111 if (delta < rdb_bits_in_bitmask) { | 114 v128_set_bit(&rdb->bitmask, delta); |
112 | 115 |
113 /* if the p_index is within the window, set the appropriate bit */ | 116 } else { |
114 v128_set_bit(&rdb->bitmask, delta); | |
115 | 117 |
116 } else { | 118 delta -= rdb_bits_in_bitmask - 1; |
117 | |
118 delta -= rdb_bits_in_bitmask - 1; | |
119 | 119 |
120 /* shift the window forward by delta bits*/ | 120 /* shift the window forward by delta bits*/ |
121 v128_left_shift(&rdb->bitmask, delta); | 121 v128_left_shift(&rdb->bitmask, delta); |
122 v128_set_bit(&rdb->bitmask, rdb_bits_in_bitmask-1); | 122 v128_set_bit(&rdb->bitmask, rdb_bits_in_bitmask - 1); |
123 rdb->window_start += delta; | 123 rdb->window_start += delta; |
124 | 124 |
125 } | 125 } |
126 | 126 |
127 return err_status_ok; | 127 return srtp_err_status_ok; |
128 } | 128 } |
129 | 129 |
130 err_status_t | 130 srtp_err_status_t srtp_rdb_increment (srtp_rdb_t *rdb) |
131 rdb_increment(rdb_t *rdb) { | 131 { |
132 | 132 |
133 if (rdb->window_start++ > 0x7fffffff) | 133 if (rdb->window_start++ > 0x7fffffff) { |
134 return err_status_key_expired; | 134 return srtp_err_status_key_expired; |
135 return err_status_ok; | 135 } |
| 136 return srtp_err_status_ok; |
136 } | 137 } |
137 | 138 |
138 uint32_t | 139 uint32_t srtp_rdb_get_value (const srtp_rdb_t *rdb) |
139 rdb_get_value(const rdb_t *rdb) { | 140 { |
140 return rdb->window_start; | 141 return rdb->window_start; |
141 } | 142 } |
OLD | NEW |