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-2010 OpenVPN Technologies, 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 20 * along with this program (see the file COPYING included with this 21 * distribution); if not, write to the Free Software Foundation, Inc., 22 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 */ 24 25/* 26 * These routines are designed to catch replay attacks, 27 * where a man-in-the-middle captures packets and then 28 * attempts to replay them back later. 29 */ 30 31#ifdef ENABLE_CRYPTO 32 33#ifndef PACKET_ID_H 34#define PACKET_ID_H 35 36#include "circ_list.h" 37#include "buffer.h" 38#include "error.h" 39#include "otime.h" 40 41/* 42 * Enables OpenVPN to be compiled in special packet_id test mode. 43 */ 44/*#define PID_TEST*/ 45 46#if 1 47/* 48 * These are the types that members of 49 * a struct packet_id_net are converted 50 * to for network transmission. 51 */ 52typedef uint32_t packet_id_type; 53typedef uint32_t net_time_t; 54 55/* 56 * In TLS mode, when a packet ID gets to this level, 57 * start thinking about triggering a new 58 * SSL/TLS handshake. 59 */ 60#define PACKET_ID_WRAP_TRIGGER 0xFF000000 61 62/* convert a packet_id_type from host to network order */ 63#define htonpid(x) htonl(x) 64 65/* convert a packet_id_type from network to host order */ 66#define ntohpid(x) ntohl(x) 67 68/* convert a time_t in host order to a net_time_t in network order */ 69#define htontime(x) htonl((net_time_t)x) 70 71/* convert a net_time_t in network order to a time_t in host order */ 72#define ntohtime(x) ((time_t)ntohl(x)) 73 74#else 75 76/* 77 * DEBUGGING ONLY. 78 * Make packet_id_type and net_time_t small 79 * to test wraparound logic and corner cases. 80 */ 81 82typedef uint8_t packet_id_type; 83typedef uint16_t net_time_t; 84 85#define PACKET_ID_WRAP_TRIGGER 0x80 86 87#define htonpid(x) (x) 88#define ntohpid(x) (x) 89#define htontime(x) htons((net_time_t)x) 90#define ntohtime(x) ((time_t)ntohs(x)) 91 92#endif 93 94/* 95 * Printf formats for special types 96 */ 97#define packet_id_format "%u" 98typedef unsigned int packet_id_print_type; 99 100/* 101 * Maximum allowed backtrack in 102 * sequence number due to packets arriving 103 * out of order. 104 */ 105#define MIN_SEQ_BACKTRACK 0 106#define MAX_SEQ_BACKTRACK 65536 107#define DEFAULT_SEQ_BACKTRACK 64 108 109/* 110 * Maximum allowed backtrack in 111 * seconds due to packets arriving 112 * out of order. 113 */ 114#define MIN_TIME_BACKTRACK 0 115#define MAX_TIME_BACKTRACK 600 116#define DEFAULT_TIME_BACKTRACK 15 117 118/* 119 * Do a reap pass through the sequence number 120 * array once every n seconds in order to 121 * expire sequence numbers which can no longer 122 * be accepted because they would violate 123 * TIME_BACKTRACK. 124 */ 125#define SEQ_REAP_INTERVAL 5 126 127CIRC_LIST (seq_list, time_t); 128 129/* 130 * This is the data structure we keep on the receiving side, 131 * to check that no packet-id (i.e. sequence number + optional timestamp) 132 * is accepted more than once. 133 */ 134struct packet_id_rec 135{ 136 time_t last_reap; /* last call of packet_id_reap */ 137 time_t time; /* highest time stamp received */ 138 packet_id_type id; /* highest sequence number received */ 139 int seq_backtrack; /* set from --replay-window */ 140 int time_backtrack; /* set from --replay-window */ 141 int max_backtrack_stat; /* maximum backtrack seen so far */ 142 bool initialized; /* true if packet_id_init was called */ 143 struct seq_list *seq_list; /* packet-id "memory" */ 144 const char *name; 145 int unit; 146}; 147 148/* 149 * file to facilitate cross-session persistence 150 * of time/id 151 */ 152struct packet_id_persist 153{ 154 const char *filename; 155 int fd; 156 time_t time; /* time stamp */ 157 packet_id_type id; /* sequence number */ 158 time_t time_last_written; 159 packet_id_type id_last_written; 160}; 161 162struct packet_id_persist_file_image 163{ 164 time_t time; /* time stamp */ 165 packet_id_type id; /* sequence number */ 166}; 167 168/* 169 * Keep a record of our current packet-id state 170 * on the sending side. 171 */ 172struct packet_id_send 173{ 174 packet_id_type id; 175 time_t time; 176}; 177 178/* 179 * Communicate packet-id over the wire. 180 * A short packet-id is just a 32 bit 181 * sequence number. A long packet-id 182 * includes a timestamp as well. 183 * 184 * Long packet-ids are used as IVs for 185 * CFB/OFB ciphers. 186 * 187 * This data structure is always sent 188 * over the net in network byte order, 189 * by calling htonpid, ntohpid, 190 * htontime, and ntohtime on the 191 * data elements to change them 192 * to and from standard sizes. 193 * 194 * In addition, time is converted to 195 * a net_time_t before sending, 196 * since openvpn always 197 * uses a 32-bit time_t but some 198 * 64 bit platforms use a 199 * 64 bit time_t. 200 */ 201struct packet_id_net 202{ 203 packet_id_type id; 204 time_t time; /* converted to net_time_t before transmission */ 205}; 206 207struct packet_id 208{ 209 struct packet_id_send send; 210 struct packet_id_rec rec; 211}; 212 213void packet_id_init (struct packet_id *p, bool tcp_mode, int seq_backtrack, int time_backtrack, const char *name, int unit); 214void packet_id_free (struct packet_id *p); 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 */ 232void packet_id_persist_init (struct packet_id_persist *p); 233 234/* close the file descriptor if it is open, and switch to disabled state */ 235void packet_id_persist_close (struct packet_id_persist *p); 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) */ 241void packet_id_persist_save (struct packet_id_persist *p); 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); 255bool packet_id_write (const struct packet_id_net *pin, struct buffer *buf, bool long_form, bool prepend); 256 257/* 258 * Inline functions. 259 */ 260 261/* are we in enabled state? */ 262static inline bool 263packet_id_persist_enabled (const struct packet_id_persist *p) 264{ 265 return p->fd >= 0; 266} 267 268/* transfer packet_id -> packet_id_persist */ 269static inline void 270packet_id_persist_save_obj (struct packet_id_persist *p, const struct packet_id* pid) 271{ 272 if (packet_id_persist_enabled (p) && pid->rec.time) 273 { 274 p->time = pid->rec.time; 275 p->id = pid->rec.id; 276 } 277} 278 279const char* packet_id_net_print(const struct packet_id_net *pin, bool print_timestamp, struct gc_arena *gc); 280 281#ifdef PID_TEST 282void packet_id_interactive_test(); 283#endif 284 285static inline int 286packet_id_size (bool long_form) 287{ 288 return sizeof (packet_id_type) + (long_form ? sizeof (net_time_t) : 0); 289} 290 291static inline bool 292packet_id_close_to_wrapping (const struct packet_id_send *p) 293{ 294 return p->id >= PACKET_ID_WRAP_TRIGGER; 295} 296 297/* 298 * Allocate an outgoing packet id. 299 * Sequence number ranges from 1 to 2^32-1. 300 * In long_form, a time_t is added as well. 301 */ 302static inline void 303packet_id_alloc_outgoing (struct packet_id_send *p, struct packet_id_net *pin, bool long_form) 304{ 305 if (!p->time) 306 p->time = now; 307 pin->id = ++p->id; 308 if (!pin->id) 309 { 310 ASSERT (long_form); 311 p->time = now; 312 pin->id = p->id = 1; 313 } 314 pin->time = p->time; 315} 316 317static inline bool 318check_timestamp_delta (time_t remote, unsigned int max_delta) 319{ 320 unsigned int abs; 321 const time_t local_now = now; 322 323 if (local_now >= remote) 324 abs = local_now - remote; 325 else 326 abs = remote - local_now; 327 return abs <= max_delta; 328} 329 330static inline void 331packet_id_reap_test (struct packet_id_rec *p) 332{ 333 if (p->last_reap + SEQ_REAP_INTERVAL <= now) 334 packet_id_reap (p); 335} 336 337#endif /* PACKET_ID_H */ 338#endif /* ENABLE_CRYPTO */ 339