1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #ifndef _INET_SADB_H 28*7c478bd9Sstevel@tonic-gate #define _INET_SADB_H 29*7c478bd9Sstevel@tonic-gate 30*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 31*7c478bd9Sstevel@tonic-gate 32*7c478bd9Sstevel@tonic-gate #ifdef __cplusplus 33*7c478bd9Sstevel@tonic-gate extern "C" { 34*7c478bd9Sstevel@tonic-gate #endif 35*7c478bd9Sstevel@tonic-gate 36*7c478bd9Sstevel@tonic-gate #include <inet/ipsec_info.h> 37*7c478bd9Sstevel@tonic-gate #include <sys/crypto/common.h> 38*7c478bd9Sstevel@tonic-gate #include <sys/crypto/api.h> 39*7c478bd9Sstevel@tonic-gate 40*7c478bd9Sstevel@tonic-gate #define IPSA_MAX_ADDRLEN 4 /* Max address len. (in 32-bits) for an SA. */ 41*7c478bd9Sstevel@tonic-gate 42*7c478bd9Sstevel@tonic-gate /* 43*7c478bd9Sstevel@tonic-gate * Return codes of IPsec processing functions. 44*7c478bd9Sstevel@tonic-gate */ 45*7c478bd9Sstevel@tonic-gate typedef enum { 46*7c478bd9Sstevel@tonic-gate IPSEC_STATUS_SUCCESS = 1, 47*7c478bd9Sstevel@tonic-gate IPSEC_STATUS_FAILED = 2, 48*7c478bd9Sstevel@tonic-gate IPSEC_STATUS_PENDING = 3 49*7c478bd9Sstevel@tonic-gate } ipsec_status_t; 50*7c478bd9Sstevel@tonic-gate 51*7c478bd9Sstevel@tonic-gate /* 52*7c478bd9Sstevel@tonic-gate * IP security association. Synchronization assumes 32-bit loads, so 53*7c478bd9Sstevel@tonic-gate * the 64-bit quantities can't even be be read w/o locking it down! 54*7c478bd9Sstevel@tonic-gate */ 55*7c478bd9Sstevel@tonic-gate 56*7c478bd9Sstevel@tonic-gate /* keying info */ 57*7c478bd9Sstevel@tonic-gate typedef struct ipsa_key_s { 58*7c478bd9Sstevel@tonic-gate void *sak_key; /* Algorithm key. */ 59*7c478bd9Sstevel@tonic-gate uint_t sak_keylen; /* Algorithm key length (in bytes). */ 60*7c478bd9Sstevel@tonic-gate uint_t sak_keybits; /* Algorithm key length (in bits) */ 61*7c478bd9Sstevel@tonic-gate uint_t sak_algid; /* Algorithm ID number. */ 62*7c478bd9Sstevel@tonic-gate } ipsa_key_t; 63*7c478bd9Sstevel@tonic-gate 64*7c478bd9Sstevel@tonic-gate /* the security association */ 65*7c478bd9Sstevel@tonic-gate typedef struct ipsa_s { 66*7c478bd9Sstevel@tonic-gate struct ipsa_s *ipsa_next; /* Next in hash bucket */ 67*7c478bd9Sstevel@tonic-gate struct ipsa_s **ipsa_ptpn; /* Pointer to previous next pointer. */ 68*7c478bd9Sstevel@tonic-gate kmutex_t *ipsa_linklock; /* Pointer to hash-chain lock. */ 69*7c478bd9Sstevel@tonic-gate void (*ipsa_freefunc)(struct ipsa_s *); /* freeassoc function */ 70*7c478bd9Sstevel@tonic-gate /* 71*7c478bd9Sstevel@tonic-gate * NOTE: I may need more pointers, depending on future SA 72*7c478bd9Sstevel@tonic-gate * requirements. 73*7c478bd9Sstevel@tonic-gate */ 74*7c478bd9Sstevel@tonic-gate ipsa_key_t ipsa_authkeydata; 75*7c478bd9Sstevel@tonic-gate #define ipsa_authkey ipsa_authkeydata.sak_key 76*7c478bd9Sstevel@tonic-gate #define ipsa_authkeylen ipsa_authkeydata.sak_keylen 77*7c478bd9Sstevel@tonic-gate #define ipsa_authkeybits ipsa_authkeydata.sak_keybits 78*7c478bd9Sstevel@tonic-gate #define ipsa_auth_alg ipsa_authkeydata.sak_algid 79*7c478bd9Sstevel@tonic-gate ipsa_key_t ipsa_encrkeydata; 80*7c478bd9Sstevel@tonic-gate #define ipsa_encrkey ipsa_encrkeydata.sak_key 81*7c478bd9Sstevel@tonic-gate #define ipsa_encrkeylen ipsa_encrkeydata.sak_keylen 82*7c478bd9Sstevel@tonic-gate #define ipsa_encrkeybits ipsa_encrkeydata.sak_keybits 83*7c478bd9Sstevel@tonic-gate #define ipsa_encr_alg ipsa_encrkeydata.sak_algid 84*7c478bd9Sstevel@tonic-gate 85*7c478bd9Sstevel@tonic-gate struct ipsid_s *ipsa_src_cid; /* Source certificate identity */ 86*7c478bd9Sstevel@tonic-gate struct ipsid_s *ipsa_dst_cid; /* Destination certificate identity */ 87*7c478bd9Sstevel@tonic-gate struct ipsid_s *ipsa_proxy_cid; /* (src) Proxy agent's cert. id. */ 88*7c478bd9Sstevel@tonic-gate uint64_t *ipsa_integ; /* Integrity bitmap */ 89*7c478bd9Sstevel@tonic-gate uint64_t *ipsa_sens; /* Sensitivity bitmap */ 90*7c478bd9Sstevel@tonic-gate mblk_t *ipsa_lpkt; /* Packet received while larval (CAS me) */ 91*7c478bd9Sstevel@tonic-gate 92*7c478bd9Sstevel@tonic-gate /* 93*7c478bd9Sstevel@tonic-gate * PF_KEYv2 supports a replay window size of 255. Hence there is a 94*7c478bd9Sstevel@tonic-gate * need a bit vector to support a replay window of 255. 256 is a nice 95*7c478bd9Sstevel@tonic-gate * round number, so I support that. 96*7c478bd9Sstevel@tonic-gate * 97*7c478bd9Sstevel@tonic-gate * Use an array of uint64_t for best performance on 64-bit 98*7c478bd9Sstevel@tonic-gate * processors. (And hope that 32-bit compilers can handle things 99*7c478bd9Sstevel@tonic-gate * okay.) The " >> 6 " is to get the appropriate number of 64-bit 100*7c478bd9Sstevel@tonic-gate * ints. 101*7c478bd9Sstevel@tonic-gate */ 102*7c478bd9Sstevel@tonic-gate #define SADB_MAX_REPLAY 256 /* Must be 0 mod 64. */ 103*7c478bd9Sstevel@tonic-gate uint64_t ipsa_replay_arr[SADB_MAX_REPLAY >> 6]; 104*7c478bd9Sstevel@tonic-gate 105*7c478bd9Sstevel@tonic-gate uint64_t ipsa_unique_id; /* Non-zero for unique SAs */ 106*7c478bd9Sstevel@tonic-gate uint64_t ipsa_unique_mask; /* mask value for unique_id */ 107*7c478bd9Sstevel@tonic-gate 108*7c478bd9Sstevel@tonic-gate /* 109*7c478bd9Sstevel@tonic-gate * Reference count semantics: 110*7c478bd9Sstevel@tonic-gate * 111*7c478bd9Sstevel@tonic-gate * An SA has a reference count of 1 if something's pointing 112*7c478bd9Sstevel@tonic-gate * to it. This includes being in a hash table. So if an 113*7c478bd9Sstevel@tonic-gate * SA is in a hash table, it has a reference count of at least 1. 114*7c478bd9Sstevel@tonic-gate * 115*7c478bd9Sstevel@tonic-gate * When a ptr. to an IPSA is assigned, you MUST REFHOLD after 116*7c478bd9Sstevel@tonic-gate * said assignment. When a ptr. to an IPSA is released 117*7c478bd9Sstevel@tonic-gate * you MUST REFRELE. When the refcount hits 0, REFRELE 118*7c478bd9Sstevel@tonic-gate * will free the IPSA. 119*7c478bd9Sstevel@tonic-gate */ 120*7c478bd9Sstevel@tonic-gate kmutex_t ipsa_lock; /* Locks non-linkage/refcnt fields. */ 121*7c478bd9Sstevel@tonic-gate /* Q: Since I may be doing refcnts differently, will I need cv? */ 122*7c478bd9Sstevel@tonic-gate uint_t ipsa_refcnt; /* Reference count. */ 123*7c478bd9Sstevel@tonic-gate 124*7c478bd9Sstevel@tonic-gate /* 125*7c478bd9Sstevel@tonic-gate * The following four time fields are the ones monitored by ah_ager() 126*7c478bd9Sstevel@tonic-gate * and esp_ager() respectively. They are all absolute wall-clock 127*7c478bd9Sstevel@tonic-gate * times. The times of creation (i.e. add time) and first use are 128*7c478bd9Sstevel@tonic-gate * pretty straightforward. The soft and hard expire times are 129*7c478bd9Sstevel@tonic-gate * derived from the times of first use and creation, plus the minimum 130*7c478bd9Sstevel@tonic-gate * expiration times in the fields that follow this. 131*7c478bd9Sstevel@tonic-gate * 132*7c478bd9Sstevel@tonic-gate * For example, if I had a hard add time of 30 seconds, and a hard 133*7c478bd9Sstevel@tonic-gate * use time of 15, the ipsa_hardexpiretime would be time of add, plus 134*7c478bd9Sstevel@tonic-gate * 30 seconds. If I USE the SA such that time of first use plus 15 135*7c478bd9Sstevel@tonic-gate * seconds would be earlier than the add time plus 30 seconds, then 136*7c478bd9Sstevel@tonic-gate * ipsa_hardexpiretime would become this earlier time. 137*7c478bd9Sstevel@tonic-gate */ 138*7c478bd9Sstevel@tonic-gate time_t ipsa_addtime; /* Time I was added. */ 139*7c478bd9Sstevel@tonic-gate time_t ipsa_usetime; /* Time of my first use. */ 140*7c478bd9Sstevel@tonic-gate time_t ipsa_softexpiretime; /* Time of my first soft expire. */ 141*7c478bd9Sstevel@tonic-gate time_t ipsa_hardexpiretime; /* Time of my first hard expire. */ 142*7c478bd9Sstevel@tonic-gate 143*7c478bd9Sstevel@tonic-gate /* 144*7c478bd9Sstevel@tonic-gate * The following fields are directly reflected in PF_KEYv2 LIFETIME 145*7c478bd9Sstevel@tonic-gate * extensions. The time_ts are in number-of-seconds, and the bytes 146*7c478bd9Sstevel@tonic-gate * are in... bytes. 147*7c478bd9Sstevel@tonic-gate */ 148*7c478bd9Sstevel@tonic-gate time_t ipsa_softaddlt; /* Seconds of soft lifetime after add. */ 149*7c478bd9Sstevel@tonic-gate time_t ipsa_softuselt; /* Seconds of soft lifetime after first use. */ 150*7c478bd9Sstevel@tonic-gate time_t ipsa_hardaddlt; /* Seconds of hard lifetime after add. */ 151*7c478bd9Sstevel@tonic-gate time_t ipsa_harduselt; /* Seconds of hard lifetime after first use. */ 152*7c478bd9Sstevel@tonic-gate uint64_t ipsa_softbyteslt; /* Bytes of soft lifetime. */ 153*7c478bd9Sstevel@tonic-gate uint64_t ipsa_hardbyteslt; /* Bytes of hard lifetime. */ 154*7c478bd9Sstevel@tonic-gate uint64_t ipsa_bytes; /* Bytes encrypted/authed by this SA. */ 155*7c478bd9Sstevel@tonic-gate 156*7c478bd9Sstevel@tonic-gate /* 157*7c478bd9Sstevel@tonic-gate * "Allocations" are a concept mentioned in PF_KEYv2. We do not 158*7c478bd9Sstevel@tonic-gate * support them, except to record them per the PF_KEYv2 spec. 159*7c478bd9Sstevel@tonic-gate */ 160*7c478bd9Sstevel@tonic-gate uint_t ipsa_softalloc; /* Allocations allowed (soft). */ 161*7c478bd9Sstevel@tonic-gate uint_t ipsa_hardalloc; /* Allocations allowed (hard). */ 162*7c478bd9Sstevel@tonic-gate uint_t ipsa_alloc; /* Allocations made. */ 163*7c478bd9Sstevel@tonic-gate 164*7c478bd9Sstevel@tonic-gate uint_t ipsa_integlen; /* Length of the integrity bitmap (bytes). */ 165*7c478bd9Sstevel@tonic-gate uint_t ipsa_senslen; /* Length of the sensitivity bitmap (bytes). */ 166*7c478bd9Sstevel@tonic-gate 167*7c478bd9Sstevel@tonic-gate uint_t ipsa_type; /* Type of security association. (AH/etc.) */ 168*7c478bd9Sstevel@tonic-gate uint_t ipsa_dpd; /* Domain for sensitivity bit vectors. */ 169*7c478bd9Sstevel@tonic-gate uint_t ipsa_senslevel; /* Sensitivity level. */ 170*7c478bd9Sstevel@tonic-gate uint_t ipsa_integlevel; /* Integrity level. */ 171*7c478bd9Sstevel@tonic-gate uint_t ipsa_state; /* State of my association. */ 172*7c478bd9Sstevel@tonic-gate uint_t ipsa_replay_wsize; /* Size of replay window */ 173*7c478bd9Sstevel@tonic-gate uint32_t ipsa_flags; /* Flags for security association. */ 174*7c478bd9Sstevel@tonic-gate uint32_t ipsa_spi; /* Security parameters index. */ 175*7c478bd9Sstevel@tonic-gate uint32_t ipsa_replay; /* Highest seen replay value for this SA. */ 176*7c478bd9Sstevel@tonic-gate uint32_t ipsa_kmp; /* key management proto */ 177*7c478bd9Sstevel@tonic-gate uint32_t ipsa_kmc; /* key management cookie */ 178*7c478bd9Sstevel@tonic-gate 179*7c478bd9Sstevel@tonic-gate boolean_t ipsa_haspeer; /* Has peer in another table. */ 180*7c478bd9Sstevel@tonic-gate 181*7c478bd9Sstevel@tonic-gate /* 182*7c478bd9Sstevel@tonic-gate * Address storage. 183*7c478bd9Sstevel@tonic-gate * The source address can be INADDR_ANY, IN6ADDR_ANY, etc. 184*7c478bd9Sstevel@tonic-gate * 185*7c478bd9Sstevel@tonic-gate * Address families (per sys/socket.h) guide us. We could have just 186*7c478bd9Sstevel@tonic-gate * used sockaddr_storage 187*7c478bd9Sstevel@tonic-gate */ 188*7c478bd9Sstevel@tonic-gate sa_family_t ipsa_addrfam; 189*7c478bd9Sstevel@tonic-gate sa_family_t ipsa_proxyfam; /* Proxy AF can be != src/dst AF. */ 190*7c478bd9Sstevel@tonic-gate 191*7c478bd9Sstevel@tonic-gate uint32_t ipsa_srcaddr[IPSA_MAX_ADDRLEN]; 192*7c478bd9Sstevel@tonic-gate uint32_t ipsa_dstaddr[IPSA_MAX_ADDRLEN]; 193*7c478bd9Sstevel@tonic-gate uint32_t ipsa_proxysrc[IPSA_MAX_ADDRLEN]; 194*7c478bd9Sstevel@tonic-gate uint32_t ipsa_proxydst[IPSA_MAX_ADDRLEN]; 195*7c478bd9Sstevel@tonic-gate 196*7c478bd9Sstevel@tonic-gate /* these can only be v4 */ 197*7c478bd9Sstevel@tonic-gate uint32_t ipsa_natt_addr_loc[IPSA_MAX_ADDRLEN]; 198*7c478bd9Sstevel@tonic-gate uint32_t ipsa_natt_addr_rem[IPSA_MAX_ADDRLEN]; 199*7c478bd9Sstevel@tonic-gate 200*7c478bd9Sstevel@tonic-gate uint16_t ipsa_inbound_cksum; /* cksum correction for inbound packets */ 201*7c478bd9Sstevel@tonic-gate uint16_t ipsa_remote_port; /* the other port that isn't 4500 */ 202*7c478bd9Sstevel@tonic-gate 203*7c478bd9Sstevel@tonic-gate timeout_id_t ipsa_natt_ka_timer; 204*7c478bd9Sstevel@tonic-gate queue_t *ipsa_natt_q; 205*7c478bd9Sstevel@tonic-gate /* 206*7c478bd9Sstevel@tonic-gate * icmp type and code. *_end are to specify ranges. if only 207*7c478bd9Sstevel@tonic-gate * a single value, * and *_end are the same value. 208*7c478bd9Sstevel@tonic-gate */ 209*7c478bd9Sstevel@tonic-gate uint8_t ipsa_icmp_type; 210*7c478bd9Sstevel@tonic-gate uint8_t ipsa_icmp_type_end; 211*7c478bd9Sstevel@tonic-gate uint8_t ipsa_icmp_code; 212*7c478bd9Sstevel@tonic-gate uint8_t ipsa_icmp_code_end; 213*7c478bd9Sstevel@tonic-gate 214*7c478bd9Sstevel@tonic-gate /* 215*7c478bd9Sstevel@tonic-gate * For the kernel crypto framework. 216*7c478bd9Sstevel@tonic-gate */ 217*7c478bd9Sstevel@tonic-gate crypto_key_t ipsa_kcfauthkey; /* authentication key */ 218*7c478bd9Sstevel@tonic-gate crypto_key_t ipsa_kcfencrkey; /* encryption key */ 219*7c478bd9Sstevel@tonic-gate crypto_ctx_template_t ipsa_authtmpl; /* auth context template */ 220*7c478bd9Sstevel@tonic-gate crypto_ctx_template_t ipsa_encrtmpl; /* encr context template */ 221*7c478bd9Sstevel@tonic-gate crypto_mechanism_t ipsa_amech; /* auth mech type and ICV len */ 222*7c478bd9Sstevel@tonic-gate crypto_mechanism_t ipsa_emech; /* encr mech type */ 223*7c478bd9Sstevel@tonic-gate size_t ipsa_mac_len; /* auth MAC length */ 224*7c478bd9Sstevel@tonic-gate size_t ipsa_iv_len; /* encr IV length */ 225*7c478bd9Sstevel@tonic-gate 226*7c478bd9Sstevel@tonic-gate /* 227*7c478bd9Sstevel@tonic-gate * Input and output processing functions called from IP. 228*7c478bd9Sstevel@tonic-gate */ 229*7c478bd9Sstevel@tonic-gate ipsec_status_t (*ipsa_output_func)(mblk_t *); 230*7c478bd9Sstevel@tonic-gate ipsec_status_t (*ipsa_input_func)(mblk_t *, void *); 231*7c478bd9Sstevel@tonic-gate 232*7c478bd9Sstevel@tonic-gate /* MLS boxen will probably need more fields in here. */ 233*7c478bd9Sstevel@tonic-gate 234*7c478bd9Sstevel@tonic-gate } ipsa_t; 235*7c478bd9Sstevel@tonic-gate 236*7c478bd9Sstevel@tonic-gate /* 237*7c478bd9Sstevel@tonic-gate * ipsa_t address handling macros. We want these to be inlined, and deal 238*7c478bd9Sstevel@tonic-gate * with 32-bit words to avoid bcmp/bcopy calls. 239*7c478bd9Sstevel@tonic-gate * 240*7c478bd9Sstevel@tonic-gate * Assume we only have AF_INET and AF_INET6 addresses for now. Also assume 241*7c478bd9Sstevel@tonic-gate * that we have 32-bit alignment on everything. 242*7c478bd9Sstevel@tonic-gate */ 243*7c478bd9Sstevel@tonic-gate #define IPSA_IS_ADDR_UNSPEC(addr, fam) ((((uint32_t *)(addr))[0] == 0) && \ 244*7c478bd9Sstevel@tonic-gate (((fam) == AF_INET) || (((uint32_t *)(addr))[3] == 0 && \ 245*7c478bd9Sstevel@tonic-gate ((uint32_t *)(addr))[2] == 0 && ((uint32_t *)(addr))[1] == 0))) 246*7c478bd9Sstevel@tonic-gate #define IPSA_ARE_ADDR_EQUAL(addr1, addr2, fam) \ 247*7c478bd9Sstevel@tonic-gate ((((uint32_t *)(addr1))[0] == ((uint32_t *)(addr2))[0]) && \ 248*7c478bd9Sstevel@tonic-gate (((fam) == AF_INET) || \ 249*7c478bd9Sstevel@tonic-gate (((uint32_t *)(addr1))[3] == ((uint32_t *)(addr2))[3] && \ 250*7c478bd9Sstevel@tonic-gate ((uint32_t *)(addr1))[2] == ((uint32_t *)(addr2))[2] && \ 251*7c478bd9Sstevel@tonic-gate ((uint32_t *)(addr1))[1] == ((uint32_t *)(addr2))[1]))) 252*7c478bd9Sstevel@tonic-gate #define IPSA_COPY_ADDR(dstaddr, srcaddr, fam) { \ 253*7c478bd9Sstevel@tonic-gate ((uint32_t *)(dstaddr))[0] = ((uint32_t *)(srcaddr))[0]; \ 254*7c478bd9Sstevel@tonic-gate if ((fam) == AF_INET6) {\ 255*7c478bd9Sstevel@tonic-gate ((uint32_t *)(dstaddr))[1] = ((uint32_t *)(srcaddr))[1]; \ 256*7c478bd9Sstevel@tonic-gate ((uint32_t *)(dstaddr))[2] = ((uint32_t *)(srcaddr))[2]; \ 257*7c478bd9Sstevel@tonic-gate ((uint32_t *)(dstaddr))[3] = ((uint32_t *)(srcaddr))[3]; } } 258*7c478bd9Sstevel@tonic-gate 259*7c478bd9Sstevel@tonic-gate /* 260*7c478bd9Sstevel@tonic-gate * ipsa_t reference hold/release macros. 261*7c478bd9Sstevel@tonic-gate * 262*7c478bd9Sstevel@tonic-gate * If you have a pointer, you REFHOLD. If you are releasing a pointer, you 263*7c478bd9Sstevel@tonic-gate * REFRELE. An ipsa_t that is newly inserted into the table should have 264*7c478bd9Sstevel@tonic-gate * a reference count of 1 (for the table's pointer), plus 1 more for every 265*7c478bd9Sstevel@tonic-gate * pointer that is referencing the ipsa_t. 266*7c478bd9Sstevel@tonic-gate */ 267*7c478bd9Sstevel@tonic-gate 268*7c478bd9Sstevel@tonic-gate #define IPSA_REFHOLD(ipsa) { \ 269*7c478bd9Sstevel@tonic-gate atomic_add_32(&(ipsa)->ipsa_refcnt, 1); \ 270*7c478bd9Sstevel@tonic-gate ASSERT((ipsa)->ipsa_refcnt != 0); \ 271*7c478bd9Sstevel@tonic-gate } 272*7c478bd9Sstevel@tonic-gate 273*7c478bd9Sstevel@tonic-gate /* 274*7c478bd9Sstevel@tonic-gate * Decrement the reference count on the SA. 275*7c478bd9Sstevel@tonic-gate * In architectures e.g sun4u, where atomic_add_32_nv is just 276*7c478bd9Sstevel@tonic-gate * a cas, we need to maintain the right memory barrier semantics 277*7c478bd9Sstevel@tonic-gate * as that of mutex_exit i.e all the loads and stores should complete 278*7c478bd9Sstevel@tonic-gate * before the cas is executed. membar_exit() does that here. 279*7c478bd9Sstevel@tonic-gate */ 280*7c478bd9Sstevel@tonic-gate 281*7c478bd9Sstevel@tonic-gate #define IPSA_REFRELE(ipsa) { \ 282*7c478bd9Sstevel@tonic-gate ASSERT((ipsa)->ipsa_refcnt != 0); \ 283*7c478bd9Sstevel@tonic-gate membar_exit(); \ 284*7c478bd9Sstevel@tonic-gate if (atomic_add_32_nv(&(ipsa)->ipsa_refcnt, -1) == 0) \ 285*7c478bd9Sstevel@tonic-gate ((ipsa)->ipsa_freefunc)(ipsa); \ 286*7c478bd9Sstevel@tonic-gate } 287*7c478bd9Sstevel@tonic-gate 288*7c478bd9Sstevel@tonic-gate /* 289*7c478bd9Sstevel@tonic-gate * Security association hash macros and definitions. For now, assume the 290*7c478bd9Sstevel@tonic-gate * IPsec model, and hash outbounds on destination address, and inbounds on 291*7c478bd9Sstevel@tonic-gate * SPI. 292*7c478bd9Sstevel@tonic-gate * 293*7c478bd9Sstevel@tonic-gate * Also assume a 256 bucket hash. 294*7c478bd9Sstevel@tonic-gate */ 295*7c478bd9Sstevel@tonic-gate #define OUTBOUND_BUCKETS 256 296*7c478bd9Sstevel@tonic-gate /* Outbound hash treats v4addr like a 32-bit quantity */ 297*7c478bd9Sstevel@tonic-gate #define OUTBOUND_HASH_V4(v4addr) (((uint32_t)(v4addr) ^ \ 298*7c478bd9Sstevel@tonic-gate (((uint32_t)v4addr) >> 8) ^ (((uint32_t)v4addr) >> 16) ^ \ 299*7c478bd9Sstevel@tonic-gate (((uint32_t)v4addr) >> 24)) & 0xff) 300*7c478bd9Sstevel@tonic-gate /* Its v6 counterpart treats v6addr like something I can take the address of. */ 301*7c478bd9Sstevel@tonic-gate #define OUTBOUND_HASH_V6(v6addr) OUTBOUND_HASH_V4((*(uint32_t *)&(v6addr)) ^ \ 302*7c478bd9Sstevel@tonic-gate (*((uint32_t *)&(v6addr)) + 1) ^ (*((uint32_t *)&(v6addr)) + 2) ^ \ 303*7c478bd9Sstevel@tonic-gate (*((uint32_t *)&(v6addr)) + 3)) 304*7c478bd9Sstevel@tonic-gate 305*7c478bd9Sstevel@tonic-gate /* No v4/v6 distinction needed for inbound. */ 306*7c478bd9Sstevel@tonic-gate #define INBOUND_BUCKETS 256 307*7c478bd9Sstevel@tonic-gate #define INBOUND_HASH(spi) OUTBOUND_HASH_V4(spi) 308*7c478bd9Sstevel@tonic-gate 309*7c478bd9Sstevel@tonic-gate #define IPSA_F_PFS SADB_SAFLAGS_PFS /* PFS in use for this SA? */ 310*7c478bd9Sstevel@tonic-gate #define IPSA_F_NOREPFLD SADB_SAFLAGS_NOREPLAY /* No replay field, for */ 311*7c478bd9Sstevel@tonic-gate /* backward compat. */ 312*7c478bd9Sstevel@tonic-gate #define IPSA_F_USED SADB_X_SAFLAGS_USED /* SA has been used. */ 313*7c478bd9Sstevel@tonic-gate #define IPSA_F_UNIQUE SADB_X_SAFLAGS_UNIQUE /* SA is unique */ 314*7c478bd9Sstevel@tonic-gate #define IPSA_F_AALG1 SADB_X_SAFLAGS_AALG1 /* Auth alg flag 1 */ 315*7c478bd9Sstevel@tonic-gate #define IPSA_F_AALG2 SADB_X_SAFLAGS_AALG2 /* Auth alg flag 2 */ 316*7c478bd9Sstevel@tonic-gate #define IPSA_F_EALG1 SADB_X_SAFLAGS_EALG1 /* Encrypt alg flag 1 */ 317*7c478bd9Sstevel@tonic-gate #define IPSA_F_EALG2 SADB_X_SAFLAGS_EALG2 /* Encrypt alg flag 2 */ 318*7c478bd9Sstevel@tonic-gate 319*7c478bd9Sstevel@tonic-gate #define IPSA_F_HW 0x200000 /* hwaccel capable SA */ 320*7c478bd9Sstevel@tonic-gate #define IPSA_F_NATT_LOC SADB_X_SAFLAGS_NATT_LOC 321*7c478bd9Sstevel@tonic-gate #define IPSA_F_NATT_REM SADB_X_SAFLAGS_NATT_REM 322*7c478bd9Sstevel@tonic-gate #define IPSA_F_NATT (SADB_X_SAFLAGS_NATT_LOC | SADB_X_SAFLAGS_NATT_REM) 323*7c478bd9Sstevel@tonic-gate #define IPSA_F_CINVALID 0x40000 /* SA shouldn't be cached */ 324*7c478bd9Sstevel@tonic-gate 325*7c478bd9Sstevel@tonic-gate /* SA states are important for handling UPDATE PF_KEY messages. */ 326*7c478bd9Sstevel@tonic-gate #define IPSA_STATE_LARVAL SADB_SASTATE_LARVAL 327*7c478bd9Sstevel@tonic-gate #define IPSA_STATE_MATURE SADB_SASTATE_MATURE 328*7c478bd9Sstevel@tonic-gate #define IPSA_STATE_DYING SADB_SASTATE_DYING 329*7c478bd9Sstevel@tonic-gate #define IPSA_STATE_DEAD SADB_SASTATE_DEAD 330*7c478bd9Sstevel@tonic-gate 331*7c478bd9Sstevel@tonic-gate /* 332*7c478bd9Sstevel@tonic-gate * NOTE: If the document authors do things right in defining algorithms, we'll 333*7c478bd9Sstevel@tonic-gate * probably have flags for what all is here w.r.t. replay, ESP w/HMAC, 334*7c478bd9Sstevel@tonic-gate * etc. 335*7c478bd9Sstevel@tonic-gate */ 336*7c478bd9Sstevel@tonic-gate 337*7c478bd9Sstevel@tonic-gate #define IPSA_T_ACQUIRE SEC_TYPE_NONE /* If this typed returned, sa needed */ 338*7c478bd9Sstevel@tonic-gate #define IPSA_T_AH SEC_TYPE_AH /* IPsec AH association */ 339*7c478bd9Sstevel@tonic-gate #define IPSA_T_ESP SEC_TYPE_ESP /* IPsec ESP association */ 340*7c478bd9Sstevel@tonic-gate 341*7c478bd9Sstevel@tonic-gate #define IPSA_AALG_NONE SADB_AALG_NONE /* No auth. algorithm */ 342*7c478bd9Sstevel@tonic-gate #define IPSA_AALG_MD5H SADB_AALG_MD5HMAC /* MD5-HMAC algorithm */ 343*7c478bd9Sstevel@tonic-gate #define IPSA_AALG_SHA1H SADB_AALG_SHA1HMAC /* SHA1-HMAC algorithm */ 344*7c478bd9Sstevel@tonic-gate 345*7c478bd9Sstevel@tonic-gate #define IPSA_EALG_NONE SADB_EALG_NONE /* No encryption algorithm */ 346*7c478bd9Sstevel@tonic-gate #define IPSA_EALG_DES_CBC SADB_EALG_DESCBC 347*7c478bd9Sstevel@tonic-gate #define IPSA_EALG_3DES SADB_EALG_3DESCBC 348*7c478bd9Sstevel@tonic-gate 349*7c478bd9Sstevel@tonic-gate /* 350*7c478bd9Sstevel@tonic-gate * Protect each ipsa_t bucket (and linkage) with a lock. 351*7c478bd9Sstevel@tonic-gate */ 352*7c478bd9Sstevel@tonic-gate 353*7c478bd9Sstevel@tonic-gate typedef struct isaf_s { 354*7c478bd9Sstevel@tonic-gate ipsa_t *isaf_ipsa; 355*7c478bd9Sstevel@tonic-gate kmutex_t isaf_lock; 356*7c478bd9Sstevel@tonic-gate uint64_t isaf_gen; 357*7c478bd9Sstevel@tonic-gate } isaf_t; 358*7c478bd9Sstevel@tonic-gate 359*7c478bd9Sstevel@tonic-gate /* 360*7c478bd9Sstevel@tonic-gate * ACQUIRE record. If AH/ESP/whatever cannot find an association for outbound 361*7c478bd9Sstevel@tonic-gate * traffic, it sends up an SADB_ACQUIRE message and create an ACQUIRE record. 362*7c478bd9Sstevel@tonic-gate */ 363*7c478bd9Sstevel@tonic-gate 364*7c478bd9Sstevel@tonic-gate #define IPSACQ_MAXPACKETS 4 /* Number of packets that can be queued up */ 365*7c478bd9Sstevel@tonic-gate /* waiting for an ACQUIRE to finish. */ 366*7c478bd9Sstevel@tonic-gate 367*7c478bd9Sstevel@tonic-gate typedef struct ipsacq_s { 368*7c478bd9Sstevel@tonic-gate struct ipsacq_s *ipsacq_next; 369*7c478bd9Sstevel@tonic-gate struct ipsacq_s **ipsacq_ptpn; 370*7c478bd9Sstevel@tonic-gate kmutex_t *ipsacq_linklock; 371*7c478bd9Sstevel@tonic-gate struct ipsec_policy_s *ipsacq_policy; 372*7c478bd9Sstevel@tonic-gate struct ipsec_action_s *ipsacq_act; 373*7c478bd9Sstevel@tonic-gate 374*7c478bd9Sstevel@tonic-gate sa_family_t ipsacq_addrfam; /* Address family. */ 375*7c478bd9Sstevel@tonic-gate int ipsacq_numpackets; /* How many packets queued up so far. */ 376*7c478bd9Sstevel@tonic-gate uint32_t ipsacq_seq; /* PF_KEY sequence number. */ 377*7c478bd9Sstevel@tonic-gate uint64_t ipsacq_unique_id; /* Unique ID for SAs that need it. */ 378*7c478bd9Sstevel@tonic-gate 379*7c478bd9Sstevel@tonic-gate kmutex_t ipsacq_lock; /* Protects non-linkage fields. */ 380*7c478bd9Sstevel@tonic-gate time_t ipsacq_expire; /* Wall-clock time when this record expires. */ 381*7c478bd9Sstevel@tonic-gate mblk_t *ipsacq_mp; /* List of datagrams waiting for an SA. */ 382*7c478bd9Sstevel@tonic-gate 383*7c478bd9Sstevel@tonic-gate /* These two point inside the last mblk inserted. */ 384*7c478bd9Sstevel@tonic-gate uint32_t *ipsacq_srcaddr; 385*7c478bd9Sstevel@tonic-gate uint32_t *ipsacq_dstaddr; 386*7c478bd9Sstevel@tonic-gate 387*7c478bd9Sstevel@tonic-gate /* uint32_t ipsacq_proxysrc[IPSA_MAX_ADDRLEN]; */ /* For later */ 388*7c478bd9Sstevel@tonic-gate /* uint32_t ipsacq_proxydst[IPSA_MAX_ADDRLEN]; */ /* For later */ 389*7c478bd9Sstevel@tonic-gate 390*7c478bd9Sstevel@tonic-gate /* These may change per-acquire. */ 391*7c478bd9Sstevel@tonic-gate uint16_t ipsacq_srcport; 392*7c478bd9Sstevel@tonic-gate uint16_t ipsacq_dstport; 393*7c478bd9Sstevel@tonic-gate uint8_t ipsacq_proto; 394*7c478bd9Sstevel@tonic-gate /* icmp type and code of triggering packet (if applicable) */ 395*7c478bd9Sstevel@tonic-gate uint8_t ipsacq_icmp_type; 396*7c478bd9Sstevel@tonic-gate uint8_t ipsacq_icmp_code; 397*7c478bd9Sstevel@tonic-gate } ipsacq_t; 398*7c478bd9Sstevel@tonic-gate 399*7c478bd9Sstevel@tonic-gate /* 400*7c478bd9Sstevel@tonic-gate * Kernel-generated sequence numbers will be no less than 0x80000000 to 401*7c478bd9Sstevel@tonic-gate * forestall any cretinous problems with manual keying accidentally updating 402*7c478bd9Sstevel@tonic-gate * an ACQUIRE entry. 403*7c478bd9Sstevel@tonic-gate */ 404*7c478bd9Sstevel@tonic-gate #define IACQF_LOWEST_SEQ 0x80000000 405*7c478bd9Sstevel@tonic-gate 406*7c478bd9Sstevel@tonic-gate #define SADB_AGE_INTERVAL_DEFAULT 1000 407*7c478bd9Sstevel@tonic-gate 408*7c478bd9Sstevel@tonic-gate /* 409*7c478bd9Sstevel@tonic-gate * ACQUIRE fanout. Protect each linkage with a lock. 410*7c478bd9Sstevel@tonic-gate */ 411*7c478bd9Sstevel@tonic-gate 412*7c478bd9Sstevel@tonic-gate typedef struct iacqf_s { 413*7c478bd9Sstevel@tonic-gate ipsacq_t *iacqf_ipsacq; 414*7c478bd9Sstevel@tonic-gate kmutex_t iacqf_lock; 415*7c478bd9Sstevel@tonic-gate } iacqf_t; 416*7c478bd9Sstevel@tonic-gate 417*7c478bd9Sstevel@tonic-gate /* 418*7c478bd9Sstevel@tonic-gate * A (network protocol, ipsec protocol) specific SADB. 419*7c478bd9Sstevel@tonic-gate * (i.e., one each for {ah, esp} and {v4, v6}. 420*7c478bd9Sstevel@tonic-gate * 421*7c478bd9Sstevel@tonic-gate * Keep outbound assocs about the same as ire_cache entries for now. 422*7c478bd9Sstevel@tonic-gate * One danger point, multiple SAs for a single dest will clog a bucket. 423*7c478bd9Sstevel@tonic-gate * For the future, consider two-level hashing (2nd hash on IPC?), then probe. 424*7c478bd9Sstevel@tonic-gate */ 425*7c478bd9Sstevel@tonic-gate 426*7c478bd9Sstevel@tonic-gate typedef struct sadb_s 427*7c478bd9Sstevel@tonic-gate { 428*7c478bd9Sstevel@tonic-gate isaf_t *sdb_of; 429*7c478bd9Sstevel@tonic-gate isaf_t *sdb_if; 430*7c478bd9Sstevel@tonic-gate iacqf_t *sdb_acq; 431*7c478bd9Sstevel@tonic-gate } sadb_t; 432*7c478bd9Sstevel@tonic-gate 433*7c478bd9Sstevel@tonic-gate /* 434*7c478bd9Sstevel@tonic-gate * A pair of SADB's (one for v4, one for v6), and related state (including 435*7c478bd9Sstevel@tonic-gate * acquire callbacks). 436*7c478bd9Sstevel@tonic-gate */ 437*7c478bd9Sstevel@tonic-gate 438*7c478bd9Sstevel@tonic-gate typedef struct sadbp_s 439*7c478bd9Sstevel@tonic-gate { 440*7c478bd9Sstevel@tonic-gate uint32_t s_satype; 441*7c478bd9Sstevel@tonic-gate queue_t *s_ip_q; 442*7c478bd9Sstevel@tonic-gate uint32_t *s_acquire_timeout; 443*7c478bd9Sstevel@tonic-gate void (*s_acqfn)(ipsacq_t *, mblk_t *); 444*7c478bd9Sstevel@tonic-gate sadb_t s_v4; 445*7c478bd9Sstevel@tonic-gate sadb_t s_v6; 446*7c478bd9Sstevel@tonic-gate } sadbp_t; 447*7c478bd9Sstevel@tonic-gate 448*7c478bd9Sstevel@tonic-gate /* 449*7c478bd9Sstevel@tonic-gate * Global IPsec security association databases (and all that go with them). 450*7c478bd9Sstevel@tonic-gate */ 451*7c478bd9Sstevel@tonic-gate extern sadbp_t ah_sadb, esp_sadb; 452*7c478bd9Sstevel@tonic-gate 453*7c478bd9Sstevel@tonic-gate /* Pointer to an all-zeroes IPv6 address. */ 454*7c478bd9Sstevel@tonic-gate #define ALL_ZEROES_PTR ((uint32_t *)&ipv6_all_zeros) 455*7c478bd9Sstevel@tonic-gate 456*7c478bd9Sstevel@tonic-gate /* 457*7c478bd9Sstevel@tonic-gate * Form unique id from ipsec_out_t 458*7c478bd9Sstevel@tonic-gate */ 459*7c478bd9Sstevel@tonic-gate 460*7c478bd9Sstevel@tonic-gate #define SA_FORM_UNIQUE_ID(io) \ 461*7c478bd9Sstevel@tonic-gate SA_UNIQUE_ID((io)->ipsec_out_src_port, (io)->ipsec_out_dst_port, \ 462*7c478bd9Sstevel@tonic-gate (io)->ipsec_out_proto) 463*7c478bd9Sstevel@tonic-gate 464*7c478bd9Sstevel@tonic-gate /* 465*7c478bd9Sstevel@tonic-gate * This macro is used to generate unique ids (along with the addresses) for 466*7c478bd9Sstevel@tonic-gate * outbound datagrams that require unique SAs. 467*7c478bd9Sstevel@tonic-gate * 468*7c478bd9Sstevel@tonic-gate * N.B. casts and unsigned shift amounts discourage unwarranted 469*7c478bd9Sstevel@tonic-gate * sign extension of dstport and proto. 470*7c478bd9Sstevel@tonic-gate */ 471*7c478bd9Sstevel@tonic-gate #define SA_UNIQUE_ID(srcport, dstport, proto) \ 472*7c478bd9Sstevel@tonic-gate ((srcport) | ((uint64_t)(dstport) << 16U) | ((uint64_t)(proto) << 32U)) 473*7c478bd9Sstevel@tonic-gate 474*7c478bd9Sstevel@tonic-gate /* 475*7c478bd9Sstevel@tonic-gate * SA_UNIQUE_MASK generates a mask value to use when comparing the unique value 476*7c478bd9Sstevel@tonic-gate * from a packet to an SA. 477*7c478bd9Sstevel@tonic-gate */ 478*7c478bd9Sstevel@tonic-gate 479*7c478bd9Sstevel@tonic-gate #define SA_UNIQUE_MASK(srcport, dstport, proto) \ 480*7c478bd9Sstevel@tonic-gate SA_UNIQUE_ID((srcport != 0)? 0xffff : 0, \ 481*7c478bd9Sstevel@tonic-gate (dstport != 0)? 0xffff : 0, \ 482*7c478bd9Sstevel@tonic-gate (proto != 0)? 0xff : 0) 483*7c478bd9Sstevel@tonic-gate 484*7c478bd9Sstevel@tonic-gate /* 485*7c478bd9Sstevel@tonic-gate * Decompose unique id back into its original fields. 486*7c478bd9Sstevel@tonic-gate */ 487*7c478bd9Sstevel@tonic-gate #define SA_PROTO(ipsa) ((ipsa)->ipsa_unique_id>>32)&0xff 488*7c478bd9Sstevel@tonic-gate #define SA_SRCPORT(ipsa) ((ipsa)->ipsa_unique_id & 0xffff) 489*7c478bd9Sstevel@tonic-gate #define SA_DSTPORT(ipsa) (((ipsa)->ipsa_unique_id >> 16) & 0xffff) 490*7c478bd9Sstevel@tonic-gate 491*7c478bd9Sstevel@tonic-gate /* 492*7c478bd9Sstevel@tonic-gate * All functions that return an ipsa_t will return it with IPSA_REFHOLD() 493*7c478bd9Sstevel@tonic-gate * already called. 494*7c478bd9Sstevel@tonic-gate */ 495*7c478bd9Sstevel@tonic-gate 496*7c478bd9Sstevel@tonic-gate /* SA retrieval (inbound and outbound) */ 497*7c478bd9Sstevel@tonic-gate ipsa_t *ipsec_getassocbyspi(isaf_t *, uint32_t, uint32_t *, uint32_t *, 498*7c478bd9Sstevel@tonic-gate sa_family_t); 499*7c478bd9Sstevel@tonic-gate ipsa_t *ipsec_getassocbyconn(isaf_t *, ipsec_out_t *, uint32_t *, uint32_t *, 500*7c478bd9Sstevel@tonic-gate sa_family_t, uint8_t); 501*7c478bd9Sstevel@tonic-gate 502*7c478bd9Sstevel@tonic-gate /* SA insertion. */ 503*7c478bd9Sstevel@tonic-gate int sadb_insertassoc(ipsa_t *, isaf_t *); 504*7c478bd9Sstevel@tonic-gate 505*7c478bd9Sstevel@tonic-gate /* SA table construction and destruction. */ 506*7c478bd9Sstevel@tonic-gate void sadbp_init(sadbp_t *, int); 507*7c478bd9Sstevel@tonic-gate void sadbp_flush(sadbp_t *); 508*7c478bd9Sstevel@tonic-gate void sadbp_destroy(sadbp_t *); 509*7c478bd9Sstevel@tonic-gate 510*7c478bd9Sstevel@tonic-gate /* SA insertion and deletion. */ 511*7c478bd9Sstevel@tonic-gate int sadb_insertassoc(ipsa_t *, isaf_t *); 512*7c478bd9Sstevel@tonic-gate void sadb_unlinkassoc(ipsa_t *); 513*7c478bd9Sstevel@tonic-gate 514*7c478bd9Sstevel@tonic-gate /* Support routines to interface a keysock consumer to PF_KEY. */ 515*7c478bd9Sstevel@tonic-gate mblk_t *sadb_keysock_out(minor_t); 516*7c478bd9Sstevel@tonic-gate int sadb_hardsoftchk(sadb_lifetime_t *, sadb_lifetime_t *); 517*7c478bd9Sstevel@tonic-gate void sadb_pfkey_echo(queue_t *, mblk_t *, sadb_msg_t *, struct keysock_in_s *, 518*7c478bd9Sstevel@tonic-gate ipsa_t *); 519*7c478bd9Sstevel@tonic-gate void sadb_pfkey_error(queue_t *, mblk_t *, int, int, uint_t); 520*7c478bd9Sstevel@tonic-gate void sadb_keysock_hello(queue_t **, queue_t *, mblk_t *, void (*)(void *), 521*7c478bd9Sstevel@tonic-gate timeout_id_t *, int); 522*7c478bd9Sstevel@tonic-gate int sadb_addrcheck(queue_t *, queue_t *, mblk_t *, sadb_ext_t *, uint_t); 523*7c478bd9Sstevel@tonic-gate void sadb_srcaddrfix(keysock_in_t *); 524*7c478bd9Sstevel@tonic-gate int sadb_addrset(ire_t *); 525*7c478bd9Sstevel@tonic-gate int sadb_delget_sa(mblk_t *, keysock_in_t *, sadbp_t *, int *, queue_t *, 526*7c478bd9Sstevel@tonic-gate boolean_t); 527*7c478bd9Sstevel@tonic-gate #define sadb_get_sa(m, k, s, i, q) sadb_delget_sa(m, k, s, i, q, B_FALSE) 528*7c478bd9Sstevel@tonic-gate #define sadb_del_sa(m, k, s, i, q) sadb_delget_sa(m, k, s, i, q, B_TRUE) 529*7c478bd9Sstevel@tonic-gate 530*7c478bd9Sstevel@tonic-gate int sadb_purge_sa(mblk_t *, keysock_in_t *, sadb_t *, int *, 531*7c478bd9Sstevel@tonic-gate queue_t *, queue_t *); 532*7c478bd9Sstevel@tonic-gate int sadb_common_add(queue_t *, queue_t *, mblk_t *, sadb_msg_t *, 533*7c478bd9Sstevel@tonic-gate keysock_in_t *, isaf_t *, isaf_t *, ipsa_t *, boolean_t, boolean_t); 534*7c478bd9Sstevel@tonic-gate void sadb_set_usetime(ipsa_t *); 535*7c478bd9Sstevel@tonic-gate boolean_t sadb_age_bytes(queue_t *, ipsa_t *, uint64_t, boolean_t); 536*7c478bd9Sstevel@tonic-gate int sadb_update_sa(mblk_t *, keysock_in_t *, sadb_t *, 537*7c478bd9Sstevel@tonic-gate int *, queue_t *, int (*)(mblk_t *, keysock_in_t *, int *)); 538*7c478bd9Sstevel@tonic-gate void sadb_acquire(mblk_t *, ipsec_out_t *, boolean_t, boolean_t); 539*7c478bd9Sstevel@tonic-gate 540*7c478bd9Sstevel@tonic-gate void sadb_destroy_acquire(ipsacq_t *); 541*7c478bd9Sstevel@tonic-gate void sadb_destroy_acqlist(iacqf_t *, uint_t, boolean_t); 542*7c478bd9Sstevel@tonic-gate uint8_t *sadb_setup_acquire(uint8_t *, uint8_t *, ipsacq_t *); 543*7c478bd9Sstevel@tonic-gate ipsa_t *sadb_getspi(keysock_in_t *, uint32_t, int *); 544*7c478bd9Sstevel@tonic-gate void sadb_in_acquire(sadb_msg_t *, sadbp_t *, queue_t *); 545*7c478bd9Sstevel@tonic-gate boolean_t sadb_replay_check(ipsa_t *, uint32_t); 546*7c478bd9Sstevel@tonic-gate boolean_t sadb_replay_peek(ipsa_t *, uint32_t); 547*7c478bd9Sstevel@tonic-gate mblk_t *sadb_sa2msg(ipsa_t *, sadb_msg_t *); 548*7c478bd9Sstevel@tonic-gate int sadb_dump(queue_t *, mblk_t *, minor_t, sadb_t *); 549*7c478bd9Sstevel@tonic-gate void sadb_replay_delete(ipsa_t *); 550*7c478bd9Sstevel@tonic-gate void sadb_ager(sadb_t *, queue_t *, queue_t *, int); 551*7c478bd9Sstevel@tonic-gate 552*7c478bd9Sstevel@tonic-gate timeout_id_t sadb_retimeout(hrtime_t, queue_t *, void (*)(void *), 553*7c478bd9Sstevel@tonic-gate uint_t *, uint_t, short); 554*7c478bd9Sstevel@tonic-gate void sadb_sa_refrele(void *target); 555*7c478bd9Sstevel@tonic-gate void sadb_set_lpkt(ipsa_t *, mblk_t *); 556*7c478bd9Sstevel@tonic-gate mblk_t *sadb_clear_lpkt(ipsa_t *); 557*7c478bd9Sstevel@tonic-gate 558*7c478bd9Sstevel@tonic-gate /* 559*7c478bd9Sstevel@tonic-gate * Hw accel-related calls (downloading sadb to driver) 560*7c478bd9Sstevel@tonic-gate */ 561*7c478bd9Sstevel@tonic-gate void sadb_ill_download(ill_t *, uint_t); 562*7c478bd9Sstevel@tonic-gate mblk_t *sadb_fmt_sa_req(uint_t, uint_t, ipsa_t *, boolean_t); 563*7c478bd9Sstevel@tonic-gate /* 564*7c478bd9Sstevel@tonic-gate * Sub-set of the IPsec hardware acceleration capabilities functions 565*7c478bd9Sstevel@tonic-gate * implemented by ip_if.c 566*7c478bd9Sstevel@tonic-gate */ 567*7c478bd9Sstevel@tonic-gate extern boolean_t ipsec_capab_match(ill_t *, uint_t, boolean_t, ipsa_t *); 568*7c478bd9Sstevel@tonic-gate extern void ill_ipsec_capab_send_all(uint_t, mblk_t *, ipsa_t *); 569*7c478bd9Sstevel@tonic-gate 570*7c478bd9Sstevel@tonic-gate 571*7c478bd9Sstevel@tonic-gate /* 572*7c478bd9Sstevel@tonic-gate * One IPsec -> IP linking routine, and two IPsec rate-limiting routines. 573*7c478bd9Sstevel@tonic-gate */ 574*7c478bd9Sstevel@tonic-gate extern boolean_t sadb_t_bind_req(queue_t *, int); 575*7c478bd9Sstevel@tonic-gate /*PRINTFLIKE5*/ 576*7c478bd9Sstevel@tonic-gate extern void ipsec_rl_strlog(short, short, char, ushort_t, char *, ...) 577*7c478bd9Sstevel@tonic-gate __KPRINTFLIKE(5); 578*7c478bd9Sstevel@tonic-gate extern void ipsec_assocfailure(short, short, char, ushort_t, char *, uint32_t, 579*7c478bd9Sstevel@tonic-gate void *, int); 580*7c478bd9Sstevel@tonic-gate 581*7c478bd9Sstevel@tonic-gate /* 582*7c478bd9Sstevel@tonic-gate * Algorithm types. 583*7c478bd9Sstevel@tonic-gate */ 584*7c478bd9Sstevel@tonic-gate 585*7c478bd9Sstevel@tonic-gate #define IPSEC_NALGTYPES 2 586*7c478bd9Sstevel@tonic-gate 587*7c478bd9Sstevel@tonic-gate typedef enum ipsec_algtype { 588*7c478bd9Sstevel@tonic-gate IPSEC_ALG_AUTH = 0, 589*7c478bd9Sstevel@tonic-gate IPSEC_ALG_ENCR = 1 590*7c478bd9Sstevel@tonic-gate } ipsec_algtype_t; 591*7c478bd9Sstevel@tonic-gate 592*7c478bd9Sstevel@tonic-gate /* 593*7c478bd9Sstevel@tonic-gate * Definitions as per IPsec/ISAKMP DOI. 594*7c478bd9Sstevel@tonic-gate */ 595*7c478bd9Sstevel@tonic-gate 596*7c478bd9Sstevel@tonic-gate #define IPSEC_MAX_ALGS 256 597*7c478bd9Sstevel@tonic-gate #define PROTO_IPSEC_AH 2 598*7c478bd9Sstevel@tonic-gate #define PROTO_IPSEC_ESP 3 599*7c478bd9Sstevel@tonic-gate 600*7c478bd9Sstevel@tonic-gate /* 601*7c478bd9Sstevel@tonic-gate * Common algorithm info. 602*7c478bd9Sstevel@tonic-gate */ 603*7c478bd9Sstevel@tonic-gate typedef struct ipsec_alginfo 604*7c478bd9Sstevel@tonic-gate { 605*7c478bd9Sstevel@tonic-gate uint8_t alg_id; 606*7c478bd9Sstevel@tonic-gate uint8_t alg_flags; 607*7c478bd9Sstevel@tonic-gate uint16_t *alg_key_sizes; 608*7c478bd9Sstevel@tonic-gate uint16_t *alg_block_sizes; 609*7c478bd9Sstevel@tonic-gate uint16_t alg_nkey_sizes; 610*7c478bd9Sstevel@tonic-gate uint16_t alg_nblock_sizes; 611*7c478bd9Sstevel@tonic-gate uint16_t alg_minbits; 612*7c478bd9Sstevel@tonic-gate uint16_t alg_maxbits; 613*7c478bd9Sstevel@tonic-gate uint16_t alg_datalen; 614*7c478bd9Sstevel@tonic-gate /* 615*7c478bd9Sstevel@tonic-gate * increment: number of bits from keysize to keysize 616*7c478bd9Sstevel@tonic-gate * default: # of increments from min to default key len 617*7c478bd9Sstevel@tonic-gate */ 618*7c478bd9Sstevel@tonic-gate uint16_t alg_increment; 619*7c478bd9Sstevel@tonic-gate uint16_t alg_default; 620*7c478bd9Sstevel@tonic-gate uint16_t alg_default_bits; 621*7c478bd9Sstevel@tonic-gate /* 622*7c478bd9Sstevel@tonic-gate * Min, max, and default key sizes effectively supported 623*7c478bd9Sstevel@tonic-gate * by the encryption framework. 624*7c478bd9Sstevel@tonic-gate */ 625*7c478bd9Sstevel@tonic-gate uint16_t alg_ef_minbits; 626*7c478bd9Sstevel@tonic-gate uint16_t alg_ef_maxbits; 627*7c478bd9Sstevel@tonic-gate uint16_t alg_ef_default; 628*7c478bd9Sstevel@tonic-gate uint16_t alg_ef_default_bits; 629*7c478bd9Sstevel@tonic-gate 630*7c478bd9Sstevel@tonic-gate crypto_mech_type_t alg_mech_type; /* KCF mechanism type */ 631*7c478bd9Sstevel@tonic-gate crypto_mech_name_t alg_mech_name; /* KCF mechanism name */ 632*7c478bd9Sstevel@tonic-gate } ipsec_alginfo_t; 633*7c478bd9Sstevel@tonic-gate 634*7c478bd9Sstevel@tonic-gate #define alg_datalen alg_block_sizes[0] 635*7c478bd9Sstevel@tonic-gate 636*7c478bd9Sstevel@tonic-gate #define ALG_FLAG_VALID 0x01 637*7c478bd9Sstevel@tonic-gate #define ALG_VALID(_alg) ((_alg)->alg_flags & ALG_FLAG_VALID) 638*7c478bd9Sstevel@tonic-gate 639*7c478bd9Sstevel@tonic-gate /* 640*7c478bd9Sstevel@tonic-gate * Software crypto execution mode. 641*7c478bd9Sstevel@tonic-gate */ 642*7c478bd9Sstevel@tonic-gate typedef enum { 643*7c478bd9Sstevel@tonic-gate IPSEC_ALGS_EXEC_SYNC = 0, 644*7c478bd9Sstevel@tonic-gate IPSEC_ALGS_EXEC_ASYNC = 1 645*7c478bd9Sstevel@tonic-gate } ipsec_algs_exec_mode_t; 646*7c478bd9Sstevel@tonic-gate 647*7c478bd9Sstevel@tonic-gate extern uint8_t ipsec_nalgs[IPSEC_NALGTYPES]; 648*7c478bd9Sstevel@tonic-gate extern ipsec_alginfo_t *ipsec_alglists[IPSEC_NALGTYPES][IPSEC_MAX_ALGS]; 649*7c478bd9Sstevel@tonic-gate extern uint8_t ipsec_sortlist[IPSEC_NALGTYPES][IPSEC_MAX_ALGS]; 650*7c478bd9Sstevel@tonic-gate extern ipsec_algs_exec_mode_t ipsec_algs_exec_mode[IPSEC_NALGTYPES]; 651*7c478bd9Sstevel@tonic-gate 652*7c478bd9Sstevel@tonic-gate extern kmutex_t alg_lock; 653*7c478bd9Sstevel@tonic-gate 654*7c478bd9Sstevel@tonic-gate extern void ipsec_alg_reg(ipsec_algtype_t, ipsec_alginfo_t *); 655*7c478bd9Sstevel@tonic-gate extern void ipsec_alg_unreg(ipsec_algtype_t, uint8_t); 656*7c478bd9Sstevel@tonic-gate extern void ipsec_alg_fix_min_max(ipsec_alginfo_t *, ipsec_algtype_t); 657*7c478bd9Sstevel@tonic-gate extern void ipsec_alg_free(ipsec_alginfo_t *); 658*7c478bd9Sstevel@tonic-gate extern void ipsec_register_prov_update(void); 659*7c478bd9Sstevel@tonic-gate extern void sadb_alg_update(ipsec_algtype_t, uint8_t, boolean_t); 660*7c478bd9Sstevel@tonic-gate 661*7c478bd9Sstevel@tonic-gate /* 662*7c478bd9Sstevel@tonic-gate * Context templates management. 663*7c478bd9Sstevel@tonic-gate */ 664*7c478bd9Sstevel@tonic-gate 665*7c478bd9Sstevel@tonic-gate #define IPSEC_CTX_TMPL_ALLOC ((crypto_ctx_template_t)-1) 666*7c478bd9Sstevel@tonic-gate #define IPSEC_CTX_TMPL(_sa, _which, _type, _tmpl) { \ 667*7c478bd9Sstevel@tonic-gate if ((_tmpl = (_sa)->_which) == IPSEC_CTX_TMPL_ALLOC) { \ 668*7c478bd9Sstevel@tonic-gate mutex_enter(&assoc->ipsa_lock); \ 669*7c478bd9Sstevel@tonic-gate if ((_sa)->_which == IPSEC_CTX_TMPL_ALLOC) { \ 670*7c478bd9Sstevel@tonic-gate mutex_enter(&alg_lock); \ 671*7c478bd9Sstevel@tonic-gate (void) ipsec_create_ctx_tmpl(_sa, _type); \ 672*7c478bd9Sstevel@tonic-gate mutex_exit(&alg_lock); \ 673*7c478bd9Sstevel@tonic-gate } \ 674*7c478bd9Sstevel@tonic-gate mutex_exit(&assoc->ipsa_lock); \ 675*7c478bd9Sstevel@tonic-gate if ((_tmpl = (_sa)->_which) == IPSEC_CTX_TMPL_ALLOC) \ 676*7c478bd9Sstevel@tonic-gate _tmpl = NULL; \ 677*7c478bd9Sstevel@tonic-gate } \ 678*7c478bd9Sstevel@tonic-gate } 679*7c478bd9Sstevel@tonic-gate 680*7c478bd9Sstevel@tonic-gate extern int ipsec_create_ctx_tmpl(ipsa_t *, ipsec_algtype_t); 681*7c478bd9Sstevel@tonic-gate extern void ipsec_destroy_ctx_tmpl(ipsa_t *, ipsec_algtype_t); 682*7c478bd9Sstevel@tonic-gate 683*7c478bd9Sstevel@tonic-gate /* key checking */ 684*7c478bd9Sstevel@tonic-gate extern int ipsec_check_key(crypto_mech_type_t, sadb_key_t *, boolean_t, int *); 685*7c478bd9Sstevel@tonic-gate 686*7c478bd9Sstevel@tonic-gate /* natt cleanup */ 687*7c478bd9Sstevel@tonic-gate extern void sadb_clear_timeouts(queue_t *); 688*7c478bd9Sstevel@tonic-gate 689*7c478bd9Sstevel@tonic-gate typedef struct { 690*7c478bd9Sstevel@tonic-gate kstat_named_t esp_stat_in_requests; 691*7c478bd9Sstevel@tonic-gate kstat_named_t esp_stat_in_discards; 692*7c478bd9Sstevel@tonic-gate kstat_named_t esp_stat_lookup_failure; 693*7c478bd9Sstevel@tonic-gate kstat_named_t ah_stat_in_requests; 694*7c478bd9Sstevel@tonic-gate kstat_named_t ah_stat_in_discards; 695*7c478bd9Sstevel@tonic-gate kstat_named_t ah_stat_lookup_failure; 696*7c478bd9Sstevel@tonic-gate } ipsec_kstats_t; 697*7c478bd9Sstevel@tonic-gate 698*7c478bd9Sstevel@tonic-gate extern ipsec_kstats_t *ipsec_kstats; 699*7c478bd9Sstevel@tonic-gate extern void ipsec_kstat_init(void); 700*7c478bd9Sstevel@tonic-gate extern void ipsec_kstat_destroy(void); 701*7c478bd9Sstevel@tonic-gate 702*7c478bd9Sstevel@tonic-gate #define IP_ESP_BUMP_STAT(x) (ipsec_kstats->esp_stat_ ## x).value.ui64++ 703*7c478bd9Sstevel@tonic-gate #define IP_AH_BUMP_STAT(x) (ipsec_kstats->ah_stat_ ## x).value.ui64++ 704*7c478bd9Sstevel@tonic-gate 705*7c478bd9Sstevel@tonic-gate #ifdef __cplusplus 706*7c478bd9Sstevel@tonic-gate } 707*7c478bd9Sstevel@tonic-gate #endif 708*7c478bd9Sstevel@tonic-gate 709*7c478bd9Sstevel@tonic-gate #endif /* _INET_SADB_H */ 710