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-2018 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 /*
39  * Enables OpenVPN to be compiled in special packet_id test mode.
40  */
41 /*#define PID_TEST*/
42 
43 #if 1
44 /*
45  * These are the types that members of
46  * a struct packet_id_net are converted
47  * to for network transmission.
48  */
50 #define PACKET_ID_MAX UINT32_MAX
52 
53 /*
54  * In TLS mode, when a packet ID gets to this level,
55  * start thinking about triggering a new
56  * SSL/TLS handshake.
57  */
58 #define PACKET_ID_WRAP_TRIGGER 0xFF000000
59 
60 /* convert a packet_id_type from host to network order */
61 #define htonpid(x) htonl(x)
62 
63 /* convert a packet_id_type from network to host order */
64 #define ntohpid(x) ntohl(x)
65 
66 /* convert a time_t in host order to a net_time_t in network order */
67 #define htontime(x) htonl((net_time_t)x)
68 
69 /* convert a net_time_t in network order to a time_t in host order */
70 #define ntohtime(x) ((time_t)ntohl(x))
71 
72 #else /* if 1 */
73 
74 /*
75  * DEBUGGING ONLY.
76  * Make packet_id_type and net_time_t small
77  * to test wraparound logic and corner cases.
78  */
79 
80 typedef uint8_t packet_id_type;
81 typedef uint16_t net_time_t;
82 
83 #define PACKET_ID_WRAP_TRIGGER 0x80
84 
85 #define htonpid(x) (x)
86 #define ntohpid(x) (x)
87 #define htontime(x) htons((net_time_t)x)
88 #define ntohtime(x) ((time_t)ntohs(x))
89 
90 #endif /* if 1 */
91 
92 /*
93  * Printf formats for special types
94  */
95 #define packet_id_format "%u"
96 typedef unsigned int packet_id_print_type;
97 
98 /*
99  * Maximum allowed backtrack in
100  * sequence number due to packets arriving
101  * out of order.
102  */
103 #define MIN_SEQ_BACKTRACK 0
104 #define MAX_SEQ_BACKTRACK 65536
105 #define DEFAULT_SEQ_BACKTRACK 64
106 
107 /*
108  * Maximum allowed backtrack in
109  * seconds due to packets arriving
110  * out of order.
111  */
112 #define MIN_TIME_BACKTRACK 0
113 #define MAX_TIME_BACKTRACK 600
114 #define DEFAULT_TIME_BACKTRACK 15
115 
116 /*
117  * Do a reap pass through the sequence number
118  * array once every n seconds in order to
119  * expire sequence numbers which can no longer
120  * be accepted because they would violate
121  * TIME_BACKTRACK.
122  */
123 #define SEQ_REAP_INTERVAL 5
124 
125 CIRC_LIST(seq_list, time_t);
126 
127 /*
128  * This is the data structure we keep on the receiving side,
129  * to check that no packet-id (i.e. sequence number + optional timestamp)
130  * is accepted more than once.
131  */
133 {
134  time_t last_reap; /* last call of packet_id_reap */
135  time_t time; /* highest time stamp received */
136  packet_id_type id; /* highest sequence number received */
137  int seq_backtrack; /* set from --replay-window */
138  int time_backtrack; /* set from --replay-window */
139  int max_backtrack_stat; /* maximum backtrack seen so far */
140  bool initialized; /* true if packet_id_init was called */
141  struct seq_list *seq_list; /* packet-id "memory" */
142  const char *name;
143  int unit;
144 };
145 
146 /*
147  * file to facilitate cross-session persistence
148  * of time/id
149  */
150 struct packet_id_persist
151 {
152  const char *filename;
153  int fd;
154  time_t time; /* time stamp */
155  packet_id_type id; /* sequence number */
158 };
159 
161 {
162  time_t time; /* time stamp */
163  packet_id_type id; /* sequence number */
164 };
165 
166 /*
167  * Keep a record of our current packet-id state
168  * on the sending side.
169  */
171 {
173  time_t time;
174 };
175 
176 /*
177  * Communicate packet-id over the wire.
178  * A short packet-id is just a 32 bit
179  * sequence number. A long packet-id
180  * includes a timestamp as well.
181  *
182  * Long packet-ids are used as IVs for
183  * CFB/OFB ciphers.
184  *
185  * This data structure is always sent
186  * over the net in network byte order,
187  * by calling htonpid, ntohpid,
188  * htontime, and ntohtime on the
189  * data elements to change them
190  * to and from standard sizes.
191  *
192  * In addition, time is converted to
193  * a net_time_t before sending,
194  * since openvpn always
195  * uses a 32-bit time_t but some
196  * 64 bit platforms use a
197  * 64 bit time_t.
198  */
200 {
202  time_t time; /* converted to net_time_t before transmission */
203 };
204 
205 struct packet_id
206 {
207  struct packet_id_send send;
208  struct packet_id_rec rec;
209 };
210 
211 void packet_id_init(struct packet_id *p, int seq_backtrack, int time_backtrack, const char *name, int unit);
212 
213 void packet_id_free(struct packet_id *p);
214 
215 /* should we accept an incoming packet id ? */
216 bool packet_id_test(struct packet_id_rec *p,
217  const struct packet_id_net *pin);
218 
219 /* change our current state to reflect an accepted packet id */
220 void packet_id_add(struct packet_id_rec *p,
221  const struct packet_id_net *pin);
222 
223 /* expire TIME_BACKTRACK sequence numbers */
224 void packet_id_reap(struct packet_id_rec *p);
225 
226 /*
227  * packet ID persistence
228  */
229 
230 /* initialize the packet_id_persist structure in a disabled state */
232 
233 /* close the file descriptor if it is open, and switch to disabled state */
235 
236 /* load persisted rec packet_id (time and id) only once from file, and set state to enabled */
237 void packet_id_persist_load(struct packet_id_persist *p, const char *filename);
238 
239 /* save persisted rec packet_id (time and id) to file (only if enabled state) */
241 
242 /* transfer packet_id_persist -> packet_id */
243 void packet_id_persist_load_obj(const struct packet_id_persist *p, struct packet_id *pid);
244 
245 /* return an ascii string representing a packet_id_persist object */
246 const char *packet_id_persist_print(const struct packet_id_persist *p, struct gc_arena *gc);
247 
248 /*
249  * Read/write a packet ID to/from the buffer. Short form is sequence number
250  * only. Long form is sequence number and timestamp.
251  */
252 
253 bool packet_id_read(struct packet_id_net *pin, struct buffer *buf, bool long_form);
254 
265 bool packet_id_write(struct packet_id_send *p, struct buffer *buf,
266  bool long_form, bool prepend);
267 
268 /*
269  * Inline functions.
270  */
271 
273 static inline bool
275 {
276  return pid->rec.initialized;
277 }
278 
279 /* are we in enabled state? */
280 static inline bool
282 {
283  return p->fd >= 0;
284 }
285 
286 /* transfer packet_id -> packet_id_persist */
287 static inline void
289 {
290  if (packet_id_persist_enabled(p) && pid->rec.time)
291  {
292  p->time = pid->rec.time;
293  p->id = pid->rec.id;
294  }
295 }
296 
297 const char *packet_id_net_print(const struct packet_id_net *pin, bool print_timestamp, struct gc_arena *gc);
298 
299 #ifdef PID_TEST
300 void packet_id_interactive_test(void);
301 
302 #endif
303 
304 static inline int
305 packet_id_size(bool long_form)
306 {
307  return sizeof(packet_id_type) + (long_form ? sizeof(net_time_t) : 0);
308 }
309 
310 static inline bool
312 {
313  return p->id >= PACKET_ID_WRAP_TRIGGER;
314 }
315 
316 static inline bool
317 check_timestamp_delta(time_t remote, unsigned int max_delta)
318 {
319  unsigned int abs;
320  const time_t local_now = now;
321 
322  if (local_now >= remote)
323  {
324  abs = local_now - remote;
325  }
326  else
327  {
328  abs = remote - local_now;
329  }
330  return abs <= max_delta;
331 }
332 
333 static inline void
335 {
336  if (p->last_reap + SEQ_REAP_INTERVAL <= now)
337  {
338  packet_id_reap(p);
339  }
340 }
341 
342 #endif /* PACKET_ID_H */
void packet_id_persist_load(struct packet_id_persist *p, const char *filename)
Definition: packet_id.c:433
bool packet_id_read(struct packet_id_net *pin, struct buffer *buf, bool long_form)
Definition: packet_id.c:301
int time_backtrack
Definition: packet_id.h:138
int max_backtrack_stat
Definition: packet_id.h:139
int seq_backtrack
Definition: packet_id.h:137
void packet_id_free(struct packet_id *p)
Definition: packet_id.c:101
void packet_id_persist_save(struct packet_id_persist *p)
Definition: packet_id.c:482
#define SEQ_REAP_INTERVAL
Definition: packet_id.h:123
packet_id_type id
Definition: packet_id.h:201
packet_id_type id_last_written
Definition: packet_id.h:157
time_t last_reap
Definition: packet_id.h:134
time_t time_last_written
Definition: packet_id.h:156
const char * name
Definition: packet_id.h:142
static bool check_timestamp_delta(time_t remote, unsigned int max_delta)
Definition: packet_id.h:317
time_t time
Definition: packet_id.h:135
static bool packet_id_initialized(const struct packet_id *pid)
Is this struct packet_id initialized?
Definition: packet_id.h:274
struct packet_id_rec rec
Definition: packet_id.h:208
uint32_t net_time_t
Definition: packet_id.h:51
packet_id_type id
Definition: packet_id.h:136
unsigned int packet_id_print_type
Definition: packet_id.h:96
static bool packet_id_close_to_wrapping(const struct packet_id_send *p)
Definition: packet_id.h:311
static void packet_id_reap_test(struct packet_id_rec *p)
Definition: packet_id.h:334
struct seq_list * seq_list
Definition: packet_id.h:141
time_t now
Definition: otime.c:36
time_t time
Definition: packet_id.h:202
unsigned __int32 uint32_t
Definition: config-msvc.h:121
CIRC_LIST(seq_list, time_t)
const char * filename
Definition: packet_id.h:152
void packet_id_add(struct packet_id_rec *p, const struct packet_id_net *pin)
Definition: packet_id.c:115
packet_id_type id
Definition: packet_id.h:155
void packet_id_persist_close(struct packet_id_persist *p)
Definition: packet_id.c:419
bool packet_id_test(struct packet_id_rec *p, const struct packet_id_net *pin)
Definition: packet_id.c:202
void packet_id_persist_init(struct packet_id_persist *p)
Definition: packet_id.c:409
unsigned __int8 uint8_t
Definition: config-msvc.h:123
void packet_id_reap(struct packet_id_rec *p)
Definition: packet_id.c:170
bool initialized
Definition: packet_id.h:140
Wrapper structure for dynamically allocated memory.
Definition: buffer.h:60
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:349
uint32_t packet_id_type
Definition: packet_id.h:49
const char * packet_id_persist_print(const struct packet_id_persist *p, struct gc_arena *gc)
Definition: packet_id.c:534
unsigned __int16 uint16_t
Definition: config-msvc.h:122
Garbage collection arena used to keep track of dynamically allocated memory.
Definition: buffer.h:116
static void packet_id_persist_save_obj(struct packet_id_persist *p, const struct packet_id *pid)
Definition: packet_id.h:288
static bool packet_id_persist_enabled(const struct packet_id_persist *p)
Definition: packet_id.h:281
void packet_id_persist_load_obj(const struct packet_id_persist *p, struct packet_id *pid)
Definition: packet_id.c:524
#define PACKET_ID_WRAP_TRIGGER
Definition: packet_id.h:58
const char * packet_id_net_print(const struct packet_id_net *pin, bool print_timestamp, struct gc_arena *gc)
Definition: packet_id.c:391
packet_id_type id
Definition: packet_id.h:172
static int packet_id_size(bool long_form)
Definition: packet_id.h:305
void packet_id_init(struct packet_id *p, int seq_backtrack, int time_backtrack, const char *name, int unit)
Definition: packet_id.c:78