1 0 stevel /* 2 0 stevel * CDDL HEADER START 3 0 stevel * 4 0 stevel * The contents of this file are subject to the terms of the 5 1659 markfen * Common Development and Distribution License (the "License"). 6 1659 markfen * You may not use this file except in compliance with the License. 7 0 stevel * 8 0 stevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 0 stevel * or http://www.opensolaris.org/os/licensing. 10 0 stevel * See the License for the specific language governing permissions 11 0 stevel * and limitations under the License. 12 0 stevel * 13 0 stevel * When distributing Covered Code, include this CDDL HEADER in each 14 0 stevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 0 stevel * If applicable, add the following below this CDDL HEADER, with the 16 0 stevel * fields enclosed by brackets "[]" replaced with your own identifying 17 0 stevel * information: Portions Copyright [yyyy] [name of copyright owner] 18 0 stevel * 19 0 stevel * CDDL HEADER END 20 0 stevel */ 21 0 stevel /* 22 8485 Peter * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 0 stevel * Use is subject to license terms. 24 0 stevel */ 25 0 stevel 26 0 stevel /* 27 0 stevel * IPsec Security Policy Database. 28 0 stevel * 29 0 stevel * This module maintains the SPD and provides routines used by ip and ip6 30 0 stevel * to apply IPsec policy to inbound and outbound datagrams. 31 0 stevel */ 32 0 stevel 33 0 stevel #include <sys/types.h> 34 0 stevel #include <sys/stream.h> 35 0 stevel #include <sys/stropts.h> 36 0 stevel #include <sys/sysmacros.h> 37 0 stevel #include <sys/strsubr.h> 38 10934 sommerfeld #include <sys/strsun.h> 39 0 stevel #include <sys/strlog.h> 40 11042 Erik #include <sys/strsun.h> 41 0 stevel #include <sys/cmn_err.h> 42 0 stevel #include <sys/zone.h> 43 0 stevel 44 0 stevel #include <sys/systm.h> 45 0 stevel #include <sys/param.h> 46 0 stevel #include <sys/kmem.h> 47 3055 danmcd #include <sys/ddi.h> 48 0 stevel 49 0 stevel #include <sys/crypto/api.h> 50 0 stevel 51 0 stevel #include <inet/common.h> 52 0 stevel #include <inet/mi.h> 53 0 stevel 54 0 stevel #include <netinet/ip6.h> 55 0 stevel #include <netinet/icmp6.h> 56 0 stevel #include <netinet/udp.h> 57 0 stevel 58 0 stevel #include <inet/ip.h> 59 0 stevel #include <inet/ip6.h> 60 0 stevel 61 0 stevel #include <net/pfkeyv2.h> 62 0 stevel #include <net/pfpolicy.h> 63 0 stevel #include <inet/sadb.h> 64 0 stevel #include <inet/ipsec_impl.h> 65 3192 danmcd 66 3192 danmcd #include <inet/ip_impl.h> /* For IP_MOD_ID */ 67 3192 danmcd 68 0 stevel #include <inet/ipsecah.h> 69 0 stevel #include <inet/ipsecesp.h> 70 0 stevel #include <inet/ipdrop.h> 71 0 stevel #include <inet/ipclassifier.h> 72 10616 Sebastien #include <inet/iptun.h> 73 10616 Sebastien #include <inet/iptun/iptun_impl.h> 74 0 stevel 75 3448 dh155122 static void ipsec_update_present_flags(ipsec_stack_t *); 76 3448 dh155122 static ipsec_act_t *ipsec_act_wildcard_expand(ipsec_act_t *, uint_t *, 77 3448 dh155122 netstack_t *); 78 3192 danmcd static mblk_t *ipsec_check_ipsecin_policy(mblk_t *, ipsec_policy_t *, 79 11042 Erik ipha_t *, ip6_t *, uint64_t, ip_recv_attr_t *, netstack_t *); 80 3448 dh155122 static void ipsec_action_free_table(ipsec_action_t *); 81 0 stevel static void ipsec_action_reclaim(void *); 82 3448 dh155122 static void ipsec_action_reclaim_stack(netstack_t *); 83 3448 dh155122 static void ipsid_init(netstack_t *); 84 3448 dh155122 static void ipsid_fini(netstack_t *); 85 3055 danmcd 86 3055 danmcd /* sel_flags values for ipsec_init_inbound_sel(). */ 87 3055 danmcd #define SEL_NONE 0x0000 88 3055 danmcd #define SEL_PORT_POLICY 0x0001 89 3055 danmcd #define SEL_IS_ICMP 0x0002 90 3055 danmcd #define SEL_TUNNEL_MODE 0x0004 91 10616 Sebastien #define SEL_POST_FRAG 0x0008 92 3055 danmcd 93 3055 danmcd /* Return values for ipsec_init_inbound_sel(). */ 94 3055 danmcd typedef enum { SELRET_NOMEM, SELRET_BADPKT, SELRET_SUCCESS, SELRET_TUNFRAG} 95 3055 danmcd selret_t; 96 3055 danmcd 97 3055 danmcd static selret_t ipsec_init_inbound_sel(ipsec_selector_t *, mblk_t *, 98 3055 danmcd ipha_t *, ip6_t *, uint8_t); 99 3055 danmcd 100 11042 Erik static boolean_t ipsec_check_ipsecin_action(ip_recv_attr_t *, mblk_t *, 101 0 stevel struct ipsec_action_s *, ipha_t *ipha, ip6_t *ip6h, const char **, 102 11042 Erik kstat_named_t **, netstack_t *); 103 0 stevel static void ipsec_unregister_prov_update(void); 104 3448 dh155122 static void ipsec_prov_update_callback_stack(uint32_t, void *, netstack_t *); 105 81 sommerfe static boolean_t ipsec_compare_action(ipsec_policy_t *, ipsec_policy_t *); 106 3055 danmcd static uint32_t selector_hash(ipsec_selector_t *, ipsec_policy_root_t *); 107 3448 dh155122 static boolean_t ipsec_kstat_init(ipsec_stack_t *); 108 3448 dh155122 static void ipsec_kstat_destroy(ipsec_stack_t *); 109 3448 dh155122 static int ipsec_free_tables(ipsec_stack_t *); 110 3055 danmcd static int tunnel_compare(const void *, const void *); 111 3055 danmcd static void ipsec_freemsg_chain(mblk_t *); 112 11042 Erik static void ip_drop_packet_chain(mblk_t *, boolean_t, ill_t *, 113 3055 danmcd struct kstat_named *, ipdropper_t *); 114 3448 dh155122 static boolean_t ipsec_kstat_init(ipsec_stack_t *); 115 3448 dh155122 static void ipsec_kstat_destroy(ipsec_stack_t *); 116 3448 dh155122 static int ipsec_free_tables(ipsec_stack_t *); 117 3448 dh155122 static int tunnel_compare(const void *, const void *); 118 3448 dh155122 static void ipsec_freemsg_chain(mblk_t *); 119 81 sommerfe 120 81 sommerfe /* 121 81 sommerfe * Selector hash table is statically sized at module load time. 122 81 sommerfe * we default to 251 buckets, which is the largest prime number under 255 123 81 sommerfe */ 124 81 sommerfe 125 81 sommerfe #define IPSEC_SPDHASH_DEFAULT 251 126 3055 danmcd 127 3055 danmcd /* SPD hash-size tunable per tunnel. */ 128 3055 danmcd #define TUN_SPDHASH_DEFAULT 5 129 3055 danmcd 130 5245 danmcd uint32_t ipsec_spd_hashsize; 131 5245 danmcd uint32_t tun_spd_hashsize; 132 81 sommerfe 133 81 sommerfe #define IPSEC_SEL_NOHASH ((uint32_t)(~0)) 134 0 stevel 135 3448 dh155122 /* 136 3448 dh155122 * Handle global across all stack instances 137 3448 dh155122 */ 138 3448 dh155122 static crypto_notify_handle_t prov_update_handle = NULL; 139 81 sommerfe 140 0 stevel static kmem_cache_t *ipsec_action_cache; 141 0 stevel static kmem_cache_t *ipsec_sel_cache; 142 0 stevel static kmem_cache_t *ipsec_pol_cache; 143 0 stevel 144 3055 danmcd /* Frag cache prototypes */ 145 11042 Erik static void ipsec_fragcache_clean(ipsec_fragcache_t *, ipsec_stack_t *); 146 3055 danmcd static ipsec_fragcache_entry_t *fragcache_delentry(int, 147 11042 Erik ipsec_fragcache_entry_t *, ipsec_fragcache_t *, ipsec_stack_t *); 148 3055 danmcd boolean_t ipsec_fragcache_init(ipsec_fragcache_t *); 149 11042 Erik void ipsec_fragcache_uninit(ipsec_fragcache_t *, ipsec_stack_t *ipss); 150 11042 Erik mblk_t *ipsec_fragcache_add(ipsec_fragcache_t *, mblk_t *, mblk_t *, 151 11042 Erik int, ipsec_stack_t *); 152 0 stevel 153 691 sommerfe int ipsec_hdr_pullup_needed = 0; 154 691 sommerfe int ipsec_weird_null_inbound_policy = 0; 155 691 sommerfe 156 0 stevel #define ALGBITS_ROUND_DOWN(x, align) (((x)/(align))*(align)) 157 0 stevel #define ALGBITS_ROUND_UP(x, align) ALGBITS_ROUND_DOWN((x)+(align)-1, align) 158 0 stevel 159 0 stevel /* 160 0 stevel * Inbound traffic should have matching identities for both SA's. 161 0 stevel */ 162 0 stevel 163 0 stevel #define SA_IDS_MATCH(sa1, sa2) \ 164 0 stevel (((sa1) == NULL) || ((sa2) == NULL) || \ 165 0 stevel (((sa1)->ipsa_src_cid == (sa2)->ipsa_src_cid) && \ 166 0 stevel (((sa1)->ipsa_dst_cid == (sa2)->ipsa_dst_cid)))) 167 3055 danmcd 168 3055 danmcd /* 169 3055 danmcd * IPv6 Fragments 170 3055 danmcd */ 171 3055 danmcd #define IS_V6_FRAGMENT(ipp) (ipp.ipp_fields & IPPF_FRAGHDR) 172 81 sommerfe 173 0 stevel /* 174 0 stevel * Policy failure messages. 175 0 stevel */ 176 0 stevel static char *ipsec_policy_failure_msgs[] = { 177 0 stevel 178 0 stevel /* IPSEC_POLICY_NOT_NEEDED */ 179 0 stevel "%s: Dropping the datagram because the incoming packet " 180 0 stevel "is %s, but the recipient expects clear; Source %s, " 181 0 stevel "Destination %s.\n", 182 0 stevel 183 0 stevel /* IPSEC_POLICY_MISMATCH */ 184 0 stevel "%s: Policy Failure for the incoming packet (%s); Source %s, " 185 0 stevel "Destination %s.\n", 186 0 stevel 187 0 stevel /* IPSEC_POLICY_AUTH_NOT_NEEDED */ 188 0 stevel "%s: Authentication present while not expected in the " 189 0 stevel "incoming %s packet; Source %s, Destination %s.\n", 190 0 stevel 191 0 stevel /* IPSEC_POLICY_ENCR_NOT_NEEDED */ 192 0 stevel "%s: Encryption present while not expected in the " 193 0 stevel "incoming %s packet; Source %s, Destination %s.\n", 194 0 stevel 195 0 stevel /* IPSEC_POLICY_SE_NOT_NEEDED */ 196 0 stevel "%s: Self-Encapsulation present while not expected in the " 197 0 stevel "incoming %s packet; Source %s, Destination %s.\n", 198 0 stevel }; 199 0 stevel 200 0 stevel /* 201 0 stevel * General overviews: 202 0 stevel * 203 0 stevel * Locking: 204 0 stevel * 205 0 stevel * All of the system policy structures are protected by a single 206 3448 dh155122 * rwlock. These structures are threaded in a 207 0 stevel * fairly complex fashion and are not expected to change on a 208 0 stevel * regular basis, so this should not cause scaling/contention 209 0 stevel * problems. As a result, policy checks should (hopefully) be MT-hot. 210 0 stevel * 211 0 stevel * Allocation policy: 212 0 stevel * 213 0 stevel * We use custom kmem cache types for the various 214 0 stevel * bits & pieces of the policy data structures. All allocations 215 0 stevel * use KM_NOSLEEP instead of KM_SLEEP for policy allocation. The 216 0 stevel * policy table is of potentially unbounded size, so we don't 217 0 stevel * want to provide a way to hog all system memory with policy 218 0 stevel * entries.. 219 0 stevel */ 220 0 stevel 221 3055 danmcd /* Convenient functions for freeing or dropping a b_next linked mblk chain */ 222 3055 danmcd 223 3055 danmcd /* Free all messages in an mblk chain */ 224 3055 danmcd static void 225 3055 danmcd ipsec_freemsg_chain(mblk_t *mp) 226 3055 danmcd { 227 3055 danmcd mblk_t *mpnext; 228 3055 danmcd while (mp != NULL) { 229 3055 danmcd ASSERT(mp->b_prev == NULL); 230 3055 danmcd mpnext = mp->b_next; 231 3055 danmcd mp->b_next = NULL; 232 11042 Erik freemsg(mp); 233 3055 danmcd mp = mpnext; 234 3055 danmcd } 235 3055 danmcd } 236 3055 danmcd 237 11042 Erik /* 238 11042 Erik * ip_drop all messages in an mblk chain 239 11042 Erik * Can handle a b_next chain of ip_recv_attr_t mblks, or just a b_next chain 240 11042 Erik * of data. 241 11042 Erik */ 242 11042 Erik static void 243 11042 Erik ip_drop_packet_chain(mblk_t *mp, boolean_t inbound, ill_t *ill, 244 11042 Erik struct kstat_named *counter, ipdropper_t *who_called) 245 3055 danmcd { 246 3055 danmcd mblk_t *mpnext; 247 3055 danmcd while (mp != NULL) { 248 3055 danmcd ASSERT(mp->b_prev == NULL); 249 3055 danmcd mpnext = mp->b_next; 250 3055 danmcd mp->b_next = NULL; 251 11042 Erik if (ip_recv_attr_is_mblk(mp)) 252 11042 Erik mp = ip_recv_attr_free_mblk(mp); 253 11042 Erik ip_drop_packet(mp, inbound, ill, counter, who_called); 254 3055 danmcd mp = mpnext; 255 3055 danmcd } 256 3055 danmcd } 257 81 sommerfe 258 81 sommerfe /* 259 81 sommerfe * AVL tree comparison function. 260 81 sommerfe * the in-kernel avl assumes unique keys for all objects. 261 81 sommerfe * Since sometimes policy will duplicate rules, we may insert 262 81 sommerfe * multiple rules with the same rule id, so we need a tie-breaker. 263 81 sommerfe */ 264 81 sommerfe static int 265 81 sommerfe ipsec_policy_cmpbyid(const void *a, const void *b) 266 81 sommerfe { 267 81 sommerfe const ipsec_policy_t *ipa, *ipb; 268 81 sommerfe uint64_t idxa, idxb; 269 81 sommerfe 270 81 sommerfe ipa = (const ipsec_policy_t *)a; 271 81 sommerfe ipb = (const ipsec_policy_t *)b; 272 81 sommerfe idxa = ipa->ipsp_index; 273 81 sommerfe idxb = ipb->ipsp_index; 274 81 sommerfe 275 81 sommerfe if (idxa < idxb) 276 81 sommerfe return (-1); 277 81 sommerfe if (idxa > idxb) 278 81 sommerfe return (1); 279 81 sommerfe /* 280 81 sommerfe * Tie-breaker #1: All installed policy rules have a non-NULL 281 81 sommerfe * ipsl_sel (selector set), so an entry with a NULL ipsp_sel is not 282 81 sommerfe * actually in-tree but rather a template node being used in 283 81 sommerfe * an avl_find query; see ipsec_policy_delete(). This gives us 284 11042 Erik * a placeholder in the ordering just before the first entry with 285 81 sommerfe * a key >= the one we're looking for, so we can walk forward from 286 81 sommerfe * that point to get the remaining entries with the same id. 287 81 sommerfe */ 288 81 sommerfe if ((ipa->ipsp_sel == NULL) && (ipb->ipsp_sel != NULL)) 289 81 sommerfe return (-1); 290 81 sommerfe if ((ipb->ipsp_sel == NULL) && (ipa->ipsp_sel != NULL)) 291 81 sommerfe return (1); 292 81 sommerfe /* 293 81 sommerfe * At most one of the arguments to the comparison should have a 294 81 sommerfe * NULL selector pointer; if not, the tree is broken. 295 81 sommerfe */ 296 81 sommerfe ASSERT(ipa->ipsp_sel != NULL); 297 81 sommerfe ASSERT(ipb->ipsp_sel != NULL); 298 81 sommerfe /* 299 81 sommerfe * Tie-breaker #2: use the virtual address of the policy node 300 81 sommerfe * to arbitrarily break ties. Since we use the new tree node in 301 81 sommerfe * the avl_find() in ipsec_insert_always, the new node will be 302 81 sommerfe * inserted into the tree in the right place in the sequence. 303 81 sommerfe */ 304 81 sommerfe if (ipa < ipb) 305 81 sommerfe return (-1); 306 81 sommerfe if (ipa > ipb) 307 81 sommerfe return (1); 308 81 sommerfe return (0); 309 81 sommerfe } 310 81 sommerfe 311 3448 dh155122 /* 312 3448 dh155122 * Free what ipsec_alloc_table allocated. 313 3448 dh155122 */ 314 3055 danmcd void 315 81 sommerfe ipsec_polhead_free_table(ipsec_policy_head_t *iph) 316 81 sommerfe { 317 3055 danmcd int dir; 318 3448 dh155122 int i; 319 81 sommerfe 320 81 sommerfe for (dir = 0; dir < IPSEC_NTYPES; dir++) { 321 81 sommerfe ipsec_policy_root_t *ipr = &iph->iph_root[dir]; 322 81 sommerfe 323 81 sommerfe if (ipr->ipr_hash == NULL) 324 81 sommerfe continue; 325 81 sommerfe 326 3448 dh155122 for (i = 0; i < ipr->ipr_nchains; i++) { 327 3448 dh155122 ASSERT(ipr->ipr_hash[i].hash_head == NULL); 328 3448 dh155122 } 329 3055 danmcd kmem_free(ipr->ipr_hash, ipr->ipr_nchains * 330 81 sommerfe sizeof (ipsec_policy_hash_t)); 331 3448 dh155122 ipr->ipr_hash = NULL; 332 81 sommerfe } 333 81 sommerfe } 334 81 sommerfe 335 3055 danmcd void 336 81 sommerfe ipsec_polhead_destroy(ipsec_policy_head_t *iph) 337 81 sommerfe { 338 81 sommerfe int dir; 339 81 sommerfe 340 81 sommerfe avl_destroy(&iph->iph_rulebyid); 341 81 sommerfe rw_destroy(&iph->iph_lock); 342 81 sommerfe 343 81 sommerfe for (dir = 0; dir < IPSEC_NTYPES; dir++) { 344 81 sommerfe ipsec_policy_root_t *ipr = &iph->iph_root[dir]; 345 81 sommerfe int chain; 346 81 sommerfe 347 3055 danmcd for (chain = 0; chain < ipr->ipr_nchains; chain++) 348 81 sommerfe mutex_destroy(&(ipr->ipr_hash[chain].hash_lock)); 349 81 sommerfe 350 81 sommerfe } 351 81 sommerfe ipsec_polhead_free_table(iph); 352 81 sommerfe } 353 81 sommerfe 354 0 stevel /* 355 3448 dh155122 * Free the IPsec stack instance. 356 3448 dh155122 */ 357 3448 dh155122 /* ARGSUSED */ 358 3448 dh155122 static void 359 3448 dh155122 ipsec_stack_fini(netstackid_t stackid, void *arg) 360 3448 dh155122 { 361 3448 dh155122 ipsec_stack_t *ipss = (ipsec_stack_t *)arg; 362 3055 danmcd void *cookie; 363 3055 danmcd ipsec_tun_pol_t *node; 364 3448 dh155122 netstack_t *ns = ipss->ipsec_netstack; 365 3448 dh155122 int i; 366 3448 dh155122 ipsec_algtype_t algtype; 367 3448 dh155122 368 3448 dh155122 ipsec_loader_destroy(ipss); 369 3448 dh155122 370 3448 dh155122 rw_enter(&ipss->ipsec_tunnel_policy_lock, RW_WRITER); 371 3055 danmcd /* 372 3055 danmcd * It's possible we can just ASSERT() the tree is empty. After all, 373 3055 danmcd * we aren't called until IP is ready to unload (and presumably all 374 3055 danmcd * tunnels have been unplumbed). But we'll play it safe for now, the 375 3055 danmcd * loop will just exit immediately if it's empty. 376 3055 danmcd */ 377 3055 danmcd cookie = NULL; 378 3055 danmcd while ((node = (ipsec_tun_pol_t *) 379 3448 dh155122 avl_destroy_nodes(&ipss->ipsec_tunnel_policies, 380 3448 dh155122 &cookie)) != NULL) { 381 3448 dh155122 ITP_REFRELE(node, ns); 382 3448 dh155122 } 383 3448 dh155122 avl_destroy(&ipss->ipsec_tunnel_policies); 384 3448 dh155122 rw_exit(&ipss->ipsec_tunnel_policy_lock); 385 3448 dh155122 rw_destroy(&ipss->ipsec_tunnel_policy_lock); 386 3448 dh155122 387 3448 dh155122 ipsec_config_flush(ns); 388 3448 dh155122 389 3448 dh155122 ipsec_kstat_destroy(ipss); 390 3448 dh155122 391 3448 dh155122 ip_drop_unregister(&ipss->ipsec_dropper); 392 3448 dh155122 393 3448 dh155122 ip_drop_unregister(&ipss->ipsec_spd_dropper); 394 3448 dh155122 ip_drop_destroy(ipss); 395 3448 dh155122 /* 396 3448 dh155122 * Globals start with ref == 1 to prevent IPPH_REFRELE() from 397 3448 dh155122 * attempting to free them, hence they should have 1 now. 398 3448 dh155122 */ 399 3448 dh155122 ipsec_polhead_destroy(&ipss->ipsec_system_policy); 400 3448 dh155122 ASSERT(ipss->ipsec_system_policy.iph_refs == 1); 401 3448 dh155122 ipsec_polhead_destroy(&ipss->ipsec_inactive_policy); 402 3448 dh155122 ASSERT(ipss->ipsec_inactive_policy.iph_refs == 1); 403 3448 dh155122 404 3448 dh155122 for (i = 0; i < IPSEC_ACTION_HASH_SIZE; i++) { 405 3448 dh155122 ipsec_action_free_table(ipss->ipsec_action_hash[i].hash_head); 406 3448 dh155122 ipss->ipsec_action_hash[i].hash_head = NULL; 407 3448 dh155122 mutex_destroy(&(ipss->ipsec_action_hash[i].hash_lock)); 408 3448 dh155122 } 409 3448 dh155122 410 3448 dh155122 for (i = 0; i < ipss->ipsec_spd_hashsize; i++) { 411 3448 dh155122 ASSERT(ipss->ipsec_sel_hash[i].hash_head == NULL); 412 3448 dh155122 mutex_destroy(&(ipss->ipsec_sel_hash[i].hash_lock)); 413 3448 dh155122 } 414 3448 dh155122 415 3448 dh155122 mutex_enter(&ipss->ipsec_alg_lock); 416 3448 dh155122 for (algtype = 0; algtype < IPSEC_NALGTYPES; algtype ++) { 417 3448 dh155122 int nalgs = ipss->ipsec_nalgs[algtype]; 418 3448 dh155122 419 3448 dh155122 for (i = 0; i < nalgs; i++) { 420 3448 dh155122 if (ipss->ipsec_alglists[algtype][i] != NULL) 421 3448 dh155122 ipsec_alg_unreg(algtype, i, ns); 422 3448 dh155122 } 423 3448 dh155122 } 424 3448 dh155122 mutex_exit(&ipss->ipsec_alg_lock); 425 3448 dh155122 mutex_destroy(&ipss->ipsec_alg_lock); 426 3448 dh155122 427 3448 dh155122 ipsid_gc(ns); 428 3448 dh155122 ipsid_fini(ns); 429 3448 dh155122 430 3448 dh155122 (void) ipsec_free_tables(ipss); 431 3448 dh155122 kmem_free(ipss, sizeof (*ipss)); 432 3448 dh155122 } 433 3448 dh155122 434 3448 dh155122 void 435 3448 dh155122 ipsec_policy_g_destroy(void) 436 3448 dh155122 { 437 0 stevel kmem_cache_destroy(ipsec_action_cache); 438 0 stevel kmem_cache_destroy(ipsec_sel_cache); 439 0 stevel kmem_cache_destroy(ipsec_pol_cache); 440 3448 dh155122 441 3448 dh155122 ipsec_unregister_prov_update(); 442 3448 dh155122 443 3448 dh155122 netstack_unregister(NS_IPSEC); 444 3448 dh155122 } 445 3448 dh155122 446 3448 dh155122 447 3448 dh155122 /* 448 3448 dh155122 * Free what ipsec_alloc_tables allocated. 449 81 sommerfe * Called when table allocation fails to free the table. 450 81 sommerfe */ 451 81 sommerfe static int 452 3448 dh155122 ipsec_free_tables(ipsec_stack_t *ipss) 453 3448 dh155122 { 454 3448 dh155122 int i; 455 3448 dh155122 456 3448 dh155122 if (ipss->ipsec_sel_hash != NULL) { 457 3448 dh155122 for (i = 0; i < ipss->ipsec_spd_hashsize; i++) { 458 3448 dh155122 ASSERT(ipss->ipsec_sel_hash[i].hash_head == NULL); 459 3448 dh155122 } 460 3448 dh155122 kmem_free(ipss->ipsec_sel_hash, ipss->ipsec_spd_hashsize * 461 3448 dh155122 sizeof (*ipss->ipsec_sel_hash)); 462 3448 dh155122 ipss->ipsec_sel_hash = NULL; 463 3448 dh155122 ipss->ipsec_spd_hashsize = 0; 464 3448 dh155122 } 465 3448 dh155122 ipsec_polhead_free_table(&ipss->ipsec_system_policy); 466 3448 dh155122 ipsec_polhead_free_table(&ipss->ipsec_inactive_policy); 467 81 sommerfe 468 81 sommerfe return (ENOMEM); 469 81 sommerfe } 470 81 sommerfe 471 81 sommerfe /* 472 81 sommerfe * Attempt to allocate the tables in a single policy head. 473 81 sommerfe * Return nonzero on failure after cleaning up any work in progress. 474 81 sommerfe */ 475 3055 danmcd int 476 3055 danmcd ipsec_alloc_table(ipsec_policy_head_t *iph, int nchains, int kmflag, 477 3448 dh155122 boolean_t global_cleanup, netstack_t *ns) 478 3055 danmcd { 479 3055 danmcd int dir; 480 81 sommerfe 481 81 sommerfe for (dir = 0; dir < IPSEC_NTYPES; dir++) { 482 81 sommerfe ipsec_policy_root_t *ipr = &iph->iph_root[dir]; 483 81 sommerfe 484 3055 danmcd ipr->ipr_nchains = nchains; 485 81 sommerfe ipr->ipr_hash = kmem_zalloc(nchains * 486 81 sommerfe sizeof (ipsec_policy_hash_t), kmflag); 487 81 sommerfe if (ipr->ipr_hash == NULL) 488 3448 dh155122 return (global_cleanup ? 489 3448 dh155122 ipsec_free_tables(ns->netstack_ipsec) : 490 3055 danmcd ENOMEM); 491 81 sommerfe } 492 81 sommerfe return (0); 493 81 sommerfe } 494 81 sommerfe 495 81 sommerfe /* 496 81 sommerfe * Attempt to allocate the various tables. Return nonzero on failure 497 81 sommerfe * after cleaning up any work in progress. 498 81 sommerfe */ 499 81 sommerfe static int 500 3448 dh155122 ipsec_alloc_tables(int kmflag, netstack_t *ns) 501 81 sommerfe { 502 81 sommerfe int error; 503 3448 dh155122 ipsec_stack_t *ipss = ns->netstack_ipsec; 504 3448 dh155122 505 3448 dh155122 error = ipsec_alloc_table(&ipss->ipsec_system_policy, 506 3448 dh155122 ipss->ipsec_spd_hashsize, kmflag, B_TRUE, ns); 507 81 sommerfe if (error != 0) 508 81 sommerfe return (error); 509 81 sommerfe 510 3448 dh155122 error = ipsec_alloc_table(&ipss->ipsec_inactive_policy, 511 3448 dh155122 ipss->ipsec_spd_hashsize, kmflag, B_TRUE, ns); 512 81 sommerfe if (error != 0) 513 81 sommerfe return (error); 514 81 sommerfe 515 3448 dh155122 ipss->ipsec_sel_hash = kmem_zalloc(ipss->ipsec_spd_hashsize * 516 3448 dh155122 sizeof (*ipss->ipsec_sel_hash), kmflag); 517 3448 dh155122 518 3448 dh155122 if (ipss->ipsec_sel_hash == NULL) 519 3448 dh155122 return (ipsec_free_tables(ipss)); 520 81 sommerfe 521 81 sommerfe return (0); 522 81 sommerfe } 523 81 sommerfe 524 81 sommerfe /* 525 81 sommerfe * After table allocation, initialize a policy head. 526 81 sommerfe */ 527 3055 danmcd void 528 3055 danmcd ipsec_polhead_init(ipsec_policy_head_t *iph, int nchains) 529 3055 danmcd { 530 3055 danmcd int dir, chain; 531 81 sommerfe 532 81 sommerfe rw_init(&iph->iph_lock, NULL, RW_DEFAULT, NULL); 533 81 sommerfe avl_create(&iph->iph_rulebyid, ipsec_policy_cmpbyid, 534 81 sommerfe sizeof (ipsec_policy_t), offsetof(ipsec_policy_t, ipsp_byid)); 535 81 sommerfe 536 81 sommerfe for (dir = 0; dir < IPSEC_NTYPES; dir++) { 537 81 sommerfe ipsec_policy_root_t *ipr = &iph->iph_root[dir]; 538 81 sommerfe ipr->ipr_nchains = nchains; 539 81 sommerfe 540 81 sommerfe for (chain = 0; chain < nchains; chain++) { 541 81 sommerfe mutex_init(&(ipr->ipr_hash[chain].hash_lock), 542 81 sommerfe NULL, MUTEX_DEFAULT, NULL); 543 81 sommerfe } 544 81 sommerfe } 545 81 sommerfe } 546 81 sommerfe 547 3448 dh155122 static boolean_t 548 3448 dh155122 ipsec_kstat_init(ipsec_stack_t *ipss) 549 3448 dh155122 { 550 3448 dh155122 ipss->ipsec_ksp = kstat_create_netstack("ip", 0, "ipsec_stat", "net", 551 3448 dh155122 KSTAT_TYPE_NAMED, sizeof (ipsec_kstats_t) / sizeof (kstat_named_t), 552 3448 dh155122 KSTAT_FLAG_PERSISTENT, ipss->ipsec_netstack->netstack_stackid); 553 3448 dh155122 554 3448 dh155122 if (ipss->ipsec_ksp == NULL || ipss->ipsec_ksp->ks_data == NULL) 555 3448 dh155122 return (B_FALSE); 556 3448 dh155122 557 3448 dh155122 ipss->ipsec_kstats = ipss->ipsec_ksp->ks_data; 558 3448 dh155122 559 3448 dh155122 #define KI(x) kstat_named_init(&ipss->ipsec_kstats->x, #x, KSTAT_DATA_UINT64) 560 3448 dh155122 KI(esp_stat_in_requests); 561 3448 dh155122 KI(esp_stat_in_discards); 562 3448 dh155122 KI(esp_stat_lookup_failure); 563 3448 dh155122 KI(ah_stat_in_requests); 564 3448 dh155122 KI(ah_stat_in_discards); 565 3448 dh155122 KI(ah_stat_lookup_failure); 566 3448 dh155122 KI(sadb_acquire_maxpackets); 567 3448 dh155122 KI(sadb_acquire_qhiwater); 568 3448 dh155122 #undef KI 569 3448 dh155122 570 3448 dh155122 kstat_install(ipss->ipsec_ksp); 571 3448 dh155122 return (B_TRUE); 572 3448 dh155122 } 573 3448 dh155122 574 3448 dh155122 static void 575 3448 dh155122 ipsec_kstat_destroy(ipsec_stack_t *ipss) 576 3448 dh155122 { 577 3448 dh155122 kstat_delete_netstack(ipss->ipsec_ksp, 578 3448 dh155122 ipss->ipsec_netstack->netstack_stackid); 579 3448 dh155122 ipss->ipsec_kstats = NULL; 580 3448 dh155122 581 3448 dh155122 } 582 3448 dh155122 583 3448 dh155122 /* 584 3448 dh155122 * Initialize the IPsec stack instance. 585 3448 dh155122 */ 586 3448 dh155122 /* ARGSUSED */ 587 3448 dh155122 static void * 588 3448 dh155122 ipsec_stack_init(netstackid_t stackid, netstack_t *ns) 589 3448 dh155122 { 590 3448 dh155122 ipsec_stack_t *ipss; 591 3448 dh155122 int i; 592 3448 dh155122 593 3448 dh155122 ipss = (ipsec_stack_t *)kmem_zalloc(sizeof (*ipss), KM_SLEEP); 594 3448 dh155122 ipss->ipsec_netstack = ns; 595 3448 dh155122 596 3448 dh155122 /* 597 3448 dh155122 * FIXME: netstack_ipsec is used by some of the routines we call 598 3448 dh155122 * below, but it isn't set until this routine returns. 599 3448 dh155122 * Either we introduce optional xxx_stack_alloc() functions 600 3448 dh155122 * that will be called by the netstack framework before xxx_stack_init, 601 3448 dh155122 * or we switch spd.c and sadb.c to operate on ipsec_stack_t 602 3448 dh155122 * (latter has some include file order issues for sadb.h, but makes 603 3448 dh155122 * sense if we merge some of the ipsec related stack_t's together. 604 3448 dh155122 */ 605 3448 dh155122 ns->netstack_ipsec = ipss; 606 81 sommerfe 607 81 sommerfe /* 608 81 sommerfe * Make two attempts to allocate policy hash tables; try it at 609 81 sommerfe * the "preferred" size (may be set in /etc/system) first, 610 81 sommerfe * then fall back to the default size. 611 81 sommerfe */ 612 5245 danmcd ipss->ipsec_spd_hashsize = (ipsec_spd_hashsize == 0) ? 613 5245 danmcd IPSEC_SPDHASH_DEFAULT : ipsec_spd_hashsize; 614 3448 dh155122 615 3448 dh155122 if (ipsec_alloc_tables(KM_NOSLEEP, ns) != 0) { 616 81 sommerfe cmn_err(CE_WARN, 617 81 sommerfe "Unable to allocate %d entry IPsec policy hash table", 618 3448 dh155122 ipss->ipsec_spd_hashsize); 619 3448 dh155122 ipss->ipsec_spd_hashsize = IPSEC_SPDHASH_DEFAULT; 620 81 sommerfe cmn_err(CE_WARN, "Falling back to %d entries", 621 3448 dh155122 ipss->ipsec_spd_hashsize); 622 3448 dh155122 (void) ipsec_alloc_tables(KM_SLEEP, ns); 623 81 sommerfe } 624 81 sommerfe 625 3055 danmcd /* Just set a default for tunnels. */ 626 5245 danmcd ipss->ipsec_tun_spd_hashsize = (tun_spd_hashsize == 0) ? 627 5245 danmcd TUN_SPDHASH_DEFAULT : tun_spd_hashsize; 628 3448 dh155122 629 3448 dh155122 ipsid_init(ns); 630 3055 danmcd /* 631 3055 danmcd * Globals need ref == 1 to prevent IPPH_REFRELE() from attempting 632 3055 danmcd * to free them. 633 3055 danmcd */ 634 3448 dh155122 ipss->ipsec_system_policy.iph_refs = 1; 635 3448 dh155122 ipss->ipsec_inactive_policy.iph_refs = 1; 636 3448 dh155122 ipsec_polhead_init(&ipss->ipsec_system_policy, 637 3448 dh155122 ipss->ipsec_spd_hashsize); 638 3448 dh155122 ipsec_polhead_init(&ipss->ipsec_inactive_policy, 639 3448 dh155122 ipss->ipsec_spd_hashsize); 640 3448 dh155122 rw_init(&ipss->ipsec_tunnel_policy_lock, NULL, RW_DEFAULT, NULL); 641 3448 dh155122 avl_create(&ipss->ipsec_tunnel_policies, tunnel_compare, 642 3448 dh155122 sizeof (ipsec_tun_pol_t), 0); 643 3448 dh155122 644 3448 dh155122 ipss->ipsec_next_policy_index = 1; 645 3448 dh155122 646 3448 dh155122 rw_init(&ipss->ipsec_system_policy.iph_lock, NULL, RW_DEFAULT, NULL); 647 3448 dh155122 rw_init(&ipss->ipsec_inactive_policy.iph_lock, NULL, RW_DEFAULT, NULL); 648 0 stevel 649 0 stevel for (i = 0; i < IPSEC_ACTION_HASH_SIZE; i++) 650 3448 dh155122 mutex_init(&(ipss->ipsec_action_hash[i].hash_lock), 651 0 stevel NULL, MUTEX_DEFAULT, NULL); 652 0 stevel 653 3448 dh155122 for (i = 0; i < ipss->ipsec_spd_hashsize; i++) 654 3448 dh155122 mutex_init(&(ipss->ipsec_sel_hash[i].hash_lock), 655 0 stevel NULL, MUTEX_DEFAULT, NULL); 656 0 stevel 657 3448 dh155122 mutex_init(&ipss->ipsec_alg_lock, NULL, MUTEX_DEFAULT, NULL); 658 3448 dh155122 for (i = 0; i < IPSEC_NALGTYPES; i++) { 659 3448 dh155122 ipss->ipsec_nalgs[i] = 0; 660 3448 dh155122 } 661 3448 dh155122 662 3448 dh155122 ip_drop_init(ipss); 663 3448 dh155122 ip_drop_register(&ipss->ipsec_spd_dropper, "IPsec SPD"); 664 3448 dh155122 665 3448 dh155122 /* IP's IPsec code calls the packet dropper */ 666 3448 dh155122 ip_drop_register(&ipss->ipsec_dropper, "IP IPsec processing"); 667 3448 dh155122 668 3448 dh155122 (void) ipsec_kstat_init(ipss); 669 3448 dh155122 670 3448 dh155122 ipsec_loader_init(ipss); 671 3448 dh155122 ipsec_loader_start(ipss); 672 3448 dh155122 673 3448 dh155122 return (ipss); 674 3448 dh155122 } 675 3448 dh155122 676 3448 dh155122 /* Global across all stack instances */ 677 3448 dh155122 void 678 3448 dh155122 ipsec_policy_g_init(void) 679 3448 dh155122 { 680 0 stevel ipsec_action_cache = kmem_cache_create("ipsec_actions", 681 0 stevel sizeof (ipsec_action_t), _POINTER_ALIGNMENT, NULL, NULL, 682 0 stevel ipsec_action_reclaim, NULL, NULL, 0); 683 0 stevel ipsec_sel_cache = kmem_cache_create("ipsec_selectors", 684 0 stevel sizeof (ipsec_sel_t), _POINTER_ALIGNMENT, NULL, NULL, 685 0 stevel NULL, NULL, NULL, 0); 686 0 stevel ipsec_pol_cache = kmem_cache_create("ipsec_policy", 687 0 stevel sizeof (ipsec_policy_t), _POINTER_ALIGNMENT, NULL, NULL, 688 0 stevel NULL, NULL, NULL, 0); 689 0 stevel 690 3448 dh155122 /* 691 3448 dh155122 * We want to be informed each time a stack is created or 692 3448 dh155122 * destroyed in the kernel, so we can maintain the 693 3448 dh155122 * set of ipsec_stack_t's. 694 3448 dh155122 */ 695 3448 dh155122 netstack_register(NS_IPSEC, ipsec_stack_init, NULL, ipsec_stack_fini); 696 0 stevel } 697 0 stevel 698 0 stevel /* 699 0 stevel * Sort algorithm lists. 700 134 danmcd * 701 0 stevel * I may need to split this based on 702 0 stevel * authentication/encryption, and I may wish to have an administrator 703 0 stevel * configure this list. Hold on to some NDD variables... 704 0 stevel * 705 0 stevel * XXX For now, sort on minimum key size (GAG!). While minimum key size is 706 134 danmcd * not the ideal metric, it's the only quantifiable measure available. 707 134 danmcd * We need a better metric for sorting algorithms by preference. 708 0 stevel */ 709 0 stevel static void 710 3448 dh155122 alg_insert_sortlist(enum ipsec_algtype at, uint8_t algid, netstack_t *ns) 711 3448 dh155122 { 712 3448 dh155122 ipsec_stack_t *ipss = ns->netstack_ipsec; 713 3448 dh155122 ipsec_alginfo_t *ai = ipss->ipsec_alglists[at][algid]; 714 0 stevel uint8_t holder, swap; 715 0 stevel uint_t i; 716 3448 dh155122 uint_t count = ipss->ipsec_nalgs[at]; 717 0 stevel ASSERT(ai != NULL); 718 0 stevel ASSERT(algid == ai->alg_id); 719 0 stevel 720 3448 dh155122 ASSERT(MUTEX_HELD(&ipss->ipsec_alg_lock)); 721 0 stevel 722 0 stevel holder = algid; 723 0 stevel 724 0 stevel for (i = 0; i < count - 1; i++) { 725 0 stevel ipsec_alginfo_t *alt; 726 0 stevel 727 3448 dh155122 alt = ipss->ipsec_alglists[at][ipss->ipsec_sortlist[at][i]]; 728 0 stevel /* 729 0 stevel * If you want to give precedence to newly added algs, 730 0 stevel * add the = in the > comparison. 731 0 stevel */ 732 0 stevel if ((holder != algid) || (ai->alg_minbits > alt->alg_minbits)) { 733 0 stevel /* Swap sortlist[i] and holder. */ 734 3448 dh155122 swap = ipss->ipsec_sortlist[at][i]; 735 3448 dh155122 ipss->ipsec_sortlist[at][i] = holder; 736 0 stevel holder = swap; 737 0 stevel ai = alt; 738 0 stevel } /* Else just continue. */ 739 0 stevel } 740 0 stevel 741 0 stevel /* Store holder in last slot. */ 742 3448 dh155122 ipss->ipsec_sortlist[at][i] = holder; 743 0 stevel } 744 0 stevel 745 0 stevel /* 746 0 stevel * Remove an algorithm from a sorted algorithm list. 747 0 stevel * This should be considerably easier, even with complex sorting. 748 0 stevel */ 749 0 stevel static void 750 3448 dh155122 alg_remove_sortlist(enum ipsec_algtype at, uint8_t algid, netstack_t *ns) 751 0 stevel { 752 0 stevel boolean_t copyback = B_FALSE; 753 0 stevel int i; 754 3448 dh155122 ipsec_stack_t *ipss = ns->netstack_ipsec; 755 3448 dh155122 int newcount = ipss->ipsec_nalgs[at]; 756 3448 dh155122 757 3448 dh155122 ASSERT(MUTEX_HELD(&ipss->ipsec_alg_lock)); 758 0 stevel 759 0 stevel for (i = 0; i <= newcount; i++) { 760 3448 dh155122 if (copyback) { 761 3448 dh155122 ipss->ipsec_sortlist[at][i-1] = 762 3448 dh155122 ipss->ipsec_sortlist[at][i]; 763 3448 dh155122 } else if (ipss->ipsec_sortlist[at][i] == algid) { 764 0 stevel copyback = B_TRUE; 765 3448 dh155122 } 766 0 stevel } 767 0 stevel } 768 0 stevel 769 0 stevel /* 770 0 stevel * Add the specified algorithm to the algorithm tables. 771 0 stevel * Must be called while holding the algorithm table writer lock. 772 0 stevel */ 773 0 stevel void 774 3448 dh155122 ipsec_alg_reg(ipsec_algtype_t algtype, ipsec_alginfo_t *alg, netstack_t *ns) 775 3448 dh155122 { 776 3448 dh155122 ipsec_stack_t *ipss = ns->netstack_ipsec; 777 3448 dh155122 778 3448 dh155122 ASSERT(MUTEX_HELD(&ipss->ipsec_alg_lock)); 779 3448 dh155122 780 3448 dh155122 ASSERT(ipss->ipsec_alglists[algtype][alg->alg_id] == NULL); 781 3448 dh155122 ipsec_alg_fix_min_max(alg, algtype, ns); 782 3448 dh155122 ipss->ipsec_alglists[algtype][alg->alg_id] = alg; 783 3448 dh155122 784 3448 dh155122 ipss->ipsec_nalgs[algtype]++; 785 3448 dh155122 alg_insert_sortlist(algtype, alg->alg_id, ns); 786 0 stevel } 787 0 stevel 788 0 stevel /* 789 0 stevel * Remove the specified algorithm from the algorithm tables. 790 0 stevel * Must be called while holding the algorithm table writer lock. 791 0 stevel */ 792 0 stevel void 793 3448 dh155122 ipsec_alg_unreg(ipsec_algtype_t algtype, uint8_t algid, netstack_t *ns) 794 3448 dh155122 { 795 3448 dh155122 ipsec_stack_t *ipss = ns->netstack_ipsec; 796 3448 dh155122 797 3448 dh155122 ASSERT(MUTEX_HELD(&ipss->ipsec_alg_lock)); 798 3448 dh155122 799 3448 dh155122 ASSERT(ipss->ipsec_alglists[algtype][algid] != NULL); 800 3448 dh155122 ipsec_alg_free(ipss->ipsec_alglists[algtype][algid]); 801 3448 dh155122 ipss->ipsec_alglists[algtype][algid] = NULL; 802 3448 dh155122 803 3448 dh155122 ipss->ipsec_nalgs[algtype]--; 804 3448 dh155122 alg_remove_sortlist(algtype, algid, ns); 805 0 stevel } 806 0 stevel 807 0 stevel /* 808 0 stevel * Hooks for spdsock to get a grip on system policy. 809 0 stevel */ 810 0 stevel 811 0 stevel ipsec_policy_head_t * 812 3448 dh155122 ipsec_system_policy(netstack_t *ns) 813 3448 dh155122 { 814 3448 dh155122 ipsec_stack_t *ipss = ns->netstack_ipsec; 815 3448 dh155122 ipsec_policy_head_t *h = &ipss->ipsec_system_policy; 816 3448 dh155122 817 0 stevel IPPH_REFHOLD(h); 818 0 stevel return (h); 819 0 stevel } 820 0 stevel 821 0 stevel ipsec_policy_head_t * 822 3448 dh155122 ipsec_inactive_policy(netstack_t *ns) 823 3448 dh155122 { 824 3448 dh155122 ipsec_stack_t *ipss = ns->netstack_ipsec; 825 3448 dh155122 ipsec_policy_head_t *h = &ipss->ipsec_inactive_policy; 826 3448 dh155122 827 0 stevel IPPH_REFHOLD(h); 828 0 stevel return (h); 829 0 stevel } 830 0 stevel 831 0 stevel /* 832 0 stevel * Lock inactive policy, then active policy, then exchange policy root 833 0 stevel * pointers. 834 0 stevel */ 835 0 stevel void 836 3448 dh155122 ipsec_swap_policy(ipsec_policy_head_t *active, ipsec_policy_head_t *inactive, 837 3448 dh155122 netstack_t *ns) 838 0 stevel { 839 0 stevel int af, dir; 840 81 sommerfe avl_tree_t r1, r2; 841 0 stevel 842 3055 danmcd rw_enter(&inactive->iph_lock, RW_WRITER); 843 3055 danmcd rw_enter(&active->iph_lock, RW_WRITER); 844 3055 danmcd 845 3055 danmcd r1 = active->iph_rulebyid; 846 3055 danmcd r2 = inactive->iph_rulebyid; 847 3055 danmcd active->iph_rulebyid = r2; 848 3055 danmcd inactive->iph_rulebyid = r1; 849 81 sommerfe 850 81 sommerfe for (dir = 0; dir < IPSEC_NTYPES; dir++) { 851 81 sommerfe ipsec_policy_hash_t *h1, *h2; 852 81 sommerfe 853 3055 danmcd h1 = active->iph_root[dir].ipr_hash; 854 3055 danmcd h2 = inactive->iph_root[dir].ipr_hash; 855 3055 danmcd active->iph_root[dir].ipr_hash = h2; 856 3055 danmcd inactive->iph_root[dir].ipr_hash = h1; 857 81 sommerfe 858 0 stevel for (af = 0; af < IPSEC_NAF; af++) { 859 81 sommerfe ipsec_policy_t *t1, *t2; 860 81 sommerfe 861 3055 danmcd t1 = active->iph_root[dir].ipr_nonhash[af]; 862 3055 danmcd t2 = inactive->iph_root[dir].ipr_nonhash[af]; 863 3055 danmcd active->iph_root[dir].ipr_nonhash[af] = t2; 864 3055 danmcd inactive->iph_root[dir].ipr_nonhash[af] = t1; 865 81 sommerfe if (t1 != NULL) { 866 81 sommerfe t1->ipsp_hash.hash_pp = 867 3055 danmcd &(inactive->iph_root[dir].ipr_nonhash[af]); 868 81 sommerfe } 869 81 sommerfe if (t2 != NULL) { 870 81 sommerfe t2->ipsp_hash.hash_pp = 871 3055 danmcd &(active->iph_root[dir].ipr_nonhash[af]); 872 3055 danmcd } 873 3055 danmcd 874 3055 danmcd } 875 3055 danmcd } 876 3055 danmcd active->iph_gen++; 877 3055 danmcd inactive->iph_gen++; 878 3448 dh155122 ipsec_update_present_flags(ns->netstack_ipsec); 879 3055 danmcd rw_exit(&active->iph_lock); 880 3055 danmcd rw_exit(&inactive->iph_lock); 881 3055 danmcd } 882 3055 danmcd 883 3055 danmcd /* 884 3055 danmcd * Swap global policy primary/secondary. 885 3055 danmcd */ 886 3055 danmcd void 887 3448 dh155122 ipsec_swap_global_policy(netstack_t *ns) 888 3448 dh155122 { 889 3448 dh155122 ipsec_stack_t *ipss = ns->netstack_ipsec; 890 3448 dh155122 891 3448 dh155122 ipsec_swap_policy(&ipss->ipsec_system_policy, 892 3448 dh155122 &ipss->ipsec_inactive_policy, ns); 893 0 stevel } 894 0 stevel 895 0 stevel /* 896 0 stevel * Clone one policy rule.. 897 0 stevel */ 898 0 stevel static ipsec_policy_t * 899 0 stevel ipsec_copy_policy(const ipsec_policy_t *src) 900 0 stevel { 901 0 stevel ipsec_policy_t *dst = kmem_cache_alloc(ipsec_pol_cache, KM_NOSLEEP); 902 0 stevel 903 0 stevel if (dst == NULL) 904 0 stevel return (NULL); 905 0 stevel 906 0 stevel /* 907 0 stevel * Adjust refcounts of cloned state. 908 0 stevel */ 909 0 stevel IPACT_REFHOLD(src->ipsp_act); 910 0 stevel src->ipsp_sel->ipsl_refs++; 911 0 stevel 912 81 sommerfe HASH_NULL(dst, ipsp_hash); 913 11042 Erik dst->ipsp_netstack = src->ipsp_netstack; 914 0 stevel dst->ipsp_refs = 1; 915 0 stevel dst->ipsp_sel = src->ipsp_sel; 916 0 stevel dst->ipsp_act = src->ipsp_act; 917 0 stevel dst->ipsp_prio = src->ipsp_prio; 918 0 stevel dst->ipsp_index = src->ipsp_index; 919 0 stevel 920 0 stevel return (dst); 921 0 stevel } 922 0 stevel 923 81 sommerfe void 924 81 sommerfe ipsec_insert_always(avl_tree_t *tree, void *new_node) 925 81 sommerfe { 926 81 sommerfe void *node; 927 81 sommerfe avl_index_t where; 928 81 sommerfe 929 81 sommerfe node = avl_find(tree, new_node, &where); 930 81 sommerfe ASSERT(node == NULL); 931 81 sommerfe avl_insert(tree, new_node, where); 932 81 sommerfe } 933 81 sommerfe 934 81 sommerfe 935 81 sommerfe static int 936 81 sommerfe ipsec_copy_chain(ipsec_policy_head_t *dph, ipsec_policy_t *src, 937 81 sommerfe ipsec_policy_t **dstp) 938 81 sommerfe { 939 81 sommerfe for (; src != NULL; src = src->ipsp_hash.hash_next) { 940 81 sommerfe ipsec_policy_t *dst = ipsec_copy_policy(src); 941 81 sommerfe if (dst == NULL) 942 81 sommerfe return (ENOMEM); 943 81 sommerfe 944 81 sommerfe HASHLIST_INSERT(dst, ipsp_hash, *dstp); 945 81 sommerfe ipsec_insert_always(&dph->iph_rulebyid, dst); 946 81 sommerfe } 947 81 sommerfe return (0); 948 81 sommerfe } 949 81 sommerfe 950 81 sommerfe 951 81 sommerfe 952 0 stevel /* 953 0 stevel * Make one policy head look exactly like another. 954 0 stevel * 955 0 stevel * As with ipsec_swap_policy, we lock the destination policy head first, then 956 0 stevel * the source policy head. Note that we only need to read-lock the source 957 0 stevel * policy head as we are not changing it. 958 0 stevel */ 959 3055 danmcd int 960 3448 dh155122 ipsec_copy_polhead(ipsec_policy_head_t *sph, ipsec_policy_head_t *dph, 961 3448 dh155122 netstack_t *ns) 962 0 stevel { 963 81 sommerfe int af, dir, chain, nchains; 964 0 stevel 965 0 stevel rw_enter(&dph->iph_lock, RW_WRITER); 966 0 stevel 967 3448 dh155122 ipsec_polhead_flush(dph, ns); 968 0 stevel 969 0 stevel rw_enter(&sph->iph_lock, RW_READER); 970 0 stevel 971 0 stevel for (dir = 0; dir < IPSEC_NTYPES; dir++) { 972 81 sommerfe ipsec_policy_root_t *dpr = &dph->iph_root[dir]; 973 81 sommerfe ipsec_policy_root_t *spr = &sph->iph_root[dir]; 974 81 sommerfe nchains = dpr->ipr_nchains; 975 81 sommerfe 976 81 sommerfe ASSERT(dpr->ipr_nchains == spr->ipr_nchains); 977 81 sommerfe 978 0 stevel for (af = 0; af < IPSEC_NAF; af++) { 979 81 sommerfe if (ipsec_copy_chain(dph, spr->ipr_nonhash[af], 980 81 sommerfe &dpr->ipr_nonhash[af])) 981 81 sommerfe goto abort_copy; 982 81 sommerfe } 983 81 sommerfe 984 81 sommerfe for (chain = 0; chain < nchains; chain++) { 985 81 sommerfe if (ipsec_copy_chain(dph, 986 81 sommerfe spr->ipr_hash[chain].hash_head, 987 81 sommerfe &dpr->ipr_hash[chain].hash_head)) 988 81 sommerfe goto abort_copy; 989 0 stevel } 990 0 stevel } 991 0 stevel 992 0 stevel dph->iph_gen++; 993 0 stevel 994 0 stevel rw_exit(&sph->iph_lock); 995 0 stevel rw_exit(&dph->iph_lock); 996 0 stevel return (0); 997 81 sommerfe 998 81 sommerfe abort_copy: 999 3448 dh155122 ipsec_polhead_flush(dph, ns); 1000 81 sommerfe rw_exit(&sph->iph_lock); 1001 81 sommerfe rw_exit(&dph->iph_lock); 1002 81 sommerfe return (ENOMEM); 1003 0 stevel } 1004 0 stevel 1005 0 stevel /* 1006 0 stevel * Clone currently active policy to the inactive policy list. 1007 0 stevel */ 1008 0 stevel int 1009 3448 dh155122 ipsec_clone_system_policy(netstack_t *ns) 1010 3448 dh155122 { 1011 3448 dh155122 ipsec_stack_t *ipss = ns->netstack_ipsec; 1012 3448 dh155122 1013 3448 dh155122 return (ipsec_copy_polhead(&ipss->ipsec_system_policy, 1014 5245 danmcd &ipss->ipsec_inactive_policy, ns)); 1015 0 stevel } 1016 0 stevel 1017 3055 danmcd /* 1018 0 stevel * Extract the string from ipsec_policy_failure_msgs[type] and 1019 0 stevel * log it. 1020 0 stevel * 1021 0 stevel */ 1022 0 stevel void 1023 3192 danmcd ipsec_log_policy_failure(int type, char *func_name, ipha_t *ipha, ip6_t *ip6h, 1024 3448 dh155122 boolean_t secure, netstack_t *ns) 1025 0 stevel { 1026 0 stevel char sbuf[INET6_ADDRSTRLEN]; 1027 0 stevel char dbuf[INET6_ADDRSTRLEN]; 1028 0 stevel char *s; 1029 0 stevel char *d; 1030 3448 dh155122 ipsec_stack_t *ipss = ns->netstack_ipsec; 1031 0 stevel 1032 0 stevel ASSERT((ipha == NULL && ip6h != NULL) || 1033 0 stevel (ip6h == NULL && ipha != NULL)); 1034 0 stevel 1035 0 stevel if (ipha != NULL) { 1036 0 stevel s = inet_ntop(AF_INET, &ipha->ipha_src, sbuf, sizeof (sbuf)); 1037 0 stevel d = inet_ntop(AF_INET, &ipha->ipha_dst, dbuf, sizeof (dbuf)); 1038 0 stevel } else { 1039 0 stevel s = inet_ntop(AF_INET6, &ip6h->ip6_src, sbuf, sizeof (sbuf)); 1040 0 stevel d = inet_ntop(AF_INET6, &ip6h->ip6_dst, dbuf, sizeof (dbuf)); 1041 0 stevel 1042 0 stevel } 1043 0 stevel 1044 0 stevel /* Always bump the policy failure counter. */ 1045 3448 dh155122 ipss->ipsec_policy_failure_count[type]++; 1046 3448 dh155122 1047 3448 dh155122 ipsec_rl_strlog(ns, IP_MOD_ID, 0, 0, SL_ERROR|SL_WARN|SL_CONSOLE, 1048 3192 danmcd ipsec_policy_failure_msgs[type], func_name, 1049 3192 danmcd (secure ? "secure" : "not secure"), s, d); 1050 1659 markfen } 1051 1659 markfen 1052 1659 markfen /* 1053 1659 markfen * Rate-limiting front-end to strlog() for AH and ESP. Uses the ndd variables 1054 1659 markfen * in /dev/ip and the same rate-limiting clock so that there's a single 1055 1659 markfen * knob to turn to throttle the rate of messages. 1056 1659 markfen */ 1057 1659 markfen void 1058 3448 dh155122 ipsec_rl_strlog(netstack_t *ns, short mid, short sid, char level, ushort_t sl, 1059 3448 dh155122 char *fmt, ...) 1060 1659 markfen { 1061 1659 markfen va_list adx; 1062 1659 markfen hrtime_t current = gethrtime(); 1063 3448 dh155122 ip_stack_t *ipst = ns->netstack_ip; 1064 3448 dh155122 ipsec_stack_t *ipss = ns->netstack_ipsec; 1065 1659 markfen 1066 1659 markfen sl |= SL_CONSOLE; 1067 1659 markfen /* 1068 1659 markfen * Throttle logging to stop syslog from being swamped. If variable 1069 1659 markfen * 'ipsec_policy_log_interval' is zero, don't log any messages at 1070 1659 markfen * all, otherwise log only one message every 'ipsec_policy_log_interval' 1071 1659 markfen * msec. Convert interval (in msec) to hrtime (in nsec). 1072 1659 markfen */ 1073 1659 markfen 1074 3448 dh155122 if (ipst->ips_ipsec_policy_log_interval) { 1075 3448 dh155122 if (ipss->ipsec_policy_failure_last + 1076 3448 dh155122 ((hrtime_t)ipst->ips_ipsec_policy_log_interval * 1077 3448 dh155122 (hrtime_t)1000000) <= current) { 1078 1659 markfen va_start(adx, fmt); 1079 1659 markfen (void) vstrlog(mid, sid, level, sl, fmt, adx); 1080 1659 markfen va_end(adx); 1081 3448 dh155122 ipss->ipsec_policy_failure_last = current; 1082 3448 dh155122 } 1083 3448 dh155122 } 1084 3448 dh155122 } 1085 3448 dh155122 1086 3448 dh155122 void 1087 3448 dh155122 ipsec_config_flush(netstack_t *ns) 1088 3448 dh155122 { 1089 3448 dh155122 ipsec_stack_t *ipss = ns->netstack_ipsec; 1090 3448 dh155122 1091 3448 dh155122 rw_enter(&ipss->ipsec_system_policy.iph_lock, RW_WRITER); 1092 3448 dh155122 ipsec_polhead_flush(&ipss->ipsec_system_policy, ns); 1093 3448 dh155122 ipss->ipsec_next_policy_index = 1; 1094 3448 dh155122 rw_exit(&ipss->ipsec_system_policy.iph_lock); 1095 3448 dh155122 ipsec_action_reclaim_stack(ns); 1096 0 stevel } 1097 0 stevel 1098 0 stevel /* 1099 0 stevel * Clip a policy's min/max keybits vs. the capabilities of the 1100 0 stevel * algorithm. 1101 0 stevel */ 1102 0 stevel static void 1103 0 stevel act_alg_adjust(uint_t algtype, uint_t algid, 1104 3448 dh155122 uint16_t *minbits, uint16_t *maxbits, netstack_t *ns) 1105 3448 dh155122 { 1106 3448 dh155122 ipsec_stack_t *ipss = ns->netstack_ipsec; 1107 3448 dh155122 ipsec_alginfo_t *algp = ipss->ipsec_alglists[algtype][algid]; 1108 3448 dh155122 1109 0 stevel if (algp != NULL) { 1110 0 stevel /* 1111 0 stevel * If passed-in minbits is zero, we assume the caller trusts 1112 0 stevel * us with setting the minimum key size. We pick the 1113 0 stevel * algorithms DEFAULT key size for the minimum in this case. 1114 0 stevel */ 1115 0 stevel if (*minbits == 0) { 1116 0 stevel *minbits = algp->alg_default_bits; 1117 0 stevel ASSERT(*minbits >= algp->alg_minbits); 1118 0 stevel } else { 1119 3055 danmcd *minbits = MAX(MIN(*minbits, algp->alg_maxbits), 1120 3055 danmcd algp->alg_minbits); 1121 0 stevel } 1122 0 stevel if (*maxbits == 0) 1123 0 stevel *maxbits = algp->alg_maxbits; 1124 0 stevel else 1125 3055 danmcd *maxbits = MIN(MAX(*maxbits, algp->alg_minbits), 1126 3055 danmcd algp->alg_maxbits); 1127 0 stevel ASSERT(*minbits <= *maxbits); 1128 0 stevel } else { 1129 0 stevel *minbits = 0; 1130 0 stevel *maxbits = 0; 1131 0 stevel } 1132 0 stevel } 1133 0 stevel 1134 0 stevel /* 1135 0 stevel * Check an action's requested algorithms against the algorithms currently 1136 0 stevel * loaded in the system. 1137 0 stevel */ 1138 0 stevel boolean_t 1139 3448 dh155122 ipsec_check_action(ipsec_act_t *act, int *diag, netstack_t *ns) 1140 0 stevel { 1141 0 stevel ipsec_prot_t *ipp; 1142 3448 dh155122 ipsec_stack_t *ipss = ns->netstack_ipsec; 1143 0 stevel 1144 0 stevel ipp = &act->ipa_apply; 1145 0 stevel 1146 0 stevel if (ipp->ipp_use_ah && 1147 3448 dh155122 ipss->ipsec_alglists[IPSEC_ALG_AUTH][ipp->ipp_auth_alg] == NULL) { 1148 0 stevel *diag = SPD_DIAGNOSTIC_UNSUPP_AH_ALG; 1149 0 stevel return (B_FALSE); 1150 0 stevel } 1151 0 stevel if (ipp->ipp_use_espa && 1152 3448 dh155122 ipss->ipsec_alglists[IPSEC_ALG_AUTH][ipp->ipp_esp_auth_alg] == 1153 3448 dh155122 NULL) { 1154 0 stevel *diag = SPD_DIAGNOSTIC_UNSUPP_ESP_AUTH_ALG; 1155 0 stevel return (B_FALSE); 1156 0 stevel } 1157 0 stevel if (ipp->ipp_use_esp && 1158 3448 dh155122 ipss->ipsec_alglists[IPSEC_ALG_ENCR][ipp->ipp_encr_alg] == NULL) { 1159 0 stevel *diag = SPD_DIAGNOSTIC_UNSUPP_ESP_ENCR_ALG; 1160 0 stevel return (B_FALSE); 1161 0 stevel } 1162 0 stevel 1163 0 stevel act_alg_adjust(IPSEC_ALG_AUTH, ipp->ipp_auth_alg, 1164 3448 dh155122 &ipp->ipp_ah_minbits, &ipp->ipp_ah_maxbits, ns); 1165 0 stevel act_alg_adjust(IPSEC_ALG_AUTH, ipp->ipp_esp_auth_alg, 1166 3448 dh155122 &ipp->ipp_espa_minbits, &ipp->ipp_espa_maxbits, ns); 1167 0 stevel act_alg_adjust(IPSEC_ALG_ENCR, ipp->ipp_encr_alg, 1168 3448 dh155122 &ipp->ipp_espe_minbits, &ipp->ipp_espe_maxbits, ns); 1169 0 stevel 1170 0 stevel if (ipp->ipp_ah_minbits > ipp->ipp_ah_maxbits) { 1171 0 stevel *diag = SPD_DIAGNOSTIC_UNSUPP_AH_KEYSIZE; 1172 0 stevel return (B_FALSE); 1173 0 stevel } 1174 0 stevel if (ipp->ipp_espa_minbits > ipp->ipp_espa_maxbits) { 1175 0 stevel *diag = SPD_DIAGNOSTIC_UNSUPP_ESP_AUTH_KEYSIZE; 1176 0 stevel return (B_FALSE); 1177 0 stevel } 1178 0 stevel if (ipp->ipp_espe_minbits > ipp->ipp_espe_maxbits) { 1179 0 stevel *diag = SPD_DIAGNOSTIC_UNSUPP_ESP_ENCR_KEYSIZE; 1180 0 stevel return (B_FALSE); 1181 0 stevel } 1182 0 stevel /* TODO: sanity check lifetimes */ 1183 0 stevel return (B_TRUE); 1184 0 stevel } 1185 0 stevel 1186 0 stevel /* 1187 0 stevel * Set up a single action during wildcard expansion.. 1188 0 stevel */ 1189 0 stevel static void 1190 0 stevel ipsec_setup_act(ipsec_act_t *outact, ipsec_act_t *act, 1191 3448 dh155122 uint_t auth_alg, uint_t encr_alg, uint_t eauth_alg, netstack_t *ns) 1192 0 stevel { 1193 0 stevel ipsec_prot_t *ipp; 1194 0 stevel 1195 0 stevel *outact = *act; 1196 0 stevel ipp = &outact->ipa_apply; 1197 0 stevel ipp->ipp_auth_alg = (uint8_t)auth_alg; 1198 0 stevel ipp->ipp_encr_alg = (uint8_t)encr_alg; 1199 0 stevel ipp->ipp_esp_auth_alg = (uint8_t)eauth_alg; 1200 0 stevel 1201 0 stevel act_alg_adjust(IPSEC_ALG_AUTH, auth_alg, 1202 3448 dh155122 &ipp->ipp_ah_minbits, &ipp->ipp_ah_maxbits, ns); 1203 0 stevel act_alg_adjust(IPSEC_ALG_AUTH, eauth_alg, 1204 3448 dh155122 &ipp->ipp_espa_minbits, &ipp->ipp_espa_maxbits, ns); 1205 0 stevel act_alg_adjust(IPSEC_ALG_ENCR, encr_alg, 1206 3448 dh155122 &ipp->ipp_espe_minbits, &ipp->ipp_espe_maxbits, ns); 1207 0 stevel } 1208 0 stevel 1209 0 stevel /* 1210 0 stevel * combinatoric expansion time: expand a wildcarded action into an 1211 0 stevel * array of wildcarded actions; we return the exploded action list, 1212 0 stevel * and return a count in *nact (output only). 1213 0 stevel */ 1214 0 stevel static ipsec_act_t * 1215 3448 dh155122 ipsec_act_wildcard_expand(ipsec_act_t *act, uint_t *nact, netstack_t *ns) 1216 0 stevel { 1217 0 stevel boolean_t use_ah, use_esp, use_espa; 1218 0 stevel boolean_t wild_auth, wild_encr, wild_eauth; 1219 0 stevel uint_t auth_alg, auth_idx, auth_min, auth_max; 1220 0 stevel uint_t eauth_alg, eauth_idx, eauth_min, eauth_max; 1221 0 stevel uint_t encr_alg, encr_idx, encr_min, encr_max; 1222 0 stevel uint_t action_count, ai; 1223 0 stevel ipsec_act_t *outact; 1224 3448 dh155122 ipsec_stack_t *ipss = ns->netstack_ipsec; 1225 0 stevel 1226 0 stevel if (act->ipa_type != IPSEC_ACT_APPLY) { 1227 0 stevel outact = kmem_alloc(sizeof (*act), KM_NOSLEEP); 1228 0 stevel *nact = 1; 1229 0 stevel if (outact != NULL) 1230 0 stevel bcopy(act, outact, sizeof (*act)); 1231 0 stevel return (outact); 1232 0 stevel } 1233 0 stevel /* 1234 0 stevel * compute the combinatoric explosion.. 1235 0 stevel * 1236 0 stevel * we assume a request for encr if esp_req is PREF_REQUIRED 1237 0 stevel * we assume a request for ah auth if ah_req is PREF_REQUIRED. 1238 0 stevel * we assume a request for esp auth if !ah and esp_req is PREF_REQUIRED 1239 0 stevel */ 1240 0 stevel 1241 0 stevel use_ah = act->ipa_apply.ipp_use_ah; 1242 0 stevel use_esp = act->ipa_apply.ipp_use_esp; 1243 0 stevel use_espa = act->ipa_apply.ipp_use_espa; 1244 0 stevel auth_alg = act->ipa_apply.ipp_auth_alg; 1245 0 stevel eauth_alg = act->ipa_apply.ipp_esp_auth_alg; 1246 0 stevel encr_alg = act->ipa_apply.ipp_encr_alg; 1247 0 stevel 1248 0 stevel wild_auth = use_ah && (auth_alg == 0); 1249 0 stevel wild_eauth = use_espa && (eauth_alg == 0); 1250 0 stevel wild_encr = use_esp && (encr_alg == 0); 1251 0 stevel 1252 0 stevel action_count = 1; 1253 0 stevel auth_min = auth_max = auth_alg; 1254 0 stevel eauth_min = eauth_max = eauth_alg; 1255 0 stevel encr_min = encr_max = encr_alg; 1256 0 stevel 1257 0 stevel /* 1258 0 stevel * set up for explosion.. for each dimension, expand output 1259 0 stevel * size by the explosion factor. 1260 0 stevel * 1261 0 stevel * Don't include the "any" algorithms, if defined, as no 1262 0 stevel * kernel policies should be set for these algorithms. 1263 0 stevel */ 1264 0 stevel 1265 3448 dh155122 #define SET_EXP_MINMAX(type, wild, alg, min, max, ipss) \ 1266 3448 dh155122 if (wild) { \ 1267 3448 dh155122 int nalgs = ipss->ipsec_nalgs[type]; \ 1268 3448 dh155122 if (ipss->ipsec_alglists[type][alg] != NULL) \ 1269 0 stevel nalgs--; \ 1270 0 stevel action_count *= nalgs; \ 1271 0 stevel min = 0; \ 1272 3448 dh155122 max = ipss->ipsec_nalgs[type] - 1; \ 1273 0 stevel } 1274 0 stevel 1275 0 stevel SET_EXP_MINMAX(IPSEC_ALG_AUTH, wild_auth, SADB_AALG_NONE, 1276 3448 dh155122 auth_min, auth_max, ipss); 1277 0 stevel SET_EXP_MINMAX(IPSEC_ALG_AUTH, wild_eauth, SADB_AALG_NONE, 1278 3448 dh155122 eauth_min, eauth_max, ipss); 1279 0 stevel SET_EXP_MINMAX(IPSEC_ALG_ENCR, wild_encr, SADB_EALG_NONE, 1280 3448 dh155122 encr_min, encr_max, ipss); 1281 0 stevel 1282 0 stevel #undef SET_EXP_MINMAX 1283 0 stevel 1284 0 stevel /* 1285 0 stevel * ok, allocate the whole mess.. 1286 0 stevel */ 1287 0 stevel 1288 0 stevel outact = kmem_alloc(sizeof (*outact) * action_count, KM_NOSLEEP); 1289 0 stevel if (outact == NULL) 1290 0 stevel return (NULL); 1291 0 stevel 1292 0 stevel /* 1293 0 stevel * Now compute all combinations. Note that non-wildcarded 1294 0 stevel * dimensions just get a single value from auth_min, while 1295 0 stevel * wildcarded dimensions indirect through the sortlist. 1296 0 stevel * 1297 0 stevel * We do encryption outermost since, at this time, there's 1298 0 stevel * greater difference in security and performance between 1299 0 stevel * encryption algorithms vs. authentication algorithms. 1300 0 stevel */ 1301 0 stevel 1302 0 stevel ai = 0; 1303 0 stevel 1304 3448 dh155122 #define WHICH_ALG(type, wild, idx, ipss) \ 1305 3448 dh155122 ((wild)?(ipss->ipsec_sortlist[type][idx]):(idx)) 1306 0 stevel 1307 0 stevel for (encr_idx = encr_min; encr_idx <= encr_max; encr_idx++) { 1308 3448 dh155122 encr_alg = WHICH_ALG(IPSEC_ALG_ENCR, wild_encr, encr_idx, ipss); 1309 0 stevel if (wild_encr && encr_alg == SADB_EALG_NONE) 1310 0 stevel continue; 1311 0 stevel for (auth_idx = auth_min; auth_idx <= auth_max; auth_idx++) { 1312 0 stevel auth_alg = WHICH_ALG(IPSEC_ALG_AUTH, wild_auth, 1313 3448 dh155122 auth_idx, ipss); 1314 0 stevel if (wild_auth && auth_alg == SADB_AALG_NONE) 1315 0 stevel continue; 1316 0 stevel for (eauth_idx = eauth_min; eauth_idx <= eauth_max; 1317 0 stevel eauth_idx++) { 1318 0 stevel eauth_alg = WHICH_ALG(IPSEC_ALG_AUTH, 1319 3448 dh155122 wild_eauth, eauth_idx, ipss); 1320 0 stevel if (wild_eauth && eauth_alg == SADB_AALG_NONE) 1321 0 stevel continue; 1322 0 stevel 1323 0 stevel ipsec_setup_act(&outact[ai], act, 1324 3448 dh155122 auth_alg, encr_alg, eauth_alg, ns); 1325 0 stevel ai++; 1326 0 stevel } 1327 0 stevel } 1328 0 stevel } 1329 0 stevel 1330 0 stevel #undef WHICH_ALG 1331 0 stevel 1332 0 stevel ASSERT(ai == action_count); 1333 0 stevel *nact = action_count; 1334 0 stevel return (outact); 1335 0 stevel } 1336 0 stevel 1337 0 stevel /* 1338 0 stevel * Extract the parts of an ipsec_prot_t from an old-style ipsec_req_t. 1339 0 stevel */ 1340 0 stevel static void 1341 10616 Sebastien ipsec_prot_from_req(const ipsec_req_t *req, ipsec_prot_t *ipp) 1342 0 stevel { 1343 0 stevel bzero(ipp, sizeof (*ipp)); 1344 0 stevel /* 1345 0 stevel * ipp_use_* are bitfields. Look at "!!" in the following as a 1346 0 stevel * "boolean canonicalization" operator. 1347 0 stevel */ 1348 0 stevel ipp->ipp_use_ah = !!(req->ipsr_ah_req & IPSEC_PREF_REQUIRED); 1349 0 stevel ipp->ipp_use_esp = !!(req->ipsr_esp_req & IPSEC_PREF_REQUIRED); 1350 6524 pwernau ipp->ipp_use_espa = !!(req->ipsr_esp_auth_alg); 1351 0 stevel ipp->ipp_use_se = !!(req->ipsr_self_encap_req & IPSEC_PREF_REQUIRED); 1352 0 stevel ipp->ipp_use_unique = !!((req->ipsr_ah_req|req->ipsr_esp_req) & 1353 0 stevel IPSEC_PREF_UNIQUE); 1354 0 stevel ipp->ipp_encr_alg = req->ipsr_esp_alg; 1355 6524 pwernau /* 1356 6524 pwernau * SADB_AALG_ANY is a placeholder to distinguish "any" from 1357 6524 pwernau * "none" above. If auth is required, as determined above, 1358 6524 pwernau * SADB_AALG_ANY becomes 0, which is the representation 1359 6524 pwernau * of "any" and "none" in PF_KEY v2. 1360 6524 pwernau */ 1361 6524 pwernau ipp->ipp_auth_alg = (req->ipsr_auth_alg != SADB_AALG_ANY) ? 1362 6524 pwernau req->ipsr_auth_alg : 0; 1363 6524 pwernau ipp->ipp_esp_auth_alg = (req->ipsr_esp_auth_alg != SADB_AALG_ANY) ? 1364 6524 pwernau req->ipsr_esp_auth_alg : 0; 1365 0 stevel } 1366 0 stevel 1367 0 stevel /* 1368 0 stevel * Extract a new-style action from a request. 1369 0 stevel */ 1370 0 stevel void 1371 10616 Sebastien ipsec_actvec_from_req(const ipsec_req_t *req, ipsec_act_t **actp, uint_t *nactp, 1372 3448 dh155122 netstack_t *ns) 1373 0 stevel { 1374 0 stevel struct ipsec_act act; 1375 3448 dh155122 1376 0 stevel bzero(&act, sizeof (act)); 1377 0 stevel if ((req->ipsr_ah_req & IPSEC_PREF_NEVER) && 1378 0 stevel (req->ipsr_esp_req & IPSEC_PREF_NEVER)) { 1379 0 stevel act.ipa_type = IPSEC_ACT_BYPASS; 1380 0 stevel } else { 1381 0 stevel act.ipa_type = IPSEC_ACT_APPLY; 1382 0 stevel ipsec_prot_from_req(req, &act.ipa_apply); 1383 0 stevel } 1384 3448 dh155122 *actp = ipsec_act_wildcard_expand(&act, nactp, ns); 1385 0 stevel } 1386 0 stevel 1387 0 stevel /* 1388 0 stevel * Convert a new-style "prot" back to an ipsec_req_t (more backwards compat). 1389 0 stevel * We assume caller has already zero'ed *req for us. 1390 0 stevel */ 1391 0 stevel static int 1392 0 stevel ipsec_req_from_prot(ipsec_prot_t *ipp, ipsec_req_t *req) 1393 0 stevel { 1394 0 stevel req->ipsr_esp_alg = ipp->ipp_encr_alg; 1395 0 stevel req->ipsr_auth_alg = ipp->ipp_auth_alg; 1396 0 stevel req->ipsr_esp_auth_alg = ipp->ipp_esp_auth_alg; 1397 0 stevel 1398 0 stevel if (ipp->ipp_use_unique) { 1399 0 stevel req->ipsr_ah_req |= IPSEC_PREF_UNIQUE; 1400 0 stevel req->ipsr_esp_req |= IPSEC_PREF_UNIQUE; 1401 0 stevel } 1402 0 stevel if (ipp->ipp_use_se) 1403 0 stevel req->ipsr_self_encap_req |= IPSEC_PREF_REQUIRED; 1404 0 stevel if (ipp->ipp_use_ah) 1405 0 stevel req->ipsr_ah_req |= IPSEC_PREF_REQUIRED; 1406 0 stevel if (ipp->ipp_use_esp) 1407 0 stevel req->ipsr_esp_req |= IPSEC_PREF_REQUIRED; 1408 0 stevel return (sizeof (*req)); 1409 0 stevel } 1410 0 stevel 1411 0 stevel /* 1412 0 stevel * Convert a new-style action back to an ipsec_req_t (more backwards compat). 1413 0 stevel * We assume caller has already zero'ed *req for us. 1414 0 stevel */ 1415 0 stevel static int 1416 0 stevel ipsec_req_from_act(ipsec_action_t *ap, ipsec_req_t *req) 1417 0 stevel { 1418 0 stevel switch (ap->ipa_act.ipa_type) { 1419 0 stevel case IPSEC_ACT_BYPASS: 1420 0 stevel req->ipsr_ah_req = IPSEC_PREF_NEVER; 1421 0 stevel req->ipsr_esp_req = IPSEC_PREF_NEVER; 1422 0 stevel return (sizeof (*req)); 1423 0 stevel case IPSEC_ACT_APPLY: 1424 0 stevel return (ipsec_req_from_prot(&ap->ipa_act.ipa_apply, req)); 1425 0 stevel } 1426 0 stevel return (sizeof (*req)); 1427 0 stevel } 1428 0 stevel 1429 0 stevel /* 1430 0 stevel * Convert a new-style action back to an ipsec_req_t (more backwards compat). 1431 0 stevel * We assume caller has already zero'ed *req for us. 1432 0 stevel */ 1433 3055 danmcd int 1434 0 stevel ipsec_req_from_head(ipsec_policy_head_t *ph, ipsec_req_t *req, int af) 1435 0 stevel { 1436 0 stevel ipsec_policy_t *p; 1437 0 stevel 1438 81 sommerfe /* 1439 81 sommerfe * FULL-PERSOCK: consult hash table, too? 1440 81 sommerfe */ 1441 81 sommerfe for (p = ph->iph_root[IPSEC_INBOUND].ipr_nonhash[af]; 1442 0 stevel p != NULL; 1443 81 sommerfe p = p->ipsp_hash.hash_next) { 1444 3055 danmcd if ((p->ipsp_sel->ipsl_key.ipsl_valid & IPSL_WILDCARD) == 0) 1445 0 stevel return (ipsec_req_from_act(p->ipsp_act, req)); 1446 0 stevel } 1447 0 stevel return (sizeof (*req)); 1448 0 stevel } 1449 0 stevel 1450 0 stevel /* 1451 0 stevel * Based on per-socket or latched policy, convert to an appropriate 1452 0 stevel * IP_SEC_OPT ipsec_req_t for the socket option; return size so we can 1453 0 stevel * be tail-called from ip. 1454 0 stevel */ 1455 0 stevel int 1456 0 stevel ipsec_req_from_conn(conn_t *connp, ipsec_req_t *req, int af) 1457 0 stevel { 1458 0 stevel ipsec_latch_t *ipl; 1459 0 stevel int rv = sizeof (ipsec_req_t); 1460 0 stevel 1461 0 stevel bzero(req, sizeof (*req)); 1462 0 stevel 1463 11042 Erik ASSERT(MUTEX_HELD(&connp->conn_lock)); 1464 0 stevel ipl = connp->conn_latch; 1465 0 stevel 1466 0 stevel /* 1467 0 stevel * Find appropriate policy. First choice is latched action; 1468 0 stevel * failing that, see latched policy; failing that, 1469 0 stevel * look at configured policy. 1470 0 stevel */ 1471 0 stevel if (ipl != NULL) { 1472 11042 Erik if (connp->conn_latch_in_action != NULL) { 1473 11042 Erik rv = ipsec_req_from_act(connp->conn_latch_in_action, 1474 11042 Erik req); 1475 0 stevel goto done; 1476 0 stevel } 1477 11042 Erik if (connp->conn_latch_in_policy != NULL) { 1478 11042 Erik rv = ipsec_req_from_act( 1479 11042 Erik connp->conn_latch_in_policy->ipsp_act, req); 1480 0 stevel goto done; 1481 0 stevel } 1482 0 stevel } 1483 0 stevel if (connp->conn_policy != NULL) 1484 0 stevel rv = ipsec_req_from_head(connp->conn_policy, req, af); 1485 0 stevel done: 1486 0 stevel return (rv); 1487 0 stevel } 1488 0 stevel 1489 0 stevel void 1490 0 stevel ipsec_actvec_free(ipsec_act_t *act, uint_t nact) 1491 0 stevel { 1492 0 stevel kmem_free(act, nact * sizeof (*act)); 1493 0 stevel } 1494 0 stevel 1495 0 stevel /* 1496 11042 Erik * Consumes a reference to ipsp. 1497 0 stevel */ 1498 0 stevel static mblk_t * 1499 11042 Erik ipsec_check_loopback_policy(mblk_t *data_mp, ip_recv_attr_t *ira, 1500 3192 danmcd ipsec_policy_t *ipsp) 1501 0 stevel { 1502 11042 Erik if (!(ira->ira_flags & IRAF_IPSEC_SECURE)) 1503 11042 Erik return (data_mp); 1504 11042 Erik 1505 11042 Erik ASSERT(ira->ira_flags & IRAF_LOOPBACK); 1506 11042 Erik 1507 11042 Erik IPPOL_REFRELE(ipsp); 1508 0 stevel 1509 0 stevel /* 1510 0 stevel * We should do an actual policy check here. Revisit this 1511 3192 danmcd * when we revisit the IPsec API. (And pass a conn_t in when we 1512 3192 danmcd * get there.) 1513 0 stevel */ 1514 0 stevel 1515 11042 Erik return (data_mp); 1516 0 stevel } 1517 0 stevel 1518 691 sommerfe /* 1519 691 sommerfe * Check that packet's inbound ports & proto match the selectors 1520 691 sommerfe * expected by the SAs it traversed on the way in. 1521 691 sommerfe */ 1522 691 sommerfe static boolean_t 1523 11042 Erik ipsec_check_ipsecin_unique(ip_recv_attr_t *ira, const char **reason, 1524 11042 Erik kstat_named_t **counter, uint64_t pkt_unique, netstack_t *ns) 1525 3055 danmcd { 1526 3055 danmcd uint64_t ah_mask, esp_mask; 1527 983 sommerfe ipsa_t *ah_assoc; 1528 983 sommerfe ipsa_t *esp_assoc; 1529 11042 Erik ipsec_stack_t *ipss = ns->netstack_ipsec; 1530 11042 Erik 1531 11042 Erik ASSERT(ira->ira_flags & IRAF_IPSEC_SECURE); 1532 11042 Erik ASSERT(!(ira->ira_flags & IRAF_LOOPBACK)); 1533 11042 Erik 1534 11042 Erik ah_assoc = ira->ira_ipsec_ah_sa; 1535 11042 Erik esp_assoc = ira->ira_ipsec_esp_sa; 1536 691 sommerfe ASSERT((ah_assoc != NULL) || (esp_assoc != NULL)); 1537 691 sommerfe 1538 691 sommerfe ah_mask = (ah_assoc != NULL) ? ah_assoc->ipsa_unique_mask : 0; 1539 691 sommerfe esp_mask = (esp_assoc != NULL) ? esp_assoc->ipsa_unique_mask : 0; 1540 691 sommerfe 1541 691 sommerfe if ((ah_mask == 0) && (esp_mask == 0)) 1542 691 sommerfe return (B_TRUE); 1543 691 sommerfe 1544 3055 danmcd /* 1545 3055 danmcd * The pkt_unique check will also check for tunnel mode on the SA 1546 3055 danmcd * vs. the tunneled_packet boolean. "Be liberal in what you receive" 1547 3055 danmcd * should not apply in this case. ;) 1548 3055 danmcd */ 1549 3055 danmcd 1550 3055 danmcd if (ah_mask != 0 && 1551 3055 danmcd ah_assoc->ipsa_unique_id != (pkt_unique & ah_mask)) { 1552 3055 danmcd *reason = "AH inner header mismatch"; 1553 3448 dh155122 *counter = DROPPER(ipss, ipds_spd_ah_innermismatch); 1554 3055 danmcd return (B_FALSE); 1555 3055 danmcd } 1556 3055 danmcd if (esp_mask != 0 && 1557 3055 danmcd esp_assoc->ipsa_unique_id != (pkt_unique & esp_mask)) { 1558 3055 danmcd *reason = "ESP inner header mismatch"; 1559 3448 dh155122 *counter = DROPPER(ipss, ipds_spd_esp_innermismatch); 1560 3055 danmcd return (B_FALSE); 1561 691 sommerfe } 1562 691 sommerfe return (B_TRUE); 1563 691 sommerfe } 1564 691 sommerfe 1565 0 stevel static boolean_t 1566 11042 Erik ipsec_check_ipsecin_action(ip_recv_attr_t *ira, mblk_t *mp, ipsec_action_t *ap, 1567 11042 Erik ipha_t *ipha, ip6_t *ip6h, const char **reason, kstat_named_t **counter, 1568 11042 Erik netstack_t *ns) 1569 0 stevel { 1570 0 stevel boolean_t ret = B_TRUE; 1571 0 stevel ipsec_prot_t *ipp; 1572 0 stevel ipsa_t *ah_assoc; 1573 0 stevel ipsa_t *esp_assoc; 1574 0 stevel boolean_t decaps; 1575 3448 dh155122 ipsec_stack_t *ipss = ns->netstack_ipsec; 1576 0 stevel 1577 0 stevel ASSERT((ipha == NULL && ip6h != NULL) || 1578 0 stevel (ip6h == NULL && ipha != NULL)); 1579 0 stevel 1580 11042 Erik if (ira->ira_flags & IRAF_LOOPBACK) { 1581 0 stevel /* 1582 0 stevel * Besides accepting pointer-equivalent actions, we also 1583 0 stevel * accept any ICMP errors we generated for ourselves, 1584 0 stevel * regardless of policy. If we do not wish to make this 1585 0 stevel * assumption in the future, check here, and where 1586 11042 Erik * IXAF_TRUSTED_ICMP is initialized in ip.c and ip6.c. 1587 11042 Erik */ 1588 11042 Erik if (ap == ira->ira_ipsec_action || 1589 11042 Erik (ira->ira_flags & IRAF_TRUSTED_ICMP)) 1590 0 stevel return (B_TRUE); 1591 0 stevel 1592 0 stevel /* Deep compare necessary here?? */ 1593 3448 dh155122 *counter = DROPPER(ipss, ipds_spd_loopback_mismatch); 1594 0 stevel *reason = "loopback policy mismatch"; 1595 0 stevel return (B_FALSE); 1596 0 stevel } 1597 11042 Erik ASSERT(!(ira->ira_flags & IRAF_TRUSTED_ICMP)); 1598 11042 Erik ASSERT(ira->ira_flags & IRAF_IPSEC_SECURE); 1599 11042 Erik 1600 11042 Erik ah_assoc = ira->ira_ipsec_ah_sa; 1601 11042 Erik esp_assoc = ira->ira_ipsec_esp_sa; 1602 11042 Erik 1603 11042 Erik decaps = (ira->ira_flags & IRAF_IPSEC_DECAPS); 1604 0 stevel 1605 0 stevel switch (ap->ipa_act.ipa_type) { 1606 0 stevel case IPSEC_ACT_DISCARD: 1607 0 stevel case IPSEC_ACT_REJECT: 1608 0 stevel /* Should "fail hard" */ 1609 3448 dh155122 *counter = DROPPER(ipss, ipds_spd_explicit); 1610 0 stevel *reason = "blocked by policy"; 1611 0 stevel return (B_FALSE); 1612 0 stevel 1613 0 stevel case IPSEC_ACT_BYPASS: 1614 0 stevel case IPSEC_ACT_CLEAR: 1615 3448 dh155122 *counter = DROPPER(ipss, ipds_spd_got_secure); 1616 0 stevel *reason = "expected clear, got protected"; 1617 0 stevel return (B_FALSE); 1618 0 stevel 1619 0 stevel case IPSEC_ACT_APPLY: 1620 0 stevel ipp = &ap->ipa_act.ipa_apply; 1621 0 stevel /* 1622 0 stevel * As of now we do the simple checks of whether 1623 0 stevel * the datagram has gone through the required IPSEC 1624 0 stevel * protocol constraints or not. We might have more 1625 0 stevel * in the future like sensitive levels, key bits, etc. 1626 0 stevel * If it fails the constraints, check whether we would 1627 0 stevel * have accepted this if it had come in clear. 1628 0 stevel */ 1629 0 stevel if (ipp->ipp_use_ah) { 1630 0 stevel if (ah_assoc == NULL) { 1631 0 stevel ret = ipsec_inbound_accept_clear(mp, ipha, 1632 0 stevel ip6h); 1633 3448 dh155122 *counter = DROPPER(ipss, ipds_spd_got_clear); 1634 0 stevel *reason = "unprotected not accepted"; 1635 0 stevel break; 1636 0 stevel } 1637 0 stevel ASSERT(ah_assoc != NULL); 1638 0 stevel ASSERT(ipp->ipp_auth_alg != 0); 1639 0 stevel 1640 0 stevel if (ah_assoc->ipsa_auth_alg != 1641 0 stevel ipp->ipp_auth_alg) { 1642 3448 dh155122 *counter = DROPPER(ipss, ipds_spd_bad_ahalg); 1643 0 stevel *reason = "unacceptable ah alg"; 1644 0 stevel ret = B_FALSE; 1645 0 stevel break; 1646 0 stevel } 1647 0 stevel } else if (ah_assoc != NULL) { 1648 0 stevel /* 1649 0 stevel * Don't allow this. Check IPSEC NOTE above 1650 0 stevel * ip_fanout_proto(). 1651 0 stevel */ 1652 3448 dh155122 *counter = DROPPER(ipss, ipds_spd_got_ah); 1653 0 stevel *reason = "unexpected AH"; 1654 0 stevel ret = B_FALSE; 1655 0 stevel break; 1656 0 stevel } 1657 0 stevel if (ipp->ipp_use_esp) { 1658 0 stevel if (esp_assoc == NULL) { 1659 0 stevel ret = ipsec_inbound_accept_clear(mp, ipha, 1660 0 stevel ip6h); 1661 3448 dh155122 *counter = DROPPER(ipss, ipds_spd_got_clear); 1662 0 stevel *reason = "unprotected not accepted"; 1663 0 stevel break; 1664 0 stevel } 1665 0 stevel ASSERT(esp_assoc != NULL); 1666 0 stevel ASSERT(ipp->ipp_encr_alg != 0); 1667 0 stevel 1668 0 stevel if (esp_assoc->ipsa_encr_alg != 1669 0 stevel ipp->ipp_encr_alg) { 1670 3448 dh155122 *counter = DROPPER(ipss, ipds_spd_bad_espealg); 1671 0 stevel *reason = "unacceptable esp alg"; 1672 0 stevel ret = B_FALSE; 1673 0 stevel break; 1674 0 stevel } 1675 0 stevel /* 1676 0 stevel * If the client does not need authentication, 1677 0 stevel * we don't verify the alogrithm. 1678 0 stevel */ 1679 0 stevel if (ipp->ipp_use_espa) { 1680 0 stevel if (esp_assoc->ipsa_auth_alg != 1681 0 stevel ipp->ipp_esp_auth_alg) { 1682 3448 dh155122 *counter = DROPPER(ipss, 1683 3448 dh155122 ipds_spd_bad_espaalg); 1684 0 stevel *reason = "unacceptable esp auth alg"; 1685 0 stevel ret = B_FALSE; 1686 0 stevel break; 1687 0 stevel } 1688 0 stevel } 1689 0 stevel } else if (esp_assoc != NULL) { 1690 11042 Erik /* 1691 11042 Erik * Don't allow this. Check IPSEC NOTE above 1692 11042 Erik * ip_fanout_proto(). 1693 11042 Erik */ 1694 3448 dh155122 *counter = DROPPER(ipss, ipds_spd_got_esp); 1695 0 stevel *reason = "unexpected ESP"; 1696 0 stevel ret = B_FALSE; 1697 0 stevel break; 1698 0 stevel } 1699 0 stevel if (ipp->ipp_use_se) { 1700 0 stevel if (!decaps) { 1701 0 stevel ret = ipsec_inbound_accept_clear(mp, ipha, 1702 0 stevel ip6h); 1703 0 stevel if (!ret) { 1704 0 stevel /* XXX mutant? */ 1705 3448 dh155122 *counter = DROPPER(ipss, 1706 3448 dh155122 ipds_spd_bad_selfencap); 1707 0 stevel *reason = "self encap not found"; 1708 0 stevel break; 1709 0 stevel } 1710 0 stevel } 1711 0 stevel } else if (decaps) { 1712 0 stevel /* 1713 0 stevel * XXX If the packet comes in tunneled and the 1714 0 stevel * recipient does not expect it to be tunneled, it 1715 0 stevel * is okay. But we drop to be consistent with the 1716 0 stevel * other cases. 1717 0 stevel */ 1718 3448 dh155122 *counter = DROPPER(ipss, ipds_spd_got_selfencap); 1719 0 stevel *reason = "unexpected self encap"; 1720 0 stevel ret = B_FALSE; 1721 0 stevel break; 1722 0 stevel } 1723 11042 Erik if (ira->ira_ipsec_action != NULL) { 1724 0 stevel /* 1725 0 stevel * This can happen if we do a double policy-check on 1726 0 stevel * a packet 1727 0 stevel * XXX XXX should fix this case! 1728 0 stevel */ 1729 11042 Erik IPACT_REFRELE(ira->ira_ipsec_action); 1730 11042 Erik } 1731 11042 Erik ASSERT(ira->ira_flags & IRAF_IPSEC_SECURE); 1732 11042 Erik ASSERT(ira->ira_ipsec_action == NULL); 1733 0 stevel IPACT_REFHOLD(ap); 1734 11042 Erik ira->ira_ipsec_action = ap; 1735 0 stevel break; /* from switch */ 1736 0 stevel } 1737 0 stevel return (ret); 1738 0 stevel } 1739 0 stevel 1740 0 stevel static boolean_t 1741 0 stevel spd_match_inbound_ids(ipsec_latch_t *ipl, ipsa_t *sa) 1742 0 stevel { 1743 0 stevel ASSERT(ipl->ipl_ids_latched == B_TRUE); 1744 0 stevel return ipsid_equal(ipl->ipl_remote_cid, sa->ipsa_src_cid) && 1745 0 stevel ipsid_equal(ipl->ipl_local_cid, sa->ipsa_dst_cid); 1746 0 stevel } 1747 0 stevel 1748 0 stevel /* 1749 3055 danmcd * Takes a latched conn and an inbound packet and returns a unique_id suitable 1750 3055 danmcd * for SA comparisons. Most of the time we will copy from the conn_t, but 1751 3055 danmcd * there are cases when the conn_t is latched but it has wildcard selectors, 1752 3055 danmcd * and then we need to fallback to scooping them out of the packet. 1753 3055 danmcd * 1754 3055 danmcd * Assume we'll never have 0 with a conn_t present, so use 0 as a failure. We 1755 3055 danmcd * can get away with this because we only have non-zero ports/proto for 1756 3055 danmcd * latched conn_ts. 1757 3055 danmcd * 1758 3055 danmcd * Ideal candidate for an "inline" keyword, as we're JUST convoluted enough 1759 3055 danmcd * to not be a nice macro. 1760 3055 danmcd */ 1761 3055 danmcd static uint64_t 1762 3055 danmcd conn_to_unique(conn_t *connp, mblk_t *data_mp, ipha_t *ipha, ip6_t *ip6h) 1763 3055 danmcd { 1764 3055 danmcd ipsec_selector_t sel; 1765 11042 Erik uint8_t ulp = connp->conn_proto; 1766 11042 Erik 1767 11042 Erik ASSERT(connp->conn_latch_in_policy != NULL); 1768 3055 danmcd 1769 3055 danmcd if ((ulp == IPPROTO_TCP || ulp == IPPROTO_UDP || ulp == IPPROTO_SCTP) && 1770 3055 danmcd (connp->conn_fport == 0 || connp->conn_lport == 0)) { 1771 3055 danmcd /* Slow path - we gotta grab from the packet. */ 1772 3055 danmcd if (ipsec_init_inbound_sel(&sel, data_mp, ipha, ip6h, 1773 5245 danmcd SEL_NONE) != SELRET_SUCCESS) { 1774 3055 danmcd /* Failure -> have caller free packet with ENOMEM. */ 1775 3055 danmcd return (0); 1776 3055 danmcd } 1777 3055 danmcd return (SA_UNIQUE_ID(sel.ips_remote_port, sel.ips_local_port, 1778 5245 danmcd sel.ips_protocol, 0)); 1779 3055 danmcd } 1780 3055 danmcd 1781 3055 danmcd #ifdef DEBUG_NOT_UNTIL_6478464 1782 3055 danmcd if (ipsec_init_inbound_sel(&sel, data_mp, ipha, ip6h, SEL_NONE) == 1783 3055 danmcd SELRET_SUCCESS) { 1784 3055 danmcd ASSERT(sel.ips_local_port == connp->conn_lport); 1785 3055 danmcd ASSERT(sel.ips_remote_port == connp->conn_fport); 1786 11042 Erik ASSERT(sel.ips_protocol == connp->conn_proto); 1787 11042 Erik } 1788 11042 Erik ASSERT(connp->conn_proto != 0); 1789 3055 danmcd #endif 1790 3055 danmcd 1791 3055 danmcd return (SA_UNIQUE_ID(connp->conn_fport, connp->conn_lport, ulp, 0)); 1792 3055 danmcd } 1793 3055 danmcd 1794 3055 danmcd /* 1795 11042 Erik * Called to check policy on a latched connection. 1796 11042 Erik * Note that we don't dereference conn_latch or conn_ihere since the conn might 1797 11042 Erik * be closing. The caller passes a held ipsec_latch_t instead. 1798 11042 Erik */ 1799 11042 Erik static boolean_t 1800 11042 Erik ipsec_check_ipsecin_latch(ip_recv_attr_t *ira, mblk_t *mp, ipsec_latch_t *ipl, 1801 11042 Erik ipsec_action_t *ap, ipha_t *ipha, ip6_t *ip6h, const char **reason, 1802 11042 Erik kstat_named_t **counter, conn_t *connp, netstack_t *ns) 1803 11042 Erik { 1804 3448 dh155122 ipsec_stack_t *ipss = ns->netstack_ipsec; 1805 3448 dh155122 1806 0 stevel ASSERT(ipl->ipl_ids_latched == B_TRUE); 1807 11042 Erik ASSERT(ira->ira_flags & IRAF_IPSEC_SECURE); 1808 11042 Erik 1809 11042 Erik if (!(ira->ira_flags & IRAF_LOOPBACK)) { 1810 983 sommerfe /* 1811 983 sommerfe * Over loopback, there aren't real security associations, 1812 983 sommerfe * so there are neither identities nor "unique" values 1813 983 sommerfe * for us to check the packet against. 1814 983 sommerfe */ 1815 11042 Erik if (ira->ira_ipsec_ah_sa != NULL) { 1816 11042 Erik if (!spd_match_inbound_ids(ipl, 1817 11042 Erik ira->ira_ipsec_ah_sa)) { 1818 11042 Erik *counter = DROPPER(ipss, ipds_spd_ah_badid); 1819 11042 Erik *reason = "AH identity mismatch"; 1820 11042 Erik return (B_FALSE); 1821 11042 Erik } 1822 11042 Erik } 1823 11042 Erik 1824 11042 Erik if (ira->ira_ipsec_esp_sa != NULL) { 1825 11042 Erik if (!spd_match_inbound_ids(ipl, 1826 11042 Erik ira->ira_ipsec_esp_sa)) { 1827 11042 Erik *counter = DROPPER(ipss, ipds_spd_esp_badid); 1828 11042 Erik *reason = "ESP identity mismatch"; 1829 11042 Erik return (B_FALSE); 1830 11042 Erik } 1831 983 sommerfe } 1832 983 sommerfe 1833 3055 danmcd /* 1834 3055 danmcd * Can fudge pkt_unique from connp because we're latched. 1835 3055 danmcd * In DEBUG kernels (see conn_to_unique()'s implementation), 1836 3055 danmcd * verify this even if it REALLY slows things down. 1837 3055 danmcd */ 1838 11042 Erik if (!ipsec_check_ipsecin_unique(ira, reason, counter, 1839 11042 Erik conn_to_unique(connp, mp, ipha, ip6h), ns)) { 1840 11042 Erik return (B_FALSE); 1841 11042 Erik } 1842 11042 Erik } 1843 11042 Erik return (ipsec_check_ipsecin_action(ira, mp, ap, ipha, ip6h, reason, 1844 11042 Erik counter, ns)); 1845 0 stevel } 1846 0 stevel 1847 0 stevel /* 1848 0 stevel * Check to see whether this secured datagram meets the policy 1849 0 stevel * constraints specified in ipsp. 1850 0 stevel * 1851 0 stevel * Called from ipsec_check_global_policy, and ipsec_check_inbound_policy. 1852 0 stevel * 1853 0 stevel * Consumes a reference to ipsp. 1854 11042 Erik * Returns the mblk if ok. 1855 0 stevel */ 1856 0 stevel static mblk_t * 1857 11042 Erik ipsec_check_ipsecin_policy(mblk_t *data_mp, ipsec_policy_t *ipsp, 1858 11042 Erik ipha_t *ipha, ip6_t *ip6h, uint64_t pkt_unique, ip_recv_attr_t *ira, 1859 11042 Erik netstack_t *ns) 1860 11042 Erik { 1861 0 stevel ipsec_action_t *ap; 1862 0 stevel const char *reason = "no policy actions found"; 1863 3448 dh155122 ip_stack_t *ipst = ns->netstack_ip; 1864 11042 Erik ipsec_stack_t *ipss = ns->netstack_ipsec; 1865 3448 dh155122 kstat_named_t *counter; 1866 3448 dh155122 1867 3448 dh155122 counter = DROPPER(ipss, ipds_spd_got_secure); 1868 0 stevel 1869 0 stevel ASSERT(ipsp != NULL); 1870 0 stevel 1871 0 stevel ASSERT((ipha == NULL && ip6h != NULL) || 1872 0 stevel (ip6h == NULL && ipha != NULL)); 1873 0 stevel 1874 11042 Erik if (ira->ira_flags & IRAF_LOOPBACK) 1875 11042 Erik return (ipsec_check_loopback_policy(data_mp, ira, ipsp)); 1876 11042 Erik 1877 11042 Erik ASSERT(ira->ira_flags & IRAF_IPSEC_SECURE); 1878 11042 Erik 1879 11042 Erik if (ira->ira_ipsec_action != NULL) { 1880 0 stevel /* 1881 0 stevel * this can happen if we do a double policy-check on a packet 1882 0 stevel * Would be nice to be able to delete this test.. 1883 0 stevel */ 1884 11042 Erik IPACT_REFRELE(ira->ira_ipsec_action); 1885 11042 Erik } 1886 11042 Erik ASSERT(ira->ira_ipsec_action == NULL); 1887 11042 Erik 1888 11042 Erik if (!SA_IDS_MATCH(ira->ira_ipsec_ah_sa, ira->ira_ipsec_esp_sa)) { 1889 0 stevel reason = "inbound AH and ESP identities differ"; 1890 3448 dh155122 counter = DROPPER(ipss, ipds_spd_ahesp_diffid); 1891 0 stevel goto drop; 1892 0 stevel } 1893 691 sommerfe 1894 11042 Erik if (!ipsec_check_ipsecin_unique(ira, &reason, &counter, pkt_unique, 1895 11042 Erik ns)) 1896 691 sommerfe goto drop; 1897 0 stevel 1898 0 stevel /* 1899 0 stevel * Ok, now loop through the possible actions and see if any 1900 0 stevel * of them work for us. 1901 0 stevel */ 1902 0 stevel 1903 0 stevel for (ap = ipsp->ipsp_act; ap != NULL; ap = ap->ipa_next) { 1904 11042 Erik if (ipsec_check_ipsecin_action(ira, data_mp, ap, 1905 11042 Erik ipha, ip6h, &reason, &counter, ns)) { 1906 3448 dh155122 BUMP_MIB(&ipst->ips_ip_mib, ipsecInSucceeded); 1907 11042 Erik IPPOL_REFRELE(ipsp); 1908 11042 Erik return (data_mp); 1909 0 stevel } 1910 0 stevel } 1911 0 stevel drop: 1912 3448 dh155122 ipsec_rl_strlog(ns, IP_MOD_ID, 0, 0, SL_ERROR|SL_WARN|SL_CONSOLE, 1913 0 stevel "ipsec inbound policy mismatch: %s, packet dropped\n", 1914 0 stevel reason); 1915 11042 Erik IPPOL_REFRELE(ipsp); 1916 11042 Erik ASSERT(ira->ira_ipsec_action == NULL); 1917 3448 dh155122 BUMP_MIB(&ipst->ips_ip_mib, ipsecInFailed); 1918 11042 Erik ip_drop_packet(data_mp, B_TRUE, NULL, counter, 1919 3448 dh155122 &ipss->ipsec_spd_dropper); 1920 0 stevel return (NULL); 1921 0 stevel } 1922 0 stevel 1923 0 stevel /* 1924 0 stevel * sleazy prefix-length-based compare. 1925 0 stevel * another inlining candidate.. 1926 0 stevel */ 1927 3055 danmcd boolean_t 1928 0 stevel ip_addr_match(uint8_t *addr1, int pfxlen, in6_addr_t *addr2p) 1929 0 stevel { 1930 0 stevel int offset = pfxlen>>3; 1931 0 stevel int bitsleft = pfxlen & 7; 1932 0 stevel uint8_t *addr2 = (uint8_t *)addr2p; 1933 0 stevel 1934 0 stevel /* 1935 0 stevel * and there was much evil.. 1936 0 stevel * XXX should inline-expand the bcmp here and do this 32 bits 1937 0 stevel * or 64 bits at a time.. 1938 0 stevel */ 1939 0 stevel return ((bcmp(addr1, addr2, offset) == 0) && 1940 0 stevel ((bitsleft == 0) || 1941 5245 danmcd (((addr1[offset] ^ addr2[offset]) & (0xff<<(8-bitsleft))) == 0))); 1942 0 stevel } 1943 0 stevel 1944 81 sommerfe static ipsec_policy_t * 1945 81 sommerfe ipsec_find_policy_chain(ipsec_policy_t *best, ipsec_policy_t *chain, 1946 81 sommerfe ipsec_selector_t *sel, boolean_t is_icmp_inv_acq) 1947 81 sommerfe { 1948 81 sommerfe ipsec_selkey_t *isel; 1949 81 sommerfe ipsec_policy_t *p; 1950 81 sommerfe int bpri = best ? best->ipsp_prio : 0; 1951 81 sommerfe 1952 81 sommerfe for (p = chain; p != NULL; p = p->ipsp_hash.hash_next) { 1953 81 sommerfe uint32_t valid; 1954 81 sommerfe 1955 81 sommerfe if (p->ipsp_prio <= bpri) 1956 81 sommerfe continue; 1957 81 sommerfe isel = &p->ipsp_sel->ipsl_key; 1958 81 sommerfe valid = isel->ipsl_valid; 1959 81 sommerfe 1960 81 sommerfe if ((valid & IPSL_PROTOCOL) && 1961 81 sommerfe (isel->ipsl_proto != sel->ips_protocol)) 1962 81 sommerfe continue; 1963 81 sommerfe 1964 81 sommerfe if ((valid & IPSL_REMOTE_ADDR) && 1965 81 sommerfe !ip_addr_match((uint8_t *)&isel->ipsl_remote, 1966 5245 danmcd isel->ipsl_remote_pfxlen, &sel->ips_remote_addr_v6)) 1967 81 sommerfe continue; 1968 81 sommerfe 1969 81 sommerfe if ((valid & IPSL_LOCAL_ADDR) && 1970 81 sommerfe !ip_addr_match((uint8_t *)&isel->ipsl_local, 1971 5245 danmcd isel->ipsl_local_pfxlen, &sel->ips_local_addr_v6)) 1972 81 sommerfe continue; 1973 81 sommerfe 1974 81 sommerfe if ((valid & IPSL_REMOTE_PORT) && 1975 81 sommerfe isel->ipsl_rport != sel->ips_remote_port) 1976 81 sommerfe continue; 1977 81 sommerfe 1978 81 sommerfe if ((valid & IPSL_LOCAL_PORT) && 1979 81 sommerfe isel->ipsl_lport != sel->ips_local_port) 1980 81 sommerfe continue; 1981 81 sommerfe 1982 81 sommerfe if (!is_icmp_inv_acq) { 1983 81 sommerfe if ((valid & IPSL_ICMP_TYPE) && 1984 81 sommerfe (isel->ipsl_icmp_type > sel->ips_icmp_type || 1985 81 sommerfe isel->ipsl_icmp_type_end < sel->ips_icmp_type)) { 1986 81 sommerfe continue; 1987 81 sommerfe } 1988 81 sommerfe 1989 81 sommerfe if ((valid & IPSL_ICMP_CODE) && 1990 81 sommerfe (isel->ipsl_icmp_code > sel->ips_icmp_code || 1991 81 sommerfe isel->ipsl_icmp_code_end < 1992 81 sommerfe sel->ips_icmp_code)) { 1993 81 sommerfe continue; 1994 81 sommerfe } 1995 81 sommerfe } else { 1996 81 sommerfe /* 1997 81 sommerfe * special case for icmp inverse acquire 1998 81 sommerfe * we only want policies that aren't drop/pass 1999 81 sommerfe */ 2000 81 sommerfe if (p->ipsp_act->ipa_act.ipa_type != IPSEC_ACT_APPLY) 2001 81 sommerfe continue; 2002 81 sommerfe } 2003 81 sommerfe 2004 81 sommerfe /* we matched all the packet-port-field selectors! */ 2005 81 sommerfe best = p; 2006 81 sommerfe bpri = p->ipsp_prio; 2007 81 sommerfe } 2008 81 sommerfe 2009 81 sommerfe return (best); 2010 81 sommerfe } 2011 81 sommerfe 2012 0 stevel /* 2013 0 stevel * Try to find and return the best policy entry under a given policy 2014 0 stevel * root for a given set of selectors; the first parameter "best" is 2015 0 stevel * the current best policy so far. If "best" is non-null, we have a 2016 0 stevel * reference to it. We return a reference to a policy; if that policy 2017 0 stevel * is not the original "best", we need to release that reference 2018 0 stevel * before returning. 2019 0 stevel */ 2020 3055 danmcd ipsec_policy_t * 2021 3055 danmcd ipsec_find_policy_head(ipsec_policy_t *best, ipsec_policy_head_t *head, 2022 11042 Erik int direction, ipsec_selector_t *sel) 2023 81 sommerfe { 2024 81 sommerfe ipsec_policy_t *curbest; 2025 0 stevel ipsec_policy_root_t *root; 2026 0 stevel uint8_t is_icmp_inv_acq = sel->ips_is_icmp_inv_acq; 2027 0 stevel int af = sel->ips_isv4 ? IPSEC_AF_V4 : IPSEC_AF_V6; 2028 0 stevel 2029 0 stevel curbest = best; 2030 0 stevel root = &head->iph_root[direction]; 2031 0 stevel 2032 0 stevel #ifdef DEBUG 2033 0 stevel if (is_icmp_inv_acq) { 2034 0 stevel if (sel->ips_isv4) { 2035 0 stevel if (sel->ips_protocol != IPPROTO_ICMP) { 2036 5245 danmcd cmn_err(CE_WARN, "ipsec_find_policy_head:" 2037 5245 danmcd " expecting icmp, got %d", 2038 5245 danmcd sel->ips_protocol); 2039 0 stevel } 2040 0 stevel } else { 2041 81 sommerfe if (sel->ips_protocol != IPPROTO_ICMPV6) { 2042 0 stevel cmn_err(CE_WARN, "ipsec_find_policy_head:" 2043 5245 danmcd " expecting icmpv6, got %d", 2044 5245 danmcd sel->ips_protocol); 2045 0 stevel } 2046 0 stevel } 2047 0 stevel } 2048 0 stevel #endif 2049 0 stevel 2050 0 stevel rw_enter(&head->iph_lock, RW_READER); 2051 0 stevel 2052 81 sommerfe if (root->ipr_nchains > 0) { 2053 81 sommerfe curbest = ipsec_find_policy_chain(curbest, 2054 3055 danmcd root->ipr_hash[selector_hash(sel, root)].hash_head, sel, 2055 3055 danmcd is_icmp_inv_acq); 2056 81 sommerfe } 2057 81 sommerfe curbest = ipsec_find_policy_chain(curbest, root->ipr_nonhash[af], sel, 2058 81 sommerfe is_icmp_inv_acq); 2059 81 sommerfe 2060 81 sommerfe /* 2061 81 sommerfe * Adjust reference counts if we found anything new. 2062 0 stevel */ 2063 0 stevel if (curbest != best) { 2064 81 sommerfe ASSERT(curbest != NULL); 2065 81 sommerfe IPPOL_REFHOLD(curbest); 2066 81 sommerfe 2067 0 stevel if (best != NULL) { 2068 11042 Erik IPPOL_REFRELE(best); 2069 0 stevel } 2070 0 stevel } 2071 0 stevel 2072 0 stevel rw_exit(&head->iph_lock); 2073 0 stevel 2074 0 stevel return (curbest); 2075 0 stevel } 2076 0 stevel 2077 0 stevel /* 2078 0 stevel * Find the best system policy (either global or per-interface) which 2079 0 stevel * applies to the given selector; look in all the relevant policy roots 2080 0 stevel * to figure out which policy wins. 2081 0 stevel * 2082 0 stevel * Returns a reference to a policy; caller must release this 2083 0 stevel * reference when done. 2084 0 stevel */ 2085 0 stevel ipsec_policy_t * 2086 11042 Erik ipsec_find_policy(int direction, const conn_t *connp, ipsec_selector_t *sel, 2087 11042 Erik netstack_t *ns) 2088 0 stevel { 2089 0 stevel ipsec_policy_t *p; 2090 3448 dh155122 ipsec_stack_t *ipss = ns->netstack_ipsec; 2091 3448 dh155122 2092 3448 dh155122 p = ipsec_find_policy_head(NULL, &ipss->ipsec_system_policy, 2093 11042 Erik direction, sel); 2094 0 stevel if ((connp != NULL) && (connp->conn_policy != NULL)) { 2095 0 stevel p = ipsec_find_policy_head(p, connp->conn_policy, 2096 11042 Erik direction, sel); 2097 0 stevel } 2098 0 stevel 2099 0 stevel return (p); 2100 0 stevel } 2101 0 stevel 2102 0 stevel /* 2103 0 stevel * Check with global policy and see whether this inbound 2104 0 stevel * packet meets the policy constraints. 2105 0 stevel * 2106 0 stevel * Locate appropriate policy from global policy, supplemented by the 2107 0 stevel * conn's configured and/or cached policy if the conn is supplied. 2108 0 stevel * 2109 0 stevel * Dispatch to ipsec_check_ipsecin_policy if we have policy and an 2110 0 stevel * encrypted packet to see if they match. 2111 0 stevel * 2112 0 stevel * Otherwise, see if the policy allows cleartext; if not, drop it on the 2113 0 stevel * floor. 2114 0 stevel */ 2115 0 stevel mblk_t * 2116 11042 Erik ipsec_check_global_policy(mblk_t *data_mp, conn_t *connp, 2117 11042 Erik ipha_t *ipha, ip6_t *ip6h, ip_recv_attr_t *ira, netstack_t *ns) 2118 0 stevel { 2119 0 stevel ipsec_policy_t *p; 2120 0 stevel ipsec_selector_t sel; 2121 0 stevel boolean_t policy_present; 2122 0 stevel kstat_named_t *counter; 2123 3055 danmcd uint64_t pkt_unique; 2124 3448 dh155122 ip_stack_t *ipst = ns->netstack_ip; 2125 11042 Erik ipsec_stack_t *ipss = ns->netstack_ipsec; 2126 0 stevel 2127 0 stevel sel.ips_is_icmp_inv_acq = 0; 2128 0 stevel 2129 0 stevel ASSERT((ipha == NULL && ip6h != NULL) || 2130 0 stevel (ip6h == NULL && ipha != NULL)); 2131 0 stevel 2132 0 stevel if (ipha != NULL) 2133 3448 dh155122 policy_present = ipss->ipsec_inbound_v4_policy_present; 2134 0 stevel else 2135 3448 dh155122 policy_present = ipss->ipsec_inbound_v6_policy_present; 2136 0 stevel 2137 0 stevel if (!policy_present && connp == NULL) { 2138 0 stevel /* 2139 0 stevel * No global policy and no per-socket policy; 2140 0 stevel * just pass it back (but we shouldn't get here in that case) 2141 0 stevel */ 2142 11042 Erik return (data_mp); 2143 0 stevel } 2144 0 stevel 2145 0 stevel /* 2146 0 stevel * If we have cached policy, use it. 2147 0 stevel * Otherwise consult system policy. 2148 0 stevel */ 2149 0 stevel if ((connp != NULL) && (connp->conn_latch != NULL)) { 2150 11042 Erik p = connp->conn_latch_in_policy; 2151 0 stevel if (p != NULL) { 2152 0 stevel IPPOL_REFHOLD(p); 2153 10934 sommerfeld } 2154 10934 sommerfeld /* 2155 3055 danmcd * Fudge sel for UNIQUE_ID setting below. 2156 3055 danmcd */ 2157 3055 danmcd pkt_unique = conn_to_unique(connp, data_mp, ipha, ip6h); 2158 0 stevel } else { 2159 0 stevel /* Initialize the ports in the selector */ 2160 3055 danmcd if (ipsec_init_inbound_sel(&sel, data_mp, ipha, ip6h, 2161 5245 danmcd SEL_NONE) == SELRET_NOMEM) { 2162 0 stevel /* 2163 0 stevel * Technically not a policy mismatch, but it is 2164 0 stevel * an internal failure. 2165 0 stevel */ 2166 3192 danmcd ipsec_log_policy_failure(IPSEC_POLICY_MISMATCH, 2167 10934 sommerfeld "ipsec_init_inbound_sel", ipha, ip6h, B_TRUE, ns); 2168 3448 dh155122 counter = DROPPER(ipss, ipds_spd_nomem); 2169 0 stevel goto fail; 2170 0 stevel } 2171 0 stevel 2172 0 stevel /* 2173 0 stevel * Find the policy which best applies. 2174 0 stevel * 2175 0 stevel * If we find global policy, we should look at both 2176 0 stevel * local policy and global policy and see which is 2177 0 stevel * stronger and match accordingly. 2178 0 stevel * 2179 0 stevel * If we don't find a global policy, check with 2180 0 stevel * local policy alone. 2181 0 stevel */ 2182 0 stevel 2183 11042 Erik p = ipsec_find_policy(IPSEC_TYPE_INBOUND, connp, &sel, ns); 2184 3055 danmcd pkt_unique = SA_UNIQUE_ID(sel.ips_remote_port, 2185 3055 danmcd sel.ips_local_port, sel.ips_protocol, 0); 2186 0 stevel } 2187 0 stevel 2188 0 stevel if (p == NULL) { 2189 11042 Erik if (!(ira->ira_flags & IRAF_IPSEC_SECURE)) { 2190 0 stevel /* 2191 0 stevel * We have no policy; default to succeeding. 2192 0 stevel * XXX paranoid system design doesn't do this. 2193 0 stevel */ 2194 3448 dh155122 BUMP_MIB(&ipst->ips_ip_mib, ipsecInSucceeded); 2195 11042 Erik return (data_mp); 2196 0 stevel } else { 2197 3448 dh155122 counter = DROPPER(ipss, ipds_spd_got_secure); 2198 3192 danmcd ipsec_log_policy_failure(IPSEC_POLICY_NOT_NEEDED, 2199 3448 dh155122 "ipsec_check_global_policy", ipha, ip6h, B_TRUE, 2200 3448 dh155122 ns); 2201 0 stevel goto fail; 2202 0 stevel } 2203 0 stevel } 2204 11042 Erik if (ira->ira_flags & IRAF_IPSEC_SECURE) { 2205 11042 Erik return (ipsec_check_ipsecin_policy(data_mp, p, ipha, ip6h, 2206 11042 Erik pkt_unique, ira, ns)); 2207 3192 danmcd } 2208 0 stevel if (p->ipsp_act->ipa_allow_clear) { 2209 3448 dh155122 BUMP_MIB(&ipst->ips_ip_mib, ipsecInSucceeded); 2210 11042 Erik IPPOL_REFRELE(p); 2211 11042 Erik return (data_mp); 2212 11042 Erik } 2213 11042 Erik IPPOL_REFRELE(p); 2214 0 stevel /* 2215 0 stevel * If we reach here, we will drop the packet because it failed the 2216 0 stevel * global policy check because the packet was cleartext, and it 2217 0 stevel * should not have been. 2218 0 stevel */ 2219 3192 danmcd ipsec_log_policy_failure(IPSEC_POLICY_MISMATCH, 2220 3448 dh155122 "ipsec_check_global_policy", ipha, ip6h, B_FALSE, ns); 2221 3448 dh155122 counter = DROPPER(ipss, ipds_spd_got_clear); 2222 0 stevel 2223 0 stevel fail: 2224 11042 Erik ip_drop_packet(data_mp, B_TRUE, NULL, counter, 2225 3448 dh155122 &ipss->ipsec_spd_dropper); 2226 3448 dh155122 BUMP_MIB(&ipst->ips_ip_mib, ipsecInFailed); 2227 0 stevel return (NULL); 2228 0 stevel } 2229 0 stevel 2230 0 stevel /* 2231 0 stevel * We check whether an inbound datagram is a valid one 2232 0 stevel * to accept in clear. If it is secure, it is the job 2233 0 stevel * of IPSEC to log information appropriately if it 2234 0 stevel * suspects that it may not be the real one. 2235 0 stevel * 2236 0 stevel * It is called only while fanning out to the ULP 2237 0 stevel * where ULP accepts only secure data and the incoming 2238 0 stevel * is clear. Usually we never accept clear datagrams in 2239 0 stevel * such cases. ICMP is the only exception. 2240 0 stevel * 2241 0 stevel * NOTE : We don't call this function if the client (ULP) 2242 0 stevel * is willing to accept things in clear. 2243 0 stevel */ 2244 0 stevel boolean_t 2245 0 stevel ipsec_inbound_accept_clear(mblk_t *mp, ipha_t *ipha, ip6_t *ip6h) 2246 0 stevel { 2247 0 stevel ushort_t iph_hdr_length; 2248 0 stevel icmph_t *icmph; 2249 0 stevel icmp6_t *icmp6; 2250 0 stevel uint8_t *nexthdrp; 2251 0 stevel 2252 0 stevel ASSERT((ipha != NULL && ip6h == NULL) || 2253 0 stevel (ipha == NULL && ip6h != NULL)); 2254 0 stevel 2255 0 stevel if (ip6h != NULL) { 2256 0 stevel iph_hdr_length = ip_hdr_length_v6(mp, ip6h); 2257 0 stevel if (!ip_hdr_length_nexthdr_v6(mp, ip6h, &iph_hdr_length, 2258 0 stevel &nexthdrp)) { 2259 0 stevel return (B_FALSE); 2260 0 stevel } 2261 0 stevel if (*nexthdrp != IPPROTO_ICMPV6) 2262 0 stevel return (B_FALSE); 2263 0 stevel icmp6 = (icmp6_t *)(&mp->b_rptr[iph_hdr_length]); 2264 0 stevel /* Match IPv6 ICMP policy as closely as IPv4 as possible. */ 2265 0 stevel switch (icmp6->icmp6_type) { 2266 0 stevel case ICMP6_PARAM_PROB: 2267 0 stevel /* Corresponds to port/proto unreach in IPv4. */ 2268 0 stevel case ICMP6_ECHO_REQUEST: 2269 0 stevel /* Just like IPv4. */ 2270 0 stevel return (B_FALSE); 2271 0 stevel 2272 0 stevel case MLD_LISTENER_QUERY: 2273 0 stevel case MLD_LISTENER_REPORT: 2274 0 stevel case MLD_LISTENER_REDUCTION: 2275 0 stevel /* 2276 0 stevel * XXX Seperate NDD in IPv4 what about here? 2277 0 stevel * Plus, mcast is important to ND. 2278 0 stevel */ 2279 0 stevel case ICMP6_DST_UNREACH: 2280 0 stevel /* Corresponds to HOST/NET unreachable in IPv4. */ 2281 0 stevel case ICMP6_PACKET_TOO_BIG: 2282 0 stevel case ICMP6_ECHO_REPLY: 2283 0 stevel /* These are trusted in IPv4. */ 2284 0 stevel case ND_ROUTER_SOLICIT: 2285 0 stevel case ND_ROUTER_ADVERT: 2286 0 stevel case ND_NEIGHBOR_SOLICIT: 2287 0 stevel case ND_NEIGHBOR_ADVERT: 2288 0 stevel case ND_REDIRECT: 2289 0 stevel /* Trust ND messages for now. */ 2290 0 stevel case ICMP6_TIME_EXCEEDED: 2291 0 stevel default: 2292 0 stevel return (B_TRUE); 2293 0 stevel } 2294 0 stevel } else { 2295 0 stevel /* 2296 0 stevel * If it is not ICMP, fail this request. 2297 0 stevel */ 2298 3055 danmcd if (ipha->ipha_protocol != IPPROTO_ICMP) { 2299 3055 danmcd #ifdef FRAGCACHE_DEBUG 2300 3055 danmcd cmn_err(CE_WARN, "Dropping - ipha_proto = %d\n", 2301 3055 danmcd ipha->ipha_protocol); 2302 3055 danmcd #endif 2303 3055 danmcd return (B_FALSE); 2304 3055 danmcd } 2305 0 stevel iph_hdr_length = IPH_HDR_LENGTH(ipha); 2306 0 stevel icmph = (icmph_t *)&mp->b_rptr[iph_hdr_length]; 2307 0 stevel /* 2308 0 stevel * It is an insecure icmp message. Check to see whether we are 2309 0 stevel * willing to accept this one. 2310 0 stevel */ 2311 0 stevel 2312 0 stevel switch (icmph->icmph_type) { 2313 0 stevel case ICMP_ECHO_REPLY: 2314 0 stevel case ICMP_TIME_STAMP_REPLY: 2315 0 stevel case ICMP_INFO_REPLY: 2316 0 stevel case ICMP_ROUTER_ADVERTISEMENT: 2317 0 stevel /* 2318 0 stevel * We should not encourage clear replies if this 2319 0 stevel * client expects secure. If somebody is replying 2320 0 stevel * in clear some mailicious user watching both the 2321 0 stevel * request and reply, can do chosen-plain-text attacks. 2322 0 stevel * With global policy we might be just expecting secure 2323 0 stevel * but sending out clear. We don't know what the right 2324 0 stevel * thing is. We can't do much here as we can't control 2325 0 stevel * the sender here. Till we are sure of what to do, 2326 0 stevel * accept them. 2327 0 stevel */ 2328 0 stevel return (B_TRUE); 2329 0 stevel case ICMP_ECHO_REQUEST: 2330 0 stevel case ICMP_TIME_STAMP_REQUEST: 2331 0 stevel case ICMP_INFO_REQUEST: 2332 0 stevel case ICMP_ADDRESS_MASK_REQUEST: 2333 0 stevel case ICMP_ROUTER_SOLICITATION: 2334 0 stevel case ICMP_ADDRESS_MASK_REPLY: 2335 0 stevel /* 2336 0 stevel * Don't accept this as somebody could be sending 2337 0 stevel * us plain text to get encrypted data. If we reply, 2338 0 stevel * it will lead to chosen plain text attack. 2339 0 stevel */ 2340 0 stevel return (B_FALSE); 2341 0 stevel case ICMP_DEST_UNREACHABLE: 2342 0 stevel switch (icmph->icmph_code) { 2343 0 stevel case ICMP_FRAGMENTATION_NEEDED: 2344 0 stevel /* 2345 0 stevel * Be in sync with icmp_inbound, where we have 2346 11042 Erik * already set dce_pmtu 2347 0 stevel */ 2348 3055 danmcd #ifdef FRAGCACHE_DEBUG 2349 3055 danmcd cmn_err(CE_WARN, "ICMP frag needed\n"); 2350 3055 danmcd #endif 2351 0 stevel return (B_TRUE); 2352 0 stevel case ICMP_HOST_UNREACHABLE: 2353 0 stevel case ICMP_NET_UNREACHABLE: 2354 0 stevel /* 2355 0 stevel * By accepting, we could reset a connection. 2356 0 stevel * How do we solve the problem of some 2357 0 stevel * intermediate router sending in-secure ICMP 2358 0 stevel * messages ? 2359 0 stevel */ 2360 0 stevel return (B_TRUE); 2361 0 stevel case ICMP_PORT_UNREACHABLE: 2362 0 stevel case ICMP_PROTOCOL_UNREACHABLE: 2363 0 stevel default : 2364 0 stevel return (B_FALSE); 2365 0 stevel } 2366 0 stevel case ICMP_SOURCE_QUENCH: 2367 0 stevel /* 2368 0 stevel * If this is an attack, TCP will slow start 2369 0 stevel * because of this. Is it very harmful ? 2370 0 stevel */ 2371 0 stevel return (B_TRUE); 2372 0 stevel case ICMP_PARAM_PROBLEM: 2373 0 stevel return (B_FALSE); 2374 0 stevel case ICMP_TIME_EXCEEDED: 2375 0 stevel return (B_TRUE); 2376 0 stevel case ICMP_REDIRECT: 2377 0 stevel return (B_FALSE); 2378 0 stevel default : 2379 0 stevel return (B_FALSE); 2380 0 stevel } 2381 0 stevel } 2382 0 stevel } 2383 0 stevel 2384 0 stevel void 2385 0 stevel ipsec_latch_ids(ipsec_latch_t *ipl, ipsid_t *local, ipsid_t *remote) 2386 0 stevel { 2387 0 stevel mutex_enter(&ipl->ipl_lock); 2388 0 stevel 2389 0 stevel if (ipl->ipl_ids_latched) { 2390 0 stevel /* I lost, someone else got here before me */ 2391 0 stevel mutex_exit(&ipl->ipl_lock); 2392 0 stevel return; 2393 0 stevel } 2394 0 stevel 2395 0 stevel if (local != NULL) 2396 0 stevel IPSID_REFHOLD(local); 2397 0 stevel if (remote != NULL) 2398 0 stevel IPSID_REFHOLD(remote); 2399 0 stevel 2400 0 stevel ipl->ipl_local_cid = local; 2401 0 stevel ipl->ipl_remote_cid = remote; 2402 0 stevel ipl->ipl_ids_latched = B_TRUE; 2403 0 stevel mutex_exit(&ipl->ipl_lock); 2404 0 stevel } 2405 0 stevel 2406 0 stevel void 2407 11042 Erik ipsec_latch_inbound(conn_t *connp, ip_recv_attr_t *ira) 2408 0 stevel { 2409 0 stevel ipsa_t *sa; 2410 11042 Erik ipsec_latch_t *ipl = connp->conn_latch; 2411 0 stevel 2412 0 stevel if (!ipl->ipl_ids_latched) { 2413 0 stevel ipsid_t *local = NULL; 2414 0 stevel ipsid_t *remote = NULL; 2415 0 stevel 2416 11042 Erik if (!(ira->ira_flags & IRAF_LOOPBACK)) { 2417 11042 Erik ASSERT(ira->ira_flags & IRAF_IPSEC_SECURE); 2418 11042 Erik if (ira->ira_ipsec_esp_sa != NULL) 2419 11042 Erik sa = ira->ira_ipsec_esp_sa; 2420 0 stevel else 2421 11042 Erik sa = ira->ira_ipsec_ah_sa; 2422 0 stevel ASSERT(sa != NULL); 2423 0 stevel local = sa->ipsa_dst_cid; 2424 0 stevel remote = sa->ipsa_src_cid; 2425 0 stevel } 2426 0 stevel ipsec_latch_ids(ipl, local, remote); 2427 0 stevel } 2428 11042 Erik if (ira->ira_flags & IRAF_IPSEC_SECURE) { 2429 11042 Erik if (connp->conn_latch_in_action != NULL) { 2430 11042 Erik /* 2431 11042 Erik * Previously cached action. This is probably 2432 11042 Erik * harmless, but in DEBUG kernels, check for 2433 11042 Erik * action equality. 2434 11042 Erik * 2435 11042 Erik * Preserve the existing action to preserve latch 2436 11042 Erik * invariance. 2437 11042 Erik */ 2438 11042 Erik ASSERT(connp->conn_latch_in_action == 2439 11042 Erik ira->ira_ipsec_action); 2440 11042 Erik return; 2441 11042 Erik } 2442 11042 Erik connp->conn_latch_in_action = ira->ira_ipsec_action; 2443 11042 Erik IPACT_REFHOLD(connp->conn_latch_in_action); 2444 11042 Erik } 2445 0 stevel } 2446 0 stevel 2447 0 stevel /* 2448 0 stevel * Check whether the policy constraints are met either for an 2449 0 stevel * inbound datagram; called from IP in numerous places. 2450 0 stevel * 2451 0 stevel * Note that this is not a chokepoint for inbound policy checks; 2452 691 sommerfe * see also ipsec_check_ipsecin_latch() and ipsec_check_global_policy() 2453 0 stevel */ 2454 0 stevel mblk_t * 2455 11042 Erik ipsec_check_inbound_policy(mblk_t *mp, conn_t *connp, 2456 11042 Erik ipha_t *ipha, ip6_t *ip6h, ip_recv_attr_t *ira) 2457 11042 Erik { 2458 11042 Erik boolean_t ret; 2459 11042 Erik ipsec_latch_t *ipl; 2460 11042 Erik ipsec_action_t *ap; 2461 11042 Erik uint64_t unique_id; 2462 3448 dh155122 ipsec_stack_t *ipss; 2463 3448 dh155122 ip_stack_t *ipst; 2464 3448 dh155122 netstack_t *ns; 2465 9953 Vladimir ipsec_policy_head_t *policy_head; 2466 11042 Erik ipsec_policy_t *p = NULL; 2467 0 stevel 2468 0 stevel ASSERT(connp != NULL); 2469 3448 dh155122 ns = connp->conn_netstack; 2470 3448 dh155122 ipss = ns->netstack_ipsec; 2471 3448 dh155122 ipst = ns->netstack_ip; 2472 0 stevel 2473 11042 Erik if (!(ira->ira_flags & IRAF_IPSEC_SECURE)) { 2474 0 stevel /* 2475 0 stevel * This is the case where the incoming datagram is 2476 0 stevel * cleartext and we need to see whether this client 2477 0 stevel * would like to receive such untrustworthy things from 2478 0 stevel * the wire. 2479 0 stevel */ 2480 0 stevel ASSERT(mp != NULL); 2481 0 stevel 2482 7443 George mutex_enter(&connp->conn_lock); 2483 7443 George if (connp->conn_state_flags & CONN_CONDEMNED) { 2484 7443 George mutex_exit(&connp->conn_lock); 2485 11042 Erik ip_drop_packet(mp, B_TRUE, NULL, 2486 11042 Erik DROPPER(ipss, ipds_spd_got_clear), 2487 7443 George &ipss->ipsec_spd_dropper); 2488 7443 George BUMP_MIB(&ipst->ips_ip_mib, ipsecInFailed); 2489 7443 George return (NULL); 2490 7443 George } 2491 11042 Erik if (connp->conn_latch != NULL) { 2492 7443 George /* Hold a reference in case the conn is closing */ 2493 11042 Erik p = connp->conn_latch_in_policy; 2494 11042 Erik if (p != NULL) 2495 11042 Erik IPPOL_REFHOLD(p); 2496 7443 George mutex_exit(&connp->conn_lock); 2497 0 stevel /* 2498 0 stevel * Policy is cached in the conn. 2499 0 stevel */ 2500 11042 Erik if (p != NULL && !p->ipsp_act->ipa_allow_clear) { 2501 0 stevel ret = ipsec_inbound_accept_clear(mp, 2502 0 stevel ipha, ip6h); 2503 0 stevel if (ret) { 2504 3448 dh155122 BUMP_MIB(&ipst->ips_ip_mib, 2505 3448 dh155122 ipsecInSucceeded); 2506 11042 Erik IPPOL_REFRELE(p); 2507 11042 Erik return (mp); 2508 0 stevel } else { 2509 0 stevel ipsec_log_policy_failure( 2510 0 stevel IPSEC_POLICY_MISMATCH, 2511 0 stevel "ipsec_check_inbound_policy", ipha, 2512 3448 dh155122 ip6h, B_FALSE, ns); 2513 11042 Erik ip_drop_packet(mp, B_TRUE, NULL, 2514 3448 dh155122 DROPPER(ipss, ipds_spd_got_clear), 2515 3448 dh155122 &ipss->ipsec_spd_dropper); 2516 3448 dh155122 BUMP_MIB(&ipst->ips_ip_mib, 2517 3448 dh155122 ipsecInFailed); 2518 11042 Erik IPPOL_REFRELE(p); 2519 0 stevel return (NULL); 2520 0 stevel } 2521 0 stevel } else { 2522 3448 dh155122 BUMP_MIB(&ipst->ips_ip_mib, ipsecInSucceeded); 2523 11042 Erik if (p != NULL) 2524 11042 Erik IPPOL_REFRELE(p); 2525 11042 Erik return (mp); 2526 11042 Erik } 2527 11042 Erik } else { 2528 9953 Vladimir policy_head = connp->conn_policy; 2529 9953 Vladimir 2530 9953 Vladimir /* Hold a reference in case the conn is closing */ 2531 9953 Vladimir if (policy_head != NULL) 2532 9953 Vladimir IPPH_REFHOLD(policy_head); 2533 7443 George mutex_exit(&connp->conn_lock); 2534 0 stevel /* 2535 0 stevel * As this is a non-hardbound connection we need 2536 0 stevel * to look at both per-socket policy and global 2537 11042 Erik * policy. 2538 11042 Erik */ 2539 11042 Erik mp = ipsec_check_global_policy(mp, connp, 2540 11042 Erik ipha, ip6h, ira, ns); 2541 9953 Vladimir if (policy_head != NULL) 2542 9953 Vladimir IPPH_REFRELE(policy_head, ns); 2543 11042 Erik return (mp); 2544 11042 Erik } 2545 11042 Erik } 2546 0 stevel 2547 7443 George mutex_enter(&connp->conn_lock); 2548 7443 George /* Connection is closing */ 2549 7443 George if (connp->conn_state_flags & CONN_CONDEMNED) { 2550 7443 George mutex_exit(&connp->conn_lock); 2551 11042 Erik ip_drop_packet(mp, B_TRUE, NULL, 2552 11042 Erik DROPPER(ipss, ipds_spd_got_clear), 2553 7443 George &ipss->ipsec_spd_dropper); 2554 7443 George BUMP_MIB(&ipst->ips_ip_mib, ipsecInFailed); 2555 7443 George return (NULL); 2556 7443 George } 2557 7443 George 2558 7443 George /* 2559 7443 George * Once a connection is latched it remains so for life, the conn_latch 2560 7443 George * pointer on the conn has not changed, simply initializing ipl here 2561 7443 George * as the earlier initialization was done only in the cleartext case. 2562 7443 George */ 2563 7456 danmcd if ((ipl = connp->conn_latch) == NULL) { 2564 9953 Vladimir mblk_t *retmp; 2565 9953 Vladimir policy_head = connp->conn_policy; 2566 9953 Vladimir 2567 9953 Vladimir /* Hold a reference in case the conn is closing */ 2568 9953 Vladimir if (policy_head != NULL) 2569 9953 Vladimir IPPH_REFHOLD(policy_head); 2570 7443 George mutex_exit(&connp->conn_lock); 2571 0 stevel /* 2572 691 sommerfe * We don't have policies cached in the conn 2573 0 stevel * for this stream. So, look at the global 2574 0 stevel * policy. It will check against conn or global 2575 0 stevel * depending on whichever is stronger. 2576 0 stevel */ 2577 11042 Erik retmp = ipsec_check_global_policy(mp, connp, 2578 11042 Erik ipha, ip6h, ira, ns); 2579 9953 Vladimir if (policy_head != NULL) 2580 9953 Vladimir IPPH_REFRELE(policy_head, ns); 2581 9953 Vladimir return (retmp); 2582 691 sommerfe } 2583 691 sommerfe 2584 7443 George IPLATCH_REFHOLD(ipl); 2585 11042 Erik /* Hold reference on conn_latch_in_action in case conn is closing */ 2586 11042 Erik ap = connp->conn_latch_in_action; 2587 11042 Erik if (ap != NULL) 2588 11042 Erik IPACT_REFHOLD(ap); 2589 7443 George mutex_exit(&connp->conn_lock); 2590 7443 George 2591 11042 Erik if (ap != NULL) { 2592 0 stevel /* Policy is cached & latched; fast(er) path */ 2593 0 stevel const char *reason; 2594 0 stevel kstat_named_t *counter; 2595 3448 dh155122 2596 11042 Erik if (ipsec_check_ipsecin_latch(ira, mp, ipl, ap, 2597 11042 Erik ipha, ip6h, &reason, &counter, connp, ns)) { 2598 3448 dh155122 BUMP_MIB(&ipst->ips_ip_mib, ipsecInSucceeded); 2599 11042 Erik IPLATCH_REFRELE(ipl); 2600 11042 Erik IPACT_REFRELE(ap); 2601 11042 Erik return (mp); 2602 0 stevel } 2603 3448 dh155122 ipsec_rl_strlog(ns, IP_MOD_ID, 0, 0, 2604 3448 dh155122 SL_ERROR|SL_WARN|SL_CONSOLE, 2605 0 stevel "ipsec inbound policy mismatch: %s, packet dropped\n", 2606 0 stevel reason); 2607 11042 Erik ip_drop_packet(mp, B_TRUE, NULL, counter, 2608 3448 dh155122 &ipss->ipsec_spd_dropper); 2609 3448 dh155122 BUMP_MIB(&ipst->ips_ip_mib, ipsecInFailed); 2610 11042 Erik IPLATCH_REFRELE(ipl); 2611 11042 Erik IPACT_REFRELE(ap); 2612 11042 Erik return (NULL); 2613 11042 Erik } 2614 11042 Erik if ((p = connp->conn_latch_in_policy) == NULL) { 2615 691 sommerfe ipsec_weird_null_inbound_policy++; 2616 11042 Erik IPLATCH_REFRELE(ipl); 2617 11042 Erik return (mp); 2618 691 sommerfe } 2619 0 stevel 2620 3055 danmcd unique_id = conn_to_unique(connp, mp, ipha, ip6h); 2621 11042 Erik IPPOL_REFHOLD(p); 2622 11042 Erik mp = ipsec_check_ipsecin_policy(mp, p, ipha, ip6h, unique_id, ira, ns); 2623 0 stevel /* 2624 0 stevel * NOTE: ipsecIn{Failed,Succeeeded} bumped by 2625 0 stevel * ipsec_check_ipsecin_policy(). 2626 0 stevel */ 2627 11042 Erik if (mp != NULL) 2628 11042 Erik ipsec_latch_inbound(connp, ira); 2629 11042 Erik IPLATCH_REFRELE(ipl); 2630 11042 Erik return (mp); 2631 11042 Erik } 2632 11042 Erik 2633 11042 Erik /* 2634 11042 Erik * Handle all sorts of cases like tunnel-mode and ICMP. 2635 10934 sommerfeld */ 2636 10934 sommerfeld static int 2637 10934 sommerfeld prepended_length(mblk_t *mp, uintptr_t hptr) 2638 10934 sommerfeld { 2639 10934 sommerfeld int rc = 0; 2640 10934 sommerfeld 2641 10934 sommerfeld while (mp != NULL) { 2642 10934 sommerfeld if (hptr >= (uintptr_t)mp->b_rptr && hptr < 2643 10934 sommerfeld (uintptr_t)mp->b_wptr) { 2644 10934 sommerfeld rc += (int)(hptr - (uintptr_t)mp->b_rptr); 2645 10934 sommerfeld break; /* out of while loop */ 2646 10934 sommerfeld } 2647 10934 sommerfeld rc += (int)MBLKL(mp); 2648 10934 sommerfeld mp = mp->b_cont; 2649 10934 sommerfeld } 2650 10934 sommerfeld 2651 10934 sommerfeld if (mp == NULL) { 2652 10934 sommerfeld /* 2653 10934 sommerfeld * IF (big IF) we make it here by naturally exiting the loop, 2654 10934 sommerfeld * then ip6h isn't in the mblk chain "mp" at all. 2655 10934 sommerfeld * 2656 10934 sommerfeld * The only case where this happens is with a reversed IP 2657 10934 sommerfeld * header that gets passed up by inbound ICMP processing. 2658 10934 sommerfeld * This unfortunately triggers longstanding bug 6478464. For 2659 10934 sommerfeld * now, just pass up 0 for the answer. 2660 10934 sommerfeld */ 2661 10934 sommerfeld #ifdef DEBUG_NOT_UNTIL_6478464 2662 10934 sommerfeld ASSERT(mp != NULL); 2663 10934 sommerfeld #endif 2664 10934 sommerfeld rc = 0; 2665 10934 sommerfeld } 2666 10934 sommerfeld 2667 10934 sommerfeld return (rc); 2668 10934 sommerfeld } 2669 10934 sommerfeld 2670 10934 sommerfeld /* 2671 3055 danmcd * Returns: 2672 3055 danmcd * 2673 3055 danmcd * SELRET_NOMEM --> msgpullup() needed to gather things failed. 2674 3055 danmcd * SELRET_BADPKT --> If we're being called after tunnel-mode fragment 2675 3055 danmcd * gathering, the initial fragment is too short for 2676 3055 danmcd * useful data. Only returned if SEL_TUNNEL_FIRSTFRAG is 2677 3055 danmcd * set. 2678 3055 danmcd * SELRET_SUCCESS --> "sel" now has initialized IPsec selector data. 2679 3055 danmcd * SELRET_TUNFRAG --> This is a fragment in a tunnel-mode packet. Caller 2680 3055 danmcd * should put this packet in a fragment-gathering queue. 2681 3055 danmcd * Only returned if SEL_TUNNEL_MODE and SEL_PORT_POLICY 2682 3055 danmcd * is set. 2683 11042 Erik * 2684 11042 Erik * Note that ipha/ip6h can be in a different mblk (mp->b_cont) in the case 2685 11042 Erik * of tunneled packets. 2686 11042 Erik * Also, mp->b_rptr can be an ICMP error where ipha/ip6h is the packet in 2687 11042 Erik * error past the ICMP error. 2688 3055 danmcd */ 2689 3055 danmcd static selret_t 2690 3055 danmcd ipsec_init_inbound_sel(ipsec_selector_t *sel, mblk_t *mp, ipha_t *ipha, 2691 3055 danmcd ip6_t *ip6h, uint8_t sel_flags) 2692 3055 danmcd { 2693 3055 danmcd uint16_t *ports; 2694 11042 Erik int outer_hdr_len = 0; /* For ICMP or tunnel-mode cases... */ 2695 3055 danmcd ushort_t hdr_len; 2696 3055 danmcd mblk_t *spare_mp = NULL; 2697 10934 sommerfeld uint8_t *nexthdrp, *transportp; 2698 3055 danmcd uint8_t nexthdr; 2699 10934 sommerfeld uint8_t icmp_proto; 2700 11042 Erik ip_pkt_t ipp; 2701 3055 danmcd boolean_t port_policy_present = (sel_flags & SEL_PORT_POLICY); 2702 3055 danmcd boolean_t is_icmp = (sel_flags & SEL_IS_ICMP); 2703 3055 danmcd boolean_t tunnel_mode = (sel_flags & SEL_TUNNEL_MODE); 2704 10616 Sebastien boolean_t post_frag = (sel_flags & SEL_POST_FRAG); 2705 3055 danmcd 2706 3055 danmcd ASSERT((ipha == NULL && ip6h != NULL) || 2707 3055 danmcd (ipha != NULL && ip6h == NULL)); 2708 3055 danmcd 2709 3055 danmcd if (ip6h != NULL) { 2710 10934 sommerfeld outer_hdr_len = prepended_length(mp, (uintptr_t)ip6h); 2711 10934 sommerfeld nexthdr = ip6h->ip6_nxt; 2712 10934 sommerfeld icmp_proto = IPPROTO_ICMPV6; 2713 3055 danmcd sel->ips_isv4 = B_FALSE; 2714 3055 danmcd sel->ips_local_addr_v6 = ip6h->ip6_dst; 2715 3055 danmcd sel->ips_remote_addr_v6 = ip6h->ip6_src; 2716 3055 danmcd 2717 3055 danmcd bzero(&ipp, sizeof (ipp)); 2718 11042 Erik (void) ip_find_hdr_v6(mp, ip6h, B_FALSE, &ipp, NULL); 2719 3055 danmcd 2720 3055 danmcd switch (nexthdr) { 2721 3055 danmcd case IPPROTO_HOPOPTS: 2722 3055 danmcd case IPPROTO_ROUTING: 2723 3055 danmcd case IPPROTO_DSTOPTS: 2724 3055 danmcd case IPPROTO_FRAGMENT: 2725 3055 danmcd /* 2726 3055 danmcd * Use ip_hdr_length_nexthdr_v6(). And have a spare 2727 3055 danmcd * mblk that's contiguous to feed it 2728 3055 danmcd */ 2729 3055 danmcd if ((spare_mp = msgpullup(mp, -1)) == NULL) 2730 3055 danmcd return (SELRET_NOMEM); 2731 3055 danmcd if (!ip_hdr_length_nexthdr_v6(spare_mp, 2732 3055 danmcd (ip6_t *)(spare_mp->b_rptr + outer_hdr_len), 2733 5245 danmcd &hdr_len, &nexthdrp)) { 2734 3055 danmcd /* Malformed packet - caller frees. */ 2735 3055 danmcd ipsec_freemsg_chain(spare_mp); 2736 3055 danmcd return (SELRET_BADPKT); 2737 3055 danmcd } 2738 3055 danmcd nexthdr = *nexthdrp; 2739 3055 danmcd /* We can just extract based on hdr_len now. */ 2740 3055 danmcd break; 2741 3055 danmcd default: 2742 3055 danmcd hdr_len = IPV6_HDR_LEN; 2743 3055 danmcd break; 2744 3055 danmcd } 2745 3055 danmcd 2746 3055 danmcd if (port_policy_present && IS_V6_FRAGMENT(ipp) && !is_icmp) { 2747 3055 danmcd /* IPv6 Fragment */ 2748 3055 danmcd ipsec_freemsg_chain(spare_mp); 2749 3055 danmcd return (SELRET_TUNFRAG); 2750 3055 danmcd } 2751 10934 sommerfeld transportp = (uint8_t *)ip6h + hdr_len; 2752 10934 sommerfeld } else { 2753 10934 sommerfeld outer_hdr_len = prepended_length(mp, (uintptr_t)ipha); 2754 10934 sommerfeld icmp_proto = IPPROTO_ICMP; 2755 3055 danmcd sel->ips_isv4 = B_TRUE; 2756 3055 danmcd sel->ips_local_addr_v4 = ipha->ipha_dst; 2757 3055 danmcd sel->ips_remote_addr_v4 = ipha->ipha_src; 2758 3055 danmcd nexthdr = ipha->ipha_protocol; 2759 3055 danmcd hdr_len = IPH_HDR_LENGTH(ipha); 2760 3055 danmcd 2761 3055 danmcd if (port_policy_present && 2762 3055 danmcd IS_V4_FRAGMENT(ipha->ipha_fragment_offset_and_flags) && 2763 3055 danmcd !is_icmp) { 2764 3055 danmcd /* IPv4 Fragment */ 2765 3055 danmcd ipsec_freemsg_chain(spare_mp); 2766 3055 danmcd return (SELRET_TUNFRAG); 2767 3055 danmcd } 2768 10934 sommerfeld transportp = (uint8_t *)ipha + hdr_len; 2769 3055 danmcd } 2770 3055 danmcd sel->ips_protocol = nexthdr; 2771 3055 danmcd 2772 3055 danmcd if ((nexthdr != IPPROTO_TCP && nexthdr != IPPROTO_UDP && 2773 10934 sommerfeld nexthdr != IPPROTO_SCTP && nexthdr != icmp_proto) || 2774 10616 Sebastien (!port_policy_present && !post_frag && tunnel_mode)) { 2775 3055 danmcd sel->ips_remote_port = sel->ips_local_port = 0; 2776 3055 danmcd ipsec_freemsg_chain(spare_mp); 2777 3055 danmcd return (SELRET_SUCCESS); 2778 3055 danmcd } 2779 3055 danmcd 2780 10934 sommerfeld if (transportp + 4 > mp->b_wptr) { 2781 3055 danmcd /* If we didn't pullup a copy already, do so now. */ 2782 3055 danmcd /* 2783 3055 danmcd * XXX performance, will upper-layers frequently split TCP/UDP 2784 3055 danmcd * apart from IP or options? If so, perhaps we should revisit 2785 3055 danmcd * the spare_mp strategy. 2786 3055 danmcd */ 2787 3055 danmcd ipsec_hdr_pullup_needed++; 2788 3055 danmcd if (spare_mp == NULL && 2789 3055 danmcd (spare_mp = msgpullup(mp, -1)) == NULL) { 2790 3055 danmcd return (SELRET_NOMEM); 2791 3055 danmcd } 2792 10934 sommerfeld transportp = &spare_mp->b_rptr[hdr_len + outer_hdr_len]; 2793 10934 sommerfeld } 2794 10934 sommerfeld 2795 10934 sommerfeld if (nexthdr == icmp_proto) { 2796 10934 sommerfeld sel->ips_icmp_type = *transportp++; 2797 10934 sommerfeld sel->ips_icmp_code = *transportp; 2798 3055 danmcd sel->ips_remote_port = sel->ips_local_port = 0; 2799 3055 danmcd } else { 2800 10934 sommerfeld ports = (uint16_t *)transportp; 2801 3055 danmcd sel->ips_remote_port = *ports++; 2802 3055 danmcd sel->ips_local_port = *ports; 2803 3055 danmcd } 2804 3055 danmcd ipsec_freemsg_chain(spare_mp); 2805 3055 danmcd return (SELRET_SUCCESS); 2806 3055 danmcd } 2807 3055 danmcd 2808 11042 Erik /* 2809 11042 Erik * This is called with a b_next chain of messages from the fragcache code, 2810 11042 Erik * hence it needs to discard a chain on error. 2811 11042 Erik */ 2812 3055 danmcd static boolean_t 2813 3055 danmcd ipsec_init_outbound_ports(ipsec_selector_t *sel, mblk_t *mp, ipha_t *ipha, 2814 3448 dh155122 ip6_t *ip6h, int outer_hdr_len, ipsec_stack_t *ipss) 2815 3055 danmcd { 2816 3055 danmcd /* 2817 3055 danmcd * XXX cut&paste shared with ipsec_init_inbound_sel 2818 3055 danmcd */ 2819 0 stevel uint16_t *ports; 2820 0 stevel ushort_t hdr_len; 2821 0 stevel mblk_t *spare_mp = NULL; 2822 0 stevel uint8_t *nexthdrp; 2823 0 stevel uint8_t nexthdr; 2824 0 stevel uint8_t *typecode; 2825 0 stevel uint8_t check_proto; 2826 0 stevel 2827 0 stevel ASSERT((ipha == NULL && ip6h != NULL) || 2828 0 stevel (ipha != NULL && ip6h == NULL)); 2829 0 stevel 2830 0 stevel if (ip6h != NULL) { 2831 0 stevel check_proto = IPPROTO_ICMPV6; 2832 0 stevel nexthdr = ip6h->ip6_nxt; 2833 0 stevel switch (nexthdr) { 2834 0 stevel case IPPROTO_HOPOPTS: 2835 0 stevel case IPPROTO_ROUTING: 2836 0 stevel case IPPROTO_DSTOPTS: 2837 3055 danmcd case IPPROTO_FRAGMENT: 2838 0 stevel /* 2839 0 stevel * Use ip_hdr_length_nexthdr_v6(). And have a spare 2840 0 stevel * mblk that's contiguous to feed it 2841 0 stevel */ 2842 3055 danmcd spare_mp = msgpullup(mp, -1); 2843 3055 danmcd if (spare_mp == NULL || 2844 3055 danmcd !ip_hdr_length_nexthdr_v6(spare_mp, 2845 5245 danmcd (ip6_t *)(spare_mp->b_rptr + outer_hdr_len), 2846 5245 danmcd &hdr_len, &nexthdrp)) { 2847 3055 danmcd /* Always works, even if NULL. */ 2848 3055 danmcd ipsec_freemsg_chain(spare_mp); 2849 11042 Erik ip_drop_packet_chain(mp, B_FALSE, NULL, 2850 3448 dh155122 DROPPER(ipss, ipds_spd_nomem), 2851 3448 dh155122 &ipss->ipsec_spd_dropper); 2852 3055 danmcd return (B_FALSE); 2853 3055 danmcd } else { 2854 3055 danmcd nexthdr = *nexthdrp; 2855 3055 danmcd /* We can just extract based on hdr_len now. */ 2856 3055 danmcd } 2857 0 stevel break; 2858 0 stevel default: 2859 0 stevel hdr_len = IPV6_HDR_LEN; 2860 0 stevel break; 2861 0 stevel } 2862 0 stevel } else { 2863 2 pwernau check_proto = IPPROTO_ICMP; 2864 3055 danmcd hdr_len = IPH_HDR_LENGTH(ipha); 2865 0 stevel nexthdr = ipha->ipha_protocol; 2866 3055 danmcd } 2867 3055 danmcd 2868 0 stevel sel->ips_protocol = nexthdr; 2869 0 stevel if (nexthdr != IPPROTO_TCP && nexthdr != IPPROTO_UDP && 2870 0 stevel nexthdr != IPPROTO_SCTP && nexthdr != check_proto) { 2871 3055 danmcd sel->ips_local_port = sel->ips_remote_port = 0; 2872 3055 danmcd ipsec_freemsg_chain(spare_mp); /* Always works, even if NULL */ 2873 0 stevel return (B_TRUE); 2874 0 stevel } 2875 0 stevel 2876 3055 danmcd if (&mp->b_rptr[hdr_len] + 4 + outer_hdr_len > mp->b_wptr) { 2877 0 stevel /* If we didn't pullup a copy already, do so now. */ 2878 0 stevel /* 2879 0 stevel * XXX performance, will upper-layers frequently split TCP/UDP 2880 0 stevel * apart from IP or options? If so, perhaps we should revisit 2881 0 stevel * the spare_mp strategy. 2882 3055 danmcd * 2883 3055 danmcd * XXX should this be msgpullup(mp, hdr_len+4) ??? 2884 3055 danmcd */ 2885 0 stevel if (spare_mp == NULL && 2886 0 stevel (spare_mp = msgpullup(mp, -1)) == NULL) { 2887 11042 Erik ip_drop_packet_chain(mp, B_FALSE, NULL, 2888 3448 dh155122 DROPPER(ipss, ipds_spd_nomem), 2889 3448 dh155122 &ipss->ipsec_spd_dropper); 2890 3055 danmcd return (B_FALSE); 2891 3055 danmcd } 2892 3055 danmcd ports = (uint16_t *)&spare_mp->b_rptr[hdr_len + outer_hdr_len]; 2893 3055 danmcd } else { 2894 3055 danmcd ports = (uint16_t *)&mp->b_rptr[hdr_len + outer_hdr_len]; 2895 0 stevel } 2896 0 stevel 2897 0 stevel if (nexthdr == check_proto) { 2898 0 stevel typecode = (uint8_t *)ports; 2899 0 stevel sel->ips_icmp_type = *typecode++; 2900 0 stevel sel->ips_icmp_code = *typecode; 2901 0 stevel sel->ips_remote_port = sel->ips_local_port = 0; 2902 3055 danmcd } else { 2903 3055 danmcd sel->ips_local_port = *ports++; 2904 3055 danmcd sel->ips_remote_port = *ports; 2905 3055 danmcd } 2906 3055 danmcd ipsec_freemsg_chain(spare_mp); /* Always works, even if NULL */ 2907 0 stevel return (B_TRUE); 2908 0 stevel } 2909 0 stevel 2910 0 stevel /* 2911 11042 Erik * Prepend an mblk with a ipsec_crypto_t to the message chain. 2912 11042 Erik * Frees the argument and returns NULL should the allocation fail. 2913 11042 Erik * Returns the pointer to the crypto data part. 2914 11042 Erik */ 2915 11042 Erik mblk_t * 2916 11042 Erik ipsec_add_crypto_data(mblk_t *data_mp, ipsec_crypto_t **icp) 2917 11042 Erik { 2918 11042 Erik mblk_t *mp; 2919 11042 Erik 2920 11042 Erik mp = allocb(sizeof (ipsec_crypto_t), BPRI_MED); 2921 11042 Erik if (mp == NULL) { 2922 11042 Erik freemsg(data_mp); 2923 11042 Erik return (NULL); 2924 11042 Erik } 2925 11042 Erik bzero(mp->b_rptr, sizeof (ipsec_crypto_t)); 2926 11042 Erik mp->b_wptr += sizeof (ipsec_crypto_t); 2927 11042 Erik mp->b_cont = data_mp; 2928 11042 Erik mp->b_datap->db_type = M_EVENT; /* For ASSERT */ 2929 11042 Erik *icp = (ipsec_crypto_t *)mp->b_rptr; 2930 11042 Erik return (mp); 2931 11042 Erik } 2932 11042 Erik 2933 11042 Erik /* 2934 11042 Erik * Remove what was prepended above. Return b_cont and a pointer to the 2935 11042 Erik * crypto data. 2936 11042 Erik * The caller must call ipsec_free_crypto_data for mblk once it is done 2937 11042 Erik * with the crypto data. 2938 11042 Erik */ 2939 11042 Erik mblk_t * 2940 11042 Erik ipsec_remove_crypto_data(mblk_t *crypto_mp, ipsec_crypto_t **icp) 2941 11042 Erik { 2942 11042 Erik ASSERT(crypto_mp->b_datap->db_type == M_EVENT); 2943 11042 Erik ASSERT(MBLKL(crypto_mp) == sizeof (ipsec_crypto_t)); 2944 11042 Erik 2945 11042 Erik *icp = (ipsec_crypto_t *)crypto_mp->b_rptr; 2946 11042 Erik return (crypto_mp->b_cont); 2947 11042 Erik } 2948 11042 Erik 2949 11042 Erik /* 2950 11042 Erik * Free what was prepended above. Return b_cont. 2951 11042 Erik */ 2952 11042 Erik mblk_t * 2953 11042 Erik ipsec_free_crypto_data(mblk_t *crypto_mp) 2954 11042 Erik { 2955 11042 Erik mblk_t *mp; 2956 11042 Erik 2957 11042 Erik ASSERT(crypto_mp->b_datap->db_type == M_EVENT); 2958 11042 Erik ASSERT(MBLKL(crypto_mp) == sizeof (ipsec_crypto_t)); 2959 11042 Erik 2960 11042 Erik mp = crypto_mp->b_cont; 2961 11042 Erik freeb(crypto_mp); 2962 11042 Erik return (mp); 2963 11042 Erik } 2964 11042 Erik 2965 11042 Erik /* 2966 0 stevel * Create an ipsec_action_t based on the way an inbound packet was protected. 2967 0 stevel * Used to reflect traffic back to a sender. 2968 0 stevel * 2969 0 stevel * We don't bother interning the action into the hash table. 2970 0 stevel */ 2971 0 stevel ipsec_action_t * 2972 11042 Erik ipsec_in_to_out_action(ip_recv_attr_t *ira) 2973 0 stevel { 2974 0 stevel ipsa_t *ah_assoc, *esp_assoc; 2975 0 stevel uint_t auth_alg = 0, encr_alg = 0, espa_alg = 0; 2976 0 stevel ipsec_action_t *ap; 2977 0 stevel boolean_t unique; 2978 0 stevel 2979 0 stevel ap = kmem_cache_alloc(ipsec_action_cache, KM_NOSLEEP); 2980 0 stevel 2981 0 stevel if (ap == NULL) 2982 0 stevel return (NULL); 2983 0 stevel 2984 0 stevel bzero(ap, sizeof (*ap)); 2985 81 sommerfe HASH_NULL(ap, ipa_hash); 2986 0 stevel ap->ipa_next = NULL; 2987 0 stevel ap->ipa_refs = 1; 2988 0 stevel 2989 0 stevel /* 2990 0 stevel * Get the algorithms that were used for this packet. 2991 0 stevel */ 2992 0 stevel ap->ipa_act.ipa_type = IPSEC_ACT_APPLY; 2993 0 stevel ap->ipa_act.ipa_log = 0; 2994 11042 Erik ASSERT(ira->ira_flags & IRAF_IPSEC_SECURE); 2995 11042 Erik 2996 11042 Erik ah_assoc = ira->ira_ipsec_ah_sa; 2997 0 stevel ap->ipa_act.ipa_apply.ipp_use_ah = (ah_assoc != NULL); 2998 0 stevel 2999 11042 Erik esp_assoc = ira->ira_ipsec_esp_sa; 3000 0 stevel ap->ipa_act.ipa_apply.ipp_use_esp = (esp_assoc != NULL); 3001 0 stevel 3002 0 stevel if (esp_assoc != NULL) { 3003 0 stevel encr_alg = esp_assoc->ipsa_encr_alg; 3004 0 stevel espa_alg = esp_assoc->ipsa_auth_alg; 3005 0 stevel ap->ipa_act.ipa_apply.ipp_use_espa = (espa_alg != 0); 3006 0 stevel } 3007 0 stevel if (ah_assoc != NULL) 3008 0 stevel auth_alg = ah_assoc->ipsa_auth_alg; 3009 0 stevel 3010 0 stevel ap->ipa_act.ipa_apply.ipp_encr_alg = (uint8_t)encr_alg; 3011 0 stevel ap->ipa_act.ipa_apply.ipp_auth_alg = (uint8_t)auth_alg; 3012 0 stevel ap->ipa_act.ipa_apply.ipp_esp_auth_alg = (uint8_t)espa_alg; 3013 11042 Erik ap->ipa_act.ipa_apply.ipp_use_se = 3014 11042 Erik !!(ira->ira_flags & IRAF_IPSEC_DECAPS); 3015 0 stevel unique = B_FALSE; 3016 0 stevel 3017 0 stevel if (esp_assoc != NULL) { 3018 0 stevel ap->ipa_act.ipa_apply.ipp_espa_minbits = 3019 0 stevel esp_assoc->