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-2024 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 * These are the types that members of a struct packet_id_net are converted
40 * to for network transmission and for saving to a persistent file.
41 *
42 * Note: data epoch data uses a 64 bit packet ID
43 * compromised of 16 bit epoch and 48 bit per-epoch packet counter.
44 * These are ephemeral and are never saved to a file.
45 */
46typedef uint32_t packet_id_type;
47#define PACKET_ID_MAX UINT32_MAX
48#define PACKET_ID_EPOCH_MAX 0x0000ffffffffffffull
51#define PACKET_ID_MASK 0x0000ffffffffffffull
52typedef uint32_t net_time_t;
53
54/*
55 * In TLS mode, when a packet ID gets to this level,
56 * start thinking about triggering a new
57 * SSL/TLS handshake.
58 */
59#define PACKET_ID_WRAP_TRIGGER 0xFF000000
60
61/* convert a packet_id_type from host to network order */
62#define htonpid(x) htonl(x)
63
64/* convert a packet_id_type from network to host order */
65#define ntohpid(x) ntohl(x)
66
67/* convert a time_t in host order to a net_time_t in network order */
68#define htontime(x) htonl((net_time_t)x)
69
70/* convert a net_time_t in network order to a time_t in host order */
71#define ntohtime(x) ((time_t)ntohl(x))
72
73
74/*
75 * Printf formats for special types
76 */
77#define packet_id_format "%" PRIu64
78typedef uint64_t packet_id_print_type;
79
80/*
81 * Maximum allowed backtrack in
82 * sequence number due to packets arriving
83 * out of order.
84 */
85#define MIN_SEQ_BACKTRACK 0
86#define MAX_SEQ_BACKTRACK 65536
87#define DEFAULT_SEQ_BACKTRACK 64
88
89/*
90 * Maximum allowed backtrack in
91 * seconds due to packets arriving
92 * out of order.
93 */
94#define MIN_TIME_BACKTRACK 0
95#define MAX_TIME_BACKTRACK 600
96#define DEFAULT_TIME_BACKTRACK 15
97
98/*
99 * Do a reap pass through the sequence number
100 * array once every n seconds in order to
101 * expire sequence numbers which can no longer
102 * be accepted because they would violate
103 * TIME_BACKTRACK.
104 */
105#define SEQ_REAP_INTERVAL 5
106
107CIRC_LIST(seq_list, time_t);
108
109/*
110 * This is the data structure we keep on the receiving side,
111 * to check that no packet-id (i.e. sequence number + optional timestamp)
112 * is accepted more than once.
113 */
115{
116 time_t last_reap; /* last call of packet_id_reap */
117 time_t time; /* highest time stamp received */
118 uint64_t id; /* highest sequence number received */
119 uint64_t seq_backtrack; /* set from --replay-window */
120 int time_backtrack; /* set from --replay-window */
121 uint64_t max_backtrack_stat; /* maximum backtrack seen so far */
122 bool initialized; /* true if packet_id_init was called */
123 struct seq_list *seq_list; /* packet-id "memory" */
124 const char *name;
125 int unit;
126};
127
128/*
129 * file to facilitate cross-session persistence
130 * of time/id
131 */
133{
134 const char *filename;
135 int fd;
136 time_t time; /* time stamp */
137 packet_id_type id; /* sequence number */
140};
141
143{
144 time_t time; /* time stamp */
145 packet_id_type id; /* sequence number */
146};
147
148/*
149 * Keep a record of our current packet-id state
150 * on the sending side.
151 */
153{
154 uint64_t id;
155 time_t time;
156};
157
158/*
159 * Communicate packet-id over the wire.
160 * A short packet-id is just a 32 bit
161 * sequence number. A long packet-id
162 * includes a timestamp as well.
163 *
164 * An epoch packet-id is a 16 bit epoch
165 * counter plus a 48 per-epoch packet-id.
166 *
167 *
168 * Long packet-ids are used as IVs for
169 * CFB/OFB ciphers and for control channel
170 * messages.
171 *
172 * This data structure is always sent
173 * over the net in network byte order,
174 * by calling htonpid, ntohpid,
175 * htontime, and ntohtime on the
176 * data elements to change them
177 * to and from standard sizes.
178 *
179 * In addition, time is converted to
180 * a net_time_t before sending,
181 * since openvpn always
182 * uses a 32-bit time_t but some
183 * 64 bit platforms use a
184 * 64 bit time_t.
185 */
186
192{
193 /* converted to packet_id_type on non-epoch data ids, does not contain
194 * the epoch but is a flat id */
195 uint64_t id;
196 time_t time; /* converted to net_time_t before transmission */
197};
198
200{
203};
204
205void packet_id_init(struct packet_id *p, int seq_backtrack, int time_backtrack, const char *name, int unit);
206
207void packet_id_free(struct packet_id *p);
208
213void
214packet_id_move_recv(struct packet_id_rec *dest, struct packet_id_rec *src);
215
216/* should we accept an incoming packet id ? */
217bool packet_id_test(struct packet_id_rec *p,
218 const struct packet_id_net *pin);
219
220/* change our current state to reflect an accepted packet id */
221void packet_id_add(struct packet_id_rec *p,
222 const struct packet_id_net *pin);
223
224/* expire TIME_BACKTRACK sequence numbers */
225void packet_id_reap(struct packet_id_rec *p);
226
227/*
228 * packet ID persistence
229 */
230
231/* initialize the packet_id_persist structure in a disabled state */
233
234/* close the file descriptor if it is open, and switch to disabled state */
236
237/* load persisted rec packet_id (time and id) only once from file, and set state to enabled */
238void packet_id_persist_load(struct packet_id_persist *p, const char *filename);
239
240/* save persisted rec packet_id (time and id) to file (only if enabled state) */
242
243/* transfer packet_id_persist -> packet_id */
244void packet_id_persist_load_obj(const struct packet_id_persist *p, struct packet_id *pid);
245
246/* return an ascii string representing a packet_id_persist object */
247const char *packet_id_persist_print(const struct packet_id_persist *p, struct gc_arena *gc);
248
249/*
250 * Read/write a packet ID to/from the buffer. Short form is sequence number
251 * only. Long form is sequence number and timestamp.
252 */
253
254bool packet_id_read(struct packet_id_net *pin, struct buffer *buf, bool long_form);
255
266bool packet_id_write(struct packet_id_send *p, struct buffer *buf,
267 bool long_form, bool prepend);
268
269/*
270 * Inline functions.
271 */
272
274static inline bool
276{
277 return pid->rec.initialized;
278}
279
280/* are we in enabled state? */
281static inline bool
283{
284 return p->fd >= 0;
285}
286
287/* transfer packet_id -> packet_id_persist */
288static inline void
290{
291 if (packet_id_persist_enabled(p) && pid->rec.time)
292 {
293 p->time = pid->rec.time;
294 p->id = pid->rec.id;
295 }
296}
297
306static inline void
308{
309 p->time = 0;
310 p->id = 0;
311}
312
313const char *packet_id_net_print(const struct packet_id_net *pin, bool print_timestamp, struct gc_arena *gc);
314
315static inline int
316packet_id_size(bool long_form)
317{
318 return sizeof(packet_id_type) + (long_form ? sizeof(net_time_t) : 0);
319}
320
321static inline bool
323{
324 return p->id >= PACKET_ID_WRAP_TRIGGER;
325}
326
327static inline void
329{
330 if (p->last_reap + SEQ_REAP_INTERVAL <= now)
331 {
333 }
334}
335
344bool
345packet_id_write_epoch(struct packet_id_send *p, uint16_t epoch, struct buffer *buf);
346
354uint16_t
356
357#endif /* PACKET_ID_H */
#define CIRC_LIST(name, type)
Definition circ_list.h:31
time_t now
Definition otime.c:34
static bool packet_id_persist_enabled(const struct packet_id_persist *p)
Definition packet_id.h:282
uint64_t packet_id_print_type
Definition packet_id.h:78
void packet_id_persist_save(struct packet_id_persist *p)
Definition packet_id.c:519
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:307
const char * packet_id_persist_print(const struct packet_id_persist *p, struct gc_arena *gc)
Definition packet_id.c:571
void packet_id_persist_load_obj(const struct packet_id_persist *p, struct packet_id *pid)
Definition packet_id.c:561
void packet_id_init(struct packet_id *p, int seq_backtrack, int time_backtrack, const char *name, int unit)
Definition packet_id.c:96
uint32_t net_time_t
Definition packet_id.h:52
uint32_t packet_id_type
Definition packet_id.h:46
#define SEQ_REAP_INTERVAL
Definition packet_id.h:105
void packet_id_persist_close(struct packet_id_persist *p)
Definition packet_id.c:456
bool packet_id_write_epoch(struct packet_id_send *p, uint16_t epoch, struct buffer *buf)
Writes the packet ID containing both the epoch and the packet id to the buffer specified by buf.
uint16_t packet_id_read_epoch(struct packet_id_net *p, struct buffer *buf)
Reads the packet ID containing both the epoch and the per-epoch counter from the buf.
void packet_id_free(struct packet_id *p)
Definition packet_id.c:127
bool packet_id_test(struct packet_id_rec *p, const struct packet_id_net *pin)
Definition packet_id.c:224
bool packet_id_read(struct packet_id_net *pin, struct buffer *buf, bool long_form)
Definition packet_id.c:323
static bool packet_id_close_to_wrapping(const struct packet_id_send *p)
Definition packet_id.h:322
void packet_id_move_recv(struct packet_id_rec *dest, struct packet_id_rec *src)
Move the packet id recv structure from src to dest.
Definition packet_id.c:109
static void packet_id_reap_test(struct packet_id_rec *p)
Definition packet_id.h:328
void packet_id_reap(struct packet_id_rec *p)
Definition packet_id.c:193
const char * packet_id_net_print(const struct packet_id_net *pin, bool print_timestamp, struct gc_arena *gc)
Definition packet_id.c:428
static void packet_id_persist_save_obj(struct packet_id_persist *p, const struct packet_id *pid)
Definition packet_id.h:289
void packet_id_add(struct packet_id_rec *p, const struct packet_id_net *pin)
Definition packet_id.c:138
static bool packet_id_initialized(const struct packet_id *pid)
Is this struct packet_id initialized?
Definition packet_id.h:275
void packet_id_persist_load(struct packet_id_persist *p, const char *filename)
Definition packet_id.c:470
void packet_id_persist_init(struct packet_id_persist *p)
Definition packet_id.c:446
#define PACKET_ID_WRAP_TRIGGER
Definition packet_id.h:59
static int packet_id_size(bool long_form)
Definition packet_id.h:316
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:386
Wrapper structure for dynamically allocated memory.
Definition buffer.h:61
Garbage collection arena used to keep track of dynamically allocated memory.
Definition buffer.h:117
Data structure for describing the packet id that is received/send to the network.
Definition packet_id.h:192
uint64_t id
Definition packet_id.h:195
const char * filename
Definition packet_id.h:134
packet_id_type id_last_written
Definition packet_id.h:139
packet_id_type id
Definition packet_id.h:137
time_t time_last_written
Definition packet_id.h:138
uint64_t max_backtrack_stat
Definition packet_id.h:121
uint64_t seq_backtrack
Definition packet_id.h:119
const char * name
Definition packet_id.h:124
uint64_t id
Definition packet_id.h:118
time_t last_reap
Definition packet_id.h:116
struct seq_list * seq_list
Definition packet_id.h:123
uint64_t id
Definition packet_id.h:154
struct packet_id_send send
Definition packet_id.h:201
struct packet_id_rec rec
Definition packet_id.h:202
struct gc_arena gc
Definition test_ssl.c:155