188768458SSam Leffler /* $KAME: keydb.h,v 1.14 2000/08/02 17:58:26 sakane Exp $ */ 288768458SSam Leffler 3c398230bSWarner Losh /*- 451369649SPedro F. Giffuni * SPDX-License-Identifier: BSD-3-Clause 551369649SPedro F. Giffuni * 688768458SSam Leffler * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 788768458SSam Leffler * All rights reserved. 888768458SSam Leffler * 988768458SSam Leffler * Redistribution and use in source and binary forms, with or without 1088768458SSam Leffler * modification, are permitted provided that the following conditions 1188768458SSam Leffler * are met: 1288768458SSam Leffler * 1. Redistributions of source code must retain the above copyright 1388768458SSam Leffler * notice, this list of conditions and the following disclaimer. 1488768458SSam Leffler * 2. Redistributions in binary form must reproduce the above copyright 1588768458SSam Leffler * notice, this list of conditions and the following disclaimer in the 1688768458SSam Leffler * documentation and/or other materials provided with the distribution. 1788768458SSam Leffler * 3. Neither the name of the project nor the names of its contributors 1888768458SSam Leffler * may be used to endorse or promote products derived from this software 1988768458SSam Leffler * without specific prior written permission. 2088768458SSam Leffler * 2188768458SSam Leffler * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 2288768458SSam Leffler * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2388768458SSam Leffler * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2488768458SSam Leffler * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 2588768458SSam Leffler * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2688768458SSam Leffler * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2788768458SSam Leffler * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2888768458SSam Leffler * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2988768458SSam Leffler * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3088768458SSam Leffler * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3188768458SSam Leffler * SUCH DAMAGE. 3288768458SSam Leffler */ 3388768458SSam Leffler 3488768458SSam Leffler #ifndef _NETIPSEC_KEYDB_H_ 3588768458SSam Leffler #define _NETIPSEC_KEYDB_H_ 3688768458SSam Leffler 3788768458SSam Leffler #ifdef _KERNEL 38fcf59617SAndrey V. Elsukov #include <sys/counter.h> 39*ef2a572bSKonstantin Belousov #include <sys/ck.h> 40b84ef731SScott Long #include <sys/lock.h> 41bf435626SFabien Thomas #include <sys/mutex.h> 420361f165SKristof Provost #include <sys/rmlock.h> 43*ef2a572bSKonstantin Belousov #include <sys/_task.h> 44bf435626SFabien Thomas 4588768458SSam Leffler #include <netipsec/key_var.h> 462e08e39fSConrad Meyer #include <opencrypto/_cryptodev.h> 4788768458SSam Leffler 487ea7663cSMax Laier #ifndef _SOCKADDR_UNION_DEFINED 497ea7663cSMax Laier #define _SOCKADDR_UNION_DEFINED 5088768458SSam Leffler /* 5188768458SSam Leffler * The union of all possible address formats we handle. 5288768458SSam Leffler */ 5388768458SSam Leffler union sockaddr_union { 5488768458SSam Leffler struct sockaddr sa; 5588768458SSam Leffler struct sockaddr_in sin; 5688768458SSam Leffler struct sockaddr_in6 sin6; 5788768458SSam Leffler }; 587ea7663cSMax Laier #endif /* _SOCKADDR_UNION_DEFINED */ 5988768458SSam Leffler 60fd4751b3SKonstantin Belousov /* Security Association Index */ 6188768458SSam Leffler /* NOTE: Ensure to be same address family */ 6288768458SSam Leffler struct secasindex { 63d0d6567dSPawel Jakub Dawidek union sockaddr_union src; /* source address for SA */ 6488768458SSam Leffler union sockaddr_union dst; /* destination address for SA */ 65fcf59617SAndrey V. Elsukov uint8_t proto; /* IPPROTO_ESP or IPPROTO_AH */ 66fcf59617SAndrey V. Elsukov uint8_t mode; /* mode of protocol, see ipsec.h */ 67fcf59617SAndrey V. Elsukov uint32_t reqid; /* reqid id who owned this SA */ 6888768458SSam Leffler /* see IPSEC_MANUAL_REQID_MAX. */ 6988768458SSam Leffler }; 7088768458SSam Leffler 71a0196c3cSGeorge V. Neville-Neil /* 72a0196c3cSGeorge V. Neville-Neil * In order to split out the keydb implementation from that of the 73a0196c3cSGeorge V. Neville-Neil * PF_KEY sockets we need to define a few structures that while they 74a0196c3cSGeorge V. Neville-Neil * may seem common are likely to diverge over time. 75a0196c3cSGeorge V. Neville-Neil */ 76a0196c3cSGeorge V. Neville-Neil 77a0196c3cSGeorge V. Neville-Neil /* sadb_identity */ 78a0196c3cSGeorge V. Neville-Neil struct secident { 79a0196c3cSGeorge V. Neville-Neil u_int16_t type; 80a0196c3cSGeorge V. Neville-Neil u_int64_t id; 81a0196c3cSGeorge V. Neville-Neil }; 82a0196c3cSGeorge V. Neville-Neil 83a0196c3cSGeorge V. Neville-Neil /* sadb_key */ 84a0196c3cSGeorge V. Neville-Neil struct seckey { 85a0196c3cSGeorge V. Neville-Neil u_int16_t bits; 86a0196c3cSGeorge V. Neville-Neil char *key_data; 87a0196c3cSGeorge V. Neville-Neil }; 88a0196c3cSGeorge V. Neville-Neil 89a0196c3cSGeorge V. Neville-Neil struct seclifetime { 90a0196c3cSGeorge V. Neville-Neil u_int32_t allocations; 91a0196c3cSGeorge V. Neville-Neil u_int64_t bytes; 92a0196c3cSGeorge V. Neville-Neil u_int64_t addtime; 93a0196c3cSGeorge V. Neville-Neil u_int64_t usetime; 94a0196c3cSGeorge V. Neville-Neil }; 95a0196c3cSGeorge V. Neville-Neil 96fcf59617SAndrey V. Elsukov struct secnatt { 97fcf59617SAndrey V. Elsukov union sockaddr_union oai; /* original addresses of initiator */ 98fcf59617SAndrey V. Elsukov union sockaddr_union oar; /* original address of responder */ 99fcf59617SAndrey V. Elsukov uint16_t sport; /* source port */ 100fcf59617SAndrey V. Elsukov uint16_t dport; /* destination port */ 101fcf59617SAndrey V. Elsukov uint16_t cksum; /* checksum delta */ 102fcf59617SAndrey V. Elsukov uint16_t flags; 103fcf59617SAndrey V. Elsukov #define IPSEC_NATT_F_OAI 0x0001 104fcf59617SAndrey V. Elsukov #define IPSEC_NATT_F_OAR 0x0002 105fcf59617SAndrey V. Elsukov }; 106fcf59617SAndrey V. Elsukov 10788768458SSam Leffler /* Security Association Data Base */ 108fcf59617SAndrey V. Elsukov TAILQ_HEAD(secasvar_queue, secasvar); 10988768458SSam Leffler struct secashead { 110fcf59617SAndrey V. Elsukov TAILQ_ENTRY(secashead) chain; 111fcf59617SAndrey V. Elsukov LIST_ENTRY(secashead) addrhash; /* hash by sproto+src+dst addresses */ 112fcf59617SAndrey V. Elsukov LIST_ENTRY(secashead) drainq; /* used ONLY by flush callout */ 11388768458SSam Leffler 11488768458SSam Leffler struct secasindex saidx; 11588768458SSam Leffler 116a0196c3cSGeorge V. Neville-Neil struct secident *idents; /* source identity */ 117a0196c3cSGeorge V. Neville-Neil struct secident *identd; /* destination identity */ 11888768458SSam Leffler /* XXX I don't know how to use them. */ 11988768458SSam Leffler 120fcf59617SAndrey V. Elsukov volatile u_int refcnt; /* reference count */ 121fcf59617SAndrey V. Elsukov uint8_t state; /* MATURE or DEAD. */ 122fcf59617SAndrey V. Elsukov struct secasvar_queue savtree_alive; /* MATURE and DYING SA */ 123fcf59617SAndrey V. Elsukov struct secasvar_queue savtree_larval; /* LARVAL SA */ 12488768458SSam Leffler }; 12588768458SSam Leffler 12688768458SSam Leffler struct xformsw; 12788768458SSam Leffler struct enc_xform; 12888768458SSam Leffler struct auth_hash; 12988768458SSam Leffler struct comp_algo; 130*ef2a572bSKonstantin Belousov struct ifp_handle_sav; 13188768458SSam Leffler 13288768458SSam Leffler /* 133fcf59617SAndrey V. Elsukov * Security Association 134fcf59617SAndrey V. Elsukov * 135fcf59617SAndrey V. Elsukov * For INBOUND packets we do SA lookup using SPI, thus only SPIHASH is used. 136fcf59617SAndrey V. Elsukov * For OUTBOUND packets there may be several SA suitable for packet. 137fcf59617SAndrey V. Elsukov * We use key_preferred_oldsa variable to choose better SA. First of we do 138fcf59617SAndrey V. Elsukov * lookup for suitable SAH using packet's saidx. Then we use SAH's savtree 139fcf59617SAndrey V. Elsukov * to search better candidate. The newer SA (by created time) are placed 140fcf59617SAndrey V. Elsukov * in the beginning of the savtree list. There is no preference between 141fcf59617SAndrey V. Elsukov * DYING and MATURE. 142fcf59617SAndrey V. Elsukov * 14388768458SSam Leffler * NB: Fields with a tdb_ prefix are part of the "glue" used 14488768458SSam Leffler * to interface to the OpenBSD crypto support. This was done 14588768458SSam Leffler * to distinguish this code from the mainline KAME code. 146fcf59617SAndrey V. Elsukov * NB: Fields are sorted on the basis of the frequency of changes, i.e. 147fcf59617SAndrey V. Elsukov * constants and unchangeable fields are going first. 148fcf59617SAndrey V. Elsukov * NB: if you want to change this structure, check that this will not break 149fcf59617SAndrey V. Elsukov * key_updateaddresses(). 15088768458SSam Leffler */ 151fcf59617SAndrey V. Elsukov struct secasvar { 152fcf59617SAndrey V. Elsukov uint32_t spi; /* SPI Value, network byte order */ 153fcf59617SAndrey V. Elsukov uint32_t flags; /* holder for SADB_KEY_FLAGS */ 154fcf59617SAndrey V. Elsukov uint32_t seq; /* sequence number */ 155fcf59617SAndrey V. Elsukov pid_t pid; /* message's pid */ 156fcf59617SAndrey V. Elsukov u_int ivlen; /* length of IV */ 1577b495c44SVANHULLEBUS Yvan 158fcf59617SAndrey V. Elsukov struct secashead *sah; /* back pointer to the secashead */ 159fcf59617SAndrey V. Elsukov struct seckey *key_auth; /* Key for Authentication */ 160fcf59617SAndrey V. Elsukov struct seckey *key_enc; /* Key for Encryption */ 161fcf59617SAndrey V. Elsukov struct secreplay *replay; /* replay prevention */ 162fcf59617SAndrey V. Elsukov struct secnatt *natt; /* NAT-T config */ 1630361f165SKristof Provost struct rmlock *lock; /* update/access lock */ 164fcf59617SAndrey V. Elsukov 165fcf59617SAndrey V. Elsukov const struct xformsw *tdb_xform; /* transform */ 166fcf59617SAndrey V. Elsukov const struct enc_xform *tdb_encalgxform;/* encoding algorithm */ 167fcf59617SAndrey V. Elsukov const struct auth_hash *tdb_authalgxform;/* authentication algorithm */ 168fcf59617SAndrey V. Elsukov const struct comp_algo *tdb_compalgxform;/* compression algorithm */ 1692e08e39fSConrad Meyer crypto_session_t tdb_cryptoid; /* crypto session */ 170fcf59617SAndrey V. Elsukov 171fcf59617SAndrey V. Elsukov uint8_t alg_auth; /* Authentication Algorithm Identifier*/ 172fcf59617SAndrey V. Elsukov uint8_t alg_enc; /* Cipher Algorithm Identifier */ 173fcf59617SAndrey V. Elsukov uint8_t alg_comp; /* Compression Algorithm Identifier */ 174fcf59617SAndrey V. Elsukov uint8_t state; /* Status of this SA (pfkeyv2.h) */ 175fcf59617SAndrey V. Elsukov 176fcf59617SAndrey V. Elsukov counter_u64_t lft_c; /* CURRENT lifetime */ 177fcf59617SAndrey V. Elsukov #define lft_c_allocations lft_c 178fcf59617SAndrey V. Elsukov #define lft_c_bytes lft_c + 1 179fcf59617SAndrey V. Elsukov struct seclifetime *lft_h; /* HARD lifetime */ 180fcf59617SAndrey V. Elsukov struct seclifetime *lft_s; /* SOFT lifetime */ 181fcf59617SAndrey V. Elsukov 182fcf59617SAndrey V. Elsukov uint64_t created; /* time when SA was created */ 183fcf59617SAndrey V. Elsukov uint64_t firstused; /* time when SA was first used */ 184fcf59617SAndrey V. Elsukov 185fcf59617SAndrey V. Elsukov TAILQ_ENTRY(secasvar) chain; 186fcf59617SAndrey V. Elsukov LIST_ENTRY(secasvar) spihash; 187fcf59617SAndrey V. Elsukov LIST_ENTRY(secasvar) drainq; /* used ONLY by flush callout */ 188fcf59617SAndrey V. Elsukov 189fcf59617SAndrey V. Elsukov uint64_t cntr; /* counter for GCM and CTR */ 190fcf59617SAndrey V. Elsukov volatile u_int refcnt; /* reference count */ 191*ef2a572bSKonstantin Belousov CK_LIST_HEAD(, ifp_handle_sav) accel_ifps; 192*ef2a572bSKonstantin Belousov uintptr_t accel_forget_tq; 193*ef2a572bSKonstantin Belousov const char *accel_ifname; 194*ef2a572bSKonstantin Belousov uint32_t accel_flags; 195*ef2a572bSKonstantin Belousov counter_u64_t accel_lft_sw; 196*ef2a572bSKonstantin Belousov uint64_t accel_hw_allocs; 197*ef2a572bSKonstantin Belousov uint64_t accel_hw_octets; 198*ef2a572bSKonstantin Belousov uint64_t accel_firstused; 19988768458SSam Leffler }; 20088768458SSam Leffler 201*ef2a572bSKonstantin Belousov #define SADB_KEY_ACCEL_INST 0x00000001 202*ef2a572bSKonstantin Belousov #define SADB_KEY_ACCEL_DEINST 0x00000002 203*ef2a572bSKonstantin Belousov 2040361f165SKristof Provost #define SECASVAR_RLOCK_TRACKER struct rm_priotracker _secas_tracker 2050361f165SKristof Provost #define SECASVAR_RLOCK(_sav) rm_rlock((_sav)->lock, &_secas_tracker) 2060361f165SKristof Provost #define SECASVAR_RUNLOCK(_sav) rm_runlock((_sav)->lock, &_secas_tracker) 2070361f165SKristof Provost #define SECASVAR_WLOCK(_sav) rm_wlock((_sav)->lock) 2080361f165SKristof Provost #define SECASVAR_WUNLOCK(_sav) rm_wunlock((_sav)->lock) 2090361f165SKristof Provost #define SECASVAR_LOCK_ASSERT(_sav) rm_assert((_sav)->lock, RA_LOCKED) 2100361f165SKristof Provost #define SECASVAR_LOCK_WASSERT(_sav) rm_assert((_sav)->lock, RA_WLOCKED) 211a2bc81bfSJohn-Mark Gurney #define SAV_ISGCM(_sav) \ 212a2bc81bfSJohn-Mark Gurney ((_sav)->alg_enc == SADB_X_EALG_AESGCM8 || \ 213a2bc81bfSJohn-Mark Gurney (_sav)->alg_enc == SADB_X_EALG_AESGCM12 || \ 214a2bc81bfSJohn-Mark Gurney (_sav)->alg_enc == SADB_X_EALG_AESGCM16) 215a2bc81bfSJohn-Mark Gurney #define SAV_ISCTR(_sav) ((_sav)->alg_enc == SADB_X_EALG_AESCTR) 2169f8f3a8eSKristof Provost #define SAV_ISCHACHA(_sav) \ 2179f8f3a8eSKristof Provost ((_sav)->alg_enc == SADB_X_EALG_CHACHA20POLY1305) 218a2bc81bfSJohn-Mark Gurney #define SAV_ISCTRORGCM(_sav) (SAV_ISCTR((_sav)) || SAV_ISGCM((_sav))) 2199ffa9677SSam Leffler 2204d36d1fdSMarcin Wojtas #define IPSEC_SEQH_SHIFT 32 2214d36d1fdSMarcin Wojtas 222bf435626SFabien Thomas /* Replay prevention, protected by SECASVAR_LOCK: 223bf435626SFabien Thomas * (m) locked by mtx 224bf435626SFabien Thomas * (c) read only except during creation / free 225bf435626SFabien Thomas */ 22688768458SSam Leffler struct secreplay { 2270361f165SKristof Provost struct mtx lock; 2288b7f3994SMarcin Wojtas u_int64_t count; /* (m) */ 229bf435626SFabien Thomas u_int wsize; /* (c) window size, i.g. 4 bytes */ 2308b7f3994SMarcin Wojtas u_int64_t last; /* (m) used by receiver */ 231bf435626SFabien Thomas u_int32_t *bitmap; /* (m) used by receiver */ 232bf435626SFabien Thomas u_int bitmap_size; /* (c) size of the bitmap array */ 233bf435626SFabien Thomas int overflow; /* (m) overflow flag */ 23488768458SSam Leffler }; 23588768458SSam Leffler 2360361f165SKristof Provost #define SECREPLAY_LOCK(_r) mtx_lock(&(_r)->lock) 2370361f165SKristof Provost #define SECREPLAY_UNLOCK(_r) mtx_unlock(&(_r)->lock) 2380361f165SKristof Provost #define SECREPLAY_ASSERT(_r) mtx_assert(&(_r)->lock, MA_OWNED) 2390361f165SKristof Provost 24088768458SSam Leffler /* socket table due to send PF_KEY messages. */ 24188768458SSam Leffler struct secreg { 24288768458SSam Leffler LIST_ENTRY(secreg) chain; 24388768458SSam Leffler 24488768458SSam Leffler struct socket *so; 24588768458SSam Leffler }; 24688768458SSam Leffler 24788768458SSam Leffler /* acquiring list table. */ 24888768458SSam Leffler struct secacq { 24988768458SSam Leffler LIST_ENTRY(secacq) chain; 250fcf59617SAndrey V. Elsukov LIST_ENTRY(secacq) addrhash; 251fcf59617SAndrey V. Elsukov LIST_ENTRY(secacq) seqhash; 25288768458SSam Leffler 25388768458SSam Leffler struct secasindex saidx; 254fcf59617SAndrey V. Elsukov uint32_t seq; /* sequence number */ 2559ffa9677SSam Leffler time_t created; /* for lifetime */ 25688768458SSam Leffler int count; /* for lifetime */ 25788768458SSam Leffler }; 25888768458SSam Leffler 25988768458SSam Leffler #endif /* _KERNEL */ 26088768458SSam Leffler 26188768458SSam Leffler #endif /* _NETIPSEC_KEYDB_H_ */ 262