OpenVPN
packet_id.h
Go to the documentation of this file.
1 /*
2  * OpenVPN -- An application to securely tunnel IP networks
3  * over a single TCP/UDP port, with support for SSL/TLS-based
4  * session authentication and key exchange,
5  * packet encryption, packet authentication, and
6  * packet compression.
7  *
8  * Copyright (C) 2002-2023 OpenVPN Inc <sales@openvpn.net>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License version 2
12  * as published by the Free Software Foundation.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License along
20  * with this program; if not, write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22  */
23 
24 /*
25  * These routines are designed to catch replay attacks,
26  * where a man-in-the-middle captures packets and then
27  * attempts to replay them back later.
28  */
29 
30 #ifndef PACKET_ID_H
31 #define PACKET_ID_H
32 
33 #include "circ_list.h"
34 #include "buffer.h"
35 #include "error.h"
36 #include "otime.h"
37 
38 #if 1
39 /*
40  * These are the types that members of
41  * a struct packet_id_net are converted
42  * to for network transmission.
43  */
44 typedef uint32_t packet_id_type;
45 #define PACKET_ID_MAX UINT32_MAX
46 typedef uint32_t net_time_t;
47 
48 /*
49  * In TLS mode, when a packet ID gets to this level,
50  * start thinking about triggering a new
51  * SSL/TLS handshake.
52  */
53 #define PACKET_ID_WRAP_TRIGGER 0xFF000000
54 
55 /* convert a packet_id_type from host to network order */
56 #define htonpid(x) htonl(x)
57 
58 /* convert a packet_id_type from network to host order */
59 #define ntohpid(x) ntohl(x)
60 
61 /* convert a time_t in host order to a net_time_t in network order */
62 #define htontime(x) htonl((net_time_t)x)
63 
64 /* convert a net_time_t in network order to a time_t in host order */
65 #define ntohtime(x) ((time_t)ntohl(x))
66 
67 #else /* if 1 */
68 
69 /*
70  * DEBUGGING ONLY.
71  * Make packet_id_type and net_time_t small
72  * to test wraparound logic and corner cases.
73  */
74 
75 typedef uint8_t packet_id_type;
76 typedef uint16_t net_time_t;
77 
78 #define PACKET_ID_WRAP_TRIGGER 0x80
79 
80 #define htonpid(x) (x)
81 #define ntohpid(x) (x)
82 #define htontime(x) htons((net_time_t)x)
83 #define ntohtime(x) ((time_t)ntohs(x))
84 
85 #endif /* if 1 */
86 
87 /*
88  * Printf formats for special types
89  */
90 #define packet_id_format "%u"
91 typedef unsigned int packet_id_print_type;
92 
93 /*
94  * Maximum allowed backtrack in
95  * sequence number due to packets arriving
96  * out of order.
97  */
98 #define MIN_SEQ_BACKTRACK 0
99 #define MAX_SEQ_BACKTRACK 65536
100 #define DEFAULT_SEQ_BACKTRACK 64
101 
102 /*
103  * Maximum allowed backtrack in
104  * seconds due to packets arriving
105  * out of order.
106  */
107 #define MIN_TIME_BACKTRACK 0
108 #define MAX_TIME_BACKTRACK 600
109 #define DEFAULT_TIME_BACKTRACK 15
110 
111 /*
112  * Do a reap pass through the sequence number
113  * array once every n seconds in order to
114  * expire sequence numbers which can no longer
115  * be accepted because they would violate
116  * TIME_BACKTRACK.
117  */
118 #define SEQ_REAP_INTERVAL 5
119 
120 CIRC_LIST(seq_list, time_t);
121 
122 /*
123  * This is the data structure we keep on the receiving side,
124  * to check that no packet-id (i.e. sequence number + optional timestamp)
125  * is accepted more than once.
126  */
128 {
129  time_t last_reap; /* last call of packet_id_reap */
130  time_t time; /* highest time stamp received */
131  packet_id_type id; /* highest sequence number received */
132  int seq_backtrack; /* set from --replay-window */
133  int time_backtrack; /* set from --replay-window */
134  int max_backtrack_stat; /* maximum backtrack seen so far */
135  bool initialized; /* true if packet_id_init was called */
136  struct seq_list *seq_list; /* packet-id "memory" */
137  const char *name;
138  int unit;
139 };
140 
141 /*
142  * file to facilitate cross-session persistence
143  * of time/id
144  */
145 struct packet_id_persist
146 {
147  const char *filename;
148  int fd;
149  time_t time; /* time stamp */
150  packet_id_type id; /* sequence number */
153 };
154 
156 {
157  time_t time; /* time stamp */
158  packet_id_type id; /* sequence number */
159 };
160 
161 /*
162  * Keep a record of our current packet-id state
163  * on the sending side.
164  */
166 {
168  time_t time;
169 };
170 
171 /*
172  * Communicate packet-id over the wire.
173  * A short packet-id is just a 32 bit
174  * sequence number. A long packet-id
175  * includes a timestamp as well.
176  *
177  * Long packet-ids are used as IVs for
178  * CFB/OFB ciphers.
179  *
180  * This data structure is always sent
181  * over the net in network byte order,
182  * by calling htonpid, ntohpid,
183  * htontime, and ntohtime on the
184  * data elements to change them
185  * to and from standard sizes.
186  *
187  * In addition, time is converted to
188  * a net_time_t before sending,
189  * since openvpn always
190  * uses a 32-bit time_t but some
191  * 64 bit platforms use a
192  * 64 bit time_t.
193  */
195 {
197  time_t time; /* converted to net_time_t before transmission */
198 };
199 
200 struct packet_id
201 {
204 };
205 
206 void packet_id_init(struct packet_id *p, int seq_backtrack, int time_backtrack, const char *name, int unit);
207 
208 void packet_id_free(struct packet_id *p);
209 
210 /* should we accept an incoming packet id ? */
211 bool packet_id_test(struct packet_id_rec *p,
212  const struct packet_id_net *pin);
213 
214 /* change our current state to reflect an accepted packet id */
215 void packet_id_add(struct packet_id_rec *p,
216  const struct packet_id_net *pin);
217 
218 /* expire TIME_BACKTRACK sequence numbers */
219 void packet_id_reap(struct packet_id_rec *p);
220 
221 /*
222  * packet ID persistence
223  */
224 
225 /* initialize the packet_id_persist structure in a disabled state */
227 
228 /* close the file descriptor if it is open, and switch to disabled state */
230 
231 /* load persisted rec packet_id (time and id) only once from file, and set state to enabled */
232 void packet_id_persist_load(struct packet_id_persist *p, const char *filename);
233 
234 /* save persisted rec packet_id (time and id) to file (only if enabled state) */
236 
237 /* transfer packet_id_persist -> packet_id */
238 void packet_id_persist_load_obj(const struct packet_id_persist *p, struct packet_id *pid);
239 
240 /* return an ascii string representing a packet_id_persist object */
241 const char *packet_id_persist_print(const struct packet_id_persist *p, struct gc_arena *gc);
242 
243 /*
244  * Read/write a packet ID to/from the buffer. Short form is sequence number
245  * only. Long form is sequence number and timestamp.
246  */
247 
248 bool packet_id_read(struct packet_id_net *pin, struct buffer *buf, bool long_form);
249 
260 bool packet_id_write(struct packet_id_send *p, struct buffer *buf,
261  bool long_form, bool prepend);
262 
263 /*
264  * Inline functions.
265  */
266 
268 static inline bool
270 {
271  return pid->rec.initialized;
272 }
273 
274 /* are we in enabled state? */
275 static inline bool
277 {
278  return p->fd >= 0;
279 }
280 
281 /* transfer packet_id -> packet_id_persist */
282 static inline void
284 {
285  if (packet_id_persist_enabled(p) && pid->rec.time)
286  {
287  p->time = pid->rec.time;
288  p->id = pid->rec.id;
289  }
290 }
291 
300 static inline void
302 {
303  p->time = 0;
304  p->id = 0;
305 }
306 
307 const char *packet_id_net_print(const struct packet_id_net *pin, bool print_timestamp, struct gc_arena *gc);
308 
309 static inline int
310 packet_id_size(bool long_form)
311 {
312  return sizeof(packet_id_type) + (long_form ? sizeof(net_time_t) : 0);
313 }
314 
315 static inline bool
317 {
318  return p->id >= PACKET_ID_WRAP_TRIGGER;
319 }
320 
321 static inline bool
322 check_timestamp_delta(time_t remote, unsigned int max_delta)
323 {
324  unsigned int abs;
325  const time_t local_now = now;
326 
327  if (local_now >= remote)
328  {
329  abs = local_now - remote;
330  }
331  else
332  {
333  abs = remote - local_now;
334  }
335  return abs <= max_delta;
336 }
337 
338 static inline void
340 {
341  if (p->last_reap + SEQ_REAP_INTERVAL <= now)
342  {
343  packet_id_reap(p);
344  }
345 }
346 
347 #endif /* PACKET_ID_H */
packet_id_send::id
packet_id_type id
Definition: packet_id.h:167
packet_id_rec::id
packet_id_type id
Definition: packet_id.h:131
packet_id_rec::unit
int unit
Definition: packet_id.h:138
error.h
packet_id_persist_init
void packet_id_persist_init(struct packet_id_persist *p)
Definition: packet_id.c:407
packet_id_persist::filename
const char * filename
Definition: packet_id.h:147
packet_id_send::time
time_t time
Definition: packet_id.h:168
packet_id_write
bool packet_id_write(struct packet_id_send *p, struct buffer *buf, bool long_form, bool prepend)
Write a packet ID to buf, and update the packet ID state.
Definition: packet_id.c:347
packet_id_persist_file_image::id
packet_id_type id
Definition: packet_id.h:158
packet_id_persist_enabled
static bool packet_id_persist_enabled(const struct packet_id_persist *p)
Definition: packet_id.h:276
packet_id_net_print
const char * packet_id_net_print(const struct packet_id_net *pin, bool print_timestamp, struct gc_arena *gc)
Definition: packet_id.c:389
packet_id::rec
struct packet_id_rec rec
Definition: packet_id.h:203
CIRC_LIST
CIRC_LIST(seq_list, time_t)
packet_id_persist_file_image
Definition: packet_id.h:155
packet_id_initialized
static bool packet_id_initialized(const struct packet_id *pid)
Is this struct packet_id initialized?
Definition: packet_id.h:269
SEQ_REAP_INTERVAL
#define SEQ_REAP_INTERVAL
Definition: packet_id.h:118
packet_id_persist_file_image::time
time_t time
Definition: packet_id.h:157
packet_id
Definition: packet_id.h:200
packet_id_persist_print
const char * packet_id_persist_print(const struct packet_id_persist *p, struct gc_arena *gc)
Definition: packet_id.c:532
packet_id_read
bool packet_id_read(struct packet_id_net *pin, struct buffer *buf, bool long_form)
Definition: packet_id.c:299
packet_id_net::id
packet_id_type id
Definition: packet_id.h:196
packet_id_persist::id
packet_id_type id
Definition: packet_id.h:150
packet_id_persist_close
void packet_id_persist_close(struct packet_id_persist *p)
Definition: packet_id.c:417
packet_id_persist_load
void packet_id_persist_load(struct packet_id_persist *p, const char *filename)
Definition: packet_id.c:431
packet_id_persist_save_obj
static void packet_id_persist_save_obj(struct packet_id_persist *p, const struct packet_id *pid)
Definition: packet_id.h:283
reset_packet_id_send
static void reset_packet_id_send(struct packet_id_send *p)
Reset the current send packet id to its initial state.
Definition: packet_id.h:301
packet_id_rec::initialized
bool initialized
Definition: packet_id.h:135
packet_id_rec::max_backtrack_stat
int max_backtrack_stat
Definition: packet_id.h:134
circ_list.h
packet_id_rec
Definition: packet_id.h:127
PACKET_ID_WRAP_TRIGGER
#define PACKET_ID_WRAP_TRIGGER
Definition: packet_id.h:53
packet_id_test
bool packet_id_test(struct packet_id_rec *p, const struct packet_id_net *pin)
Definition: packet_id.c:200
packet_id_persist::time
time_t time
Definition: packet_id.h:149
packet_id_rec::seq_backtrack
int seq_backtrack
Definition: packet_id.h:132
packet_id_persist_load_obj
void packet_id_persist_load_obj(const struct packet_id_persist *p, struct packet_id *pid)
Definition: packet_id.c:522
packet_id_type
uint32_t packet_id_type
Definition: packet_id.h:44
packet_id_net::time
time_t time
Definition: packet_id.h:197
buffer
Wrapper structure for dynamically allocated memory.
Definition: buffer.h:60
packet_id_send
Definition: packet_id.h:165
packet_id_rec::name
const char * name
Definition: packet_id.h:137
packet_id_persist_save
void packet_id_persist_save(struct packet_id_persist *p)
Definition: packet_id.c:480
buffer.h
packet_id_print_type
unsigned int packet_id_print_type
Definition: packet_id.h:91
packet_id_reap_test
static void packet_id_reap_test(struct packet_id_rec *p)
Definition: packet_id.h:339
gc_arena
Garbage collection arena used to keep track of dynamically allocated memory.
Definition: buffer.h:116
packet_id_persist::fd
int fd
Definition: packet_id.h:148
packet_id_rec::time_backtrack
int time_backtrack
Definition: packet_id.h:133
packet_id_init
void packet_id_init(struct packet_id *p, int seq_backtrack, int time_backtrack, const char *name, int unit)
Definition: packet_id.c:79
packet_id_free
void packet_id_free(struct packet_id *p)
Definition: packet_id.c:102
packet_id_persist
Definition: openvpn.h:81
packet_id_persist::id_last_written
packet_id_type id_last_written
Definition: packet_id.h:152
otime.h
packet_id::send
struct packet_id_send send
Definition: packet_id.h:202
net_time_t
uint32_t net_time_t
Definition: packet_id.h:46
packet_id_rec::last_reap
time_t last_reap
Definition: packet_id.h:129
packet_id_size
static int packet_id_size(bool long_form)
Definition: packet_id.h:310
packet_id_add
void packet_id_add(struct packet_id_rec *p, const struct packet_id_net *pin)
Definition: packet_id.c:113
packet_id_persist::time_last_written
time_t time_last_written
Definition: packet_id.h:151
now
time_t now
Definition: otime.c:34
packet_id_net
Definition: packet_id.h:194
packet_id_rec::time
time_t time
Definition: packet_id.h:130
check_timestamp_delta
static bool check_timestamp_delta(time_t remote, unsigned int max_delta)
Definition: packet_id.h:322
packet_id_close_to_wrapping
static bool packet_id_close_to_wrapping(const struct packet_id_send *p)
Definition: packet_id.h:316
packet_id_reap
void packet_id_reap(struct packet_id_rec *p)
Definition: packet_id.c:168
packet_id_rec::seq_list
struct seq_list * seq_list
Definition: packet_id.h:136