Index: projects/ipsec/sys/netipsec/keydb.h =================================================================== --- projects/ipsec/sys/netipsec/keydb.h (revision 308837) +++ projects/ipsec/sys/netipsec/keydb.h (revision 308838) @@ -1,225 +1,239 @@ /* $FreeBSD$ */ /* $KAME: keydb.h,v 1.14 2000/08/02 17:58:26 sakane Exp $ */ /*- * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef _NETIPSEC_KEYDB_H_ #define _NETIPSEC_KEYDB_H_ #ifdef _KERNEL - +#include #include #ifndef _SOCKADDR_UNION_DEFINED #define _SOCKADDR_UNION_DEFINED /* * The union of all possible address formats we handle. */ union sockaddr_union { struct sockaddr sa; struct sockaddr_in sin; struct sockaddr_in6 sin6; }; #endif /* _SOCKADDR_UNION_DEFINED */ /* Security Assocciation Index */ /* NOTE: Ensure to be same address family */ struct secasindex { union sockaddr_union src; /* source address for SA */ union sockaddr_union dst; /* destination address for SA */ uint8_t proto; /* IPPROTO_ESP or IPPROTO_AH */ uint8_t mode; /* mode of protocol, see ipsec.h */ uint32_t reqid; /* reqid id who owned this SA */ /* see IPSEC_MANUAL_REQID_MAX. */ }; /* * In order to split out the keydb implementation from that of the * PF_KEY sockets we need to define a few structures that while they * may seem common are likely to diverge over time. */ /* sadb_identity */ struct secident { u_int16_t type; u_int64_t id; }; /* sadb_key */ struct seckey { u_int16_t bits; char *key_data; }; struct seclifetime { u_int32_t allocations; u_int64_t bytes; u_int64_t addtime; u_int64_t usetime; }; /* Security Association Data Base */ +TAILQ_HEAD(secasvar_queue, secasvar); struct secashead { - LIST_ENTRY(secashead) chain; + TAILQ_ENTRY(secashead) chain; + LIST_ENTRY(secashead) addrhash; /* hash by sproto+src+dst addresses */ + LIST_ENTRY(secashead) drainq; /* used ONLY by flush callout */ struct secasindex saidx; struct secident *idents; /* source identity */ struct secident *identd; /* destination identity */ /* XXX I don't know how to use them. */ - u_int8_t state; /* MATURE or DEAD. */ - LIST_HEAD(_satree, secasvar) savtree[SADB_SASTATE_MAX+1]; - /* SA chain */ - /* The first of this list is newer SA */ + volatile u_int refcnt; /* reference count */ + uint8_t state; /* MATURE or DEAD. */ + struct secasvar_queue savtree_alive; /* MATURE and DYING SA */ + struct secasvar_queue savtree_larval; /* LARVAL SA */ }; struct xformsw; struct enc_xform; struct auth_hash; struct comp_algo; -/* Security Association */ +/* + * Security Association + * + * For INBOUND packets we do SA lookup using SPI, thus only SPIHASH is used. + * For OUTBOUND packets there may be several SA suitable for packet. + * We use key_preferred_oldsa variable to choose better SA. First of we do + * lookup for suitable SAH using packet's saidx. Then we use SAH's savtree + * to search better candidate. The newer SA (by created time) are placed + * in the beginning of the savtree list. There is no preference between + * DYING and MATURE. + */ struct secasvar { - LIST_ENTRY(secasvar) chain; - struct mtx lock; /* update/access lock */ + TAILQ_ENTRY(secasvar) chain; + LIST_ENTRY(secasvar) spihash; + LIST_ENTRY(secasvar) drainq; /* used ONLY by flush callout */ - u_int refcnt; /* reference count */ - u_int8_t state; /* Status of this Association */ + uint32_t spi; /* SPI Value, network byte order */ + uint32_t flags; /* holder for SADB_KEY_FLAGS */ - u_int8_t alg_auth; /* Authentication Algorithm Identifier*/ - u_int8_t alg_enc; /* Cipher Algorithm Identifier */ - u_int8_t alg_comp; /* Compression Algorithm Identifier */ - u_int32_t spi; /* SPI Value, network byte order */ - u_int32_t flags; /* holder for SADB_KEY_FLAGS */ + uint32_t seq; /* sequence number */ + pid_t pid; /* message's pid */ + uint8_t state; /* Status of this SA (pfkeyv2.h) */ + uint8_t alg_auth; /* Authentication Algorithm Identifier*/ + uint8_t alg_enc; /* Cipher Algorithm Identifier */ + uint8_t alg_comp; /* Compression Algorithm Identifier */ + + uint16_t natt_type; /* IKE/ESP-marker in output. */ + uint16_t natt_esp_frag_len; /* MTU for payload fragmentation. */ + + struct secashead *sah; /* back pointer to the secashead */ struct seckey *key_auth; /* Key for Authentication */ struct seckey *key_enc; /* Key for Encryption */ - u_int ivlen; /* length of IV */ - void *sched; /* intermediate encryption key */ - size_t schedlen; + struct secreplay *replay; /* replay prevention */ uint64_t cntr; /* counter for GCM and CTR */ + u_int ivlen; /* length of IV */ - struct secreplay *replay; /* replay prevention */ - time_t created; /* for lifetime */ + volatile u_int refcnt; /* reference count */ - struct seclifetime *lft_c; /* CURRENT lifetime, it's constant. */ + uint64_t created; /* time when SA was created */ + uint64_t firstused; /* time when SA was first used */ + counter_u64_t lft_c; /* CURRENT lifetime */ +#define lft_c_allocations lft_c +#define lft_c_bytes lft_c + 1 struct seclifetime *lft_h; /* HARD lifetime */ struct seclifetime *lft_s; /* SOFT lifetime */ - u_int32_t seq; /* sequence number */ - pid_t pid; /* message's pid */ - - struct secashead *sah; /* back pointer to the secashead */ - /* * NB: Fields with a tdb_ prefix are part of the "glue" used * to interface to the OpenBSD crypto support. This was done * to distinguish this code from the mainline KAME code. */ struct xformsw *tdb_xform; /* transform */ struct enc_xform *tdb_encalgxform; /* encoding algorithm */ struct auth_hash *tdb_authalgxform; /* authentication algorithm */ struct comp_algo *tdb_compalgxform; /* compression algorithm */ - u_int64_t tdb_cryptoid; /* crypto session id */ + uint64_t tdb_cryptoid; /* crypto session id */ - /* - * NAT-Traversal. - */ - u_int16_t natt_type; /* IKE/ESP-marker in output. */ - u_int16_t natt_esp_frag_len; /* MTU for payload fragmentation. */ + struct mtx lock; /* update/access lock */ }; #define SECASVAR_LOCK_INIT(_sav) \ mtx_init(&(_sav)->lock, "ipsec association", NULL, MTX_DEF) #define SECASVAR_LOCK(_sav) mtx_lock(&(_sav)->lock) #define SECASVAR_UNLOCK(_sav) mtx_unlock(&(_sav)->lock) #define SECASVAR_LOCK_DESTROY(_sav) mtx_destroy(&(_sav)->lock) #define SECASVAR_LOCK_ASSERT(_sav) mtx_assert(&(_sav)->lock, MA_OWNED) #define SAV_ISGCM(_sav) \ ((_sav)->alg_enc == SADB_X_EALG_AESGCM8 || \ (_sav)->alg_enc == SADB_X_EALG_AESGCM12 || \ (_sav)->alg_enc == SADB_X_EALG_AESGCM16) #define SAV_ISCTR(_sav) ((_sav)->alg_enc == SADB_X_EALG_AESCTR) #define SAV_ISCTRORGCM(_sav) (SAV_ISCTR((_sav)) || SAV_ISGCM((_sav))) /* replay prevention */ struct secreplay { u_int32_t count; u_int wsize; /* window size, i.g. 4 bytes */ u_int32_t seq; /* used by sender */ u_int32_t lastseq; /* used by receiver */ caddr_t bitmap; /* used by receiver */ int overflow; /* overflow flag */ }; /* socket table due to send PF_KEY messages. */ struct secreg { LIST_ENTRY(secreg) chain; struct socket *so; }; /* acquiring list table. */ struct secacq { LIST_ENTRY(secacq) chain; + LIST_ENTRY(secacq) addrhash; + LIST_ENTRY(secacq) seqhash; struct secasindex saidx; - - u_int32_t seq; /* sequence number */ + uint32_t seq; /* sequence number */ time_t created; /* for lifetime */ int count; /* for lifetime */ }; /* Sensitivity Level Specification */ /* nothing */ #define SADB_KILL_INTERVAL 600 /* six seconds */ /* secpolicy */ extern struct secpolicy *keydb_newsecpolicy(void); extern void keydb_delsecpolicy(struct secpolicy *); /* secashead */ extern struct secashead *keydb_newsecashead(void); extern void keydb_delsecashead(struct secashead *); /* secasvar */ extern struct secasvar *keydb_newsecasvar(void); extern void keydb_refsecasvar(struct secasvar *); extern void keydb_freesecasvar(struct secasvar *); /* secreplay */ extern struct secreplay *keydb_newsecreplay(size_t); extern void keydb_delsecreplay(struct secreplay *); /* secreg */ extern struct secreg *keydb_newsecreg(void); extern void keydb_delsecreg(struct secreg *); #endif /* _KERNEL */ #endif /* _NETIPSEC_KEYDB_H_ */ Index: projects/ipsec/sys/netipsec/xform.h =================================================================== --- projects/ipsec/sys/netipsec/xform.h (revision 308837) +++ projects/ipsec/sys/netipsec/xform.h (revision 308838) @@ -1,126 +1,121 @@ /* $FreeBSD$ */ /* $OpenBSD: ip_ipsp.h,v 1.119 2002/03/14 01:27:11 millert Exp $ */ /*- * The authors of this code are John Ioannidis (ji@tla.org), * Angelos D. Keromytis (kermit@csd.uch.gr), * Niels Provos (provos@physnet.uni-hamburg.de) and * Niklas Hallqvist (niklas@appli.se). * * The original version of this code was written by John Ioannidis * for BSD/OS in Athens, Greece, in November 1995. * * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996, * by Angelos D. Keromytis. * * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis * and Niels Provos. * * Additional features in 1999 by Angelos D. Keromytis and Niklas Hallqvist. * * Copyright (c) 1995, 1996, 1997, 1998, 1999 by John Ioannidis, * Angelos D. Keromytis and Niels Provos. * Copyright (c) 1999 Niklas Hallqvist. * Copyright (c) 2001, Angelos D. Keromytis. * * Permission to use, copy, and modify this software with or without fee * is hereby granted, provided that this entire notice is included in * all copies of any software which is or includes a copy or * modification of this software. * You may use this code under the GNU public license if you so wish. Please * contribute changes back to the authors under this freer than GPL license * so that we may further the use of strong encryption without limitations to * all. * * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR * PURPOSE. */ #ifndef _NETIPSEC_XFORM_H_ #define _NETIPSEC_XFORM_H_ #include #include #include #define AH_HMAC_HASHLEN 12 /* 96 bits of authenticator */ #define AH_HMAC_MAXHASHLEN (SHA2_512_HASH_LEN/2) /* Keep this updated */ #define AH_HMAC_INITIAL_RPL 1 /* replay counter initial value */ +struct secpolicy; +struct secasvar; + /* * Packet tag assigned on completion of IPsec processing; used - * to speedup processing when/if the packet comes back for more - * processing. + * to speedup security policy checking for INBOUND packets. */ -struct tdb_ident { - u_int32_t spi; - union sockaddr_union dst; - u_int8_t proto; - /* Cache those two for enc(4) in xform_ipip. */ - u_int8_t alg_auth; - u_int8_t alg_enc; +struct xform_history { + union sockaddr_union dst; /* destination address */ + uint32_t spi; /* Security Parameters Index */ + uint8_t proto; /* IPPROTO_ESP or IPPROTO_AH */ + uint8_t mode; /* transport or tunnel */ }; /* * Opaque data structure hung off a crypto operation descriptor. */ -struct tdb_crypto { - struct ipsecrequest *tc_isr; /* ipsec request state */ - u_int32_t tc_spi; /* associated SPI */ - union sockaddr_union tc_dst; /* dst addr of packet */ - u_int8_t tc_proto; /* current protocol, e.g. AH */ - u_int8_t tc_nxt; /* next protocol, e.g. IPV4 */ - int tc_protoff; /* current protocol offset */ - int tc_skip; /* data offset */ - caddr_t tc_ptr; /* associated crypto data */ - struct secasvar *tc_sav; /* related SA */ +struct xform_data { + struct secpolicy *sp; /* security policy */ + struct secasvar *sav; /* related SA */ + uint64_t cryptoid; /* used crypto session id */ + u_int idx; /* IPsec request index */ + int protoff; /* current protocol offset */ + int skip; /* data offset */ + uint8_t nxt; /* next protocol, e.g. IPV4 */ }; -struct secasvar; -struct ipescrequest; - struct xformsw { u_short xf_type; /* xform ID */ #define XF_IP4 1 /* unused */ #define XF_AH 2 /* AH */ #define XF_ESP 3 /* ESP */ #define XF_TCPSIGNATURE 5 /* TCP MD5 Signature option, RFC 2358 */ #define XF_IPCOMP 6 /* IPCOMP */ u_short xf_flags; #define XFT_AUTH 0x0001 #define XFT_CONF 0x0100 #define XFT_COMP 0x1000 char *xf_name; /* human-readable name */ int (*xf_init)(struct secasvar*, struct xformsw*); /* setup */ int (*xf_zeroize)(struct secasvar*); /* cleanup */ int (*xf_input)(struct mbuf*, struct secasvar*, /* input */ int, int); - int (*xf_output)(struct mbuf*, /* output */ - struct ipsecrequest *, struct mbuf **, int, int); + int (*xf_output)(struct mbuf*, /* output */ + struct secpolicy *, struct secasvar *, u_int, int, int); struct xformsw *xf_next; /* list of registered xforms */ }; #ifdef _KERNEL extern void xform_register(struct xformsw*); extern int xform_init(struct secasvar *sav, int xftype); extern int xform_ah_authsize(struct auth_hash *esph); struct cryptoini; /* XF_AH */ extern int ah_init0(struct secasvar *, struct xformsw *, struct cryptoini *); extern int ah_zeroize(struct secasvar *sav); extern struct auth_hash *ah_algorithm_lookup(int alg); extern size_t ah_hdrsiz(struct secasvar *); /* XF_ESP */ extern struct enc_xform *esp_algorithm_lookup(int alg); extern size_t esp_hdrsiz(struct secasvar *sav); /* XF_COMP */ extern struct comp_algo *ipcomp_algorithm_lookup(int alg); #endif /* _KERNEL */ #endif /* _NETIPSEC_XFORM_H_ */