ip_ipsp.h revision 1.31
1/* $OpenBSD: ip_ipsp.h,v 1.31 1999/05/14 23:36:21 niklas Exp $ */ 2 3/* 4 * The authors of this code are John Ioannidis (ji@tla.org), 5 * Angelos D. Keromytis (kermit@csd.uch.gr), 6 * Niels Provos (provos@physnet.uni-hamburg.de) and 7 * Niklas Hallqvist (niklas@appli.se). 8 * 9 * This code was written by John Ioannidis for BSD/OS in Athens, Greece, 10 * in November 1995. 11 * 12 * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996, 13 * by Angelos D. Keromytis. 14 * 15 * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis 16 * and Niels Provos. 17 * 18 * Additional features in 1999 by Angelos D. Keromytis and Niklas Hallqvist. 19 * 20 * Copyright (c) 1995, 1996, 1997, 1998, 1999 by John Ioannidis, 21 * Angelos D. Keromytis and Niels Provos. 22 * Copyright (c) 1999 Niklas Hallqvist. 23 * 24 * Permission to use, copy, and modify this software without fee 25 * is hereby granted, provided that this entire notice is included in 26 * all copies of any software which is or includes a copy or 27 * modification of this software. 28 * You may use this code under the GNU public license if you so wish. Please 29 * contribute changes back to the authors under this freer than GPL license 30 * so that we may further the use of strong encryption without limitations to 31 * all. 32 * 33 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR 34 * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY 35 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE 36 * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR 37 * PURPOSE. 38 */ 39 40#ifndef _NETINET_IPSP_H_ 41#define _NETINET_IPSP_H_ 42 43/* 44 * IPSP global definitions. 45 */ 46 47#include <sys/types.h> 48#include <sys/queue.h> 49#include <netinet/in.h> 50#include <sys/md5k.h> 51#include <netinet/ip_sha1.h> 52#include <netinet/ip_rmd160.h> 53#include <netinet/ip_blf.h> 54#include <netinet/ip_cast.h> 55#include <netinet/ip_skipjack.h> 56 57union sockaddr_union 58{ 59 struct sockaddr sa; 60 struct sockaddr_in sin; 61 struct sockaddr_in6 sin6; 62}; 63 64/* HMAC key sizes */ 65#define MD5HMAC96_KEYSIZE 16 66#define SHA1HMAC96_KEYSIZE 20 67#define RIPEMD160HMAC96_KEYSIZE 20 68 69/* IV lengths */ 70#define ESP_DES_IVS 8 71#define ESP_3DES_IVS 8 72#define ESP_BLF_IVS 8 73#define ESP_CAST_IVS 8 74#define ESP_SKIPJACK_IVS 8 75#define ESP_MAX_IVS 8 /* Keep updated */ 76 77/* Block sizes -- it is assumed that they're powers of 2 */ 78#define ESP_DES_BLKS 8 79#define ESP_3DES_BLKS 8 80#define ESP_BLF_BLKS 8 81#define ESP_CAST_BLKS 8 82#define ESP_SKIPJACK_BLKS 8 83#define ESP_MAX_BLKS 8 /* Keep updated */ 84 85#define HMAC_BLOCK_LEN 64 86 87#define AH_HMAC_HASHLEN 12 /* 96 bits of authenticator */ 88#define AH_HMAC_RPLENGTH 4 /* 32 bits of replay counter */ 89#define AH_HMAC_INITIAL_RPL 1 /* Replay counter initial value */ 90 91/* HMAC definitions */ 92#define HMAC_IPAD_VAL 0x36 93#define HMAC_OPAD_VAL 0x5C 94#define HMAC_BLOCK_LEN 64 95 96/* Authenticator lengths */ 97#define AH_MD5_ALEN 16 98#define AH_SHA1_ALEN 20 99#define AH_RMD160_ALEN 20 100#define AH_ALEN_MAX 20 /* Keep updated */ 101 102struct sockaddr_encap 103{ 104 u_int8_t sen_len; /* length */ 105 u_int8_t sen_family; /* PF_KEY */ 106 u_int16_t sen_type; /* see SENT_* */ 107 union 108 { 109 u_int8_t Data[16]; /* other stuff mapped here */ 110 111 struct /* SENT_IP4 */ 112 { 113 struct in_addr Src; 114 struct in_addr Dst; 115 u_int16_t Sport; 116 u_int16_t Dport; 117 u_int8_t Proto; 118 u_int8_t Filler[3]; 119 } Sip4; 120 121 struct /* SENT_IPSP */ 122 { 123 struct in_addr Dst; 124 u_int32_t Spi; 125 u_int8_t Sproto; 126 u_int8_t Filler[7]; 127 } Sipsp; 128 } Sen; 129}; 130 131#define sen_data Sen.Data 132#define sen_ip_src Sen.Sip4.Src 133#define sen_ip_dst Sen.Sip4.Dst 134#define sen_proto Sen.Sip4.Proto 135#define sen_sport Sen.Sip4.Sport 136#define sen_dport Sen.Sip4.Dport 137#define sen_ipsp_dst Sen.Sipsp.Dst 138#define sen_ipsp_spi Sen.Sipsp.Spi 139#define sen_ipsp_sproto Sen.Sipsp.Sproto 140 141/* 142 * The "type" is really part of the address as far as the routing 143 * system is concerned. By using only one bit in the type field 144 * for each type, we sort-of make sure that different types of 145 * encapsulation addresses won't be matched against the wrong type. 146 * 147 */ 148 149#define SENT_IP4 0x0001 /* data is two struct in_addr */ 150#define SENT_IPSP 0x0002 /* data as in IP4 plus SPI */ 151 152/* 153 * SENT_HDRLEN is the length of the "header" 154 * SENT_*_LEN are the lengths of various forms of sen_data 155 * SENT_*_OFF are the offsets in the sen_data array of various fields 156 */ 157 158#define SENT_HDRLEN (2 * sizeof(u_int8_t) + sizeof(u_int16_t)) 159 160#define SENT_IP4_SRCOFF (0) 161#define SENT_IP4_DSTOFF (sizeof (struct in_addr)) 162 163#define SENT_IP4_LEN 20 164#define SENT_IPSP_LEN 20 165 166#define NOTIFY_SOFT_EXPIRE 0 /* Soft expiration of SA */ 167#define NOTIFY_HARD_EXPIRE 1 /* Hard expiration of SA */ 168#define NOTIFY_REQUEST_SA 2 /* Establish an SA */ 169 170#define NOTIFY_SATYPE_CONF 1 /* SA should do encryption */ 171#define NOTIFY_SATYPE_AUTH 2 /* SA should do authentication */ 172#define NOTIFY_SATYPE_TUNNEL 4 /* SA should use tunneling */ 173 174/* 175 * For encapsulation routes are possible not only for the destination 176 * address but also for the protocol, source and destination ports 177 * if available 178 */ 179 180struct route_enc { 181 struct rtentry *re_rt; 182 struct sockaddr_encap re_dst; 183}; 184 185struct flow 186{ 187 struct flow *flow_next; /* Next in flow chain */ 188 struct flow *flow_prev; /* Previous in flow chain */ 189 struct tdb *flow_sa; /* Pointer to the SA */ 190 union sockaddr_union flow_src; /* Source address */ 191 union sockaddr_union flow_srcmask; /* Source netmask */ 192 union sockaddr_union flow_dst; /* Destination address */ 193 union sockaddr_union flow_dstmask; /* Destination netmask */ 194 u_int8_t flow_proto; /* Transport protocol, if applicable */ 195 u_int8_t foo[3]; /* Alignment */ 196}; 197 198struct tdb /* tunnel descriptor block */ 199{ 200 struct tdb *tdb_hnext; /* Next in hash chain */ 201 struct tdb *tdb_onext; /* Next in output */ 202 struct tdb *tdb_inext; /* Previous in output */ 203 204 struct xformsw *tdb_xform; /* Transformation to use */ 205 struct enc_xform *tdb_encalgxform; /* Encryption algorithm xform */ 206 struct auth_hash *tdb_authalgxform; /* Authentication algorithm xform */ 207 208#define TDBF_UNIQUE 0x00001 /* This should not be used by others */ 209#define TDBF_TIMER 0x00002 /* Absolute expiration timer in use */ 210#define TDBF_BYTES 0x00004 /* Check the byte counters */ 211#define TDBF_ALLOCATIONS 0x00008 /* Check the flows counters */ 212#define TDBF_INVALID 0x00010 /* This SPI is not valid yet/anymore */ 213#define TDBF_FIRSTUSE 0x00020 /* Expire after first use */ 214#define TDBF_HALFIV 0x00040 /* Use half-length IV (ESP old only) */ 215#define TDBF_SOFT_TIMER 0x00080 /* Soft expiration */ 216#define TDBF_SOFT_BYTES 0x00100 /* Soft expiration */ 217#define TDBF_SOFT_ALLOCATIONS 0x00200 /* Soft expiration */ 218#define TDBF_SOFT_FIRSTUSE 0x00400 /* Soft expiration */ 219#define TDBF_PFS 0x00800 /* Ask for PFS from Key Mgmt. */ 220#define TDBF_TUNNELING 0x01000 /* Force IP-IP encapsulation */ 221 u_int32_t tdb_flags; /* Flags related to this TDB */ 222 223 TAILQ_ENTRY(tdb) tdb_expnext; /* Expiration cluster list link */ 224 LIST_ENTRY(tdb) tdb_explink; /* Expiration ordered list link */ 225 226 u_int32_t tdb_exp_allocations; /* Expire after so many flows */ 227 u_int32_t tdb_soft_allocations; /* Expiration warning */ 228 u_int32_t tdb_cur_allocations; /* Total number of allocations */ 229 230 u_int64_t tdb_exp_bytes; /* Expire after so many bytes passed */ 231 u_int64_t tdb_soft_bytes; /* Expiration warning */ 232 u_int64_t tdb_cur_bytes; /* Current count of bytes */ 233 234 u_int64_t tdb_exp_timeout; /* When does the SPI expire */ 235 u_int64_t tdb_soft_timeout; /* Send a soft-expire warning */ 236 u_int64_t tdb_established; /* When was the SPI established */ 237 u_int64_t tdb_timeout; /* Next absolute expiration time. */ 238 239 u_int64_t tdb_first_use; /* When was it first used */ 240 u_int64_t tdb_soft_first_use; /* Soft warning */ 241 u_int64_t tdb_exp_first_use; /* Expire if tdb_first_use + 242 * tdb_exp_first_use <= curtime */ 243 244 u_int32_t tdb_spi; /* SPI */ 245 u_int16_t tdb_amxkeylen; /* AH-old only */ 246 u_int16_t tdb_ivlen; /* IV length */ 247 u_int8_t tdb_sproto; /* IPsec protocol */ 248 u_int8_t tdb_wnd; /* Replay window */ 249 u_int16_t tdb_FILLER; /* Padding */ 250 251 union sockaddr_union tdb_dst; /* Destination address for this SA */ 252 union sockaddr_union tdb_src; /* Source address for this SA */ 253 union sockaddr_union tdb_proxy; 254 255 u_int8_t *tdb_key; /* Key material (schedules) */ 256 u_int8_t *tdb_ictx; /* Authentication contexts */ 257 u_int8_t *tdb_octx; 258 u_int8_t *tdb_srcid; /* Source ID for this SA */ 259 u_int8_t *tdb_dstid; /* Destination ID for this SA */ 260 u_int8_t *tdb_amxkey; /* AH-old only */ 261 262 union 263 { 264 u_int8_t Iv[ESP_3DES_IVS]; /* That's enough space */ 265 u_int32_t Ivl; /* Make sure this is 4 bytes */ 266 u_int64_t Ivq; /* Make sure this is 8 bytes! */ 267 }IV; 268#define tdb_iv IV.Iv 269#define tdb_ivl IV.Ivl 270#define tdb_ivq IV.Ivq 271 272 u_int32_t tdb_rpl; /* Replay counter */ 273 u_int32_t tdb_bitmap; /* Used for replay sliding window */ 274 u_int32_t tdb_initial; /* Initial replay value */ 275 276 u_int32_t tdb_epoch; /* Used by the kernfs interface */ 277 u_int16_t tdb_srcid_len; 278 u_int16_t tdb_dstid_len; 279 u_int16_t tdb_srcid_type; 280 u_int16_t tdb_dstid_type; 281 282 struct flow *tdb_flow; /* Which flows use this SA */ 283 284 struct tdb *tdb_bind_out; /* Outgoing SA to use */ 285 TAILQ_HEAD(tdb_bind_head, tdb) tdb_bind_in; 286 TAILQ_ENTRY(tdb) tdb_bind_in_next; /* Refering Incoming SAs */ 287 TAILQ_HEAD(tdb_inp_head, inpcb) tdb_inp; 288}; 289 290#define TDB_HASHMOD 257 291 292struct tdb_ident { 293 u_int32_t spi; 294 union sockaddr_union dst; 295 u_int8_t proto; 296}; 297 298struct auth_hash { 299 int type; 300 char *name; 301 u_int16_t keysize; 302 u_int16_t hashsize; 303 u_int16_t ctxsize; 304 void (*Init)(void *); 305 void (*Update)(void *, u_int8_t *, u_int16_t); 306 void (*Final)(u_int8_t *, void *); 307}; 308 309struct enc_xform { 310 int type; 311 char *name; 312 u_int16_t blocksize, ivsize; 313 u_int16_t minkey, maxkey; 314 u_int32_t ivmask; /* Or all possible modes, zero iv = 1 */ 315 void (*encrypt)(struct tdb *, u_int8_t *); 316 void (*decrypt)(struct tdb *, u_int8_t *); 317}; 318 319struct ipsecinit 320{ 321 u_int8_t *ii_enckey; 322 u_int8_t *ii_authkey; 323 u_int16_t ii_enckeylen; 324 u_int16_t ii_authkeylen; 325 u_int8_t ii_encalg; 326 u_int8_t ii_authalg; 327}; 328 329struct xformsw 330{ 331 u_short xf_type; /* Unique ID of xform */ 332 u_short xf_flags; /* flags (see below) */ 333 char *xf_name; /* human-readable name */ 334 int (*xf_attach)(void); /* called at config time */ 335 int (*xf_init)(struct tdb *, struct xformsw *, struct ipsecinit *); 336 int (*xf_zeroize)(struct tdb *); /* termination */ 337 struct mbuf *(*xf_input)(struct mbuf *, struct tdb *); /* input */ 338 int (*xf_output)(struct mbuf *, struct sockaddr_encap *, 339 struct tdb *, struct mbuf **); /* output */ 340}; 341 342/* xform IDs */ 343#define XF_IP4 1 /* IP inside IP */ 344#define XF_OLD_AH 2 /* RFCs 1828 & 1852 */ 345#define XF_OLD_ESP 3 /* RFCs 1829 & 1851 */ 346#define XF_NEW_AH 4 /* AH HMAC 96bits */ 347#define XF_NEW_ESP 5 /* ESP + auth 96bits + replay counter */ 348 349/* xform attributes */ 350#define XFT_AUTH 0x0001 351#define XFT_CONF 0x0100 352 353#define IPSEC_ZEROES_SIZE 64 354#define IPSEC_KERNFS_BUFSIZE 4096 355 356#if BYTE_ORDER == LITTLE_ENDIAN 357static __inline u_int64_t 358htonq(u_int64_t q) 359{ 360 register u_int32_t u, l; 361 u = q >> 32; 362 l = (u_int32_t) q; 363 364 return htonl(u) | ((u_int64_t)htonl(l) << 32); 365} 366 367#define ntohq(_x) htonq(_x) 368 369#elif BYTE_ORDER == BIG_ENDIAN 370 371#define htonq(_x) (_x) 372#define ntohq(_x) htonq(_x) 373 374#else 375#error "Please fix <machine/endian.h>" 376#endif 377 378#ifdef _KERNEL 379extern int encdebug; 380extern int ipsec_in_use; 381extern u_int8_t hmac_ipad_buffer[64]; 382extern u_int8_t hmac_opad_buffer[64]; 383 384struct tdb *tdbh[TDB_HASHMOD]; 385extern TAILQ_HEAD(expclusterlist_head, tdb) expclusterlist; 386extern LIST_HEAD(explist_head, tdb) explist; 387extern struct xformsw xformsw[], *xformswNXFORMSW; 388 389/* Check if a given tdb has encryption, authentication and/or tunneling */ 390#define TDB_ATTRIB(x) (((x)->tdb_encalgxform ? NOTIFY_SATYPE_CONF : 0)| \ 391 ((x)->tdb_authalgxform ? NOTIFY_SATYPE_AUTH : 0)) 392 393/* Traverse spi chain and get attributes */ 394 395#define SPI_CHAIN_ATTRIB(have, TDB_DIR, TDBP) {\ 396 struct tdb *tmptdb = (TDBP); \ 397 (have) = 0; \ 398 \ 399 while (tmptdb && tmptdb->tdb_xform) { \ 400 if (tmptdb == NULL || tmptdb->tdb_flags & TDBF_INVALID) \ 401 break; \ 402 (have) |= TDB_ATTRIB(tmptdb); \ 403 tmptdb = tmptdb->TDB_DIR; \ 404 } \ 405} 406 407/* Misc. */ 408extern char *inet_ntoa4(struct in_addr); 409extern char *ipsp_address(union sockaddr_union); 410 411/* TDB management routines */ 412extern void tdb_add_inp(struct tdb *tdb, struct inpcb *inp); 413extern u_int32_t reserve_spi(u_int32_t, u_int32_t, union sockaddr_union *, 414 union sockaddr_union *, u_int8_t, int *); 415extern struct tdb *gettdb(u_int32_t, union sockaddr_union *, u_int8_t); 416extern void puttdb(struct tdb *); 417extern int tdb_delete(struct tdb *, int); 418extern int tdb_init (struct tdb *, u_int16_t, struct ipsecinit *); 419extern void tdb_expiration(struct tdb *, int); 420extern void handle_expirations(void *); 421 422/* Flow management routines */ 423extern struct flow *get_flow(void); 424extern void put_flow(struct flow *, struct tdb *); 425extern void delete_flow(struct flow *, struct tdb *); 426extern struct flow *find_flow(union sockaddr_union *, union sockaddr_union *, 427 union sockaddr_union *, union sockaddr_union *, 428 u_int8_t, struct tdb *); 429extern struct flow *find_global_flow(union sockaddr_union *, 430 union sockaddr_union *, 431 union sockaddr_union *, 432 union sockaddr_union *, u_int8_t); 433 434/* XF_IP4 */ 435extern int ipe4_attach(void); 436extern int ipe4_init(struct tdb *, struct xformsw *, struct ipsecinit *); 437extern int ipe4_zeroize(struct tdb *); 438extern int ipe4_output(struct mbuf *, struct sockaddr_encap *, struct tdb *, 439 struct mbuf **); 440extern void ipe4_input __P((struct mbuf *, ...)); 441extern void ip4_input __P((struct mbuf *, ...)); 442 443/* XF_OLD_AH */ 444extern int ah_old_attach(void); 445extern int ah_old_init(struct tdb *, struct xformsw *, struct ipsecinit *); 446extern int ah_old_zeroize(struct tdb *); 447extern int ah_old_output(struct mbuf *, struct sockaddr_encap *, struct tdb *, 448 struct mbuf **); 449extern struct mbuf *ah_old_input(struct mbuf *, struct tdb *); 450 451/* XF_NEW_AH */ 452extern int ah_new_attach(void); 453extern int ah_new_init(struct tdb *, struct xformsw *, struct ipsecinit *); 454extern int ah_new_zeroize(struct tdb *); 455extern int ah_new_output(struct mbuf *, struct sockaddr_encap *, struct tdb *, 456 struct mbuf **); 457extern struct mbuf *ah_new_input(struct mbuf *, struct tdb *); 458 459/* XF_OLD_ESP */ 460extern int esp_old_attach(void); 461extern int esp_old_init(struct tdb *, struct xformsw *, struct ipsecinit *); 462extern int esp_old_zeroize(struct tdb *); 463extern int esp_old_output(struct mbuf *, struct sockaddr_encap *, struct tdb *, 464 struct mbuf **); 465extern struct mbuf *esp_old_input(struct mbuf *, struct tdb *); 466 467/* XF_NEW_ESP */ 468extern int esp_new_attach(void); 469extern int esp_new_init(struct tdb *, struct xformsw *, struct ipsecinit *); 470extern int esp_new_zeroize(struct tdb *); 471extern int esp_new_output(struct mbuf *, struct sockaddr_encap *, struct tdb *, 472 struct mbuf **); 473extern struct mbuf *esp_new_input(struct mbuf *, struct tdb *); 474 475/* Padding */ 476extern caddr_t m_pad(struct mbuf *, int, int); 477 478/* Replay window */ 479extern int checkreplaywindow32(u_int32_t, u_int32_t, u_int32_t *, u_int32_t, 480 u_int32_t *); 481 482extern unsigned char ipseczeroes[]; 483#endif /* _KERNEL */ 484#endif /* _NETINET_IPSP_H_ */ 485