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-2025 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, see <https://www.gnu.org/licenses/>.
21 */
22
23/*
24 * These routines are designed to catch replay attacks,
25 * where a man-in-the-middle captures packets and then
26 * attempts to replay them back later.
27 */
28
29#ifndef PACKET_ID_H
30#define PACKET_ID_H
31
32#include "circ_list.h"
33#include "buffer.h"
34#include "error.h"
35#include "otime.h"
36
37/*
38 * These are the types that members of a struct packet_id_net are converted
39 * to for network transmission and for saving to a persistent file.
40 *
41 * Note: data epoch data uses a 64 bit packet ID
42 * compromised of 16 bit epoch and 48 bit per-epoch packet counter.
43 * These are ephemeral and are never saved to a file.
44 */
45typedef uint32_t packet_id_type;
46#define PACKET_ID_MAX UINT32_MAX
47#define PACKET_ID_EPOCH_MAX 0x0000ffffffffffffull
50#define PACKET_ID_MASK 0x0000ffffffffffffull
51typedef uint32_t net_time_t;
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
73/*
74 * Printf formats for special types
75 */
76#define packet_id_format "%" PRIu64
77typedef uint64_t packet_id_print_type;
78
79/*
80 * Maximum allowed backtrack in
81 * sequence number due to packets arriving
82 * out of order.
83 */
84#define MIN_SEQ_BACKTRACK 0
85#define MAX_SEQ_BACKTRACK 65536
86#define DEFAULT_SEQ_BACKTRACK 64
87
88/*
89 * Maximum allowed backtrack in
90 * seconds due to packets arriving
91 * out of order.
92 */
93#define MIN_TIME_BACKTRACK 0
94#define MAX_TIME_BACKTRACK 600
95#define DEFAULT_TIME_BACKTRACK 15
96
97/*
98 * Do a reap pass through the sequence number
99 * array once every n seconds in order to
100 * expire sequence numbers which can no longer
101 * be accepted because they would violate
102 * TIME_BACKTRACK.
103 */
104#define SEQ_REAP_INTERVAL 5
105
106CIRC_LIST(seq_list, time_t);
107
108/*
109 * This is the data structure we keep on the receiving side,
110 * to check that no packet-id (i.e. sequence number + optional timestamp)
111 * is accepted more than once.
112 */
114{
115 time_t last_reap; /* last call of packet_id_reap */
116 time_t time; /* highest time stamp received */
117 uint64_t id; /* highest sequence number received */
118 uint64_t seq_backtrack; /* set from --replay-window */
119 int time_backtrack; /* set from --replay-window */
120 uint64_t max_backtrack_stat; /* maximum backtrack seen so far */
121 bool initialized; /* true if packet_id_init was called */
122 struct seq_list *seq_list; /* packet-id "memory" */
123 const char *name;
124 int unit;
125};
126
127/*
128 * file to facilitate cross-session persistence
129 * of time/id
130 */
132{
133 const char *filename;
134 int fd;
135 time_t time; /* time stamp */
136 packet_id_type id; /* sequence number */
139};
140
142{
143 time_t time; /* time stamp */
144 packet_id_type id; /* sequence number */
145};
146
147/*
148 * Keep a record of our current packet-id state
149 * on the sending side.
150 */
152{
153 uint64_t id;
154 time_t time;
155};
156
157/*
158 * Communicate packet-id over the wire.
159 * A short packet-id is just a 32 bit
160 * sequence number. A long packet-id
161 * includes a timestamp as well.
162 *
163 * An epoch packet-id is a 16 bit epoch
164 * counter plus a 48 per-epoch packet-id.
165 *
166 *
167 * Long packet-ids are used as IVs for
168 * CFB/OFB ciphers and for control channel
169 * messages.
170 *
171 * This data structure is always sent
172 * over the net in network byte order,
173 * by calling htonpid, ntohpid,
174 * htontime, and ntohtime on the
175 * data elements to change them
176 * to and from standard sizes.
177 *
178 * In addition, time is converted to
179 * a net_time_t before sending,
180 * since openvpn always
181 * uses a 32-bit time_t but some
182 * 64 bit platforms use a
183 * 64 bit time_t.
184 */
185
191{
192 /* converted to packet_id_type on non-epoch data ids, does not contain
193 * the epoch but is a flat id */
194 uint64_t id;
195 time_t time; /* converted to net_time_t before transmission */
196};
197
199{
202};
203
204void packet_id_init(struct packet_id *p, int seq_backtrack, int time_backtrack, const char *name,
205 int unit);
206
207void packet_id_free(struct packet_id *p);
208
213void packet_id_move_recv(struct packet_id_rec *dest, struct packet_id_rec *src);
214
215/* should we accept an incoming packet id ? */
216bool packet_id_test(struct packet_id_rec *p, const struct packet_id_net *pin);
217
218/* change our current state to reflect an accepted packet id */
219void packet_id_add(struct packet_id_rec *p, const struct packet_id_net *pin);
220
221/* expire TIME_BACKTRACK sequence numbers */
222void packet_id_reap(struct packet_id_rec *p);
223
224/*
225 * packet ID persistence
226 */
227
228/* initialize the packet_id_persist structure in a disabled state */
230
231/* close the file descriptor if it is open, and switch to disabled state */
233
234/* load persisted rec packet_id (time and id) only once from file, and set state to enabled */
235void packet_id_persist_load(struct packet_id_persist *p, const char *filename);
236
237/* save persisted rec packet_id (time and id) to file (only if enabled state) */
239
240/* transfer packet_id_persist -> packet_id */
241void packet_id_persist_load_obj(const struct packet_id_persist *p, struct packet_id *pid);
242
243/* return an ascii string representing a packet_id_persist object */
244const char *packet_id_persist_print(const struct packet_id_persist *p, struct gc_arena *gc);
245
246/*
247 * Read/write a packet ID to/from the buffer. Short form is sequence number
248 * only. Long form is sequence number and timestamp.
249 */
250
251bool packet_id_read(struct packet_id_net *pin, struct buffer *buf, bool long_form);
252
263bool packet_id_write(struct packet_id_send *p, struct buffer *buf, bool long_form, bool prepend);
264
265/*
266 * Inline functions.
267 */
268
270static inline bool
272{
273 return pid->rec.initialized;
274}
275
276/* are we in enabled state? */
277static inline bool
279{
280 return p->fd >= 0;
281}
282
283/* transfer packet_id -> packet_id_persist */
284static inline void
286{
287 if (packet_id_persist_enabled(p) && pid->rec.time)
288 {
289 p->time = pid->rec.time;
290 p->id = pid->rec.id;
291 }
292}
293
302static inline void
304{
305 p->time = 0;
306 p->id = 0;
307}
308
309const char *packet_id_net_print(const struct packet_id_net *pin, bool print_timestamp,
310 struct gc_arena *gc);
311
312static inline int
313packet_id_size(bool long_form)
314{
315 return sizeof(packet_id_type) + (long_form ? sizeof(net_time_t) : 0);
316}
317
318static inline bool
320{
321 return p->id >= PACKET_ID_WRAP_TRIGGER;
322}
323
324static inline void
326{
327 if (p->last_reap + SEQ_REAP_INTERVAL <= now)
328 {
330 }
331}
332
341bool packet_id_write_epoch(struct packet_id_send *p, uint16_t epoch, struct buffer *buf);
342
350uint16_t packet_id_read_epoch(struct packet_id_net *p, struct buffer *buf);
351
352#endif /* PACKET_ID_H */
#define CIRC_LIST(name, type)
Definition circ_list.h:30
time_t now
Definition otime.c:33
static bool packet_id_persist_enabled(const struct packet_id_persist *p)
Definition packet_id.h:278
uint64_t packet_id_print_type
Definition packet_id.h:77
void packet_id_persist_save(struct packet_id_persist *p)
Definition packet_id.c:503
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:303
const char * packet_id_persist_print(const struct packet_id_persist *p, struct gc_arena *gc)
Definition packet_id.c:553
void packet_id_persist_load_obj(const struct packet_id_persist *p, struct packet_id *pid)
Definition packet_id.c:543
void packet_id_init(struct packet_id *p, int seq_backtrack, int time_backtrack, const char *name, int unit)
Definition packet_id.c:91
uint32_t net_time_t
Definition packet_id.h:51
uint32_t packet_id_type
Definition packet_id.h:45
#define SEQ_REAP_INTERVAL
Definition packet_id.h:104
void packet_id_persist_close(struct packet_id_persist *p)
Definition packet_id.c:445
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.
Definition packet_id.c:666
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.
Definition packet_id.c:647
void packet_id_free(struct packet_id *p)
Definition packet_id.c:121
bool packet_id_test(struct packet_id_rec *p, const struct packet_id_net *pin)
Definition packet_id.c:215
bool packet_id_read(struct packet_id_net *pin, struct buffer *buf, bool long_form)
Definition packet_id.c:314
static bool packet_id_close_to_wrapping(const struct packet_id_send *p)
Definition packet_id.h:319
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:104
static void packet_id_reap_test(struct packet_id_rec *p)
Definition packet_id.h:325
void packet_id_reap(struct packet_id_rec *p)
Definition packet_id.c:184
const char * packet_id_net_print(const struct packet_id_net *pin, bool print_timestamp, struct gc_arena *gc)
Definition packet_id.c:418
static void packet_id_persist_save_obj(struct packet_id_persist *p, const struct packet_id *pid)
Definition packet_id.h:285
void packet_id_add(struct packet_id_rec *p, const struct packet_id_net *pin)
Definition packet_id.c:132
static bool packet_id_initialized(const struct packet_id *pid)
Is this struct packet_id initialized?
Definition packet_id.h:271
void packet_id_persist_load(struct packet_id_persist *p, const char *filename)
Definition packet_id.c:459
void packet_id_persist_init(struct packet_id_persist *p)
Definition packet_id.c:435
#define PACKET_ID_WRAP_TRIGGER
Definition packet_id.h:58
static int packet_id_size(bool long_form)
Definition packet_id.h:313
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:377
Wrapper structure for dynamically allocated memory.
Definition buffer.h:60
Garbage collection arena used to keep track of dynamically allocated memory.
Definition buffer.h:116
Data structure for describing the packet id that is received/send to the network.
Definition packet_id.h:191
uint64_t id
Definition packet_id.h:194
const char * filename
Definition packet_id.h:133
packet_id_type id_last_written
Definition packet_id.h:138
packet_id_type id
Definition packet_id.h:136
time_t time_last_written
Definition packet_id.h:137
uint64_t max_backtrack_stat
Definition packet_id.h:120
uint64_t seq_backtrack
Definition packet_id.h:118
const char * name
Definition packet_id.h:123
uint64_t id
Definition packet_id.h:117
time_t last_reap
Definition packet_id.h:115
struct seq_list * seq_list
Definition packet_id.h:122
uint64_t id
Definition packet_id.h:153
struct packet_id_send send
Definition packet_id.h:200
struct packet_id_rec rec
Definition packet_id.h:201
struct gc_arena gc
Definition test_ssl.c:154