1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  * Copyright (c) 2012 Nexenta Systems, Inc. All rights reserved.
  25  */
  26 
  27 #include <sys/types.h>
  28 #include <sys/stream.h>
  29 #include <sys/stropts.h>
  30 #include <sys/strsubr.h>
  31 #include <sys/errno.h>
  32 #include <sys/ddi.h>
  33 #include <sys/debug.h>
  34 #include <sys/cmn_err.h>
  35 #include <sys/stream.h>
  36 #include <sys/strlog.h>
  37 #include <sys/kmem.h>
  38 #include <sys/sunddi.h>
  39 #include <sys/tihdr.h>
  40 #include <sys/atomic.h>
  41 #include <sys/socket.h>
  42 #include <sys/sysmacros.h>
  43 #include <sys/crypto/common.h>
  44 #include <sys/crypto/api.h>
  45 #include <sys/zone.h>
  46 #include <netinet/in.h>
  47 #include <net/if.h>
  48 #include <net/pfkeyv2.h>
  49 #include <net/pfpolicy.h>
  50 #include <inet/common.h>
  51 #include <netinet/ip6.h>
  52 #include <inet/ip.h>
  53 #include <inet/ip_ire.h>
  54 #include <inet/ip6.h>
  55 #include <inet/ipsec_info.h>
  56 #include <inet/tcp.h>
  57 #include <inet/sadb.h>
  58 #include <inet/ipsec_impl.h>
  59 #include <inet/ipsecah.h>
  60 #include <inet/ipsecesp.h>
  61 #include <sys/random.h>
  62 #include <sys/dlpi.h>
  63 #include <sys/strsun.h>
  64 #include <sys/strsubr.h>
  65 #include <inet/ip_if.h>
  66 #include <inet/ipdrop.h>
  67 #include <inet/ipclassifier.h>
  68 #include <inet/sctp_ip.h>
  69 #include <sys/tsol/tnet.h>
  70 
  71 /*
  72  * This source file contains Security Association Database (SADB) common
  73  * routines.  They are linked in with the AH module.  Since AH has no chance
  74  * of falling under export control, it was safe to link it in there.
  75  */
  76 static ipsa_t *sadb_torch_assoc(isaf_t *, ipsa_t *);
  77 static void sadb_destroy_acqlist(iacqf_t **, uint_t, boolean_t,
  78                             netstack_t *);
  79 static void sadb_destroy(sadb_t *, netstack_t *);
  80 static mblk_t *sadb_sa2msg(ipsa_t *, sadb_msg_t *);
  81 static ts_label_t *sadb_label_from_sens(sadb_sens_t *, uint64_t *);
  82 static sadb_sens_t *sadb_make_sens_ext(ts_label_t *tsl, int *len);
  83 /* Args named here, as the booleans can be hard to distinguish */
  84 static mblk_t *sadb_construct_acqmsg(ipsacq_t *acqrec, ipsec_selector_t *sel,
  85     ipsec_action_t *ap, ipsec_policy_t *pp, netstack_t *ns, sadb_sens_t *sens,
  86     boolean_t need_esp, boolean_t tunnel_mode, boolean_t extended,
  87     boolean_t with_prop);
  88 static uint8_t *sadb_construct_eprop(const ipsec_action_t *,
  89     const ipsec_policy_t *, netstack_t *, const uint8_t *, const uint8_t *);
  90 static void sadb_insert_prop(sadb_prop_t *, const ipsec_action_t *,
  91     netstack_t *, uint_t, boolean_t);
  92 
  93 static time_t sadb_add_time(time_t, uint64_t);
  94 static void lifetime_fuzz(ipsa_t *);
  95 static void age_pair_peer_list(templist_t *, sadb_t *, boolean_t);
  96 static int get_ipsa_pair(ipsa_query_t *, ipsap_t *, int *);
  97 static void init_ipsa_pair(ipsap_t *);
  98 static void destroy_ipsa_pair(ipsap_t *);
  99 static int update_pairing(ipsap_t *, ipsa_query_t *, keysock_in_t *, int *);
 100 static void ipsa_set_replay(ipsa_t *ipsa, uint32_t offset);
 101 
 102 /*
 103  * ipsacq_maxpackets is defined here to make it tunable
 104  * from /etc/system.
 105  */
 106 extern uint64_t ipsacq_maxpackets;
 107 
 108 /*
 109  * Allocation size for sin_t/sin6_t in address extensions. We allocate IPv6
 110  * because it's the larger of the two, and we roundup because the type isn't
 111  * defined to guarantee 64-bit alignment.
 112  */
 113 #define SADB_SOCKADDR_SIZE      (roundup(sizeof (sin6_t), sizeof (uint64_t)))
 114 
 115 #define SET_EXPIRE(sa, delta, exp) {                            \
 116         if (((sa)->ipsa_ ## delta) != 0) {                           \
 117                 (sa)->ipsa_ ## exp = sadb_add_time((sa)->ipsa_addtime,    \
 118                         (sa)->ipsa_ ## delta);                               \
 119         }                                                               \
 120 }
 121 
 122 #define UPDATE_EXPIRE(sa, delta, exp) {                                 \
 123         if (((sa)->ipsa_ ## delta) != 0) {                           \
 124                 time_t tmp = sadb_add_time((sa)->ipsa_usetime,               \
 125                         (sa)->ipsa_ ## delta);                               \
 126                 if (((sa)->ipsa_ ## exp) == 0)                               \
 127                         (sa)->ipsa_ ## exp = tmp;                    \
 128                 else                                                    \
 129                         (sa)->ipsa_ ## exp =                                 \
 130                             MIN((sa)->ipsa_ ## exp, tmp);            \
 131         }                                                               \
 132 }
 133 
 134 /* Warning: watch for evaluation issues with complex args */
 135 #define INITIALIZE_SAMSG(samsg, type)           \
 136         (samsg)->sadb_msg_version = PF_KEY_V2,       \
 137         (samsg)->sadb_msg_type = (type),     \
 138         (samsg)->sadb_msg_errno = 0,         \
 139         (samsg)->sadb_msg_reserved = 0
 140 
 141 /* Warning: watch for evaluation issues with complex args */
 142 #define ERRNO_SAMSG(samsg, errno)                               \
 143         (samsg)->sadb_msg_len = SADB_8TO64(sizeof (*samsg)), \
 144         (samsg)->sadb_msg_errno = (errno),                   \
 145         (samsg)->sadb_x_msg_diagnostic = 0
 146 
 147 /*
 148  * Warning: watch for evaluation issues with complex args. This is a rough,
 149  * conservative calculation (e.g. combined mode encr algs can perform both
 150  * encr/auth and ipsecconf drops auth algs in combinations). This is
 151  * nevertheless reasonable, given that the kernel doesn't make or guarantee
 152  * optimizations reducing the combination space.
 153  */
 154 #define CALC_COMBS(limit, ipss, need_esp)               {       \
 155         limit = (need_esp) ?                                    \
 156             (ipss)->ipsec_nalgs[IPSEC_ALG_AUTH] *            \
 157             (ipss)->ipsec_nalgs[IPSEC_ALG_ENCR]                      \
 158             : (ipss)->ipsec_nalgs[IPSEC_ALG_AUTH];           \
 159         ASSERT((limit) > 0);                                 \
 160 }
 161 
 162 /* wrap the macro so we can pass it as a function pointer */
 163 void
 164 sadb_sa_refrele(void *target)
 165 {
 166         IPSA_REFRELE(((ipsa_t *)target));
 167 }
 168 
 169 /*
 170  * We presume that sizeof (long) == sizeof (time_t) and that time_t is
 171  * a signed type.
 172  */
 173 #define TIME_MAX LONG_MAX
 174 
 175 /*
 176  * PF_KEY gives us lifetimes in uint64_t seconds.  We presume that
 177  * time_t is defined to be a signed type with the same range as
 178  * "long".  On ILP32 systems, we thus run the risk of wrapping around
 179  * at end of time, as well as "overwrapping" the clock back around
 180  * into a seemingly valid but incorrect future date earlier than the
 181  * desired expiration.
 182  *
 183  * In order to avoid odd behavior (either negative lifetimes or loss
 184  * of high order bits) when someone asks for bizarrely long SA
 185  * lifetimes, we do a saturating add for expire times.
 186  *
 187  * We presume that ILP32 systems will be past end of support life when
 188  * the 32-bit time_t overflows (a dangerous assumption, mind you..).
 189  *
 190  * On LP64, 2^64 seconds are about 5.8e11 years, at which point we
 191  * will hopefully have figured out clever ways to avoid the use of
 192  * fixed-sized integers in computation.
 193  */
 194 static time_t
 195 sadb_add_time(time_t base, uint64_t delta)
 196 {
 197         time_t sum;
 198 
 199         /*
 200          * Clip delta to the maximum possible time_t value to
 201          * prevent "overwrapping" back into a shorter-than-desired
 202          * future time.
 203          */
 204         if (delta > TIME_MAX)
 205                 delta = TIME_MAX;
 206         /*
 207          * This sum may still overflow.
 208          */
 209         sum = base + delta;
 210 
 211         /*
 212          * .. so if the result is less than the base, we overflowed.
 213          */
 214         if (sum < base)
 215                 sum = TIME_MAX;
 216 
 217         return (sum);
 218 }
 219 
 220 /*
 221  * Callers of this function have already created a working security
 222  * association, and have found the appropriate table & hash chain.  All this
 223  * function does is check duplicates, and insert the SA.  The caller needs to
 224  * hold the hash bucket lock and increment the refcnt before insertion.
 225  *
 226  * Return 0 if success, EEXIST if collision.
 227  */
 228 #define SA_UNIQUE_MATCH(sa1, sa2) \
 229         (((sa1)->ipsa_unique_id & (sa1)->ipsa_unique_mask) == \
 230         ((sa2)->ipsa_unique_id & (sa2)->ipsa_unique_mask))
 231 
 232 int
 233 sadb_insertassoc(ipsa_t *ipsa, isaf_t *bucket)
 234 {
 235         ipsa_t **ptpn = NULL;
 236         ipsa_t *walker;
 237         boolean_t unspecsrc;
 238 
 239         ASSERT(MUTEX_HELD(&bucket->isaf_lock));
 240 
 241         unspecsrc = IPSA_IS_ADDR_UNSPEC(ipsa->ipsa_srcaddr, ipsa->ipsa_addrfam);
 242 
 243         walker = bucket->isaf_ipsa;
 244         ASSERT(walker == NULL || ipsa->ipsa_addrfam == walker->ipsa_addrfam);
 245 
 246         /*
 247          * Find insertion point (pointed to with **ptpn).  Insert at the head
 248          * of the list unless there's an unspecified source address, then
 249          * insert it after the last SA with a specified source address.
 250          *
 251          * BTW, you'll have to walk the whole chain, matching on {DST, SPI}
 252          * checking for collisions.
 253          */
 254 
 255         while (walker != NULL) {
 256                 if (IPSA_ARE_ADDR_EQUAL(walker->ipsa_dstaddr,
 257                     ipsa->ipsa_dstaddr, ipsa->ipsa_addrfam)) {
 258                         if (walker->ipsa_spi == ipsa->ipsa_spi)
 259                                 return (EEXIST);
 260 
 261                         mutex_enter(&walker->ipsa_lock);
 262                         if (ipsa->ipsa_state == IPSA_STATE_MATURE &&
 263                             (walker->ipsa_flags & IPSA_F_USED) &&
 264                             SA_UNIQUE_MATCH(walker, ipsa)) {
 265                                 walker->ipsa_flags |= IPSA_F_CINVALID;
 266                         }
 267                         mutex_exit(&walker->ipsa_lock);
 268                 }
 269 
 270                 if (ptpn == NULL && unspecsrc) {
 271                         if (IPSA_IS_ADDR_UNSPEC(walker->ipsa_srcaddr,
 272                             walker->ipsa_addrfam))
 273                                 ptpn = walker->ipsa_ptpn;
 274                         else if (walker->ipsa_next == NULL)
 275                                 ptpn = &walker->ipsa_next;
 276                 }
 277 
 278                 walker = walker->ipsa_next;
 279         }
 280 
 281         if (ptpn == NULL)
 282                 ptpn = &bucket->isaf_ipsa;
 283         ipsa->ipsa_next = *ptpn;
 284         ipsa->ipsa_ptpn = ptpn;
 285         if (ipsa->ipsa_next != NULL)
 286                 ipsa->ipsa_next->ipsa_ptpn = &ipsa->ipsa_next;
 287         *ptpn = ipsa;
 288         ipsa->ipsa_linklock = &bucket->isaf_lock;
 289 
 290         return (0);
 291 }
 292 #undef SA_UNIQUE_MATCH
 293 
 294 /*
 295  * Free a security association.  Its reference count is 0, which means
 296  * I must free it.  The SA must be unlocked and must not be linked into
 297  * any fanout list.
 298  */
 299 static void
 300 sadb_freeassoc(ipsa_t *ipsa)
 301 {
 302         ipsec_stack_t   *ipss = ipsa->ipsa_netstack->netstack_ipsec;
 303         mblk_t          *asyncmp, *mp;
 304 
 305         ASSERT(ipss != NULL);
 306         ASSERT(MUTEX_NOT_HELD(&ipsa->ipsa_lock));
 307         ASSERT(ipsa->ipsa_refcnt == 0);
 308         ASSERT(ipsa->ipsa_next == NULL);
 309         ASSERT(ipsa->ipsa_ptpn == NULL);
 310 
 311 
 312         asyncmp = sadb_clear_lpkt(ipsa);
 313         if (asyncmp != NULL) {
 314                 mp = ip_recv_attr_free_mblk(asyncmp);
 315                 ip_drop_packet(mp, B_TRUE, NULL,
 316                     DROPPER(ipss, ipds_sadb_inlarval_timeout),
 317                     &ipss->ipsec_sadb_dropper);
 318         }
 319         mutex_enter(&ipsa->ipsa_lock);
 320 
 321         if (ipsa->ipsa_tsl != NULL) {
 322                 label_rele(ipsa->ipsa_tsl);
 323                 ipsa->ipsa_tsl = NULL;
 324         }
 325 
 326         if (ipsa->ipsa_otsl != NULL) {
 327                 label_rele(ipsa->ipsa_otsl);
 328                 ipsa->ipsa_otsl = NULL;
 329         }
 330 
 331         ipsec_destroy_ctx_tmpl(ipsa, IPSEC_ALG_AUTH);
 332         ipsec_destroy_ctx_tmpl(ipsa, IPSEC_ALG_ENCR);
 333         mutex_exit(&ipsa->ipsa_lock);
 334 
 335         /* bzero() these fields for paranoia's sake. */
 336         if (ipsa->ipsa_authkey != NULL) {
 337                 bzero(ipsa->ipsa_authkey, ipsa->ipsa_authkeylen);
 338                 kmem_free(ipsa->ipsa_authkey, ipsa->ipsa_authkeylen);
 339         }
 340         if (ipsa->ipsa_encrkey != NULL) {
 341                 bzero(ipsa->ipsa_encrkey, ipsa->ipsa_encrkeylen);
 342                 kmem_free(ipsa->ipsa_encrkey, ipsa->ipsa_encrkeylen);
 343         }
 344         if (ipsa->ipsa_nonce_buf != NULL) {
 345                 bzero(ipsa->ipsa_nonce_buf, sizeof (ipsec_nonce_t));
 346                 kmem_free(ipsa->ipsa_nonce_buf, sizeof (ipsec_nonce_t));
 347         }
 348         if (ipsa->ipsa_src_cid != NULL) {
 349                 IPSID_REFRELE(ipsa->ipsa_src_cid);
 350         }
 351         if (ipsa->ipsa_dst_cid != NULL) {
 352                 IPSID_REFRELE(ipsa->ipsa_dst_cid);
 353         }
 354         if (ipsa->ipsa_emech.cm_param != NULL)
 355                 kmem_free(ipsa->ipsa_emech.cm_param,
 356                     ipsa->ipsa_emech.cm_param_len);
 357 
 358         mutex_destroy(&ipsa->ipsa_lock);
 359         kmem_free(ipsa, sizeof (*ipsa));
 360 }
 361 
 362 /*
 363  * Unlink a security association from a hash bucket.  Assume the hash bucket
 364  * lock is held, but the association's lock is not.
 365  *
 366  * Note that we do not bump the bucket's generation number here because
 367  * we might not be making a visible change to the set of visible SA's.
 368  * All callers MUST bump the bucket's generation number before they unlock
 369  * the bucket if they use sadb_unlinkassoc to permanetly remove an SA which
 370  * was present in the bucket at the time it was locked.
 371  */
 372 void
 373 sadb_unlinkassoc(ipsa_t *ipsa)
 374 {
 375         ASSERT(ipsa->ipsa_linklock != NULL);
 376         ASSERT(MUTEX_HELD(ipsa->ipsa_linklock));
 377 
 378         /* These fields are protected by the link lock. */
 379         *(ipsa->ipsa_ptpn) = ipsa->ipsa_next;
 380         if (ipsa->ipsa_next != NULL) {
 381                 ipsa->ipsa_next->ipsa_ptpn = ipsa->ipsa_ptpn;
 382                 ipsa->ipsa_next = NULL;
 383         }
 384 
 385         ipsa->ipsa_ptpn = NULL;
 386 
 387         /* This may destroy the SA. */
 388         IPSA_REFRELE(ipsa);
 389 }
 390 
 391 void
 392 sadb_delete_cluster(ipsa_t *assoc)
 393 {
 394         uint8_t protocol;
 395 
 396         if (cl_inet_deletespi &&
 397             ((assoc->ipsa_state == IPSA_STATE_LARVAL) ||
 398             (assoc->ipsa_state == IPSA_STATE_MATURE))) {
 399                 protocol = (assoc->ipsa_type == SADB_SATYPE_AH) ?
 400                     IPPROTO_AH : IPPROTO_ESP;
 401                 cl_inet_deletespi(assoc->ipsa_netstack->netstack_stackid,
 402                     protocol, assoc->ipsa_spi, NULL);
 403         }
 404 }
 405 
 406 /*
 407  * Create a larval security association with the specified SPI.  All other
 408  * fields are zeroed.
 409  */
 410 static ipsa_t *
 411 sadb_makelarvalassoc(uint32_t spi, uint32_t *src, uint32_t *dst, int addrfam,
 412     netstack_t *ns)
 413 {
 414         ipsa_t *newbie;
 415 
 416         /*
 417          * Allocate...
 418          */
 419 
 420         newbie = (ipsa_t *)kmem_zalloc(sizeof (ipsa_t), KM_NOSLEEP);
 421         if (newbie == NULL) {
 422                 /* Can't make new larval SA. */
 423                 return (NULL);
 424         }
 425 
 426         /* Assigned requested SPI, assume caller does SPI allocation magic. */
 427         newbie->ipsa_spi = spi;
 428         newbie->ipsa_netstack = ns;  /* No netstack_hold */
 429 
 430         /*
 431          * Copy addresses...
 432          */
 433 
 434         IPSA_COPY_ADDR(newbie->ipsa_srcaddr, src, addrfam);
 435         IPSA_COPY_ADDR(newbie->ipsa_dstaddr, dst, addrfam);
 436 
 437         newbie->ipsa_addrfam = addrfam;
 438 
 439         /*
 440          * Set common initialization values, including refcnt.
 441          */
 442         mutex_init(&newbie->ipsa_lock, NULL, MUTEX_DEFAULT, NULL);
 443         newbie->ipsa_state = IPSA_STATE_LARVAL;
 444         newbie->ipsa_refcnt = 1;
 445         newbie->ipsa_freefunc = sadb_freeassoc;
 446 
 447         /*
 448          * There aren't a lot of other common initialization values, as
 449          * they are copied in from the PF_KEY message.
 450          */
 451 
 452         return (newbie);
 453 }
 454 
 455 /*
 456  * Call me to initialize a security association fanout.
 457  */
 458 static int
 459 sadb_init_fanout(isaf_t **tablep, uint_t size, int kmflag)
 460 {
 461         isaf_t *table;
 462         int i;
 463 
 464         table = (isaf_t *)kmem_alloc(size * sizeof (*table), kmflag);
 465         *tablep = table;
 466 
 467         if (table == NULL)
 468                 return (ENOMEM);
 469 
 470         for (i = 0; i < size; i++) {
 471                 mutex_init(&(table[i].isaf_lock), NULL, MUTEX_DEFAULT, NULL);
 472                 table[i].isaf_ipsa = NULL;
 473                 table[i].isaf_gen = 0;
 474         }
 475 
 476         return (0);
 477 }
 478 
 479 /*
 480  * Call me to initialize an acquire fanout
 481  */
 482 static int
 483 sadb_init_acfanout(iacqf_t **tablep, uint_t size, int kmflag)
 484 {
 485         iacqf_t *table;
 486         int i;
 487 
 488         table = (iacqf_t *)kmem_alloc(size * sizeof (*table), kmflag);
 489         *tablep = table;
 490 
 491         if (table == NULL)
 492                 return (ENOMEM);
 493 
 494         for (i = 0; i < size; i++) {
 495                 mutex_init(&(table[i].iacqf_lock), NULL, MUTEX_DEFAULT, NULL);
 496                 table[i].iacqf_ipsacq = NULL;
 497         }
 498 
 499         return (0);
 500 }
 501 
 502 /*
 503  * Attempt to initialize an SADB instance.  On failure, return ENOMEM;
 504  * caller must clean up partial allocations.
 505  */
 506 static int
 507 sadb_init_trial(sadb_t *sp, uint_t size, int kmflag)
 508 {
 509         ASSERT(sp->sdb_of == NULL);
 510         ASSERT(sp->sdb_if == NULL);
 511         ASSERT(sp->sdb_acq == NULL);
 512 
 513         sp->sdb_hashsize = size;
 514         if (sadb_init_fanout(&sp->sdb_of, size, kmflag) != 0)
 515                 return (ENOMEM);
 516         if (sadb_init_fanout(&sp->sdb_if, size, kmflag) != 0)
 517                 return (ENOMEM);
 518         if (sadb_init_acfanout(&sp->sdb_acq, size, kmflag) != 0)
 519                 return (ENOMEM);
 520 
 521         return (0);
 522 }
 523 
 524 /*
 525  * Call me to initialize an SADB instance; fall back to default size on failure.
 526  */
 527 static void
 528 sadb_init(const char *name, sadb_t *sp, uint_t size, uint_t ver,
 529     netstack_t *ns)
 530 {
 531         ASSERT(sp->sdb_of == NULL);
 532         ASSERT(sp->sdb_if == NULL);
 533         ASSERT(sp->sdb_acq == NULL);
 534 
 535         if (size < IPSEC_DEFAULT_HASH_SIZE)
 536                 size = IPSEC_DEFAULT_HASH_SIZE;
 537 
 538         if (sadb_init_trial(sp, size, KM_NOSLEEP) != 0) {
 539 
 540                 cmn_err(CE_WARN,
 541                     "Unable to allocate %u entry IPv%u %s SADB hash table",
 542                     size, ver, name);
 543 
 544                 sadb_destroy(sp, ns);
 545                 size = IPSEC_DEFAULT_HASH_SIZE;
 546                 cmn_err(CE_WARN, "Falling back to %d entries", size);
 547                 (void) sadb_init_trial(sp, size, KM_SLEEP);
 548         }
 549 }
 550 
 551 
 552 /*
 553  * Initialize an SADB-pair.
 554  */
 555 void
 556 sadbp_init(const char *name, sadbp_t *sp, int type, int size, netstack_t *ns)
 557 {
 558         sadb_init(name, &sp->s_v4, size, 4, ns);
 559         sadb_init(name, &sp->s_v6, size, 6, ns);
 560 
 561         sp->s_satype = type;
 562 
 563         ASSERT((type == SADB_SATYPE_AH) || (type == SADB_SATYPE_ESP));
 564         if (type == SADB_SATYPE_AH) {
 565                 ipsec_stack_t   *ipss = ns->netstack_ipsec;
 566 
 567                 ip_drop_register(&ipss->ipsec_sadb_dropper, "IPsec SADB");
 568                 sp->s_addflags = AH_ADD_SETTABLE_FLAGS;
 569                 sp->s_updateflags = AH_UPDATE_SETTABLE_FLAGS;
 570         } else {
 571                 sp->s_addflags = ESP_ADD_SETTABLE_FLAGS;
 572                 sp->s_updateflags = ESP_UPDATE_SETTABLE_FLAGS;
 573         }
 574 }
 575 
 576 /*
 577  * Deliver a single SADB_DUMP message representing a single SA.  This is
 578  * called many times by sadb_dump().
 579  *
 580  * If the return value of this is ENOBUFS (not the same as ENOMEM), then
 581  * the caller should take that as a hint that dupb() on the "original answer"
 582  * failed, and that perhaps the caller should try again with a copyb()ed
 583  * "original answer".
 584  */
 585 static int
 586 sadb_dump_deliver(queue_t *pfkey_q, mblk_t *original_answer, ipsa_t *ipsa,
 587     sadb_msg_t *samsg)
 588 {
 589         mblk_t *answer;
 590 
 591         answer = dupb(original_answer);
 592         if (answer == NULL)
 593                 return (ENOBUFS);
 594         answer->b_cont = sadb_sa2msg(ipsa, samsg);
 595         if (answer->b_cont == NULL) {
 596                 freeb(answer);
 597                 return (ENOMEM);
 598         }
 599 
 600         /* Just do a putnext, and let keysock deal with flow control. */
 601         putnext(pfkey_q, answer);
 602         return (0);
 603 }
 604 
 605 /*
 606  * Common function to allocate and prepare a keysock_out_t M_CTL message.
 607  */
 608 mblk_t *
 609 sadb_keysock_out(minor_t serial)
 610 {
 611         mblk_t *mp;
 612         keysock_out_t *kso;
 613 
 614         mp = allocb(sizeof (ipsec_info_t), BPRI_HI);
 615         if (mp != NULL) {
 616                 mp->b_datap->db_type = M_CTL;
 617                 mp->b_wptr += sizeof (ipsec_info_t);
 618                 kso = (keysock_out_t *)mp->b_rptr;
 619                 kso->ks_out_type = KEYSOCK_OUT;
 620                 kso->ks_out_len = sizeof (*kso);
 621                 kso->ks_out_serial = serial;
 622         }
 623 
 624         return (mp);
 625 }
 626 
 627 /*
 628  * Perform an SADB_DUMP, spewing out every SA in an array of SA fanouts
 629  * to keysock.
 630  */
 631 static int
 632 sadb_dump_fanout(queue_t *pfkey_q, mblk_t *mp, minor_t serial, isaf_t *fanout,
 633     int num_entries, boolean_t do_peers, time_t active_time)
 634 {
 635         int i, error = 0;
 636         mblk_t *original_answer;
 637         ipsa_t *walker;
 638         sadb_msg_t *samsg;
 639         time_t  current;
 640 
 641         /*
 642          * For each IPSA hash bucket do:
 643          *      - Hold the mutex
 644          *      - Walk each entry, doing an sadb_dump_deliver() on it.
 645          */
 646         ASSERT(mp->b_cont != NULL);
 647         samsg = (sadb_msg_t *)mp->b_cont->b_rptr;
 648 
 649         original_answer = sadb_keysock_out(serial);
 650         if (original_answer == NULL)
 651                 return (ENOMEM);
 652 
 653         current = gethrestime_sec();
 654         for (i = 0; i < num_entries; i++) {
 655                 mutex_enter(&fanout[i].isaf_lock);
 656                 for (walker = fanout[i].isaf_ipsa; walker != NULL;
 657                     walker = walker->ipsa_next) {
 658                         if (!do_peers && walker->ipsa_haspeer)
 659                                 continue;
 660                         if ((active_time != 0) &&
 661                             ((current - walker->ipsa_lastuse) > active_time))
 662                                 continue;
 663                         error = sadb_dump_deliver(pfkey_q, original_answer,
 664                             walker, samsg);
 665                         if (error == ENOBUFS) {
 666                                 mblk_t *new_original_answer;
 667 
 668                                 /* Ran out of dupb's.  Try a copyb. */
 669                                 new_original_answer = copyb(original_answer);
 670                                 if (new_original_answer == NULL) {
 671                                         error = ENOMEM;
 672                                 } else {
 673                                         freeb(original_answer);
 674                                         original_answer = new_original_answer;
 675                                         error = sadb_dump_deliver(pfkey_q,
 676                                             original_answer, walker, samsg);
 677                                 }
 678                         }
 679                         if (error != 0)
 680                                 break;  /* out of for loop. */
 681                 }
 682                 mutex_exit(&fanout[i].isaf_lock);
 683                 if (error != 0)
 684                         break;  /* out of for loop. */
 685         }
 686 
 687         freeb(original_answer);
 688         return (error);
 689 }
 690 
 691 /*
 692  * Dump an entire SADB; outbound first, then inbound.
 693  */
 694 
 695 int
 696 sadb_dump(queue_t *pfkey_q, mblk_t *mp, keysock_in_t *ksi, sadb_t *sp)
 697 {
 698         int error;
 699         time_t  active_time = 0;
 700         sadb_x_edump_t  *edump =
 701             (sadb_x_edump_t *)ksi->ks_in_extv[SADB_X_EXT_EDUMP];
 702 
 703         if (edump != NULL) {
 704                 active_time = edump->sadb_x_edump_timeout;
 705         }
 706 
 707         /* Dump outbound */
 708         error = sadb_dump_fanout(pfkey_q, mp, ksi->ks_in_serial, sp->sdb_of,
 709             sp->sdb_hashsize, B_TRUE, active_time);
 710         if (error)
 711                 return (error);
 712 
 713         /* Dump inbound */
 714         return sadb_dump_fanout(pfkey_q, mp, ksi->ks_in_serial, sp->sdb_if,
 715             sp->sdb_hashsize, B_FALSE, active_time);
 716 }
 717 
 718 /*
 719  * Generic sadb table walker.
 720  *
 721  * Call "walkfn" for each SA in each bucket in "table"; pass the
 722  * bucket, the entry and "cookie" to the callback function.
 723  * Take care to ensure that walkfn can delete the SA without screwing
 724  * up our traverse.
 725  *
 726  * The bucket is locked for the duration of the callback, both so that the
 727  * callback can just call sadb_unlinkassoc() when it wants to delete something,
 728  * and so that no new entries are added while we're walking the list.
 729  */
 730 static void
 731 sadb_walker(isaf_t *table, uint_t numentries,
 732     void (*walkfn)(isaf_t *head, ipsa_t *entry, void *cookie),
 733     void *cookie)
 734 {
 735         int i;
 736         for (i = 0; i < numentries; i++) {
 737                 ipsa_t *entry, *next;
 738 
 739                 mutex_enter(&table[i].isaf_lock);
 740 
 741                 for (entry = table[i].isaf_ipsa; entry != NULL;
 742                     entry = next) {
 743                         next = entry->ipsa_next;
 744                         (*walkfn)(&table[i], entry, cookie);
 745                 }
 746                 mutex_exit(&table[i].isaf_lock);
 747         }
 748 }
 749 
 750 /*
 751  * Call me to free up a security association fanout.  Use the forever
 752  * variable to indicate freeing up the SAs (forever == B_FALSE, e.g.
 753  * an SADB_FLUSH message), or destroying everything (forever == B_TRUE,
 754  * when a module is unloaded).
 755  */
 756 static void
 757 sadb_destroyer(isaf_t **tablep, uint_t numentries, boolean_t forever,
 758     boolean_t inbound)
 759 {
 760         int i;
 761         isaf_t *table = *tablep;
 762         uint8_t protocol;
 763         ipsa_t *sa;
 764         netstackid_t sid;
 765 
 766         if (table == NULL)
 767                 return;
 768 
 769         for (i = 0; i < numentries; i++) {
 770                 mutex_enter(&table[i].isaf_lock);
 771                 while ((sa = table[i].isaf_ipsa) != NULL) {
 772                         if (inbound && cl_inet_deletespi &&
 773                             (sa->ipsa_state != IPSA_STATE_ACTIVE_ELSEWHERE) &&
 774                             (sa->ipsa_state != IPSA_STATE_IDLE)) {
 775                                 protocol = (sa->ipsa_type == SADB_SATYPE_AH) ?
 776                                     IPPROTO_AH : IPPROTO_ESP;
 777                                 sid = sa->ipsa_netstack->netstack_stackid;
 778                                 cl_inet_deletespi(sid, protocol, sa->ipsa_spi,
 779                                     NULL);
 780                         }
 781                         sadb_unlinkassoc(sa);
 782                 }
 783                 table[i].isaf_gen++;
 784                 mutex_exit(&table[i].isaf_lock);
 785                 if (forever)
 786                         mutex_destroy(&(table[i].isaf_lock));
 787         }
 788 
 789         if (forever) {
 790                 *tablep = NULL;
 791                 kmem_free(table, numentries * sizeof (*table));
 792         }
 793 }
 794 
 795 /*
 796  * Entry points to sadb_destroyer().
 797  */
 798 static void
 799 sadb_flush(sadb_t *sp, netstack_t *ns)
 800 {
 801         /*
 802          * Flush out each bucket, one at a time.  Were it not for keysock's
 803          * enforcement, there would be a subtlety where I could add on the
 804          * heels of a flush.  With keysock's enforcement, however, this
 805          * makes ESP's job easy.
 806          */
 807         sadb_destroyer(&sp->sdb_of, sp->sdb_hashsize, B_FALSE, B_FALSE);
 808         sadb_destroyer(&sp->sdb_if, sp->sdb_hashsize, B_FALSE, B_TRUE);
 809 
 810         /* For each acquire, destroy it; leave the bucket mutex alone. */
 811         sadb_destroy_acqlist(&sp->sdb_acq, sp->sdb_hashsize, B_FALSE, ns);
 812 }
 813 
 814 static void
 815 sadb_destroy(sadb_t *sp, netstack_t *ns)
 816 {
 817         sadb_destroyer(&sp->sdb_of, sp->sdb_hashsize, B_TRUE, B_FALSE);
 818         sadb_destroyer(&sp->sdb_if, sp->sdb_hashsize, B_TRUE, B_TRUE);
 819 
 820         /* For each acquire, destroy it, including the bucket mutex. */
 821         sadb_destroy_acqlist(&sp->sdb_acq, sp->sdb_hashsize, B_TRUE, ns);
 822 
 823         ASSERT(sp->sdb_of == NULL);
 824         ASSERT(sp->sdb_if == NULL);
 825         ASSERT(sp->sdb_acq == NULL);
 826 }
 827 
 828 void
 829 sadbp_flush(sadbp_t *spp, netstack_t *ns)
 830 {
 831         sadb_flush(&spp->s_v4, ns);
 832         sadb_flush(&spp->s_v6, ns);
 833 }
 834 
 835 void
 836 sadbp_destroy(sadbp_t *spp, netstack_t *ns)
 837 {
 838         sadb_destroy(&spp->s_v4, ns);
 839         sadb_destroy(&spp->s_v6, ns);
 840 
 841         if (spp->s_satype == SADB_SATYPE_AH) {
 842                 ipsec_stack_t   *ipss = ns->netstack_ipsec;
 843 
 844                 ip_drop_unregister(&ipss->ipsec_sadb_dropper);
 845         }
 846 }
 847 
 848 
 849 /*
 850  * Check hard vs. soft lifetimes.  If there's a reality mismatch (e.g.
 851  * soft lifetimes > hard lifetimes) return an appropriate diagnostic for
 852  * EINVAL.
 853  */
 854 int
 855 sadb_hardsoftchk(sadb_lifetime_t *hard, sadb_lifetime_t *soft,
 856     sadb_lifetime_t *idle)
 857 {
 858         if (hard == NULL || soft == NULL)
 859                 return (0);
 860 
 861         if (hard->sadb_lifetime_allocations != 0 &&
 862             soft->sadb_lifetime_allocations != 0 &&
 863             hard->sadb_lifetime_allocations < soft->sadb_lifetime_allocations)
 864                 return (SADB_X_DIAGNOSTIC_ALLOC_HSERR);
 865 
 866         if (hard->sadb_lifetime_bytes != 0 &&
 867             soft->sadb_lifetime_bytes != 0 &&
 868             hard->sadb_lifetime_bytes < soft->sadb_lifetime_bytes)
 869                 return (SADB_X_DIAGNOSTIC_BYTES_HSERR);
 870 
 871         if (hard->sadb_lifetime_addtime != 0 &&
 872             soft->sadb_lifetime_addtime != 0 &&
 873             hard->sadb_lifetime_addtime < soft->sadb_lifetime_addtime)
 874                 return (SADB_X_DIAGNOSTIC_ADDTIME_HSERR);
 875 
 876         if (hard->sadb_lifetime_usetime != 0 &&
 877             soft->sadb_lifetime_usetime != 0 &&
 878             hard->sadb_lifetime_usetime < soft->sadb_lifetime_usetime)
 879                 return (SADB_X_DIAGNOSTIC_USETIME_HSERR);
 880 
 881         if (idle != NULL) {
 882                 if (hard->sadb_lifetime_addtime != 0 &&
 883                     idle->sadb_lifetime_addtime != 0 &&
 884                     hard->sadb_lifetime_addtime < idle->sadb_lifetime_addtime)
 885                         return (SADB_X_DIAGNOSTIC_ADDTIME_HSERR);
 886 
 887                 if (soft->sadb_lifetime_addtime != 0 &&
 888                     idle->sadb_lifetime_addtime != 0 &&
 889                     soft->sadb_lifetime_addtime < idle->sadb_lifetime_addtime)
 890                         return (SADB_X_DIAGNOSTIC_ADDTIME_HSERR);
 891 
 892                 if (hard->sadb_lifetime_usetime != 0 &&
 893                     idle->sadb_lifetime_usetime != 0 &&
 894                     hard->sadb_lifetime_usetime < idle->sadb_lifetime_usetime)
 895                         return (SADB_X_DIAGNOSTIC_USETIME_HSERR);
 896 
 897                 if (soft->sadb_lifetime_usetime != 0 &&
 898                     idle->sadb_lifetime_usetime != 0 &&
 899                     soft->sadb_lifetime_usetime < idle->sadb_lifetime_usetime)
 900                         return (SADB_X_DIAGNOSTIC_USETIME_HSERR);
 901         }
 902 
 903         return (0);
 904 }
 905 
 906 /*
 907  * Sanity check sensitivity labels.
 908  *
 909  * For now, just reject labels on unlabeled systems.
 910  */
 911 int
 912 sadb_labelchk(keysock_in_t *ksi)
 913 {
 914         if (!is_system_labeled()) {
 915                 if (ksi->ks_in_extv[SADB_EXT_SENSITIVITY] != NULL)
 916                         return (SADB_X_DIAGNOSTIC_BAD_LABEL);
 917 
 918                 if (ksi->ks_in_extv[SADB_X_EXT_OUTER_SENS] != NULL)
 919                         return (SADB_X_DIAGNOSTIC_BAD_LABEL);
 920         }
 921 
 922         return (0);
 923 }
 924 
 925 /*
 926  * Clone a security association for the purposes of inserting a single SA
 927  * into inbound and outbound tables respectively. This function should only
 928  * be called from sadb_common_add().
 929  */
 930 static ipsa_t *
 931 sadb_cloneassoc(ipsa_t *ipsa)
 932 {
 933         ipsa_t *newbie;
 934         boolean_t error = B_FALSE;
 935 
 936         ASSERT(MUTEX_NOT_HELD(&(ipsa->ipsa_lock)));
 937 
 938         newbie = kmem_alloc(sizeof (ipsa_t), KM_NOSLEEP);
 939         if (newbie == NULL)
 940                 return (NULL);
 941 
 942         /* Copy over what we can. */
 943         *newbie = *ipsa;
 944 
 945         /* bzero and initialize locks, in case *_init() allocates... */
 946         mutex_init(&newbie->ipsa_lock, NULL, MUTEX_DEFAULT, NULL);
 947 
 948         if (newbie->ipsa_tsl != NULL)
 949                 label_hold(newbie->ipsa_tsl);
 950 
 951         if (newbie->ipsa_otsl != NULL)
 952                 label_hold(newbie->ipsa_otsl);
 953 
 954         /*
 955          * While somewhat dain-bramaged, the most graceful way to
 956          * recover from errors is to keep plowing through the
 957          * allocations, and getting what I can.  It's easier to call
 958          * sadb_freeassoc() on the stillborn clone when all the
 959          * pointers aren't pointing to the parent's data.
 960          */
 961 
 962         if (ipsa->ipsa_authkey != NULL) {
 963                 newbie->ipsa_authkey = kmem_alloc(newbie->ipsa_authkeylen,
 964                     KM_NOSLEEP);
 965                 if (newbie->ipsa_authkey == NULL) {
 966                         error = B_TRUE;
 967                 } else {
 968                         bcopy(ipsa->ipsa_authkey, newbie->ipsa_authkey,
 969                             newbie->ipsa_authkeylen);
 970 
 971                         newbie->ipsa_kcfauthkey.ck_data =
 972                             newbie->ipsa_authkey;
 973                 }
 974 
 975                 if (newbie->ipsa_amech.cm_param != NULL) {
 976                         newbie->ipsa_amech.cm_param =
 977                             (char *)&newbie->ipsa_mac_len;
 978                 }
 979         }
 980 
 981         if (ipsa->ipsa_encrkey != NULL) {
 982                 newbie->ipsa_encrkey = kmem_alloc(newbie->ipsa_encrkeylen,
 983                     KM_NOSLEEP);
 984                 if (newbie->ipsa_encrkey == NULL) {
 985                         error = B_TRUE;
 986                 } else {
 987                         bcopy(ipsa->ipsa_encrkey, newbie->ipsa_encrkey,
 988                             newbie->ipsa_encrkeylen);
 989 
 990                         newbie->ipsa_kcfencrkey.ck_data =
 991                             newbie->ipsa_encrkey;
 992                 }
 993         }
 994 
 995         newbie->ipsa_authtmpl = NULL;
 996         newbie->ipsa_encrtmpl = NULL;
 997         newbie->ipsa_haspeer = B_TRUE;
 998 
 999         if (ipsa->ipsa_src_cid != NULL) {
1000                 newbie->ipsa_src_cid = ipsa->ipsa_src_cid;
1001                 IPSID_REFHOLD(ipsa->ipsa_src_cid);
1002         }
1003 
1004         if (ipsa->ipsa_dst_cid != NULL) {
1005                 newbie->ipsa_dst_cid = ipsa->ipsa_dst_cid;
1006                 IPSID_REFHOLD(ipsa->ipsa_dst_cid);
1007         }
1008 
1009         if (error) {
1010                 sadb_freeassoc(newbie);
1011                 return (NULL);
1012         }
1013 
1014         return (newbie);
1015 }
1016 
1017 /*
1018  * Takes two uint8_t (bounds on buffer in which to construct extension) and an
1019  * addr (address to write into extension) pointer, a uint16_t (type of address
1020  * in extension), and af, port, proto, and prefix values (further extension
1021  * content). Returns a byte-aligned pointer to the end of the extension, which
1022  * is of variable length depending on the address family.
1023  */
1024 static uint8_t *
1025 sadb_make_addr_ext(const uint8_t *start, const uint8_t *end, uint16_t exttype,
1026     sa_family_t af, uint32_t *addr, uint16_t port, uint8_t proto, int prefix)
1027 {
1028         struct sockaddr_in *sin;
1029         struct sockaddr_in6 *sin6;
1030         uint8_t *cur = (uint8_t *)start;
1031         int addrext_len;
1032         sadb_address_t *addrext = (sadb_address_t *)cur;
1033 
1034         ASSERT(cur != NULL && end != NULL);
1035 
1036         cur += sizeof (*addrext);
1037         sin = (struct sockaddr_in *)cur;
1038         sin6 = (struct sockaddr_in6 *)cur;
1039         cur += (af == AF_INET) ? sizeof (*sin) : sizeof (*sin6);
1040 
1041         addrext_len = roundup(cur - start, sizeof (uint64_t));
1042         cur = (uint8_t *)start + addrext_len;
1043 
1044         if (cur > end)
1045                 return (NULL);
1046 
1047         addrext->sadb_address_proto = proto;
1048         addrext->sadb_address_prefixlen = prefix;
1049         addrext->sadb_address_reserved = 0;
1050         addrext->sadb_address_exttype = exttype;
1051         addrext->sadb_address_len = SADB_8TO64(addrext_len);
1052 
1053         switch (af) {
1054         case AF_INET:
1055                 sin->sin_family = af;
1056                 bzero(sin->sin_zero, sizeof (sin->sin_zero));
1057                 sin->sin_port = port;
1058                 IPSA_COPY_ADDR(&sin->sin_addr, addr, af);
1059                 break;
1060         case AF_INET6:
1061                 bzero(sin6, sizeof (*sin6));
1062                 sin6->sin6_family = af;
1063                 sin6->sin6_port = port;
1064                 IPSA_COPY_ADDR(&sin6->sin6_addr, addr, af);
1065                 break;
1066         }
1067 
1068         return (cur);
1069 }
1070 
1071 /*
1072  * Takes ipsec_selector_t (address information used in forming addr
1073  * extensions) and ipsec_policy_t (contains pointer to selector key used in
1074  * tunnel mode) pointers, tunnel mode boolean, and creates address extensions
1075  * inside message contents bounds checked by byte-aligned start and end
1076  * pointers. Returns new value for cur pointer or NULL on failure.
1077  * XXX TODO: Original packet contents go here.
1078  */
1079 static uint8_t *
1080 sadb_sel_to_addrexts(const ipsec_selector_t *sel, const ipsec_policy_t *pp,
1081     const ipsec_action_t *ap, const uint8_t *start, const uint8_t *end,
1082     boolean_t tunnel_mode)
1083 {
1084         uint8_t         proto, pfxlen, *cur = (uint8_t *)start;
1085         ipsec_selkey_t  *ipsl;
1086         sa_family_t     af;
1087         uint16_t        lport, rport;
1088         uint32_t        *saddrptr, *daddrptr;
1089 
1090         if (tunnel_mode) {
1091                 /*
1092                  * Form inner address extensions based NOT on the inner
1093                  * selectors (i.e. the packet data), but on the policy's
1094                  * selector key (i.e. the policy's selector information).
1095                  *
1096                  * NOTE:  The position of IPv4 and IPv6 addresses is the
1097                  * same in ipsec_selkey_t (unless the compiler does very
1098                  * strange things with unions, consult your local C language
1099                  * lawyer for details).
1100                  */
1101                 ASSERT(pp != NULL);
1102 
1103                 ipsl = &(pp->ipsp_sel->ipsl_key);
1104                 if (ipsl->ipsl_valid & IPSL_IPV4) {
1105                         af = AF_INET;
1106                         ASSERT(sel->ips_protocol == IPPROTO_ENCAP);
1107                         ASSERT(!(ipsl->ipsl_valid & IPSL_IPV6));
1108                 } else {
1109                         af = AF_INET6;
1110                         ASSERT(sel->ips_protocol == IPPROTO_IPV6);
1111                         ASSERT(ipsl->ipsl_valid & IPSL_IPV6);
1112                 }
1113 
1114                 if (ipsl->ipsl_valid & IPSL_LOCAL_ADDR) {
1115                         saddrptr = (uint32_t *)(&ipsl->ipsl_local);
1116                         pfxlen = ipsl->ipsl_local_pfxlen;
1117                 } else {
1118                         saddrptr = (uint32_t *)(&ipv6_all_zeros);
1119                         pfxlen = 0;
1120                 }
1121                 /* XXX What about ICMP type/code? */
1122                 lport = (ipsl->ipsl_valid & IPSL_LOCAL_PORT) ?
1123                     ipsl->ipsl_lport : 0;
1124                 proto = (ipsl->ipsl_valid & IPSL_PROTOCOL) ?
1125                     ipsl->ipsl_proto : 0;
1126 
1127                 cur = sadb_make_addr_ext(cur, end, SADB_X_EXT_ADDRESS_INNER_SRC,
1128                     af, saddrptr, lport, proto, pfxlen);
1129                 if (cur == NULL)
1130                         goto done;
1131 
1132                 if (ipsl->ipsl_valid & IPSL_REMOTE_ADDR) {
1133                         daddrptr = (uint32_t *)(&ipsl->ipsl_remote);
1134                         pfxlen = ipsl->ipsl_remote_pfxlen;
1135                 } else {
1136                         daddrptr = (uint32_t *)(&ipv6_all_zeros);
1137                         pfxlen = 0;
1138                 }
1139                 /* XXX What about ICMP type/code? */
1140                 rport = (ipsl->ipsl_valid & IPSL_REMOTE_PORT) ?
1141                     ipsl->ipsl_rport : 0;
1142 
1143                 cur = sadb_make_addr_ext(cur, end, SADB_X_EXT_ADDRESS_INNER_DST,
1144                     af, daddrptr, rport, proto, pfxlen);
1145                 if (cur == NULL)
1146                         goto done;
1147 
1148                 /*
1149                  * TODO - if we go to RFC 3408's dream of transport mode
1150                  * IP-in-IP _with_ inner-packet address selectors, we'll need
1151                  * to further distinguish tunnel mode here.  For now, having
1152                  * inner addresses and/or ports is sufficient.
1153                  *
1154                  * Meanwhile, whack proto/ports to reflect IP-in-IP for the
1155                  * outer addresses.
1156                  */
1157                 proto = sel->ips_protocol;   /* Either _ENCAP or _IPV6 */
1158                 lport = rport = 0;
1159         } else if ((ap != NULL) && (!ap->ipa_want_unique)) {
1160                 /* Not in tunnel mode, action doesn't want pop from pkt */
1161                 proto = 0;
1162                 lport = 0;
1163                 rport = 0;
1164                 if (pp != NULL) {
1165                         ipsl = &(pp->ipsp_sel->ipsl_key);
1166                         if (ipsl->ipsl_valid & IPSL_PROTOCOL)
1167                                 proto = ipsl->ipsl_proto;
1168                         if (ipsl->ipsl_valid & IPSL_REMOTE_PORT)
1169                                 rport = ipsl->ipsl_rport;
1170                         if (ipsl->ipsl_valid & IPSL_LOCAL_PORT)
1171                                 lport = ipsl->ipsl_lport;
1172                 }
1173         } else {
1174                 /* Not in tunnel mode, action wants pop from pkt */
1175                 proto = sel->ips_protocol;
1176                 lport = sel->ips_local_port;
1177                 rport = sel->ips_remote_port;
1178         }
1179 
1180         af = sel->ips_isv4 ? AF_INET : AF_INET6;
1181 
1182         /*
1183          * NOTE:  The position of IPv4 and IPv6 addresses is the same
1184          * in ipsec_selector_t.
1185          */
1186         cur = sadb_make_addr_ext(cur, end, SADB_EXT_ADDRESS_SRC, af,
1187             (uint32_t *)(&sel->ips_local_addr_v6), lport, proto, 0);
1188         if (cur == NULL)
1189                 goto done;
1190 
1191         cur = sadb_make_addr_ext(cur, end, SADB_EXT_ADDRESS_DST, af,
1192             (uint32_t *)(&sel->ips_remote_addr_v6), rport, proto, 0);
1193 done:
1194         return (cur);
1195 }
1196 
1197 /*
1198  * Use byte aligned buffer defined by cur and end pointers to create a key
1199  * management extension using kmc and kmp uint32_t parameters.
1200  */
1201 static uint8_t *
1202 sadb_make_kmc_ext(const uint8_t *start, const uint8_t *end,
1203     uint32_t kmp, uint32_t kmc)
1204 {
1205         uint8_t         *cur = (uint8_t *)start;
1206         sadb_x_kmc_t    *kmcext = (sadb_x_kmc_t *)cur;
1207 
1208         ASSERT(cur != NULL && end != NULL);
1209 
1210         cur += sizeof (*kmcext);
1211 
1212         if (cur > end)
1213                 return (NULL);
1214 
1215         kmcext->sadb_x_kmc_len = SADB_8TO64(sizeof (*kmcext));
1216         kmcext->sadb_x_kmc_exttype = SADB_X_EXT_KM_COOKIE;
1217         kmcext->sadb_x_kmc_proto = kmp;
1218         kmcext->sadb_x_kmc_cookie = kmc;
1219         kmcext->sadb_x_kmc_reserved = 0;
1220 
1221         return (cur);
1222 }
1223 
1224 /*
1225  * Given an original message header with sufficient space following it, and an
1226  * SA, construct a full PF_KEY message with all of the relevant extensions.
1227  * This is mostly used for SADB_GET, and SADB_DUMP.
1228  */
1229 static mblk_t *
1230 sadb_sa2msg(ipsa_t *ipsa, sadb_msg_t *samsg)
1231 {
1232         int alloclen, addrsize, paddrsize, authsize, encrsize;
1233         int srcidsize, dstidsize, senslen, osenslen;
1234         sa_family_t fam, pfam;  /* Address family for SADB_EXT_ADDRESS */
1235                                 /* src/dst and proxy sockaddrs. */
1236         /*
1237          * The following are pointers into the PF_KEY message this PF_KEY
1238          * message creates.
1239          */
1240         sadb_msg_t *newsamsg;
1241         sadb_sa_t *assoc;
1242         sadb_lifetime_t *lt;
1243         sadb_key_t *key;
1244         sadb_ident_t *ident;
1245         sadb_sens_t *sens;
1246         sadb_ext_t *walker;     /* For when we need a generic ext. pointer. */
1247         sadb_x_replay_ctr_t *repl_ctr;
1248         sadb_x_pair_t *pair_ext;
1249 
1250         mblk_t *mp;
1251         uint8_t *cur, *end;
1252         /* These indicate the presence of the above extension fields. */
1253         boolean_t soft = B_FALSE, hard = B_FALSE;
1254         boolean_t isrc = B_FALSE, idst = B_FALSE;
1255         boolean_t auth = B_FALSE, encr = B_FALSE;
1256         boolean_t sensinteg = B_FALSE, osensinteg = B_FALSE;
1257         boolean_t srcid = B_FALSE, dstid = B_FALSE;
1258         boolean_t idle;
1259         boolean_t paired;
1260         uint32_t otherspi;
1261 
1262         /* First off, figure out the allocation length for this message. */
1263         /*
1264          * Constant stuff.  This includes base, SA, address (src, dst),
1265          * and lifetime (current).
1266          */
1267         alloclen = sizeof (sadb_msg_t) + sizeof (sadb_sa_t) +
1268             sizeof (sadb_lifetime_t);
1269 
1270         fam = ipsa->ipsa_addrfam;
1271         switch (fam) {
1272         case AF_INET:
1273                 addrsize = roundup(sizeof (struct sockaddr_in) +
1274                     sizeof (sadb_address_t), sizeof (uint64_t));
1275                 break;
1276         case AF_INET6:
1277                 addrsize = roundup(sizeof (struct sockaddr_in6) +
1278                     sizeof (sadb_address_t), sizeof (uint64_t));
1279                 break;
1280         default:
1281                 return (NULL);
1282         }
1283         /*
1284          * Allocate TWO address extensions, for source and destination.
1285          * (Thus, the * 2.)
1286          */
1287         alloclen += addrsize * 2;
1288         if (ipsa->ipsa_flags & IPSA_F_NATT_REM)
1289                 alloclen += addrsize;
1290         if (ipsa->ipsa_flags & IPSA_F_NATT_LOC)
1291                 alloclen += addrsize;
1292 
1293         if (ipsa->ipsa_flags & IPSA_F_PAIRED) {
1294                 paired = B_TRUE;
1295                 alloclen += sizeof (sadb_x_pair_t);
1296                 otherspi = ipsa->ipsa_otherspi;
1297         } else {
1298                 paired = B_FALSE;
1299         }
1300 
1301         /* How 'bout other lifetimes? */
1302         if (ipsa->ipsa_softaddlt != 0 || ipsa->ipsa_softuselt != 0 ||
1303             ipsa->ipsa_softbyteslt != 0 || ipsa->ipsa_softalloc != 0) {
1304                 alloclen += sizeof (sadb_lifetime_t);
1305                 soft = B_TRUE;
1306         }
1307 
1308         if (ipsa->ipsa_hardaddlt != 0 || ipsa->ipsa_harduselt != 0 ||
1309             ipsa->ipsa_hardbyteslt != 0 || ipsa->ipsa_hardalloc != 0) {
1310                 alloclen += sizeof (sadb_lifetime_t);
1311                 hard = B_TRUE;
1312         }
1313 
1314         if (ipsa->ipsa_idleaddlt != 0 || ipsa->ipsa_idleuselt != 0) {
1315                 alloclen += sizeof (sadb_lifetime_t);
1316                 idle = B_TRUE;
1317         } else {
1318                 idle = B_FALSE;
1319         }
1320 
1321         /* Inner addresses. */
1322         if (ipsa->ipsa_innerfam != 0) {
1323                 pfam = ipsa->ipsa_innerfam;
1324                 switch (pfam) {
1325                 case AF_INET6:
1326                         paddrsize = roundup(sizeof (struct sockaddr_in6) +
1327                             sizeof (sadb_address_t), sizeof (uint64_t));
1328                         break;
1329                 case AF_INET:
1330                         paddrsize = roundup(sizeof (struct sockaddr_in) +
1331                             sizeof (sadb_address_t), sizeof (uint64_t));
1332                         break;
1333                 default:
1334                         cmn_err(CE_PANIC,
1335                             "IPsec SADB: Proxy length failure.\n");
1336                         break;
1337                 }
1338                 isrc = B_TRUE;
1339                 idst = B_TRUE;
1340                 alloclen += 2 * paddrsize;
1341         }
1342 
1343         /* For the following fields, assume that length != 0 ==> stuff */
1344         if (ipsa->ipsa_authkeylen != 0) {
1345                 authsize = roundup(sizeof (sadb_key_t) + ipsa->ipsa_authkeylen,
1346                     sizeof (uint64_t));
1347                 alloclen += authsize;
1348                 auth = B_TRUE;
1349         }
1350 
1351         if (ipsa->ipsa_encrkeylen != 0) {
1352                 encrsize = roundup(sizeof (sadb_key_t) + ipsa->ipsa_encrkeylen +
1353                     ipsa->ipsa_nonce_len, sizeof (uint64_t));
1354                 alloclen += encrsize;
1355                 encr = B_TRUE;
1356         } else {
1357                 encr = B_FALSE;
1358         }
1359 
1360         if (ipsa->ipsa_tsl != NULL) {
1361                 senslen = sadb_sens_len_from_label(ipsa->ipsa_tsl);
1362                 alloclen += senslen;
1363                 sensinteg = B_TRUE;
1364         }
1365 
1366         if (ipsa->ipsa_otsl != NULL) {
1367                 osenslen = sadb_sens_len_from_label(ipsa->ipsa_otsl);
1368                 alloclen += osenslen;
1369                 osensinteg = B_TRUE;
1370         }
1371 
1372         /*
1373          * Must use strlen() here for lengths.  Identities use NULL
1374          * pointers to indicate their nonexistence.
1375          */
1376         if (ipsa->ipsa_src_cid != NULL) {
1377                 srcidsize = roundup(sizeof (sadb_ident_t) +
1378                     strlen(ipsa->ipsa_src_cid->ipsid_cid) + 1,
1379                     sizeof (uint64_t));
1380                 alloclen += srcidsize;
1381                 srcid = B_TRUE;
1382         }
1383 
1384         if (ipsa->ipsa_dst_cid != NULL) {
1385                 dstidsize = roundup(sizeof (sadb_ident_t) +
1386                     strlen(ipsa->ipsa_dst_cid->ipsid_cid) + 1,
1387                     sizeof (uint64_t));
1388                 alloclen += dstidsize;
1389                 dstid = B_TRUE;
1390         }
1391 
1392         if ((ipsa->ipsa_kmp != 0) || (ipsa->ipsa_kmc != 0))
1393                 alloclen += sizeof (sadb_x_kmc_t);
1394 
1395         if (ipsa->ipsa_replay != 0) {
1396                 alloclen += sizeof (sadb_x_replay_ctr_t);
1397         }
1398 
1399         /* Make sure the allocation length is a multiple of 8 bytes. */
1400         ASSERT((alloclen & 0x7) == 0);
1401 
1402         /* XXX Possibly make it esballoc, with a bzero-ing free_ftn. */
1403         mp = allocb(alloclen, BPRI_HI);
1404         if (mp == NULL)
1405                 return (NULL);
1406         bzero(mp->b_rptr, alloclen);
1407 
1408         mp->b_wptr += alloclen;
1409         end = mp->b_wptr;
1410         newsamsg = (sadb_msg_t *)mp->b_rptr;
1411         *newsamsg = *samsg;
1412         newsamsg->sadb_msg_len = (uint16_t)SADB_8TO64(alloclen);
1413 
1414         mutex_enter(&ipsa->ipsa_lock);   /* Since I'm grabbing SA fields... */
1415 
1416         newsamsg->sadb_msg_satype = ipsa->ipsa_type;
1417 
1418         assoc = (sadb_sa_t *)(newsamsg + 1);
1419         assoc->sadb_sa_len = SADB_8TO64(sizeof (*assoc));
1420         assoc->sadb_sa_exttype = SADB_EXT_SA;
1421         assoc->sadb_sa_spi = ipsa->ipsa_spi;
1422         assoc->sadb_sa_replay = ipsa->ipsa_replay_wsize;
1423         assoc->sadb_sa_state = ipsa->ipsa_state;
1424         assoc->sadb_sa_auth = ipsa->ipsa_auth_alg;
1425         assoc->sadb_sa_encrypt = ipsa->ipsa_encr_alg;
1426         assoc->sadb_sa_flags = ipsa->ipsa_flags;
1427 
1428         lt = (sadb_lifetime_t *)(assoc + 1);
1429         lt->sadb_lifetime_len = SADB_8TO64(sizeof (*lt));
1430         lt->sadb_lifetime_exttype = SADB_EXT_LIFETIME_CURRENT;
1431         /* We do not support the concept. */
1432         lt->sadb_lifetime_allocations = 0;
1433         lt->sadb_lifetime_bytes = ipsa->ipsa_bytes;
1434         lt->sadb_lifetime_addtime = ipsa->ipsa_addtime;
1435         lt->sadb_lifetime_usetime = ipsa->ipsa_usetime;
1436 
1437         if (hard) {
1438                 lt++;
1439                 lt->sadb_lifetime_len = SADB_8TO64(sizeof (*lt));
1440                 lt->sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD;
1441                 lt->sadb_lifetime_allocations = ipsa->ipsa_hardalloc;
1442                 lt->sadb_lifetime_bytes = ipsa->ipsa_hardbyteslt;
1443                 lt->sadb_lifetime_addtime = ipsa->ipsa_hardaddlt;
1444                 lt->sadb_lifetime_usetime = ipsa->ipsa_harduselt;
1445         }
1446 
1447         if (soft) {
1448                 lt++;
1449                 lt->sadb_lifetime_len = SADB_8TO64(sizeof (*lt));
1450                 lt->sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT;
1451                 lt->sadb_lifetime_allocations = ipsa->ipsa_softalloc;
1452                 lt->sadb_lifetime_bytes = ipsa->ipsa_softbyteslt;
1453                 lt->sadb_lifetime_addtime = ipsa->ipsa_softaddlt;
1454                 lt->sadb_lifetime_usetime = ipsa->ipsa_softuselt;
1455         }
1456 
1457         if (idle) {
1458                 lt++;
1459                 lt->sadb_lifetime_len = SADB_8TO64(sizeof (*lt));
1460                 lt->sadb_lifetime_exttype = SADB_X_EXT_LIFETIME_IDLE;
1461                 lt->sadb_lifetime_addtime = ipsa->ipsa_idleaddlt;
1462                 lt->sadb_lifetime_usetime = ipsa->ipsa_idleuselt;
1463         }
1464 
1465         cur = (uint8_t *)(lt + 1);
1466 
1467         /* NOTE:  Don't fill in ports here if we are a tunnel-mode SA. */
1468         cur = sadb_make_addr_ext(cur, end, SADB_EXT_ADDRESS_SRC, fam,
1469             ipsa->ipsa_srcaddr, (!isrc && !idst) ? SA_SRCPORT(ipsa) : 0,
1470             SA_PROTO(ipsa), 0);
1471         if (cur == NULL) {
1472                 freemsg(mp);
1473                 mp = NULL;
1474                 goto bail;
1475         }
1476 
1477         cur = sadb_make_addr_ext(cur, end, SADB_EXT_ADDRESS_DST, fam,
1478             ipsa->ipsa_dstaddr, (!isrc && !idst) ? SA_DSTPORT(ipsa) : 0,
1479             SA_PROTO(ipsa), 0);
1480         if (cur == NULL) {
1481                 freemsg(mp);
1482                 mp = NULL;
1483                 goto bail;
1484         }
1485 
1486         if (ipsa->ipsa_flags & IPSA_F_NATT_LOC) {
1487                 cur = sadb_make_addr_ext(cur, end, SADB_X_EXT_ADDRESS_NATT_LOC,
1488                     fam, &ipsa->ipsa_natt_addr_loc, ipsa->ipsa_local_nat_port,
1489                     IPPROTO_UDP, 0);
1490                 if (cur == NULL) {
1491                         freemsg(mp);
1492                         mp = NULL;
1493                         goto bail;
1494                 }
1495         }
1496 
1497         if (ipsa->ipsa_flags & IPSA_F_NATT_REM) {
1498                 cur = sadb_make_addr_ext(cur, end, SADB_X_EXT_ADDRESS_NATT_REM,
1499                     fam, &ipsa->ipsa_natt_addr_rem, ipsa->ipsa_remote_nat_port,
1500                     IPPROTO_UDP, 0);
1501                 if (cur == NULL) {
1502                         freemsg(mp);
1503                         mp = NULL;
1504                         goto bail;
1505                 }
1506         }
1507 
1508         /* If we are a tunnel-mode SA, fill in the inner-selectors. */
1509         if (isrc) {
1510                 cur = sadb_make_addr_ext(cur, end, SADB_X_EXT_ADDRESS_INNER_SRC,
1511                     pfam, ipsa->ipsa_innersrc, SA_SRCPORT(ipsa),
1512                     SA_IPROTO(ipsa), ipsa->ipsa_innersrcpfx);
1513                 if (cur == NULL) {
1514                         freemsg(mp);
1515                         mp = NULL;
1516                         goto bail;
1517                 }
1518         }
1519 
1520         if (idst) {
1521                 cur = sadb_make_addr_ext(cur, end, SADB_X_EXT_ADDRESS_INNER_DST,
1522                     pfam, ipsa->ipsa_innerdst, SA_DSTPORT(ipsa),
1523                     SA_IPROTO(ipsa), ipsa->ipsa_innerdstpfx);
1524                 if (cur == NULL) {
1525                         freemsg(mp);
1526                         mp = NULL;
1527                         goto bail;
1528                 }
1529         }
1530 
1531         if ((ipsa->ipsa_kmp != 0) || (ipsa->ipsa_kmc != 0)) {
1532                 cur = sadb_make_kmc_ext(cur, end,
1533                     ipsa->ipsa_kmp, ipsa->ipsa_kmc);
1534                 if (cur == NULL) {
1535                         freemsg(mp);
1536                         mp = NULL;
1537                         goto bail;
1538                 }
1539         }
1540 
1541         walker = (sadb_ext_t *)cur;
1542         if (auth) {
1543                 key = (sadb_key_t *)walker;
1544                 key->sadb_key_len = SADB_8TO64(authsize);
1545                 key->sadb_key_exttype = SADB_EXT_KEY_AUTH;
1546                 key->sadb_key_bits = ipsa->ipsa_authkeybits;
1547                 key->sadb_key_reserved = 0;
1548                 bcopy(ipsa->ipsa_authkey, key + 1, ipsa->ipsa_authkeylen);
1549                 walker = (sadb_ext_t *)((uint64_t *)walker +
1550                     walker->sadb_ext_len);
1551         }
1552 
1553         if (encr) {
1554                 uint8_t *buf_ptr;
1555                 key = (sadb_key_t *)walker;
1556                 key->sadb_key_len = SADB_8TO64(encrsize);
1557                 key->sadb_key_exttype = SADB_EXT_KEY_ENCRYPT;
1558                 key->sadb_key_bits = ipsa->ipsa_encrkeybits;
1559                 key->sadb_key_reserved = ipsa->ipsa_saltbits;
1560                 buf_ptr = (uint8_t *)(key + 1);
1561                 bcopy(ipsa->ipsa_encrkey, buf_ptr, ipsa->ipsa_encrkeylen);
1562                 if (ipsa->ipsa_salt != NULL) {
1563                         buf_ptr += ipsa->ipsa_encrkeylen;
1564                         bcopy(ipsa->ipsa_salt, buf_ptr, ipsa->ipsa_saltlen);
1565                 }
1566                 walker = (sadb_ext_t *)((uint64_t *)walker +
1567                     walker->sadb_ext_len);
1568         }
1569 
1570         if (srcid) {
1571                 ident = (sadb_ident_t *)walker;
1572                 ident->sadb_ident_len = SADB_8TO64(srcidsize);
1573                 ident->sadb_ident_exttype = SADB_EXT_IDENTITY_SRC;
1574                 ident->sadb_ident_type = ipsa->ipsa_src_cid->ipsid_type;
1575                 ident->sadb_ident_id = 0;
1576                 ident->sadb_ident_reserved = 0;
1577                 (void) strcpy((char *)(ident + 1),
1578                     ipsa->ipsa_src_cid->ipsid_cid);
1579                 walker = (sadb_ext_t *)((uint64_t *)walker +
1580                     walker->sadb_ext_len);
1581         }
1582 
1583         if (dstid) {
1584                 ident = (sadb_ident_t *)walker;
1585                 ident->sadb_ident_len = SADB_8TO64(dstidsize);
1586                 ident->sadb_ident_exttype = SADB_EXT_IDENTITY_DST;
1587                 ident->sadb_ident_type = ipsa->ipsa_dst_cid->ipsid_type;
1588                 ident->sadb_ident_id = 0;
1589                 ident->sadb_ident_reserved = 0;
1590                 (void) strcpy((char *)(ident + 1),
1591                     ipsa->ipsa_dst_cid->ipsid_cid);
1592                 walker = (sadb_ext_t *)((uint64_t *)walker +
1593                     walker->sadb_ext_len);
1594         }
1595 
1596         if (sensinteg) {
1597                 sens = (sadb_sens_t *)walker;
1598                 sadb_sens_from_label(sens, SADB_EXT_SENSITIVITY,
1599                     ipsa->ipsa_tsl, senslen);
1600 
1601                 walker = (sadb_ext_t *)((uint64_t *)walker +
1602                     walker->sadb_ext_len);
1603         }
1604 
1605         if (osensinteg) {
1606                 sens = (sadb_sens_t *)walker;
1607 
1608                 sadb_sens_from_label(sens, SADB_X_EXT_OUTER_SENS,
1609                     ipsa->ipsa_otsl, osenslen);
1610                 if (ipsa->ipsa_mac_exempt)
1611                         sens->sadb_x_sens_flags = SADB_X_SENS_IMPLICIT;
1612 
1613                 walker = (sadb_ext_t *)((uint64_t *)walker +
1614                     walker->sadb_ext_len);
1615         }
1616 
1617         if (paired) {
1618                 pair_ext = (sadb_x_pair_t *)walker;
1619 
1620                 pair_ext->sadb_x_pair_len = SADB_8TO64(sizeof (sadb_x_pair_t));
1621                 pair_ext->sadb_x_pair_exttype = SADB_X_EXT_PAIR;
1622                 pair_ext->sadb_x_pair_spi = otherspi;
1623 
1624                 walker = (sadb_ext_t *)((uint64_t *)walker +
1625                     walker->sadb_ext_len);
1626         }
1627 
1628         if (ipsa->ipsa_replay != 0) {
1629                 repl_ctr = (sadb_x_replay_ctr_t *)walker;
1630                 repl_ctr->sadb_x_rc_len = SADB_8TO64(sizeof (*repl_ctr));
1631                 repl_ctr->sadb_x_rc_exttype = SADB_X_EXT_REPLAY_VALUE;
1632                 repl_ctr->sadb_x_rc_replay32 = ipsa->ipsa_replay;
1633                 repl_ctr->sadb_x_rc_replay64 = 0;
1634                 walker = (sadb_ext_t *)(repl_ctr + 1);
1635         }
1636 
1637 bail:
1638         /* Pardon any delays... */
1639         mutex_exit(&ipsa->ipsa_lock);
1640 
1641         return (mp);
1642 }
1643 
1644 /*
1645  * Strip out key headers or unmarked headers (SADB_EXT_KEY_*, SADB_EXT_UNKNOWN)
1646  * and adjust base message accordingly.
1647  *
1648  * Assume message is pulled up in one piece of contiguous memory.
1649  *
1650  * Say if we start off with:
1651  *
1652  * +------+----+-------------+-----------+---------------+---------------+
1653  * | base | SA | source addr | dest addr | rsrvd. or key | soft lifetime |
1654  * +------+----+-------------+-----------+---------------+---------------+
1655  *
1656  * we will end up with
1657  *
1658  * +------+----+-------------+-----------+---------------+
1659  * | base | SA | source addr | dest addr | soft lifetime |
1660  * +------+----+-------------+-----------+---------------+
1661  */
1662 static void
1663 sadb_strip(sadb_msg_t *samsg)
1664 {
1665         sadb_ext_t *ext;
1666         uint8_t *target = NULL;
1667         uint8_t *msgend;
1668         int sofar = SADB_8TO64(sizeof (*samsg));
1669         int copylen;
1670 
1671         ext = (sadb_ext_t *)(samsg + 1);
1672         msgend = (uint8_t *)samsg;
1673         msgend += SADB_64TO8(samsg->sadb_msg_len);
1674         while ((uint8_t *)ext < msgend) {
1675                 if (ext->sadb_ext_type == SADB_EXT_RESERVED ||
1676                     ext->sadb_ext_type == SADB_EXT_KEY_AUTH ||
1677                     ext->sadb_ext_type == SADB_X_EXT_EDUMP ||
1678                     ext->sadb_ext_type == SADB_EXT_KEY_ENCRYPT) {
1679                         /*
1680                          * Aha!  I found a header to be erased.
1681                          */
1682 
1683                         if (target != NULL) {
1684                                 /*
1685                                  * If I had a previous header to be erased,
1686                                  * copy over it.  I can get away with just
1687                                  * copying backwards because the target will
1688                                  * always be 8 bytes behind the source.
1689                                  */
1690                                 copylen = ((uint8_t *)ext) - (target +
1691                                     SADB_64TO8(
1692                                     ((sadb_ext_t *)target)->sadb_ext_len));
1693                                 ovbcopy(((uint8_t *)ext - copylen), target,
1694                                     copylen);
1695                                 target += copylen;
1696                                 ((sadb_ext_t *)target)->sadb_ext_len =
1697                                     SADB_8TO64(((uint8_t *)ext) - target +
1698                                     SADB_64TO8(ext->sadb_ext_len));
1699                         } else {
1700                                 target = (uint8_t *)ext;
1701                         }
1702                 } else {
1703                         sofar += ext->sadb_ext_len;
1704                 }
1705 
1706                 ext = (sadb_ext_t *)(((uint64_t *)ext) + ext->sadb_ext_len);
1707         }
1708 
1709         ASSERT((uint8_t *)ext == msgend);
1710 
1711         if (target != NULL) {
1712                 copylen = ((uint8_t *)ext) - (target +
1713                     SADB_64TO8(((sadb_ext_t *)target)->sadb_ext_len));
1714                 if (copylen != 0)
1715                         ovbcopy(((uint8_t *)ext - copylen), target, copylen);
1716         }
1717 
1718         /* Adjust samsg. */
1719         samsg->sadb_msg_len = (uint16_t)sofar;
1720 
1721         /* Assume all of the rest is cleared by caller in sadb_pfkey_echo(). */
1722 }
1723 
1724 /*
1725  * AH needs to send an error to PF_KEY.  Assume mp points to an M_CTL
1726  * followed by an M_DATA with a PF_KEY message in it.  The serial of
1727  * the sending keysock instance is included.
1728  */
1729 void
1730 sadb_pfkey_error(queue_t *pfkey_q, mblk_t *mp, int error, int diagnostic,
1731     uint_t serial)
1732 {
1733         mblk_t *msg = mp->b_cont;
1734         sadb_msg_t *samsg;
1735         keysock_out_t *kso;
1736 
1737         /*
1738          * Enough functions call this to merit a NULL queue check.
1739          */
1740         if (pfkey_q == NULL) {
1741                 freemsg(mp);
1742                 return;
1743         }
1744 
1745         ASSERT(msg != NULL);
1746         ASSERT((mp->b_wptr - mp->b_rptr) == sizeof (ipsec_info_t));
1747         ASSERT((msg->b_wptr - msg->b_rptr) >= sizeof (sadb_msg_t));
1748         samsg = (sadb_msg_t *)msg->b_rptr;
1749         kso = (keysock_out_t *)mp->b_rptr;
1750 
1751         kso->ks_out_type = KEYSOCK_OUT;
1752         kso->ks_out_len = sizeof (*kso);
1753         kso->ks_out_serial = serial;
1754 
1755         /*
1756          * Only send the base message up in the event of an error.
1757          * Don't worry about bzero()-ing, because it was probably bogus
1758          * anyway.
1759          */
1760         msg->b_wptr = msg->b_rptr + sizeof (*samsg);
1761         samsg = (sadb_msg_t *)msg->b_rptr;
1762         samsg->sadb_msg_len = SADB_8TO64(sizeof (*samsg));
1763         samsg->sadb_msg_errno = (uint8_t)error;
1764         if (diagnostic != SADB_X_DIAGNOSTIC_PRESET)
1765                 samsg->sadb_x_msg_diagnostic = (uint16_t)diagnostic;
1766 
1767         putnext(pfkey_q, mp);
1768 }
1769 
1770 /*
1771  * Send a successful return packet back to keysock via the queue in pfkey_q.
1772  *
1773  * Often, an SA is associated with the reply message, it's passed in if needed,
1774  * and NULL if not.  BTW, that ipsa will have its refcnt appropriately held,
1775  * and the caller will release said refcnt.
1776  */
1777 void
1778 sadb_pfkey_echo(queue_t *pfkey_q, mblk_t *mp, sadb_msg_t *samsg,
1779     keysock_in_t *ksi, ipsa_t *ipsa)
1780 {
1781         keysock_out_t *kso;
1782         mblk_t *mp1;
1783         sadb_msg_t *newsamsg;
1784         uint8_t *oldend;
1785 
1786         ASSERT((mp->b_cont != NULL) &&
1787             ((void *)samsg == (void *)mp->b_cont->b_rptr) &&
1788             ((void *)mp->b_rptr == (void *)ksi));
1789 
1790         switch (samsg->sadb_msg_type) {
1791         case SADB_ADD:
1792         case SADB_UPDATE:
1793         case SADB_X_UPDATEPAIR:
1794         case SADB_X_DELPAIR_STATE:
1795         case SADB_FLUSH:
1796         case SADB_DUMP:
1797                 /*
1798                  * I have all of the message already.  I just need to strip
1799                  * out the keying material and echo the message back.
1800                  *
1801                  * NOTE: for SADB_DUMP, the function sadb_dump() did the
1802                  * work.  When DUMP reaches here, it should only be a base
1803                  * message.
1804                  */
1805         justecho:
1806                 if (ksi->ks_in_extv[SADB_EXT_KEY_AUTH] != NULL ||
1807                     ksi->ks_in_extv[SADB_EXT_KEY_ENCRYPT] != NULL ||
1808                     ksi->ks_in_extv[SADB_X_EXT_EDUMP] != NULL) {
1809                         sadb_strip(samsg);
1810                         /* Assume PF_KEY message is contiguous. */
1811                         ASSERT(mp->b_cont->b_cont == NULL);
1812                         oldend = mp->b_cont->b_wptr;
1813                         mp->b_cont->b_wptr = mp->b_cont->b_rptr +
1814                             SADB_64TO8(samsg->sadb_msg_len);
1815                         bzero(mp->b_cont->b_wptr, oldend - mp->b_cont->b_wptr);
1816                 }
1817                 break;
1818         case SADB_GET:
1819                 /*
1820                  * Do a lot of work here, because of the ipsa I just found.
1821                  * First construct the new PF_KEY message, then abandon
1822                  * the old one.
1823                  */
1824                 mp1 = sadb_sa2msg(ipsa, samsg);
1825                 if (mp1 == NULL) {
1826                         sadb_pfkey_error(pfkey_q, mp, ENOMEM,
1827                             SADB_X_DIAGNOSTIC_NONE, ksi->ks_in_serial);
1828                         return;
1829                 }
1830                 freemsg(mp->b_cont);
1831                 mp->b_cont = mp1;
1832                 break;
1833         case SADB_DELETE:
1834         case SADB_X_DELPAIR:
1835                 if (ipsa == NULL)
1836                         goto justecho;
1837                 /*
1838                  * Because listening KMds may require more info, treat
1839                  * DELETE like a special case of GET.
1840                  */
1841                 mp1 = sadb_sa2msg(ipsa, samsg);
1842                 if (mp1 == NULL) {
1843                         sadb_pfkey_error(pfkey_q, mp, ENOMEM,
1844                             SADB_X_DIAGNOSTIC_NONE, ksi->ks_in_serial);
1845                         return;
1846                 }
1847                 newsamsg = (sadb_msg_t *)mp1->b_rptr;
1848                 sadb_strip(newsamsg);
1849                 oldend = mp1->b_wptr;
1850                 mp1->b_wptr = mp1->b_rptr + SADB_64TO8(newsamsg->sadb_msg_len);
1851                 bzero(mp1->b_wptr, oldend - mp1->b_wptr);
1852                 freemsg(mp->b_cont);
1853                 mp->b_cont = mp1;
1854                 break;
1855         default:
1856                 if (mp != NULL)
1857                         freemsg(mp);
1858                 return;
1859         }
1860 
1861         /* ksi is now null and void. */
1862         kso = (keysock_out_t *)ksi;
1863         kso->ks_out_type = KEYSOCK_OUT;
1864         kso->ks_out_len = sizeof (*kso);
1865         kso->ks_out_serial = ksi->ks_in_serial;
1866         /* We're ready to send... */
1867         putnext(pfkey_q, mp);
1868 }
1869 
1870 /*
1871  * Set up a global pfkey_q instance for AH, ESP, or some other consumer.
1872  */
1873 void
1874 sadb_keysock_hello(queue_t **pfkey_qp, queue_t *q, mblk_t *mp,
1875     void (*ager)(void *), void *agerarg, timeout_id_t *top, int satype)
1876 {
1877         keysock_hello_ack_t *kha;
1878         queue_t *oldq;
1879 
1880         ASSERT(OTHERQ(q) != NULL);
1881 
1882         /*
1883          * First, check atomically that I'm the first and only keysock
1884          * instance.
1885          *
1886          * Use OTHERQ(q), because qreply(q, mp) == putnext(OTHERQ(q), mp),
1887          * and I want this module to say putnext(*_pfkey_q, mp) for PF_KEY
1888          * messages.
1889          */
1890 
1891         oldq = casptr((void **)pfkey_qp, NULL, OTHERQ(q));
1892         if (oldq != NULL) {
1893                 ASSERT(oldq != q);
1894                 cmn_err(CE_WARN, "Danger!  Multiple keysocks on top of %s.\n",
1895                     (satype == SADB_SATYPE_ESP)? "ESP" : "AH or other");
1896                 freemsg(mp);
1897                 return;
1898         }
1899 
1900         kha = (keysock_hello_ack_t *)mp->b_rptr;
1901         kha->ks_hello_len = sizeof (keysock_hello_ack_t);
1902         kha->ks_hello_type = KEYSOCK_HELLO_ACK;
1903         kha->ks_hello_satype = (uint8_t)satype;
1904 
1905         /*
1906          * If we made it past the casptr, then we have "exclusive" access
1907          * to the timeout handle.  Fire it off after the default ager
1908          * interval.
1909          */
1910         *top = qtimeout(*pfkey_qp, ager, agerarg,
1911             drv_usectohz(SADB_AGE_INTERVAL_DEFAULT * 1000));
1912 
1913         putnext(*pfkey_qp, mp);
1914 }
1915 
1916 /*
1917  * Normalize IPv4-mapped IPv6 addresses (and prefixes) as appropriate.
1918  *
1919  * Check addresses themselves for wildcard or multicast.
1920  * Check ire table for local/non-local/broadcast.
1921  */
1922 int
1923 sadb_addrcheck(queue_t *pfkey_q, mblk_t *mp, sadb_ext_t *ext, uint_t serial,
1924     netstack_t *ns)
1925 {
1926         sadb_address_t *addr = (sadb_address_t *)ext;
1927         struct sockaddr_in *sin;
1928         struct sockaddr_in6 *sin6;
1929         int diagnostic, type;
1930         boolean_t normalized = B_FALSE;
1931 
1932         ASSERT(ext != NULL);
1933         ASSERT((ext->sadb_ext_type == SADB_EXT_ADDRESS_SRC) ||
1934             (ext->sadb_ext_type == SADB_EXT_ADDRESS_DST) ||
1935             (ext->sadb_ext_type == SADB_X_EXT_ADDRESS_INNER_SRC) ||
1936             (ext->sadb_ext_type == SADB_X_EXT_ADDRESS_INNER_DST) ||
1937             (ext->sadb_ext_type == SADB_X_EXT_ADDRESS_NATT_LOC) ||
1938             (ext->sadb_ext_type == SADB_X_EXT_ADDRESS_NATT_REM));
1939 
1940         /* Assign both sockaddrs, the compiler will do the right thing. */
1941         sin = (struct sockaddr_in *)(addr + 1);
1942         sin6 = (struct sockaddr_in6 *)(addr + 1);
1943 
1944         if (sin6->sin6_family == AF_INET6) {
1945                 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
1946                         /*
1947                          * Convert to an AF_INET sockaddr.  This means the
1948                          * return messages will have the extra space, but have
1949                          * AF_INET sockaddrs instead of AF_INET6.
1950                          *
1951                          * Yes, RFC 2367 isn't clear on what to do here w.r.t.
1952                          * mapped addresses, but since AF_INET6 ::ffff:<v4> is
1953                          * equal to AF_INET <v4>, it shouldnt be a huge
1954                          * problem.
1955                          */
1956                         sin->sin_family = AF_INET;
1957                         IN6_V4MAPPED_TO_INADDR(&sin6->sin6_addr,
1958                             &sin->sin_addr);
1959                         bzero(&sin->sin_zero, sizeof (sin->sin_zero));
1960                         normalized = B_TRUE;
1961                 }
1962         } else if (sin->sin_family != AF_INET) {
1963                 switch (ext->sadb_ext_type) {
1964                 case SADB_EXT_ADDRESS_SRC:
1965                         diagnostic = SADB_X_DIAGNOSTIC_BAD_SRC_AF;
1966                         break;
1967                 case SADB_EXT_ADDRESS_DST:
1968                         diagnostic = SADB_X_DIAGNOSTIC_BAD_DST_AF;
1969                         break;
1970                 case SADB_X_EXT_ADDRESS_INNER_SRC:
1971                         diagnostic = SADB_X_DIAGNOSTIC_BAD_PROXY_AF;
1972                         break;
1973                 case SADB_X_EXT_ADDRESS_INNER_DST:
1974                         diagnostic = SADB_X_DIAGNOSTIC_BAD_INNER_DST_AF;
1975                         break;
1976                 case SADB_X_EXT_ADDRESS_NATT_LOC:
1977                         diagnostic = SADB_X_DIAGNOSTIC_BAD_NATT_LOC_AF;
1978                         break;
1979                 case SADB_X_EXT_ADDRESS_NATT_REM:
1980                         diagnostic = SADB_X_DIAGNOSTIC_BAD_NATT_REM_AF;
1981                         break;
1982                         /* There is no default, see above ASSERT. */
1983                 }
1984 bail:
1985                 if (pfkey_q != NULL) {
1986                         sadb_pfkey_error(pfkey_q, mp, EINVAL, diagnostic,
1987                             serial);
1988                 } else {
1989                         /*
1990                          * Scribble in sadb_msg that we got passed in.
1991                          * Overload "mp" to be an sadb_msg pointer.
1992                          */
1993                         sadb_msg_t *samsg = (sadb_msg_t *)mp;
1994 
1995                         samsg->sadb_msg_errno = EINVAL;
1996                         samsg->sadb_x_msg_diagnostic = diagnostic;
1997                 }
1998                 return (KS_IN_ADDR_UNKNOWN);
1999         }
2000 
2001         if (ext->sadb_ext_type == SADB_X_EXT_ADDRESS_INNER_SRC ||
2002             ext->sadb_ext_type == SADB_X_EXT_ADDRESS_INNER_DST) {
2003                 /*
2004                  * We need only check for prefix issues.
2005                  */
2006 
2007                 /* Set diagnostic now, in case we need it later. */
2008                 diagnostic =
2009                     (ext->sadb_ext_type == SADB_X_EXT_ADDRESS_INNER_SRC) ?
2010                     SADB_X_DIAGNOSTIC_PREFIX_INNER_SRC :
2011                     SADB_X_DIAGNOSTIC_PREFIX_INNER_DST;
2012 
2013                 if (normalized)
2014                         addr->sadb_address_prefixlen -= 96;
2015 
2016                 /*
2017                  * Verify and mask out inner-addresses based on prefix length.
2018                  */
2019                 if (sin->sin_family == AF_INET) {
2020                         if (addr->sadb_address_prefixlen > 32)
2021                                 goto bail;
2022                         sin->sin_addr.s_addr &=
2023                             ip_plen_to_mask(addr->sadb_address_prefixlen);
2024                 } else {
2025                         in6_addr_t mask;
2026 
2027                         ASSERT(sin->sin_family == AF_INET6);
2028                         /*
2029                          * ip_plen_to_mask_v6() returns NULL if the value in
2030                          * question is out of range.
2031                          */
2032                         if (ip_plen_to_mask_v6(addr->sadb_address_prefixlen,
2033                             &mask) == NULL)
2034                                 goto bail;
2035                         sin6->sin6_addr.s6_addr32[0] &= mask.s6_addr32[0];
2036                         sin6->sin6_addr.s6_addr32[1] &= mask.s6_addr32[1];
2037                         sin6->sin6_addr.s6_addr32[2] &= mask.s6_addr32[2];
2038                         sin6->sin6_addr.s6_addr32[3] &= mask.s6_addr32[3];
2039                 }
2040 
2041                 /* We don't care in these cases. */
2042                 return (KS_IN_ADDR_DONTCARE);
2043         }
2044 
2045         if (sin->sin_family == AF_INET6) {
2046                 /* Check the easy ones now. */
2047                 if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))
2048                         return (KS_IN_ADDR_MBCAST);
2049                 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))
2050                         return (KS_IN_ADDR_UNSPEC);
2051                 /*
2052                  * At this point, we're a unicast IPv6 address.
2053                  *
2054                  * XXX Zones alert -> me/notme decision needs to be tempered
2055                  * by what zone we're in when we go to zone-aware IPsec.
2056                  */
2057                 if (ip_type_v6(&sin6->sin6_addr, ns->netstack_ip) ==
2058                     IRE_LOCAL) {
2059                         /* Hey hey, it's local. */
2060                         return (KS_IN_ADDR_ME);
2061                 }
2062         } else {
2063                 ASSERT(sin->sin_family == AF_INET);
2064                 if (sin->sin_addr.s_addr == INADDR_ANY)
2065                         return (KS_IN_ADDR_UNSPEC);
2066                 if (CLASSD(sin->sin_addr.s_addr))
2067                         return (KS_IN_ADDR_MBCAST);
2068                 /*
2069                  * At this point we're a unicast or broadcast IPv4 address.
2070                  *
2071                  * Check if the address is IRE_BROADCAST or IRE_LOCAL.
2072                  *
2073                  * XXX Zones alert -> me/notme decision needs to be tempered
2074                  * by what zone we're in when we go to zone-aware IPsec.
2075                  */
2076                 type = ip_type_v4(sin->sin_addr.s_addr, ns->netstack_ip);
2077                 switch (type) {
2078                 case IRE_LOCAL:
2079                         return (KS_IN_ADDR_ME);
2080                 case IRE_BROADCAST:
2081                         return (KS_IN_ADDR_MBCAST);
2082                 }
2083         }
2084 
2085         return (KS_IN_ADDR_NOTME);
2086 }
2087 
2088 /*
2089  * Address normalizations and reality checks for inbound PF_KEY messages.
2090  *
2091  * For the case of src == unspecified AF_INET6, and dst == AF_INET, convert
2092  * the source to AF_INET.  Do the same for the inner sources.
2093  */
2094 boolean_t
2095 sadb_addrfix(keysock_in_t *ksi, queue_t *pfkey_q, mblk_t *mp, netstack_t *ns)
2096 {
2097         struct sockaddr_in *src, *isrc;
2098         struct sockaddr_in6 *dst, *idst;
2099         sadb_address_t *srcext, *dstext;
2100         uint16_t sport;
2101         sadb_ext_t **extv = ksi->ks_in_extv;
2102         int rc;
2103 
2104         if (extv[SADB_EXT_ADDRESS_SRC] != NULL) {
2105                 rc = sadb_addrcheck(pfkey_q, mp, extv[SADB_EXT_ADDRESS_SRC],
2106                     ksi->ks_in_serial, ns);
2107                 if (rc == KS_IN_ADDR_UNKNOWN)
2108                         return (B_FALSE);
2109                 if (rc == KS_IN_ADDR_MBCAST) {
2110                         sadb_pfkey_error(pfkey_q, mp, EINVAL,
2111                             SADB_X_DIAGNOSTIC_BAD_SRC, ksi->ks_in_serial);
2112                         return (B_FALSE);
2113                 }
2114                 ksi->ks_in_srctype = rc;
2115         }
2116 
2117         if (extv[SADB_EXT_ADDRESS_DST] != NULL) {
2118                 rc = sadb_addrcheck(pfkey_q, mp, extv[SADB_EXT_ADDRESS_DST],
2119                     ksi->ks_in_serial, ns);
2120                 if (rc == KS_IN_ADDR_UNKNOWN)
2121                         return (B_FALSE);
2122                 if (rc == KS_IN_ADDR_UNSPEC) {
2123                         sadb_pfkey_error(pfkey_q, mp, EINVAL,
2124                             SADB_X_DIAGNOSTIC_BAD_DST, ksi->ks_in_serial);
2125                         return (B_FALSE);
2126                 }
2127                 ksi->ks_in_dsttype = rc;
2128         }
2129 
2130         /*
2131          * NAT-Traversal addrs are simple enough to not require all of
2132          * the checks in sadb_addrcheck().  Just normalize or reject if not
2133          * AF_INET.
2134          */
2135         if (extv[SADB_X_EXT_ADDRESS_NATT_LOC] != NULL) {
2136                 rc = sadb_addrcheck(pfkey_q, mp,
2137                     extv[SADB_X_EXT_ADDRESS_NATT_LOC], ksi->ks_in_serial, ns);
2138 
2139                 /*
2140                  * Local NAT-T addresses never use an IRE_LOCAL, so it should
2141                  * always be NOTME, or UNSPEC (to handle both tunnel mode
2142                  * AND local-port flexibility).
2143                  */
2144                 if (rc != KS_IN_ADDR_NOTME && rc != KS_IN_ADDR_UNSPEC) {
2145                         sadb_pfkey_error(pfkey_q, mp, EINVAL,
2146                             SADB_X_DIAGNOSTIC_MALFORMED_NATT_LOC,
2147                             ksi->ks_in_serial);
2148                         return (B_FALSE);
2149                 }
2150                 src = (struct sockaddr_in *)
2151                     (((sadb_address_t *)extv[SADB_X_EXT_ADDRESS_NATT_LOC]) + 1);
2152                 if (src->sin_family != AF_INET) {
2153                         sadb_pfkey_error(pfkey_q, mp, EINVAL,
2154                             SADB_X_DIAGNOSTIC_BAD_NATT_LOC_AF,
2155                             ksi->ks_in_serial);
2156                         return (B_FALSE);
2157                 }
2158         }
2159 
2160         if (extv[SADB_X_EXT_ADDRESS_NATT_REM] != NULL) {
2161                 rc = sadb_addrcheck(pfkey_q, mp,
2162                     extv[SADB_X_EXT_ADDRESS_NATT_REM], ksi->ks_in_serial, ns);
2163 
2164                 /*
2165                  * Remote NAT-T addresses never use an IRE_LOCAL, so it should
2166                  * always be NOTME, or UNSPEC if it's a tunnel-mode SA.
2167                  */
2168                 if (rc != KS_IN_ADDR_NOTME &&
2169                     !(extv[SADB_X_EXT_ADDRESS_INNER_SRC] != NULL &&
2170                     rc == KS_IN_ADDR_UNSPEC)) {
2171                         sadb_pfkey_error(pfkey_q, mp, EINVAL,
2172                             SADB_X_DIAGNOSTIC_MALFORMED_NATT_REM,
2173                             ksi->ks_in_serial);
2174                         return (B_FALSE);
2175                 }
2176                 src = (struct sockaddr_in *)
2177                     (((sadb_address_t *)extv[SADB_X_EXT_ADDRESS_NATT_REM]) + 1);
2178                 if (src->sin_family != AF_INET) {
2179                         sadb_pfkey_error(pfkey_q, mp, EINVAL,
2180                             SADB_X_DIAGNOSTIC_BAD_NATT_REM_AF,
2181                             ksi->ks_in_serial);
2182                         return (B_FALSE);
2183                 }
2184         }
2185 
2186         if (extv[SADB_X_EXT_ADDRESS_INNER_SRC] != NULL) {
2187                 if (extv[SADB_X_EXT_ADDRESS_INNER_DST] == NULL) {
2188                         sadb_pfkey_error(pfkey_q, mp, EINVAL,
2189                             SADB_X_DIAGNOSTIC_MISSING_INNER_DST,
2190                             ksi->ks_in_serial);
2191                         return (B_FALSE);
2192                 }
2193 
2194                 if (sadb_addrcheck(pfkey_q, mp,
2195                     extv[SADB_X_EXT_ADDRESS_INNER_DST], ksi->ks_in_serial, ns)
2196                     == KS_IN_ADDR_UNKNOWN ||
2197                     sadb_addrcheck(pfkey_q, mp,
2198                     extv[SADB_X_EXT_ADDRESS_INNER_SRC], ksi->ks_in_serial, ns)
2199                     == KS_IN_ADDR_UNKNOWN)
2200                         return (B_FALSE);
2201 
2202                 isrc = (struct sockaddr_in *)
2203                     (((sadb_address_t *)extv[SADB_X_EXT_ADDRESS_INNER_SRC]) +
2204                     1);
2205                 idst = (struct sockaddr_in6 *)
2206                     (((sadb_address_t *)extv[SADB_X_EXT_ADDRESS_INNER_DST]) +
2207                     1);
2208                 if (isrc->sin_family != idst->sin6_family) {
2209                         sadb_pfkey_error(pfkey_q, mp, EINVAL,
2210                             SADB_X_DIAGNOSTIC_INNER_AF_MISMATCH,
2211                             ksi->ks_in_serial);
2212                         return (B_FALSE);
2213                 }
2214         } else if (extv[SADB_X_EXT_ADDRESS_INNER_DST] != NULL) {
2215                         sadb_pfkey_error(pfkey_q, mp, EINVAL,
2216                             SADB_X_DIAGNOSTIC_MISSING_INNER_SRC,
2217                             ksi->ks_in_serial);
2218                         return (B_FALSE);
2219         } else {
2220                 isrc = NULL;    /* For inner/outer port check below. */
2221         }
2222 
2223         dstext = (sadb_address_t *)extv[SADB_EXT_ADDRESS_DST];
2224         srcext = (sadb_address_t *)extv[SADB_EXT_ADDRESS_SRC];
2225 
2226         if (dstext == NULL || srcext == NULL)
2227                 return (B_TRUE);
2228 
2229         dst = (struct sockaddr_in6 *)(dstext + 1);
2230         src = (struct sockaddr_in *)(srcext + 1);
2231 
2232         if (isrc != NULL &&
2233             (isrc->sin_port != 0 || idst->sin6_port != 0) &&
2234             (src->sin_port != 0 || dst->sin6_port != 0)) {
2235                 /* Can't set inner and outer ports in one SA. */
2236                 sadb_pfkey_error(pfkey_q, mp, EINVAL,
2237                     SADB_X_DIAGNOSTIC_DUAL_PORT_SETS,
2238                     ksi->ks_in_serial);
2239                 return (B_FALSE);
2240         }
2241 
2242         if (dst->sin6_family == src->sin_family)
2243                 return (B_TRUE);
2244 
2245         if (srcext->sadb_address_proto != dstext->sadb_address_proto) {
2246                 if (srcext->sadb_address_proto == 0) {
2247                         srcext->sadb_address_proto = dstext->sadb_address_proto;
2248                 } else if (dstext->sadb_address_proto == 0) {
2249                         dstext->sadb_address_proto = srcext->sadb_address_proto;
2250                 } else {
2251                         /* Inequal protocols, neither were 0.  Report error. */
2252                         sadb_pfkey_error(pfkey_q, mp, EINVAL,
2253                             SADB_X_DIAGNOSTIC_PROTO_MISMATCH,
2254                             ksi->ks_in_serial);
2255                         return (B_FALSE);
2256                 }
2257         }
2258 
2259         /*
2260          * With the exception of an unspec IPv6 source and an IPv4
2261          * destination, address families MUST me matched.
2262          */
2263         if (src->sin_family == AF_INET ||
2264             ksi->ks_in_srctype != KS_IN_ADDR_UNSPEC) {
2265                 sadb_pfkey_error(pfkey_q, mp, EINVAL,
2266                     SADB_X_DIAGNOSTIC_AF_MISMATCH, ksi->ks_in_serial);
2267                 return (B_FALSE);
2268         }
2269 
2270         /*
2271          * Convert "src" to AF_INET INADDR_ANY.  We rely on sin_port being
2272          * in the same place for sockaddr_in and sockaddr_in6.
2273          */
2274         sport = src->sin_port;
2275         bzero(src, sizeof (*src));
2276         src->sin_family = AF_INET;
2277         src->sin_port = sport;
2278 
2279         return (B_TRUE);
2280 }
2281 
2282 /*
2283  * Set the results in "addrtype", given an IRE as requested by
2284  * sadb_addrcheck().
2285  */
2286 int
2287 sadb_addrset(ire_t *ire)
2288 {
2289         if ((ire->ire_type & IRE_BROADCAST) ||
2290             (ire->ire_ipversion == IPV4_VERSION && CLASSD(ire->ire_addr)) ||
2291             (ire->ire_ipversion == IPV6_VERSION &&
2292             IN6_IS_ADDR_MULTICAST(&(ire->ire_addr_v6))))
2293                 return (KS_IN_ADDR_MBCAST);
2294         if (ire->ire_type & (IRE_LOCAL | IRE_LOOPBACK))
2295                 return (KS_IN_ADDR_ME);
2296         return (KS_IN_ADDR_NOTME);
2297 }
2298 
2299 /*
2300  * Match primitives..
2301  * !!! TODO: short term: inner selectors
2302  *              ipv6 scope id (ifindex)
2303  * longer term:  zone id.  sensitivity label. uid.
2304  */
2305 boolean_t
2306 sadb_match_spi(ipsa_query_t *sq, ipsa_t *sa)
2307 {
2308         return (sq->spi == sa->ipsa_spi);
2309 }
2310 
2311 boolean_t
2312 sadb_match_dst_v6(ipsa_query_t *sq, ipsa_t *sa)
2313 {
2314         return (IPSA_ARE_ADDR_EQUAL(sa->ipsa_dstaddr, sq->dstaddr, AF_INET6));
2315 }
2316 
2317 boolean_t
2318 sadb_match_src_v6(ipsa_query_t *sq, ipsa_t *sa)
2319 {
2320         return (IPSA_ARE_ADDR_EQUAL(sa->ipsa_srcaddr, sq->srcaddr, AF_INET6));
2321 }
2322 
2323 boolean_t
2324 sadb_match_dst_v4(ipsa_query_t *sq, ipsa_t *sa)
2325 {
2326         return (sq->dstaddr[0] == sa->ipsa_dstaddr[0]);
2327 }
2328 
2329 boolean_t
2330 sadb_match_src_v4(ipsa_query_t *sq, ipsa_t *sa)
2331 {
2332         return (sq->srcaddr[0] == sa->ipsa_srcaddr[0]);
2333 }
2334 
2335 boolean_t
2336 sadb_match_dstid(ipsa_query_t *sq, ipsa_t *sa)
2337 {
2338         return ((sa->ipsa_dst_cid != NULL) &&
2339             (sq->didtype == sa->ipsa_dst_cid->ipsid_type) &&
2340             (strcmp(sq->didstr, sa->ipsa_dst_cid->ipsid_cid) == 0));
2341 
2342 }
2343 boolean_t
2344 sadb_match_srcid(ipsa_query_t *sq, ipsa_t *sa)
2345 {
2346         return ((sa->ipsa_src_cid != NULL) &&
2347             (sq->sidtype == sa->ipsa_src_cid->ipsid_type) &&
2348             (strcmp(sq->sidstr, sa->ipsa_src_cid->ipsid_cid) == 0));
2349 }
2350 
2351 boolean_t
2352 sadb_match_kmc(ipsa_query_t *sq, ipsa_t *sa)
2353 {
2354 #define M(a, b) (((a) == 0) || ((b) == 0) || ((a) == (b)))
2355 
2356         return (M(sq->kmc, sa->ipsa_kmc) && M(sq->kmp, sa->ipsa_kmp));
2357 
2358 #undef M
2359 }
2360 
2361 /*
2362  * Common function which extracts several PF_KEY extensions for ease of
2363  * SADB matching.
2364  *
2365  * XXX TODO: weed out ipsa_query_t fields not used during matching
2366  * or afterwards?
2367  */
2368 int
2369 sadb_form_query(keysock_in_t *ksi, uint32_t req, uint32_t match,
2370     ipsa_query_t *sq, int *diagnostic)
2371 {
2372         int i;
2373         ipsa_match_fn_t *mfpp = &(sq->matchers[0]);
2374 
2375         for (i = 0; i < IPSA_NMATCH; i++)
2376                 sq->matchers[i] = NULL;
2377 
2378         ASSERT((req & ~match) == 0);
2379 
2380         sq->req = req;
2381         sq->dstext = (sadb_address_t *)ksi->ks_in_extv[SADB_EXT_ADDRESS_DST];
2382         sq->srcext = (sadb_address_t *)ksi->ks_in_extv[SADB_EXT_ADDRESS_SRC];
2383         sq->assoc = (sadb_sa_t *)ksi->ks_in_extv[SADB_EXT_SA];
2384 
2385         if ((req & IPSA_Q_DST) && (sq->dstext == NULL)) {
2386                 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_DST;
2387                 return (EINVAL);
2388         }
2389         if ((req & IPSA_Q_SRC) && (sq->srcext == NULL)) {
2390                 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_SRC;
2391                 return (EINVAL);
2392         }
2393         if ((req & IPSA_Q_SA) && (sq->assoc == NULL)) {
2394                 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_SA;
2395                 return (EINVAL);
2396         }
2397 
2398         if (match & IPSA_Q_SA) {
2399                 *mfpp++ = sadb_match_spi;
2400                 sq->spi = sq->assoc->sadb_sa_spi;
2401         }
2402 
2403         if (sq->dstext != NULL)
2404                 sq->dst = (struct sockaddr_in *)(sq->dstext + 1);
2405         else {
2406                 sq->dst = NULL;
2407                 sq->dst6 = NULL;
2408                 sq->dstaddr = NULL;
2409         }
2410 
2411         if (sq->srcext != NULL)
2412                 sq->src = (struct sockaddr_in *)(sq->srcext + 1);
2413         else {
2414                 sq->src = NULL;
2415                 sq->src6 = NULL;
2416                 sq->srcaddr = NULL;
2417         }
2418 
2419         if (sq->dst != NULL)
2420                 sq->af = sq->dst->sin_family;
2421         else if (sq->src != NULL)
2422                 sq->af = sq->src->sin_family;
2423         else
2424                 sq->af = AF_INET;
2425 
2426         if (sq->af == AF_INET6) {
2427                 if ((match & IPSA_Q_DST) && (sq->dstext != NULL)) {
2428                         *mfpp++ = sadb_match_dst_v6;
2429                         sq->dst6 = (struct sockaddr_in6 *)sq->dst;
2430                         sq->dstaddr = (uint32_t *)&(sq->dst6->sin6_addr);
2431                 } else {
2432                         match &= ~IPSA_Q_DST;
2433                         sq->dstaddr = ALL_ZEROES_PTR;
2434                 }
2435 
2436                 if ((match & IPSA_Q_SRC) && (sq->srcext != NULL)) {
2437                         sq->src6 = (struct sockaddr_in6 *)(sq->srcext + 1);
2438                         sq->srcaddr = (uint32_t *)&sq->src6->sin6_addr;
2439                         if (sq->src6->sin6_family != AF_INET6) {
2440                                 *diagnostic = SADB_X_DIAGNOSTIC_AF_MISMATCH;
2441                                 return (EINVAL);
2442                         }
2443                         *mfpp++ = sadb_match_src_v6;
2444                 } else {
2445                         match &= ~IPSA_Q_SRC;
2446                         sq->srcaddr = ALL_ZEROES_PTR;
2447                 }
2448         } else {
2449                 sq->src6 = sq->dst6 = NULL;
2450                 if ((match & IPSA_Q_DST) && (sq->dstext != NULL)) {
2451                         *mfpp++ = sadb_match_dst_v4;
2452                         sq->dstaddr = (uint32_t *)&sq->dst->sin_addr;
2453                 } else {
2454                         match &= ~IPSA_Q_DST;
2455                         sq->dstaddr = ALL_ZEROES_PTR;
2456                 }
2457                 if ((match & IPSA_Q_SRC) && (sq->srcext != NULL)) {
2458                         sq->srcaddr = (uint32_t *)&sq->src->sin_addr;
2459                         if (sq->src->sin_family != AF_INET) {
2460                                 *diagnostic = SADB_X_DIAGNOSTIC_AF_MISMATCH;
2461                                 return (EINVAL);
2462                         }
2463                         *mfpp++ = sadb_match_src_v4;
2464                 } else {
2465                         match &= ~IPSA_Q_SRC;
2466                         sq->srcaddr = ALL_ZEROES_PTR;
2467                 }
2468         }
2469 
2470         sq->dstid = (sadb_ident_t *)ksi->ks_in_extv[SADB_EXT_IDENTITY_DST];
2471         if ((match & IPSA_Q_DSTID) && (sq->dstid != NULL)) {
2472                 sq->didstr = (char *)(sq->dstid + 1);
2473                 sq->didtype = sq->dstid->sadb_ident_type;
2474                 *mfpp++ = sadb_match_dstid;
2475         }
2476 
2477         sq->srcid = (sadb_ident_t *)ksi->ks_in_extv[SADB_EXT_IDENTITY_SRC];
2478 
2479         if ((match & IPSA_Q_SRCID) && (sq->srcid != NULL)) {
2480                 sq->sidstr = (char *)(sq->srcid + 1);
2481                 sq->sidtype = sq->srcid->sadb_ident_type;
2482                 *mfpp++ = sadb_match_srcid;
2483         }
2484 
2485         sq->kmcext = (sadb_x_kmc_t *)ksi->ks_in_extv[SADB_X_EXT_KM_COOKIE];
2486         sq->kmc = 0;
2487         sq->kmp = 0;
2488 
2489         if ((match & IPSA_Q_KMC) && (sq->kmcext)) {
2490                 sq->kmc = sq->kmcext->sadb_x_kmc_cookie;
2491                 sq->kmp = sq->kmcext->sadb_x_kmc_proto;
2492                 *mfpp++ = sadb_match_kmc;
2493         }
2494 
2495         if (match & (IPSA_Q_INBOUND|IPSA_Q_OUTBOUND)) {
2496                 if (sq->af == AF_INET6)
2497                         sq->sp = &sq->spp->s_v6;
2498                 else
2499                         sq->sp = &sq->spp->s_v4;
2500         } else {
2501                 sq->sp = NULL;
2502         }
2503 
2504         if (match & IPSA_Q_INBOUND) {
2505                 sq->inhash = INBOUND_HASH(sq->sp, sq->assoc->sadb_sa_spi);
2506                 sq->inbound = &sq->sp->sdb_if[sq->inhash];
2507         } else {
2508                 sq->inhash = 0;
2509                 sq->inbound = NULL;
2510         }
2511 
2512         if (match & IPSA_Q_OUTBOUND) {
2513                 if (sq->af == AF_INET6) {
2514                         sq->outhash = OUTBOUND_HASH_V6(sq->sp, *(sq->dstaddr));
2515                 } else {
2516                         sq->outhash = OUTBOUND_HASH_V4(sq->sp, *(sq->dstaddr));
2517                 }
2518                 sq->outbound = &sq->sp->sdb_of[sq->outhash];
2519         } else {
2520                 sq->outhash = 0;
2521                 sq->outbound = NULL;
2522         }
2523         sq->match = match;
2524         return (0);
2525 }
2526 
2527 /*
2528  * Match an initialized query structure with a security association;
2529  * return B_TRUE on a match, B_FALSE on a miss.
2530  * Applies match functions set up by sadb_form_query() until one returns false.
2531  */
2532 boolean_t
2533 sadb_match_query(ipsa_query_t *sq, ipsa_t *sa)
2534 {
2535         ipsa_match_fn_t *mfpp = &(sq->matchers[0]);
2536         ipsa_match_fn_t mfp;
2537 
2538         for (mfp = *mfpp++; mfp != NULL; mfp = *mfpp++) {
2539                 if (!mfp(sq, sa))
2540                         return (B_FALSE);
2541         }
2542         return (B_TRUE);
2543 }
2544 
2545 /*
2546  * Walker callback function to delete sa's based on src/dst address.
2547  * Assumes that we're called with *head locked, no other locks held;
2548  * Conveniently, and not coincidentally, this is both what sadb_walker
2549  * gives us and also what sadb_unlinkassoc expects.
2550  */
2551 struct sadb_purge_state
2552 {
2553         ipsa_query_t sq;
2554         boolean_t inbnd;
2555         uint8_t sadb_sa_state;
2556 };
2557 
2558 static void
2559 sadb_purge_cb(isaf_t *head, ipsa_t *entry, void *cookie)
2560 {
2561         struct sadb_purge_state *ps = (struct sadb_purge_state *)cookie;
2562 
2563         ASSERT(MUTEX_HELD(&head->isaf_lock));
2564 
2565         mutex_enter(&entry->ipsa_lock);
2566 
2567         if (entry->ipsa_state == IPSA_STATE_LARVAL ||
2568             !sadb_match_query(&ps->sq, entry)) {
2569                 mutex_exit(&entry->ipsa_lock);
2570                 return;
2571         }
2572 
2573         if (ps->inbnd) {
2574                 sadb_delete_cluster(entry);
2575         }
2576         entry->ipsa_state = IPSA_STATE_DEAD;
2577         (void) sadb_torch_assoc(head, entry);
2578 }
2579 
2580 /*
2581  * Common code to purge an SA with a matching src or dst address.
2582  * Don't kill larval SA's in such a purge.
2583  */
2584 int
2585 sadb_purge_sa(mblk_t *mp, keysock_in_t *ksi, sadb_t *sp,
2586         int *diagnostic, queue_t *pfkey_q)
2587 {
2588         struct sadb_purge_state ps;
2589         int error = sadb_form_query(ksi, 0,
2590             IPSA_Q_SRC|IPSA_Q_DST|IPSA_Q_SRCID|IPSA_Q_DSTID|IPSA_Q_KMC,
2591             &ps.sq, diagnostic);
2592 
2593         if (error != 0)
2594                 return (error);
2595 
2596         /*
2597          * This is simple, crude, and effective.
2598          * Unimplemented optimizations (TBD):
2599          * - we can limit how many places we search based on where we
2600          * think the SA is filed.
2601          * - if we get a dst address, we can hash based on dst addr to find
2602          * the correct bucket in the outbound table.
2603          */
2604         ps.inbnd = B_TRUE;
2605         sadb_walker(sp->sdb_if, sp->sdb_hashsize, sadb_purge_cb, &ps);
2606         ps.inbnd = B_FALSE;
2607         sadb_walker(sp->sdb_of, sp->sdb_hashsize, sadb_purge_cb, &ps);
2608 
2609         ASSERT(mp->b_cont != NULL);
2610         sadb_pfkey_echo(pfkey_q, mp, (sadb_msg_t *)mp->b_cont->b_rptr, ksi,
2611             NULL);
2612         return (0);
2613 }
2614 
2615 static void
2616 sadb_delpair_state_one(isaf_t *head, ipsa_t *entry, void *cookie)
2617 {
2618         struct sadb_purge_state *ps = (struct sadb_purge_state *)cookie;
2619         isaf_t  *inbound_bucket;
2620         ipsa_t *peer_assoc;
2621         ipsa_query_t *sq = &ps->sq;
2622 
2623         ASSERT(MUTEX_HELD(&head->isaf_lock));
2624 
2625         mutex_enter(&entry->ipsa_lock);
2626 
2627         if ((entry->ipsa_state != ps->sadb_sa_state) ||
2628             ((sq->srcaddr != NULL) &&
2629             !IPSA_ARE_ADDR_EQUAL(entry->ipsa_srcaddr, sq->srcaddr, sq->af))) {
2630                 mutex_exit(&entry->ipsa_lock);
2631                 return;
2632         }
2633 
2634         /*
2635          * The isaf_t *, which is passed in , is always an outbound bucket,
2636          * and we are preserving the outbound-then-inbound hash-bucket lock
2637          * ordering. The sadb_walker() which triggers this function is called
2638          * only on the outbound fanout, and the corresponding inbound bucket
2639          * lock is safe to acquire here.
2640          */
2641 
2642         if (entry->ipsa_haspeer) {
2643                 inbound_bucket = INBOUND_BUCKET(sq->sp, entry->ipsa_spi);
2644                 mutex_enter(&inbound_bucket->isaf_lock);
2645                 peer_assoc = ipsec_getassocbyspi(inbound_bucket,
2646                     entry->ipsa_spi, entry->ipsa_srcaddr,
2647                     entry->ipsa_dstaddr, entry->ipsa_addrfam);
2648         } else {
2649                 inbound_bucket = INBOUND_BUCKET(sq->sp, entry->ipsa_otherspi);
2650                 mutex_enter(&inbound_bucket->isaf_lock);
2651                 peer_assoc = ipsec_getassocbyspi(inbound_bucket,
2652                     entry->ipsa_otherspi, entry->ipsa_dstaddr,
2653                     entry->ipsa_srcaddr, entry->ipsa_addrfam);
2654         }
2655 
2656         entry->ipsa_state = IPSA_STATE_DEAD;
2657         (void) sadb_torch_assoc(head, entry);
2658         if (peer_assoc != NULL) {
2659                 mutex_enter(&peer_assoc->ipsa_lock);
2660                 peer_assoc->ipsa_state = IPSA_STATE_DEAD;
2661                 (void) sadb_torch_assoc(inbound_bucket, peer_assoc);
2662         }
2663         mutex_exit(&inbound_bucket->isaf_lock);
2664 }
2665 
2666 static int
2667 sadb_delpair_state(mblk_t *mp, keysock_in_t *ksi, sadbp_t *spp,
2668     int *diagnostic, queue_t *pfkey_q)
2669 {
2670         sadb_sa_t *assoc = (sadb_sa_t *)ksi->ks_in_extv[SADB_EXT_SA];
2671         struct sadb_purge_state ps;
2672         int error;
2673 
2674         ps.sq.spp = spp;                /* XXX param */
2675 
2676         error = sadb_form_query(ksi, IPSA_Q_DST|IPSA_Q_SRC,
2677             IPSA_Q_SRC|IPSA_Q_DST|IPSA_Q_SRCID|IPSA_Q_DSTID|IPSA_Q_KMC,
2678             &ps.sq, diagnostic);
2679         if (error != 0)
2680                 return (error);
2681 
2682         ps.inbnd = B_FALSE;
2683         ps.sadb_sa_state = assoc->sadb_sa_state;
2684         sadb_walker(ps.sq.sp->sdb_of, ps.sq.sp->sdb_hashsize,
2685             sadb_delpair_state_one, &ps);
2686 
2687         ASSERT(mp->b_cont != NULL);
2688         sadb_pfkey_echo(pfkey_q, mp, (sadb_msg_t *)mp->b_cont->b_rptr,
2689             ksi, NULL);
2690         return (0);
2691 }
2692 
2693 /*
2694  * Common code to delete/get an SA.
2695  */
2696 int
2697 sadb_delget_sa(mblk_t *mp, keysock_in_t *ksi, sadbp_t *spp,
2698     int *diagnostic, queue_t *pfkey_q, uint8_t sadb_msg_type)
2699 {
2700         ipsa_query_t sq;
2701         ipsa_t *echo_target = NULL;
2702         ipsap_t ipsapp;
2703         uint_t  error = 0;
2704 
2705         if (sadb_msg_type == SADB_X_DELPAIR_STATE)
2706                 return (sadb_delpair_state(mp, ksi, spp, diagnostic, pfkey_q));
2707 
2708         sq.spp = spp;           /* XXX param */
2709         error = sadb_form_query(ksi, IPSA_Q_DST|IPSA_Q_SA,
2710             IPSA_Q_SRC|IPSA_Q_DST|IPSA_Q_SA|IPSA_Q_INBOUND|IPSA_Q_OUTBOUND,
2711             &sq, diagnostic);
2712         if (error != 0)
2713                 return (error);
2714 
2715         error = get_ipsa_pair(&sq, &ipsapp, diagnostic);
2716         if (error != 0) {
2717                 return (error);
2718         }
2719 
2720         echo_target = ipsapp.ipsap_sa_ptr;
2721         if (echo_target == NULL)
2722                 echo_target = ipsapp.ipsap_psa_ptr;
2723 
2724         if (sadb_msg_type == SADB_DELETE || sadb_msg_type == SADB_X_DELPAIR) {
2725                 /*
2726                  * Bucket locks will be required if SA is actually unlinked.
2727                  * get_ipsa_pair() returns valid hash bucket pointers even
2728                  * if it can't find a pair SA pointer. To prevent a potential
2729                  * deadlock, always lock the outbound bucket before the inbound.
2730                  */
2731                 if (ipsapp.in_inbound_table) {
2732                         mutex_enter(&ipsapp.ipsap_pbucket->isaf_lock);
2733                         mutex_enter(&ipsapp.ipsap_bucket->isaf_lock);
2734                 } else {
2735                         mutex_enter(&ipsapp.ipsap_bucket->isaf_lock);
2736                         mutex_enter(&ipsapp.ipsap_pbucket->isaf_lock);
2737                 }
2738 
2739                 if (ipsapp.ipsap_sa_ptr != NULL) {
2740                         mutex_enter(&ipsapp.ipsap_sa_ptr->ipsa_lock);
2741                         if (ipsapp.ipsap_sa_ptr->ipsa_flags & IPSA_F_INBOUND) {
2742                                 sadb_delete_cluster(ipsapp.ipsap_sa_ptr);
2743                         }
2744                         ipsapp.ipsap_sa_ptr->ipsa_state = IPSA_STATE_DEAD;
2745                         (void) sadb_torch_assoc(ipsapp.ipsap_bucket,
2746                             ipsapp.ipsap_sa_ptr);
2747                         /*
2748                          * sadb_torch_assoc() releases the ipsa_lock
2749                          * and calls sadb_unlinkassoc() which does a
2750                          * IPSA_REFRELE.
2751                          */
2752                 }
2753                 if (ipsapp.ipsap_psa_ptr != NULL) {
2754                         mutex_enter(&ipsapp.ipsap_psa_ptr->ipsa_lock);
2755                         if (sadb_msg_type == SADB_X_DELPAIR ||
2756                             ipsapp.ipsap_psa_ptr->ipsa_haspeer) {
2757                                 if (ipsapp.ipsap_psa_ptr->ipsa_flags &
2758                                     IPSA_F_INBOUND) {
2759                                         sadb_delete_cluster
2760                                             (ipsapp.ipsap_psa_ptr);
2761                                 }
2762                                 ipsapp.ipsap_psa_ptr->ipsa_state =
2763                                     IPSA_STATE_DEAD;
2764                                 (void) sadb_torch_assoc(ipsapp.ipsap_pbucket,
2765                                     ipsapp.ipsap_psa_ptr);
2766                         } else {
2767                                 /*
2768                                  * Only half of the "pair" has been deleted.
2769                                  * Update the remaining SA and remove references
2770                                  * to its pair SA, which is now gone.
2771                                  */
2772                                 ipsapp.ipsap_psa_ptr->ipsa_otherspi = 0;
2773                                 ipsapp.ipsap_psa_ptr->ipsa_flags &=
2774                                     ~IPSA_F_PAIRED;
2775                                 mutex_exit(&ipsapp.ipsap_psa_ptr->ipsa_lock);
2776                         }
2777                 } else if (sadb_msg_type == SADB_X_DELPAIR) {
2778                         *diagnostic = SADB_X_DIAGNOSTIC_PAIR_SA_NOTFOUND;
2779                         error = ESRCH;
2780                 }
2781                 mutex_exit(&ipsapp.ipsap_bucket->isaf_lock);
2782                 mutex_exit(&ipsapp.ipsap_pbucket->isaf_lock);
2783         }
2784 
2785         ASSERT(mp->b_cont != NULL);
2786 
2787         if (error == 0)
2788                 sadb_pfkey_echo(pfkey_q, mp, (sadb_msg_t *)
2789                     mp->b_cont->b_rptr, ksi, echo_target);
2790 
2791         destroy_ipsa_pair(&ipsapp);
2792 
2793         return (error);
2794 }
2795 
2796 /*
2797  * This function takes a sadb_sa_t and finds the ipsa_t structure
2798  * and the isaf_t (hash bucket) that its stored under. If the security
2799  * association has a peer, the ipsa_t structure and bucket for that security
2800  * association are also searched for. The "pair" of ipsa_t's and isaf_t's
2801  * are returned as a ipsap_t.
2802  *
2803  * The hash buckets are returned for convenience, if the calling function
2804  * needs to use the hash bucket locks, say to remove the SA's, it should
2805  * take care to observe the convention of locking outbound bucket then
2806  * inbound bucket. The flag in_inbound_table provides direction.
2807  *
2808  * Note that a "pair" is defined as one (but not both) of the following:
2809  *
2810  * A security association which has a soft reference to another security
2811  * association via its SPI.
2812  *
2813  * A security association that is not obviously "inbound" or "outbound" so
2814  * it appears in both hash tables, the "peer" being the same security
2815  * association in the other hash table.
2816  *
2817  * This function will return NULL if the ipsa_t can't be found in the
2818  * inbound or outbound  hash tables (not found). If only one ipsa_t is
2819  * found, the pair ipsa_t will be NULL. Both isaf_t values are valid
2820  * provided at least one ipsa_t is found.
2821  */
2822 static int
2823 get_ipsa_pair(ipsa_query_t *sq, ipsap_t *ipsapp, int *diagnostic)
2824 {
2825         uint32_t pair_srcaddr[IPSA_MAX_ADDRLEN];
2826         uint32_t pair_dstaddr[IPSA_MAX_ADDRLEN];
2827         uint32_t pair_spi;
2828 
2829         init_ipsa_pair(ipsapp);
2830 
2831         ipsapp->in_inbound_table = B_FALSE;
2832 
2833         /* Lock down both buckets. */
2834         mutex_enter(&sq->outbound->isaf_lock);
2835         mutex_enter(&sq->inbound->isaf_lock);
2836 
2837         if (sq->assoc->sadb_sa_flags & IPSA_F_INBOUND) {
2838                 ipsapp->ipsap_sa_ptr = ipsec_getassocbyspi(sq->inbound,
2839                     sq->assoc->sadb_sa_spi, sq->srcaddr, sq->dstaddr, sq->af);
2840                 if (ipsapp->ipsap_sa_ptr != NULL) {
2841                         ipsapp->ipsap_bucket = sq->inbound;
2842                         ipsapp->ipsap_pbucket = sq->outbound;
2843                         ipsapp->in_inbound_table = B_TRUE;
2844                 } else {
2845                         ipsapp->ipsap_sa_ptr = ipsec_getassocbyspi(sq->outbound,
2846                             sq->assoc->sadb_sa_spi, sq->srcaddr, sq->dstaddr,
2847                             sq->af);
2848                         ipsapp->ipsap_bucket = sq->outbound;
2849                         ipsapp->ipsap_pbucket = sq->inbound;
2850                 }
2851         } else {
2852                 /* IPSA_F_OUTBOUND is set *or* no directions flags set. */
2853                 ipsapp->ipsap_sa_ptr =
2854                     ipsec_getassocbyspi(sq->outbound,
2855                     sq->assoc->sadb_sa_spi, sq->srcaddr, sq->dstaddr, sq->af);
2856                 if (ipsapp->ipsap_sa_ptr != NULL) {
2857                         ipsapp->ipsap_bucket = sq->outbound;
2858                         ipsapp->ipsap_pbucket = sq->inbound;
2859                 } else {
2860                         ipsapp->ipsap_sa_ptr = ipsec_getassocbyspi(sq->inbound,
2861                             sq->assoc->sadb_sa_spi, sq->srcaddr, sq->dstaddr,
2862                             sq->af);
2863                         ipsapp->ipsap_bucket = sq->inbound;
2864                         ipsapp->ipsap_pbucket = sq->outbound;
2865                         if (ipsapp->ipsap_sa_ptr != NULL)
2866                                 ipsapp->in_inbound_table = B_TRUE;
2867                 }
2868         }
2869 
2870         if (ipsapp->ipsap_sa_ptr == NULL) {
2871                 mutex_exit(&sq->outbound->isaf_lock);
2872                 mutex_exit(&sq->inbound->isaf_lock);
2873                 *diagnostic = SADB_X_DIAGNOSTIC_SA_NOTFOUND;
2874                 return (ESRCH);
2875         }
2876 
2877         if ((ipsapp->ipsap_sa_ptr->ipsa_state == IPSA_STATE_LARVAL) &&
2878             ipsapp->in_inbound_table) {
2879                 mutex_exit(&sq->outbound->isaf_lock);
2880                 mutex_exit(&sq->inbound->isaf_lock);
2881                 return (0);
2882         }
2883 
2884         mutex_enter(&ipsapp->ipsap_sa_ptr->ipsa_lock);
2885         if (ipsapp->ipsap_sa_ptr->ipsa_haspeer) {
2886                 /*
2887                  * haspeer implies no sa_pairing, look for same spi
2888                  * in other hashtable.
2889                  */
2890                 ipsapp->ipsap_psa_ptr =
2891                     ipsec_getassocbyspi(ipsapp->ipsap_pbucket,
2892                     sq->assoc->sadb_sa_spi, sq->srcaddr, sq->dstaddr, sq->af);
2893                 mutex_exit(&ipsapp->ipsap_sa_ptr->ipsa_lock);
2894                 mutex_exit(&sq->outbound->isaf_lock);
2895                 mutex_exit(&sq->inbound->isaf_lock);
2896                 return (0);
2897         }
2898         pair_spi = ipsapp->ipsap_sa_ptr->ipsa_otherspi;
2899         IPSA_COPY_ADDR(&pair_srcaddr,
2900             ipsapp->ipsap_sa_ptr->ipsa_srcaddr, sq->af);
2901         IPSA_COPY_ADDR(&pair_dstaddr,
2902             ipsapp->ipsap_sa_ptr->ipsa_dstaddr, sq->af);
2903         mutex_exit(&ipsapp->ipsap_sa_ptr->ipsa_lock);
2904         mutex_exit(&sq->inbound->isaf_lock);
2905         mutex_exit(&sq->outbound->isaf_lock);
2906 
2907         if (pair_spi == 0) {
2908                 ASSERT(ipsapp->ipsap_bucket != NULL);
2909                 ASSERT(ipsapp->ipsap_pbucket != NULL);
2910                 return (0);
2911         }
2912 
2913         /* found sa in outbound sadb, peer should be inbound */
2914 
2915         if (ipsapp->in_inbound_table) {
2916                 /* Found SA in inbound table, pair will be in outbound. */
2917                 if (sq->af == AF_INET6) {
2918                         ipsapp->ipsap_pbucket = OUTBOUND_BUCKET_V6(sq->sp,
2919                             *(uint32_t *)pair_srcaddr);
2920                 } else {
2921                         ipsapp->ipsap_pbucket = OUTBOUND_BUCKET_V4(sq->sp,
2922                             *(uint32_t *)pair_srcaddr);
2923                 }
2924         } else {
2925                 ipsapp->ipsap_pbucket = INBOUND_BUCKET(sq->sp, pair_spi);
2926         }
2927         mutex_enter(&ipsapp->ipsap_pbucket->isaf_lock);
2928         ipsapp->ipsap_psa_ptr = ipsec_getassocbyspi(ipsapp->ipsap_pbucket,
2929             pair_spi, pair_dstaddr, pair_srcaddr, sq->af);
2930         mutex_exit(&ipsapp->ipsap_pbucket->isaf_lock);
2931         ASSERT(ipsapp->ipsap_bucket != NULL);
2932         ASSERT(ipsapp->ipsap_pbucket != NULL);
2933         return (0);
2934 }
2935 
2936 /*
2937  * Perform NAT-traversal cached checksum offset calculations here.
2938  */
2939 static void
2940 sadb_nat_calculations(ipsa_t *newbie, sadb_address_t *natt_loc_ext,
2941     sadb_address_t *natt_rem_ext, uint32_t *src_addr_ptr,
2942     uint32_t *dst_addr_ptr)
2943 {
2944         struct sockaddr_in *natt_loc, *natt_rem;
2945         uint32_t *natt_loc_ptr = NULL, *natt_rem_ptr = NULL;
2946         uint32_t running_sum = 0;
2947 
2948 #define DOWN_SUM(x) (x) = ((x) & 0xFFFF) +   ((x) >> 16)
2949 
2950         if (natt_rem_ext != NULL) {
2951                 uint32_t l_src;
2952                 uint32_t l_rem;
2953 
2954                 natt_rem = (struct sockaddr_in *)(natt_rem_ext + 1);
2955 
2956                 /* Ensured by sadb_addrfix(). */
2957                 ASSERT(natt_rem->sin_family == AF_INET);
2958 
2959                 natt_rem_ptr = (uint32_t *)(&natt_rem->sin_addr);
2960                 newbie->ipsa_remote_nat_port = natt_rem->sin_port;
2961                 l_src = *src_addr_ptr;
2962                 l_rem = *natt_rem_ptr;
2963 
2964                 /* Instead of IPSA_COPY_ADDR(), just copy first 32 bits. */
2965                 newbie->ipsa_natt_addr_rem = *natt_rem_ptr;
2966 
2967                 l_src = ntohl(l_src);
2968                 DOWN_SUM(l_src);
2969                 DOWN_SUM(l_src);
2970                 l_rem = ntohl(l_rem);
2971                 DOWN_SUM(l_rem);
2972                 DOWN_SUM(l_rem);
2973 
2974                 /*
2975                  * We're 1's complement for checksums, so check for wraparound
2976                  * here.
2977                  */
2978                 if (l_rem > l_src)
2979                         l_src--;
2980 
2981                 running_sum += l_src - l_rem;
2982 
2983                 DOWN_SUM(running_sum);
2984                 DOWN_SUM(running_sum);
2985         }
2986 
2987         if (natt_loc_ext != NULL) {
2988                 natt_loc = (struct sockaddr_in *)(natt_loc_ext + 1);
2989 
2990                 /* Ensured by sadb_addrfix(). */
2991                 ASSERT(natt_loc->sin_family == AF_INET);
2992 
2993                 natt_loc_ptr = (uint32_t *)(&natt_loc->sin_addr);
2994                 newbie->ipsa_local_nat_port = natt_loc->sin_port;
2995 
2996                 /* Instead of IPSA_COPY_ADDR(), just copy first 32 bits. */
2997                 newbie->ipsa_natt_addr_loc = *natt_loc_ptr;
2998 
2999                 /*
3000                  * NAT-T port agility means we may have natt_loc_ext, but
3001                  * only for a local-port change.
3002                  */
3003                 if (natt_loc->sin_addr.s_addr != INADDR_ANY) {
3004                         uint32_t l_dst = ntohl(*dst_addr_ptr);
3005                         uint32_t l_loc = ntohl(*natt_loc_ptr);
3006 
3007                         DOWN_SUM(l_loc);
3008                         DOWN_SUM(l_loc);
3009                         DOWN_SUM(l_dst);
3010                         DOWN_SUM(l_dst);
3011 
3012                         /*
3013                          * We're 1's complement for checksums, so check for
3014                          * wraparound here.
3015                          */
3016                         if (l_loc > l_dst)
3017                                 l_dst--;
3018 
3019                         running_sum += l_dst - l_loc;
3020                         DOWN_SUM(running_sum);
3021                         DOWN_SUM(running_sum);
3022                 }
3023         }
3024 
3025         newbie->ipsa_inbound_cksum = running_sum;
3026 #undef DOWN_SUM
3027 }
3028 
3029 /*
3030  * This function is called from consumers that need to insert a fully-grown
3031  * security association into its tables.  This function takes into account that
3032  * SAs can be "inbound", "outbound", or "both".  The "primary" and "secondary"
3033  * hash bucket parameters are set in order of what the SA will be most of the
3034  * time.  (For example, an SA with an unspecified source, and a multicast
3035  * destination will primarily be an outbound SA.  OTOH, if that destination
3036  * is unicast for this node, then the SA will primarily be inbound.)
3037  *
3038  * It takes a lot of parameters because even if clone is B_FALSE, this needs
3039  * to check both buckets for purposes of collision.
3040  *
3041  * Return 0 upon success.  Return various errnos (ENOMEM, EEXIST) for
3042  * various error conditions.  We may need to set samsg->sadb_x_msg_diagnostic
3043  * with additional diagnostic information because there is at least one EINVAL
3044  * case here.
3045  */
3046 int
3047 sadb_common_add(queue_t *pfkey_q, mblk_t *mp, sadb_msg_t *samsg,
3048     keysock_in_t *ksi, isaf_t *primary, isaf_t *secondary,
3049     ipsa_t *newbie, boolean_t clone, boolean_t is_inbound, int *diagnostic,
3050     netstack_t *ns, sadbp_t *spp)
3051 {
3052         ipsa_t *newbie_clone = NULL, *scratch;
3053         ipsap_t ipsapp;
3054         sadb_sa_t *assoc = (sadb_sa_t *)ksi->ks_in_extv[SADB_EXT_SA];
3055         sadb_address_t *srcext =
3056             (sadb_address_t *)ksi->ks_in_extv[SADB_EXT_ADDRESS_SRC];
3057         sadb_address_t *dstext =
3058             (sadb_address_t *)ksi->ks_in_extv[SADB_EXT_ADDRESS_DST];
3059         sadb_address_t *isrcext =
3060             (sadb_address_t *)ksi->ks_in_extv[SADB_X_EXT_ADDRESS_INNER_SRC];
3061         sadb_address_t *idstext =
3062             (sadb_address_t *)ksi->ks_in_extv[SADB_X_EXT_ADDRESS_INNER_DST];
3063         sadb_x_kmc_t *kmcext =
3064             (sadb_x_kmc_t *)ksi->ks_in_extv[SADB_X_EXT_KM_COOKIE];
3065         sadb_key_t *akey = (sadb_key_t *)ksi->ks_in_extv[SADB_EXT_KEY_AUTH];
3066         sadb_key_t *ekey = (sadb_key_t *)ksi->ks_in_extv[SADB_EXT_KEY_ENCRYPT];
3067         sadb_sens_t *sens =
3068             (sadb_sens_t *)ksi->ks_in_extv[SADB_EXT_SENSITIVITY];
3069         sadb_sens_t *osens =
3070             (sadb_sens_t *)ksi->ks_in_extv[SADB_X_EXT_OUTER_SENS];
3071         sadb_x_pair_t *pair_ext =
3072             (sadb_x_pair_t *)ksi->ks_in_extv[SADB_X_EXT_PAIR];
3073         sadb_x_replay_ctr_t *replayext =
3074             (sadb_x_replay_ctr_t *)ksi->ks_in_extv[SADB_X_EXT_REPLAY_VALUE];
3075         uint8_t protocol =
3076             (samsg->sadb_msg_satype == SADB_SATYPE_AH) ? IPPROTO_AH:IPPROTO_ESP;
3077         int salt_offset;
3078         uint8_t *buf_ptr;
3079         struct sockaddr_in *src, *dst, *isrc, *idst;
3080         struct sockaddr_in6 *src6, *dst6, *isrc6, *idst6;
3081         sadb_lifetime_t *soft =
3082             (sadb_lifetime_t *)ksi->ks_in_extv[SADB_EXT_LIFETIME_SOFT];
3083         sadb_lifetime_t *hard =
3084             (sadb_lifetime_t *)ksi->ks_in_extv[SADB_EXT_LIFETIME_HARD];
3085         sadb_lifetime_t *idle =
3086             (sadb_lifetime_t *)ksi->ks_in_extv[SADB_X_EXT_LIFETIME_IDLE];
3087         sa_family_t af;
3088         int error = 0;
3089         boolean_t isupdate = (newbie != NULL);
3090         uint32_t *src_addr_ptr, *dst_addr_ptr, *isrc_addr_ptr, *idst_addr_ptr;
3091         ipsec_stack_t   *ipss = ns->netstack_ipsec;
3092         ip_stack_t      *ipst = ns->netstack_ip;
3093         ipsec_alginfo_t *alg;
3094         int             rcode;
3095         boolean_t       async = B_FALSE;
3096 
3097         init_ipsa_pair(&ipsapp);
3098 
3099         if (srcext == NULL) {
3100                 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_SRC;
3101                 return (EINVAL);
3102         }
3103         if (dstext == NULL) {
3104                 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_DST;
3105                 return (EINVAL);
3106         }
3107         if (assoc == NULL) {
3108                 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_SA;
3109                 return (EINVAL);
3110         }
3111 
3112         src = (struct sockaddr_in *)(srcext + 1);
3113         src6 = (struct sockaddr_in6 *)(srcext + 1);
3114         dst = (struct sockaddr_in *)(dstext + 1);
3115         dst6 = (struct sockaddr_in6 *)(dstext + 1);
3116         if (isrcext != NULL) {
3117                 isrc = (struct sockaddr_in *)(isrcext + 1);
3118                 isrc6 = (struct sockaddr_in6 *)(isrcext + 1);
3119                 ASSERT(idstext != NULL);
3120                 idst = (struct sockaddr_in *)(idstext + 1);
3121                 idst6 = (struct sockaddr_in6 *)(idstext + 1);
3122         } else {
3123                 isrc = NULL;
3124                 isrc6 = NULL;
3125         }
3126 
3127         af = src->sin_family;
3128 
3129         if (af == AF_INET) {
3130                 src_addr_ptr = (uint32_t *)&src->sin_addr;
3131                 dst_addr_ptr = (uint32_t *)&dst->sin_addr;
3132         } else {
3133                 ASSERT(af == AF_INET6);
3134                 src_addr_ptr = (uint32_t *)&src6->sin6_addr;
3135                 dst_addr_ptr = (uint32_t *)&dst6->sin6_addr;
3136         }
3137 
3138         if (!isupdate && (clone == B_TRUE || is_inbound == B_TRUE) &&
3139             cl_inet_checkspi &&
3140             (assoc->sadb_sa_state != SADB_X_SASTATE_ACTIVE_ELSEWHERE)) {
3141                 rcode = cl_inet_checkspi(ns->netstack_stackid, protocol,
3142                     assoc->sadb_sa_spi, NULL);
3143                 if (rcode == -1) {
3144                         return (EEXIST);
3145                 }
3146         }
3147 
3148         /*
3149          * Check to see if the new SA will be cloned AND paired. The
3150          * reason a SA will be cloned is the source or destination addresses
3151          * are not specific enough to determine if the SA goes in the outbound
3152          * or the inbound hash table, so its cloned and put in both. If
3153          * the SA is paired, it's soft linked to another SA for the other
3154          * direction. Keeping track and looking up SA's that are direction
3155          * unspecific and linked is too hard.
3156          */
3157         if (clone && (pair_ext != NULL)) {
3158                 *diagnostic = SADB_X_DIAGNOSTIC_PAIR_INAPPROPRIATE;
3159                 return (EINVAL);
3160         }
3161 
3162         if (!isupdate) {
3163                 newbie = sadb_makelarvalassoc(assoc->sadb_sa_spi,
3164                     src_addr_ptr, dst_addr_ptr, af, ns);
3165                 if (newbie == NULL)
3166                         return (ENOMEM);
3167         }
3168 
3169         mutex_enter(&newbie->ipsa_lock);
3170 
3171         if (isrc != NULL) {
3172                 if (isrc->sin_family == AF_INET) {
3173                         if (srcext->sadb_address_proto != IPPROTO_ENCAP) {
3174                                 if (srcext->sadb_address_proto != 0) {
3175                                         /*
3176                                          * Mismatched outer-packet protocol
3177                                          * and inner-packet address family.
3178                                          */
3179                                         mutex_exit(&newbie->ipsa_lock);
3180                                         error = EPROTOTYPE;
3181                                         *diagnostic =
3182                                             SADB_X_DIAGNOSTIC_INNER_AF_MISMATCH;
3183                                         goto error;
3184                                 } else {
3185                                         /* Fill in with explicit protocol. */
3186                                         srcext->sadb_address_proto =
3187                                             IPPROTO_ENCAP;
3188                                         dstext->sadb_address_proto =
3189                                             IPPROTO_ENCAP;
3190                                 }
3191                         }
3192                         isrc_addr_ptr = (uint32_t *)&isrc->sin_addr;
3193                         idst_addr_ptr = (uint32_t *)&idst->sin_addr;
3194                 } else {
3195                         ASSERT(isrc->sin_family == AF_INET6);
3196                         if (srcext->sadb_address_proto != IPPROTO_IPV6) {
3197                                 if (srcext->sadb_address_proto != 0) {
3198                                         /*
3199                                          * Mismatched outer-packet protocol
3200                                          * and inner-packet address family.
3201                                          */
3202                                         mutex_exit(&newbie->ipsa_lock);
3203                                         error = EPROTOTYPE;
3204                                         *diagnostic =
3205                                             SADB_X_DIAGNOSTIC_INNER_AF_MISMATCH;
3206                                         goto error;
3207                                 } else {
3208                                         /* Fill in with explicit protocol. */
3209                                         srcext->sadb_address_proto =
3210                                             IPPROTO_IPV6;
3211                                         dstext->sadb_address_proto =
3212                                             IPPROTO_IPV6;
3213                                 }
3214                         }
3215                         isrc_addr_ptr = (uint32_t *)&isrc6->sin6_addr;
3216                         idst_addr_ptr = (uint32_t *)&idst6->sin6_addr;
3217                 }
3218                 newbie->ipsa_innerfam = isrc->sin_family;
3219 
3220                 IPSA_COPY_ADDR(newbie->ipsa_innersrc, isrc_addr_ptr,
3221                     newbie->ipsa_innerfam);
3222                 IPSA_COPY_ADDR(newbie->ipsa_innerdst, idst_addr_ptr,
3223                     newbie->ipsa_innerfam);
3224                 newbie->ipsa_innersrcpfx = isrcext->sadb_address_prefixlen;
3225                 newbie->ipsa_innerdstpfx = idstext->sadb_address_prefixlen;
3226 
3227                 /* Unique value uses inner-ports for Tunnel Mode... */
3228                 newbie->ipsa_unique_id = SA_UNIQUE_ID(isrc->sin_port,
3229                     idst->sin_port, dstext->sadb_address_proto,
3230                     idstext->sadb_address_proto);
3231                 newbie->ipsa_unique_mask = SA_UNIQUE_MASK(isrc->sin_port,
3232                     idst->sin_port, dstext->sadb_address_proto,
3233                     idstext->sadb_address_proto);
3234         } else {
3235                 /* ... and outer-ports for Transport Mode. */
3236                 newbie->ipsa_unique_id = SA_UNIQUE_ID(src->sin_port,
3237                     dst->sin_port, dstext->sadb_address_proto, 0);
3238                 newbie->ipsa_unique_mask = SA_UNIQUE_MASK(src->sin_port,
3239                     dst->sin_port, dstext->sadb_address_proto, 0);
3240         }
3241         if (newbie->ipsa_unique_mask != (uint64_t)0)
3242                 newbie->ipsa_flags |= IPSA_F_UNIQUE;
3243 
3244         sadb_nat_calculations(newbie,
3245             (sadb_address_t *)ksi->ks_in_extv[SADB_X_EXT_ADDRESS_NATT_LOC],
3246             (sadb_address_t *)ksi->ks_in_extv[SADB_X_EXT_ADDRESS_NATT_REM],
3247             src_addr_ptr, dst_addr_ptr);
3248 
3249         newbie->ipsa_type = samsg->sadb_msg_satype;
3250 
3251         ASSERT((assoc->sadb_sa_state == SADB_SASTATE_MATURE) ||
3252             (assoc->sadb_sa_state == SADB_X_SASTATE_ACTIVE_ELSEWHERE));
3253         newbie->ipsa_auth_alg = assoc->sadb_sa_auth;
3254         newbie->ipsa_encr_alg = assoc->sadb_sa_encrypt;
3255 
3256         newbie->ipsa_flags |= assoc->sadb_sa_flags;
3257         if (newbie->ipsa_flags & SADB_X_SAFLAGS_NATT_LOC &&
3258             ksi->ks_in_extv[SADB_X_EXT_ADDRESS_NATT_LOC] == NULL) {
3259                 mutex_exit(&newbie->ipsa_lock);
3260                 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_NATT_LOC;
3261                 error = EINVAL;
3262                 goto error;
3263         }
3264         if (newbie->ipsa_flags & SADB_X_SAFLAGS_NATT_REM &&
3265             ksi->ks_in_extv[SADB_X_EXT_ADDRESS_NATT_REM] == NULL) {
3266                 mutex_exit(&newbie->ipsa_lock);
3267                 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_NATT_REM;
3268                 error = EINVAL;
3269                 goto error;
3270         }
3271         if (newbie->ipsa_flags & SADB_X_SAFLAGS_TUNNEL &&
3272             ksi->ks_in_extv[SADB_X_EXT_ADDRESS_INNER_SRC] == NULL) {
3273                 mutex_exit(&newbie->ipsa_lock);
3274                 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_INNER_SRC;
3275                 error = EINVAL;
3276                 goto error;
3277         }
3278         /*
3279          * If unspecified source address, force replay_wsize to 0.
3280          * This is because an SA that has multiple sources of secure
3281          * traffic cannot enforce a replay counter w/o synchronizing the
3282          * senders.
3283          */
3284         if (ksi->ks_in_srctype != KS_IN_ADDR_UNSPEC)
3285                 newbie->ipsa_replay_wsize = assoc->sadb_sa_replay;
3286         else
3287                 newbie->ipsa_replay_wsize = 0;
3288 
3289         newbie->ipsa_addtime = gethrestime_sec();
3290 
3291         if (kmcext != NULL) {
3292                 newbie->ipsa_kmp = kmcext->sadb_x_kmc_proto;
3293                 newbie->ipsa_kmc = kmcext->sadb_x_kmc_cookie;
3294         }
3295 
3296         /*
3297          * XXX CURRENT lifetime checks MAY BE needed for an UPDATE.
3298          * The spec says that one can update current lifetimes, but
3299          * that seems impractical, especially in the larval-to-mature
3300          * update that this function performs.
3301          */
3302         if (soft != NULL) {
3303                 newbie->ipsa_softaddlt = soft->sadb_lifetime_addtime;
3304                 newbie->ipsa_softuselt = soft->sadb_lifetime_usetime;
3305                 newbie->ipsa_softbyteslt = soft->sadb_lifetime_bytes;
3306                 newbie->ipsa_softalloc = soft->sadb_lifetime_allocations;
3307                 SET_EXPIRE(newbie, softaddlt, softexpiretime);
3308         }
3309         if (hard != NULL) {
3310                 newbie->ipsa_hardaddlt = hard->sadb_lifetime_addtime;
3311                 newbie->ipsa_harduselt = hard->sadb_lifetime_usetime;
3312                 newbie->ipsa_hardbyteslt = hard->sadb_lifetime_bytes;
3313                 newbie->ipsa_hardalloc = hard->sadb_lifetime_allocations;
3314                 SET_EXPIRE(newbie, hardaddlt, hardexpiretime);
3315         }
3316         if (idle != NULL) {
3317                 newbie->ipsa_idleaddlt = idle->sadb_lifetime_addtime;
3318                 newbie->ipsa_idleuselt = idle->sadb_lifetime_usetime;
3319                 newbie->ipsa_idleexpiretime = newbie->ipsa_addtime +
3320                     newbie->ipsa_idleaddlt;
3321                 newbie->ipsa_idletime = newbie->ipsa_idleaddlt;
3322         }
3323 
3324         newbie->ipsa_authtmpl = NULL;
3325         newbie->ipsa_encrtmpl = NULL;
3326 
3327 #ifdef IPSEC_LATENCY_TEST
3328         if (akey != NULL && newbie->ipsa_auth_alg != SADB_AALG_NONE) {
3329 #else
3330         if (akey != NULL) {
3331 #endif
3332                 async = (ipss->ipsec_algs_exec_mode[IPSEC_ALG_AUTH] ==
3333                     IPSEC_ALGS_EXEC_ASYNC);
3334 
3335                 newbie->ipsa_authkeybits = akey->sadb_key_bits;
3336                 newbie->ipsa_authkeylen = SADB_1TO8(akey->sadb_key_bits);
3337                 /* In case we have to round up to the next byte... */
3338                 if ((akey->sadb_key_bits & 0x7) != 0)
3339                         newbie->ipsa_authkeylen++;
3340                 newbie->ipsa_authkey = kmem_alloc(newbie->ipsa_authkeylen,
3341                     KM_NOSLEEP);
3342                 if (newbie->ipsa_authkey == NULL) {
3343                         error = ENOMEM;
3344                         mutex_exit(&newbie->ipsa_lock);
3345                         goto error;
3346                 }
3347                 bcopy(akey + 1, newbie->ipsa_authkey, newbie->ipsa_authkeylen);
3348                 bzero(akey + 1, newbie->ipsa_authkeylen);
3349 
3350                 /*
3351                  * Pre-initialize the kernel crypto framework key
3352                  * structure.
3353                  */
3354                 newbie->ipsa_kcfauthkey.ck_format = CRYPTO_KEY_RAW;
3355                 newbie->ipsa_kcfauthkey.ck_length = newbie->ipsa_authkeybits;
3356                 newbie->ipsa_kcfauthkey.ck_data = newbie->ipsa_authkey;
3357 
3358                 rw_enter(&ipss->ipsec_alg_lock, RW_READER);
3359                 alg = ipss->ipsec_alglists[IPSEC_ALG_AUTH]
3360                     [newbie->ipsa_auth_alg];
3361                 if (alg != NULL && ALG_VALID(alg)) {
3362                         newbie->ipsa_amech.cm_type = alg->alg_mech_type;
3363                         newbie->ipsa_amech.cm_param =
3364                             (char *)&newbie->ipsa_mac_len;
3365                         newbie->ipsa_amech.cm_param_len = sizeof (size_t);
3366                         newbie->ipsa_mac_len = (size_t)alg->alg_datalen;
3367                 } else {
3368                         newbie->ipsa_amech.cm_type = CRYPTO_MECHANISM_INVALID;
3369                 }
3370                 error = ipsec_create_ctx_tmpl(newbie, IPSEC_ALG_AUTH);
3371                 rw_exit(&ipss->ipsec_alg_lock);
3372                 if (error != 0) {
3373                         mutex_exit(&newbie->ipsa_lock);
3374                         /*
3375                          * An error here indicates that alg is the wrong type
3376                          * (IE: not authentication) or its not in the alg tables
3377                          * created by ipsecalgs(1m), or Kcf does not like the
3378                          * parameters passed in with this algorithm, which is
3379                          * probably a coding error!
3380                          */
3381                         *diagnostic = SADB_X_DIAGNOSTIC_BAD_CTX;
3382 
3383                         goto error;
3384                 }
3385         }
3386 
3387         if (ekey != NULL) {
3388                 rw_enter(&ipss->ipsec_alg_lock, RW_READER);
3389                 async = async || (ipss->ipsec_algs_exec_mode[IPSEC_ALG_ENCR] ==
3390                     IPSEC_ALGS_EXEC_ASYNC);
3391                 alg = ipss->ipsec_alglists[IPSEC_ALG_ENCR]
3392                     [newbie->ipsa_encr_alg];
3393 
3394                 if (alg != NULL && ALG_VALID(alg)) {
3395                         newbie->ipsa_emech.cm_type = alg->alg_mech_type;
3396                         newbie->ipsa_datalen = alg->alg_datalen;
3397                         if (alg->alg_flags & ALG_FLAG_COUNTERMODE)
3398                                 newbie->ipsa_flags |= IPSA_F_COUNTERMODE;
3399 
3400                         if (alg->alg_flags & ALG_FLAG_COMBINED) {
3401                                 newbie->ipsa_flags |= IPSA_F_COMBINED;
3402                                 newbie->ipsa_mac_len =  alg->alg_icvlen;
3403                         }
3404 
3405                         if (alg->alg_flags & ALG_FLAG_CCM)
3406                                 newbie->ipsa_noncefunc = ccm_params_init;
3407                         else if (alg->alg_flags & ALG_FLAG_GCM)
3408                                 newbie->ipsa_noncefunc = gcm_params_init;
3409                         else newbie->ipsa_noncefunc = cbc_params_init;
3410 
3411                         newbie->ipsa_saltlen = alg->alg_saltlen;
3412                         newbie->ipsa_saltbits = SADB_8TO1(newbie->ipsa_saltlen);
3413                         newbie->ipsa_iv_len = alg->alg_ivlen;
3414                         newbie->ipsa_nonce_len = newbie->ipsa_saltlen +
3415                             newbie->ipsa_iv_len;
3416                         newbie->ipsa_emech.cm_param = NULL;
3417                         newbie->ipsa_emech.cm_param_len = 0;
3418                 } else {
3419                         newbie->ipsa_emech.cm_type = CRYPTO_MECHANISM_INVALID;
3420                 }
3421                 rw_exit(&ipss->ipsec_alg_lock);
3422 
3423                 /*
3424                  * The byte stream following the sadb_key_t is made up of:
3425                  * key bytes, [salt bytes], [IV initial value]
3426                  * All of these have variable length. The IV is typically
3427                  * randomly generated by this function and not passed in.
3428                  * By supporting the injection of a known IV, the whole
3429                  * IPsec subsystem and the underlying crypto subsystem
3430                  * can be tested with known test vectors.
3431                  *
3432                  * The keying material has been checked by ext_check()
3433                  * and ipsec_valid_key_size(), after removing salt/IV
3434                  * bits, whats left is the encryption key. If this is too
3435                  * short, ipsec_create_ctx_tmpl() will fail and the SA
3436                  * won't get created.
3437                  *
3438                  * set ipsa_encrkeylen to length of key only.
3439                  */
3440                 newbie->ipsa_encrkeybits = ekey->sadb_key_bits;
3441                 newbie->ipsa_encrkeybits -= ekey->sadb_key_reserved;
3442                 newbie->ipsa_encrkeybits -= newbie->ipsa_saltbits;
3443                 newbie->ipsa_encrkeylen = SADB_1TO8(newbie->ipsa_encrkeybits);
3444 
3445                 /* In case we have to round up to the next byte... */
3446                 if ((ekey->sadb_key_bits & 0x7) != 0)
3447                         newbie->ipsa_encrkeylen++;
3448 
3449                 newbie->ipsa_encrkey = kmem_alloc(newbie->ipsa_encrkeylen,
3450                     KM_NOSLEEP);
3451                 if (newbie->ipsa_encrkey == NULL) {
3452                         error = ENOMEM;
3453                         mutex_exit(&newbie->ipsa_lock);
3454                         goto error;
3455                 }
3456 
3457                 buf_ptr = (uint8_t *)(ekey + 1);
3458                 bcopy(buf_ptr, newbie->ipsa_encrkey, newbie->ipsa_encrkeylen);
3459 
3460                 if (newbie->ipsa_flags & IPSA_F_COMBINED) {
3461                         /*
3462                          * Combined mode algs need a nonce. Copy the salt and
3463                          * IV into a buffer. The ipsa_nonce is a pointer into
3464                          * this buffer, some bytes at the start of the buffer
3465                          * may be unused, depends on the salt length. The IV
3466                          * is 64 bit aligned so it can be incremented as a
3467                          * uint64_t. Zero out key in samsg_t before freeing.
3468                          */
3469 
3470                         newbie->ipsa_nonce_buf = kmem_alloc(
3471                             sizeof (ipsec_nonce_t), KM_NOSLEEP);
3472                         if (newbie->ipsa_nonce_buf == NULL) {
3473                                 error = ENOMEM;
3474                                 mutex_exit(&newbie->ipsa_lock);
3475                                 goto error;
3476                         }
3477                         /*
3478                          * Initialize nonce and salt pointers to point
3479                          * to the nonce buffer. This is just in case we get
3480                          * bad data, the pointers will be valid, the data
3481                          * won't be.
3482                          *
3483                          * See sadb.h for layout of nonce.
3484                          */
3485                         newbie->ipsa_iv = &newbie->ipsa_nonce_buf->iv;
3486                         newbie->ipsa_salt = (uint8_t *)newbie->ipsa_nonce_buf;
3487                         newbie->ipsa_nonce = newbie->ipsa_salt;
3488                         if (newbie->ipsa_saltlen != 0) {
3489                                 salt_offset = MAXSALTSIZE -
3490                                     newbie->ipsa_saltlen;
3491                                 newbie->ipsa_salt = (uint8_t *)
3492                                     &newbie->ipsa_nonce_buf->salt[salt_offset];
3493                                 newbie->ipsa_nonce = newbie->ipsa_salt;
3494                                 buf_ptr += newbie->ipsa_encrkeylen;
3495                                 bcopy(buf_ptr, newbie->ipsa_salt,
3496                                     newbie->ipsa_saltlen);
3497                         }
3498                         /*
3499                          * The IV for CCM/GCM mode increments, it should not
3500                          * repeat. Get a random value for the IV, make a
3501                          * copy, the SA will expire when/if the IV ever
3502                          * wraps back to the initial value. If an Initial IV
3503                          * is passed in via PF_KEY, save this in the SA.
3504                          * Initialising IV for inbound is pointless as its
3505                          * taken from the inbound packet.
3506                          */
3507                         if (!is_inbound) {
3508                                 if (ekey->sadb_key_reserved != 0) {
3509                                         buf_ptr += newbie->ipsa_saltlen;
3510                                         bcopy(buf_ptr, (uint8_t *)newbie->
3511                                             ipsa_iv, SADB_1TO8(ekey->
3512                                             sadb_key_reserved));
3513                                 } else {
3514                                         (void) random_get_pseudo_bytes(
3515                                             (uint8_t *)newbie->ipsa_iv,
3516                                             newbie->ipsa_iv_len);
3517                                 }
3518                                 newbie->ipsa_iv_softexpire =
3519                                     (*newbie->ipsa_iv) << 9;
3520                                 newbie->ipsa_iv_hardexpire = *newbie->ipsa_iv;
3521                         }
3522                 }
3523                 bzero((ekey + 1), SADB_1TO8(ekey->sadb_key_bits));
3524 
3525                 /*
3526                  * Pre-initialize the kernel crypto framework key
3527                  * structure.
3528                  */
3529                 newbie->ipsa_kcfencrkey.ck_format = CRYPTO_KEY_RAW;
3530                 newbie->ipsa_kcfencrkey.ck_length = newbie->ipsa_encrkeybits;
3531                 newbie->ipsa_kcfencrkey.ck_data = newbie->ipsa_encrkey;
3532 
3533                 rw_enter(&ipss->ipsec_alg_lock, RW_READER);
3534                 error = ipsec_create_ctx_tmpl(newbie, IPSEC_ALG_ENCR);
3535                 rw_exit(&ipss->ipsec_alg_lock);
3536                 if (error != 0) {
3537                         mutex_exit(&newbie->ipsa_lock);
3538                         /* See above for error explanation. */
3539                         *diagnostic = SADB_X_DIAGNOSTIC_BAD_CTX;
3540                         goto error;
3541                 }
3542         }
3543 
3544         if (async)
3545                 newbie->ipsa_flags |= IPSA_F_ASYNC;
3546 
3547         /*
3548          * Ptrs to processing functions.
3549          */
3550         if (newbie->ipsa_type == SADB_SATYPE_ESP)
3551                 ipsecesp_init_funcs(newbie);
3552         else
3553                 ipsecah_init_funcs(newbie);
3554         ASSERT(newbie->ipsa_output_func != NULL &&
3555             newbie->ipsa_input_func != NULL);
3556 
3557         /*
3558          * Certificate ID stuff.
3559          */
3560         if (ksi->ks_in_extv[SADB_EXT_IDENTITY_SRC] != NULL) {
3561                 sadb_ident_t *id =
3562                     (sadb_ident_t *)ksi->ks_in_extv[SADB_EXT_IDENTITY_SRC];
3563 
3564                 /*
3565                  * Can assume strlen() will return okay because ext_check() in
3566                  * keysock.c prepares the string for us.
3567                  */
3568                 newbie->ipsa_src_cid = ipsid_lookup(id->sadb_ident_type,
3569                     (char *)(id+1), ns);
3570                 if (newbie->ipsa_src_cid == NULL) {
3571                         error = ENOMEM;
3572                         mutex_exit(&newbie->ipsa_lock);
3573                         goto error;
3574                 }
3575         }
3576 
3577         if (ksi->ks_in_extv[SADB_EXT_IDENTITY_DST] != NULL) {
3578                 sadb_ident_t *id =
3579                     (sadb_ident_t *)ksi->ks_in_extv[SADB_EXT_IDENTITY_DST];
3580 
3581                 /*
3582                  * Can assume strlen() will return okay because ext_check() in
3583                  * keysock.c prepares the string for us.
3584                  */
3585                 newbie->ipsa_dst_cid = ipsid_lookup(id->sadb_ident_type,
3586                     (char *)(id+1), ns);
3587                 if (newbie->ipsa_dst_cid == NULL) {
3588                         error = ENOMEM;
3589                         mutex_exit(&newbie->ipsa_lock);
3590                         goto error;
3591                 }
3592         }
3593 
3594         /*
3595          * sensitivity label handling code:
3596          * Convert sens + bitmap into cred_t, and associate it
3597          * with the new SA.
3598          */
3599         if (sens != NULL) {
3600                 uint64_t *bitmap = (uint64_t *)(sens + 1);
3601 
3602                 newbie->ipsa_tsl = sadb_label_from_sens(sens, bitmap);
3603         }
3604 
3605         /*
3606          * Likewise for outer sensitivity.
3607          */
3608         if (osens != NULL) {
3609                 uint64_t *bitmap = (uint64_t *)(osens + 1);
3610                 ts_label_t *tsl, *effective_tsl;
3611                 uint32_t *peer_addr_ptr;
3612                 zoneid_t zoneid = GLOBAL_ZONEID;
3613                 zone_t *zone;
3614 
3615                 peer_addr_ptr = is_inbound ? src_addr_ptr : dst_addr_ptr;
3616 
3617                 tsl = sadb_label_from_sens(osens, bitmap);
3618                 newbie->ipsa_mac_exempt = CONN_MAC_DEFAULT;
3619 
3620                 if (osens->sadb_x_sens_flags & SADB_X_SENS_IMPLICIT) {
3621                         newbie->ipsa_mac_exempt = CONN_MAC_IMPLICIT;
3622                 }
3623 
3624                 error = tsol_check_dest(tsl, peer_addr_ptr,
3625                     (af == AF_INET6)?IPV6_VERSION:IPV4_VERSION,
3626                     newbie->ipsa_mac_exempt, B_TRUE, &effective_tsl);
3627                 if (error != 0) {
3628                         label_rele(tsl);
3629                         mutex_exit(&newbie->ipsa_lock);
3630                         goto error;
3631                 }
3632 
3633                 if (effective_tsl != NULL) {
3634                         label_rele(tsl);
3635                         tsl = effective_tsl;
3636                 }
3637 
3638                 newbie->ipsa_otsl = tsl;
3639 
3640                 zone = zone_find_by_label(tsl);
3641                 if (zone != NULL) {
3642                         zoneid = zone->zone_id;
3643                         zone_rele(zone);
3644                 }
3645                 /*
3646                  * For exclusive stacks we set the zoneid to zero to operate
3647                  * as if in the global zone for tsol_compute_label_v4/v6
3648                  */
3649                 if (ipst->ips_netstack->netstack_stackid != GLOBAL_NETSTACKID)
3650                         zoneid = GLOBAL_ZONEID;
3651 
3652                 if (af == AF_INET6) {
3653                         error = tsol_compute_label_v6(tsl, zoneid,
3654                             (in6_addr_t *)peer_addr_ptr,
3655                             newbie->ipsa_opt_storage, ipst);
3656                 } else {
3657                         error = tsol_compute_label_v4(tsl, zoneid,
3658                             *peer_addr_ptr, newbie->ipsa_opt_storage, ipst);
3659                 }
3660                 if (error != 0) {
3661                         mutex_exit(&newbie->ipsa_lock);
3662                         goto error;
3663                 }
3664         }
3665 
3666 
3667         if (replayext != NULL) {
3668                 if ((replayext->sadb_x_rc_replay32 == 0) &&
3669                     (replayext->sadb_x_rc_replay64 != 0)) {
3670                         error = EOPNOTSUPP;
3671                         *diagnostic = SADB_X_DIAGNOSTIC_INVALID_REPLAY;
3672                         mutex_exit(&newbie->ipsa_lock);
3673                         goto error;
3674                 }
3675                 newbie->ipsa_replay = replayext->sadb_x_rc_replay32;
3676         }
3677 
3678         /* now that the SA has been updated, set its new state */
3679         newbie->ipsa_state = assoc->sadb_sa_state;
3680 
3681         if (clone) {
3682                 newbie->ipsa_haspeer = B_TRUE;
3683         } else {
3684                 if (!is_inbound) {
3685                         lifetime_fuzz(newbie);
3686                 }
3687         }
3688         /*
3689          * The less locks I hold when doing an insertion and possible cloning,
3690          * the better!
3691          */
3692         mutex_exit(&newbie->ipsa_lock);
3693 
3694         if (clone) {
3695                 newbie_clone = sadb_cloneassoc(newbie);
3696 
3697                 if (newbie_clone == NULL) {
3698                         error = ENOMEM;
3699                         goto error;
3700                 }
3701         }
3702 
3703         /*
3704          * Enter the bucket locks.  The order of entry is outbound,
3705          * inbound.  We map "primary" and "secondary" into outbound and inbound
3706          * based on the destination address type.  If the destination address
3707          * type is for a node that isn't mine (or potentially mine), the
3708          * "primary" bucket is the outbound one.
3709          */
3710         if (!is_inbound) {
3711                 /* primary == outbound */
3712                 mutex_enter(&primary->isaf_lock);
3713                 mutex_enter(&secondary->isaf_lock);
3714         } else {
3715                 /* primary == inbound */
3716                 mutex_enter(&secondary->isaf_lock);
3717                 mutex_enter(&primary->isaf_lock);
3718         }
3719 
3720         /*
3721          * sadb_insertassoc() doesn't increment the reference
3722          * count.  We therefore have to increment the
3723          * reference count one more time to reflect the
3724          * pointers of the table that reference this SA.
3725          */
3726         IPSA_REFHOLD(newbie);
3727 
3728         if (isupdate) {
3729                 /*
3730                  * Unlink from larval holding cell in the "inbound" fanout.
3731                  */
3732                 ASSERT(newbie->ipsa_linklock == &primary->isaf_lock ||
3733                     newbie->ipsa_linklock == &secondary->isaf_lock);
3734                 sadb_unlinkassoc(newbie);
3735         }
3736 
3737         mutex_enter(&newbie->ipsa_lock);
3738         error = sadb_insertassoc(newbie, primary);
3739         mutex_exit(&newbie->ipsa_lock);
3740 
3741         if (error != 0) {
3742                 /*
3743                  * Since sadb_insertassoc() failed, we must decrement the
3744                  * refcount again so the cleanup code will actually free
3745                  * the offending SA.
3746                  */
3747                 IPSA_REFRELE(newbie);
3748                 goto error_unlock;
3749         }
3750 
3751         if (newbie_clone != NULL) {
3752                 mutex_enter(&newbie_clone->ipsa_lock);
3753                 error = sadb_insertassoc(newbie_clone, secondary);
3754                 mutex_exit(&newbie_clone->ipsa_lock);
3755                 if (error != 0) {
3756                         /* Collision in secondary table. */
3757                         sadb_unlinkassoc(newbie);  /* This does REFRELE. */
3758                         goto error_unlock;
3759                 }
3760                 IPSA_REFHOLD(newbie_clone);
3761         } else {
3762                 ASSERT(primary != secondary);
3763                 scratch = ipsec_getassocbyspi(secondary, newbie->ipsa_spi,
3764                     ALL_ZEROES_PTR, newbie->ipsa_dstaddr, af);
3765                 if (scratch != NULL) {
3766                         /* Collision in secondary table. */
3767                         sadb_unlinkassoc(newbie);  /* This does REFRELE. */
3768                         /* Set the error, since ipsec_getassocbyspi() can't. */
3769                         error = EEXIST;
3770                         goto error_unlock;
3771                 }
3772         }
3773 
3774         /* OKAY!  So let's do some reality check assertions. */
3775 
3776         ASSERT(MUTEX_NOT_HELD(&newbie->ipsa_lock));
3777         ASSERT(newbie_clone == NULL ||
3778             (MUTEX_NOT_HELD(&newbie_clone->ipsa_lock)));
3779 
3780 error_unlock:
3781 
3782         /*
3783          * We can exit the locks in any order.  Only entrance needs to
3784          * follow any protocol.
3785          */
3786         mutex_exit(&secondary->isaf_lock);
3787         mutex_exit(&primary->isaf_lock);
3788 
3789         if (pair_ext != NULL && error == 0) {
3790                 /* update pair_spi if it exists. */
3791                 ipsa_query_t sq;
3792 
3793                 sq.spp = spp;           /* XXX param */
3794                 error = sadb_form_query(ksi, IPSA_Q_DST, IPSA_Q_SRC|IPSA_Q_DST|
3795                     IPSA_Q_SA|IPSA_Q_INBOUND|IPSA_Q_OUTBOUND, &sq, diagnostic);
3796                 if (error)
3797                         return (error);
3798 
3799                 error = get_ipsa_pair(&sq, &ipsapp, diagnostic);
3800 
3801                 if (error != 0)
3802                         goto error;
3803 
3804                 if (ipsapp.ipsap_psa_ptr != NULL) {
3805                         *diagnostic = SADB_X_DIAGNOSTIC_PAIR_ALREADY;
3806                         error = EINVAL;
3807                 } else {
3808                         /* update_pairing() sets diagnostic */
3809                         error = update_pairing(&ipsapp, &sq, ksi, diagnostic);
3810                 }
3811         }
3812         /* Common error point for this routine. */
3813 error:
3814         if (newbie != NULL) {
3815                 if (error != 0) {
3816                         /* This SA is broken, let the reaper clean up. */
3817                         mutex_enter(&newbie->ipsa_lock);
3818                         newbie->ipsa_state = IPSA_STATE_DEAD;
3819                         newbie->ipsa_hardexpiretime = 1;
3820                         mutex_exit(&newbie->ipsa_lock);
3821                 }
3822                 IPSA_REFRELE(newbie);
3823         }
3824         if (newbie_clone != NULL) {
3825                 IPSA_REFRELE(newbie_clone);
3826         }
3827 
3828         if (error == 0) {
3829                 /*
3830                  * Construct favorable PF_KEY return message and send to
3831                  * keysock. Update the flags in the original keysock message
3832                  * to reflect the actual flags in the new SA.
3833                  *  (Q:  Do I need to pass "newbie"?  If I do,
3834                  * make sure to REFHOLD, call, then REFRELE.)
3835                  */
3836                 assoc->sadb_sa_flags = newbie->ipsa_flags;
3837                 sadb_pfkey_echo(pfkey_q, mp, samsg, ksi, NULL);
3838         }
3839 
3840         destroy_ipsa_pair(&ipsapp);
3841         return (error);
3842 }
3843 
3844 /*
3845  * Set the time of first use for a security association.  Update any
3846  * expiration times as a result.
3847  */
3848 void
3849 sadb_set_usetime(ipsa_t *assoc)
3850 {
3851         time_t snapshot = gethrestime_sec();
3852 
3853         mutex_enter(&assoc->ipsa_lock);
3854         assoc->ipsa_lastuse = snapshot;
3855         assoc->ipsa_idleexpiretime = snapshot + assoc->ipsa_idletime;
3856 
3857         /*
3858          * Caller does check usetime before calling me usually, and
3859          * double-checking is better than a mutex_enter/exit hit.
3860          */
3861         if (assoc->ipsa_usetime == 0) {
3862                 /*
3863                  * This is redundant for outbound SA's, as
3864                  * ipsec_getassocbyconn() sets the IPSA_F_USED flag already.
3865                  * Inbound SAs, however, have no such protection.
3866                  */
3867                 assoc->ipsa_flags |= IPSA_F_USED;
3868                 assoc->ipsa_usetime = snapshot;
3869 
3870                 /*
3871                  * After setting the use time, see if we have a use lifetime
3872                  * that would cause the actual SA expiration time to shorten.
3873                  */
3874                 UPDATE_EXPIRE(assoc, softuselt, softexpiretime);
3875                 UPDATE_EXPIRE(assoc, harduselt, hardexpiretime);
3876         }
3877         mutex_exit(&assoc->ipsa_lock);
3878 }
3879 
3880 /*
3881  * Send up a PF_KEY expire message for this association.
3882  */
3883 static void
3884 sadb_expire_assoc(queue_t *pfkey_q, ipsa_t *assoc)
3885 {
3886         mblk_t *mp, *mp1;
3887         int alloclen, af;
3888         sadb_msg_t *samsg;
3889         sadb_lifetime_t *current, *expire;
3890         sadb_sa_t *saext;
3891         uint8_t *end;
3892         boolean_t tunnel_mode;
3893 
3894         ASSERT(MUTEX_HELD(&assoc->ipsa_lock));
3895 
3896         /* Don't bother sending if there's no queue. */
3897         if (pfkey_q == NULL)
3898                 return;
3899 
3900         mp = sadb_keysock_out(0);
3901         if (mp == NULL) {
3902                 /* cmn_err(CE_WARN, */
3903                 /*      "sadb_expire_assoc: Can't allocate KEYSOCK_OUT.\n"); */
3904                 return;
3905         }
3906 
3907         alloclen = sizeof (*samsg) + sizeof (*current) + sizeof (*expire) +
3908             2 * sizeof (sadb_address_t) + sizeof (*saext);
3909 
3910         af = assoc->ipsa_addrfam;
3911         switch (af) {
3912         case AF_INET:
3913                 alloclen += 2 * sizeof (struct sockaddr_in);
3914                 break;
3915         case AF_INET6:
3916                 alloclen += 2 * sizeof (struct sockaddr_in6);
3917                 break;
3918         default:
3919                 /* Won't happen unless there's a kernel bug. */
3920                 freeb(mp);
3921                 cmn_err(CE_WARN,
3922                     "sadb_expire_assoc: Unknown address length.\n");
3923                 return;
3924         }
3925 
3926         tunnel_mode = (assoc->ipsa_flags & IPSA_F_TUNNEL);
3927         if (tunnel_mode) {
3928                 alloclen += 2 * sizeof (sadb_address_t);
3929                 switch (assoc->ipsa_innerfam) {
3930                 case AF_INET:
3931                         alloclen += 2 * sizeof (struct sockaddr_in);
3932                         break;
3933                 case AF_INET6:
3934                         alloclen += 2 * sizeof (struct sockaddr_in6);
3935                         break;
3936                 default:
3937                         /* Won't happen unless there's a kernel bug. */
3938                         freeb(mp);
3939                         cmn_err(CE_WARN, "sadb_expire_assoc: "
3940                             "Unknown inner address length.\n");
3941                         return;
3942                 }
3943         }
3944 
3945         mp->b_cont = allocb(alloclen, BPRI_HI);
3946         if (mp->b_cont == NULL) {
3947                 freeb(mp);
3948                 /* cmn_err(CE_WARN, */
3949                 /*      "sadb_expire_assoc: Can't allocate message.\n"); */
3950                 return;
3951         }
3952 
3953         mp1 = mp;
3954         mp = mp->b_cont;
3955         end = mp->b_wptr + alloclen;
3956 
3957         samsg = (sadb_msg_t *)mp->b_wptr;
3958         mp->b_wptr += sizeof (*samsg);
3959         INITIALIZE_SAMSG(samsg, SADB_EXPIRE);
3960         samsg->sadb_msg_satype = assoc->ipsa_type;
3961         samsg->sadb_msg_len = SADB_8TO64(alloclen);
3962         samsg->sadb_msg_seq = 0;
3963         samsg->sadb_msg_pid = 0;
3964 
3965         saext = (sadb_sa_t *)mp->b_wptr;
3966         mp->b_wptr += sizeof (*saext);
3967         saext->sadb_sa_len = SADB_8TO64(sizeof (*saext));
3968         saext->sadb_sa_exttype = SADB_EXT_SA;
3969         saext->sadb_sa_spi = assoc->ipsa_spi;
3970         saext->sadb_sa_replay = assoc->ipsa_replay_wsize;
3971         saext->sadb_sa_state = assoc->ipsa_state;
3972         saext->sadb_sa_auth = assoc->ipsa_auth_alg;
3973         saext->sadb_sa_encrypt = assoc->ipsa_encr_alg;
3974         saext->sadb_sa_flags = assoc->ipsa_flags;
3975 
3976         current = (sadb_lifetime_t *)mp->b_wptr;
3977         mp->b_wptr += sizeof (sadb_lifetime_t);
3978         current->sadb_lifetime_len = SADB_8TO64(sizeof (*current));
3979         current->sadb_lifetime_exttype = SADB_EXT_LIFETIME_CURRENT;
3980         /* We do not support the concept. */
3981         current->sadb_lifetime_allocations = 0;
3982         current->sadb_lifetime_bytes = assoc->ipsa_bytes;
3983         current->sadb_lifetime_addtime = assoc->ipsa_addtime;
3984         current->sadb_lifetime_usetime = assoc->ipsa_usetime;
3985 
3986         expire = (sadb_lifetime_t *)mp->b_wptr;
3987         mp->b_wptr += sizeof (*expire);
3988         expire->sadb_lifetime_len = SADB_8TO64(sizeof (*expire));
3989 
3990         if (assoc->ipsa_state == IPSA_STATE_DEAD) {
3991                 expire->sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD;
3992                 expire->sadb_lifetime_allocations = assoc->ipsa_hardalloc;
3993                 expire->sadb_lifetime_bytes = assoc->ipsa_hardbyteslt;
3994                 expire->sadb_lifetime_addtime = assoc->ipsa_hardaddlt;
3995                 expire->sadb_lifetime_usetime = assoc->ipsa_harduselt;
3996         } else if (assoc->ipsa_state == IPSA_STATE_DYING) {
3997                 expire->sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT;
3998                 expire->sadb_lifetime_allocations = assoc->ipsa_softalloc;
3999                 expire->sadb_lifetime_bytes = assoc->ipsa_softbyteslt;
4000                 expire->sadb_lifetime_addtime = assoc->ipsa_softaddlt;
4001                 expire->sadb_lifetime_usetime = assoc->ipsa_softuselt;
4002         } else {
4003                 ASSERT(assoc->ipsa_state == IPSA_STATE_MATURE);
4004                 expire->sadb_lifetime_exttype = SADB_X_EXT_LIFETIME_IDLE;
4005                 expire->sadb_lifetime_allocations = 0;
4006                 expire->sadb_lifetime_bytes = 0;
4007                 expire->sadb_lifetime_addtime = assoc->ipsa_idleaddlt;
4008                 expire->sadb_lifetime_usetime = assoc->ipsa_idleuselt;
4009         }
4010 
4011         mp->b_wptr = sadb_make_addr_ext(mp->b_wptr, end, SADB_EXT_ADDRESS_SRC,
4012             af, assoc->ipsa_srcaddr, tunnel_mode ? 0 : SA_SRCPORT(assoc),
4013             SA_PROTO(assoc), 0);
4014         ASSERT(mp->b_wptr != NULL);
4015 
4016         mp->b_wptr = sadb_make_addr_ext(mp->b_wptr, end, SADB_EXT_ADDRESS_DST,
4017             af, assoc->ipsa_dstaddr, tunnel_mode ? 0 : SA_DSTPORT(assoc),
4018             SA_PROTO(assoc), 0);
4019         ASSERT(mp->b_wptr != NULL);
4020 
4021         if (tunnel_mode) {
4022                 mp->b_wptr = sadb_make_addr_ext(mp->b_wptr, end,
4023                     SADB_X_EXT_ADDRESS_INNER_SRC, assoc->ipsa_innerfam,
4024                     assoc->ipsa_innersrc, SA_SRCPORT(assoc), SA_IPROTO(assoc),
4025                     assoc->ipsa_innersrcpfx);
4026                 ASSERT(mp->b_wptr != NULL);
4027                 mp->b_wptr = sadb_make_addr_ext(mp->b_wptr, end,
4028                     SADB_X_EXT_ADDRESS_INNER_DST, assoc->ipsa_innerfam,
4029                     assoc->ipsa_innerdst, SA_DSTPORT(assoc), SA_IPROTO(assoc),
4030                     assoc->ipsa_innerdstpfx);
4031                 ASSERT(mp->b_wptr != NULL);
4032         }
4033 
4034         /* Can just putnext, we're ready to go! */
4035         putnext(pfkey_q, mp1);
4036 }
4037 
4038 /*
4039  * "Age" the SA with the number of bytes that was used to protect traffic.
4040  * Send an SADB_EXPIRE message if appropriate.  Return B_TRUE if there was
4041  * enough "charge" left in the SA to protect the data.  Return B_FALSE
4042  * otherwise.  (If B_FALSE is returned, the association either was, or became
4043  * DEAD.)
4044  */
4045 boolean_t
4046 sadb_age_bytes(queue_t *pfkey_q, ipsa_t *assoc, uint64_t bytes,
4047     boolean_t sendmsg)
4048 {
4049         boolean_t rc = B_TRUE;
4050         uint64_t newtotal;
4051 
4052         mutex_enter(&assoc->ipsa_lock);
4053         newtotal = assoc->ipsa_bytes + bytes;
4054         if (assoc->ipsa_hardbyteslt != 0 &&
4055             newtotal >= assoc->ipsa_hardbyteslt) {
4056                 if (assoc->ipsa_state != IPSA_STATE_DEAD) {
4057                         sadb_delete_cluster(assoc);
4058                         /*
4059                          * Send EXPIRE message to PF_KEY.  May wish to pawn
4060                          * this off on another non-interrupt thread.  Also
4061                          * unlink this SA immediately.
4062                          */
4063                         assoc->ipsa_state = IPSA_STATE_DEAD;
4064                         if (sendmsg)
4065                                 sadb_expire_assoc(pfkey_q, assoc);
4066                         /*
4067                          * Set non-zero expiration time so sadb_age_assoc()
4068                          * will work when reaping.
4069                          */
4070                         assoc->ipsa_hardexpiretime = (time_t)1;
4071                 } /* Else someone beat me to it! */
4072                 rc = B_FALSE;
4073         } else if (assoc->ipsa_softbyteslt != 0 &&
4074             (newtotal >= assoc->ipsa_softbyteslt)) {
4075                 if (assoc->ipsa_state < IPSA_STATE_DYING) {
4076                         /*
4077                          * Send EXPIRE message to PF_KEY.  May wish to pawn
4078                          * this off on another non-interrupt thread.
4079                          */
4080                         assoc->ipsa_state = IPSA_STATE_DYING;
4081                         assoc->ipsa_bytes = newtotal;
4082                         if (sendmsg)
4083                                 sadb_expire_assoc(pfkey_q, assoc);
4084                 } /* Else someone beat me to it! */
4085         }
4086         if (rc == B_TRUE)
4087                 assoc->ipsa_bytes = newtotal;
4088         mutex_exit(&assoc->ipsa_lock);
4089         return (rc);
4090 }
4091 
4092 /*
4093  * "Torch" an individual SA.  Returns NULL, so it can be tail-called from
4094  *     sadb_age_assoc().
4095  */
4096 static ipsa_t *
4097 sadb_torch_assoc(isaf_t *head, ipsa_t *sa)
4098 {
4099         ASSERT(MUTEX_HELD(&head->isaf_lock));
4100         ASSERT(MUTEX_HELD(&sa->ipsa_lock));
4101         ASSERT(sa->ipsa_state == IPSA_STATE_DEAD);
4102 
4103         /*
4104          * Force cached SAs to be revalidated..
4105          */
4106         head->isaf_gen++;
4107 
4108         mutex_exit(&sa->ipsa_lock);
4109         sadb_unlinkassoc(sa);
4110 
4111         return (NULL);
4112 }
4113 
4114 /*
4115  * Do various SA-is-idle activities depending on delta (the number of idle
4116  * seconds on the SA) and/or other properties of the SA.
4117  *
4118  * Return B_TRUE if I've sent a packet, because I have to drop the
4119  * association's mutex before sending a packet out the wire.
4120  */
4121 /* ARGSUSED */
4122 static boolean_t
4123 sadb_idle_activities(ipsa_t *assoc, time_t delta, boolean_t inbound)
4124 {
4125         ipsecesp_stack_t *espstack = assoc->ipsa_netstack->netstack_ipsecesp;
4126         int nat_t_interval = espstack->ipsecesp_nat_keepalive_interval;
4127 
4128         ASSERT(MUTEX_HELD(&assoc->ipsa_lock));
4129 
4130         if (!inbound && (assoc->ipsa_flags & IPSA_F_NATT_LOC) &&
4131             delta >= nat_t_interval &&
4132             gethrestime_sec() - assoc->ipsa_last_nat_t_ka >= nat_t_interval) {
4133                 ASSERT(assoc->ipsa_type == SADB_SATYPE_ESP);
4134                 assoc->ipsa_last_nat_t_ka = gethrestime_sec();
4135                 mutex_exit(&assoc->ipsa_lock);
4136                 ipsecesp_send_keepalive(assoc);
4137                 return (B_TRUE);
4138         }
4139         return (B_FALSE);
4140 }
4141 
4142 /*
4143  * Return "assoc" if haspeer is true and I send an expire.  This allows
4144  * the consumers' aging functions to tidy up an expired SA's peer.
4145  */
4146 static ipsa_t *
4147 sadb_age_assoc(isaf_t *head, queue_t *pfkey_q, ipsa_t *assoc,
4148     time_t current, int reap_delay, boolean_t inbound)
4149 {
4150         ipsa_t *retval = NULL;
4151         boolean_t dropped_mutex = B_FALSE;
4152 
4153         ASSERT(MUTEX_HELD(&head->isaf_lock));
4154 
4155         mutex_enter(&assoc->ipsa_lock);
4156 
4157         if (((assoc->ipsa_state == IPSA_STATE_LARVAL) ||
4158             ((assoc->ipsa_state == IPSA_STATE_IDLE) ||
4159             (assoc->ipsa_state == IPSA_STATE_ACTIVE_ELSEWHERE) &&
4160             (assoc->ipsa_hardexpiretime != 0))) &&
4161             (assoc->ipsa_hardexpiretime <= current)) {
4162                 assoc->ipsa_state = IPSA_STATE_DEAD;
4163                 return (sadb_torch_assoc(head, assoc));
4164         }
4165 
4166         /*
4167          * Check lifetimes.  Fortunately, SA setup is done
4168          * such that there are only two times to look at,
4169          * softexpiretime, and hardexpiretime.
4170          *
4171          * Check hard first.
4172          */
4173 
4174         if (assoc->ipsa_hardexpiretime != 0 &&
4175             assoc->ipsa_hardexpiretime <= current) {
4176                 if (assoc->ipsa_state == IPSA_STATE_DEAD)
4177                         return (sadb_torch_assoc(head, assoc));
4178 
4179                 if (inbound) {
4180                         sadb_delete_cluster(assoc);
4181                 }
4182 
4183                 /*
4184                  * Send SADB_EXPIRE with hard lifetime, delay for unlinking.
4185                  */
4186                 assoc->ipsa_state = IPSA_STATE_DEAD;
4187                 if (assoc->ipsa_haspeer || assoc->ipsa_otherspi != 0) {
4188                         /*
4189                          * If the SA is paired or peered with another, put
4190                          * a copy on a list which can be processed later, the
4191                          * pair/peer SA needs to be updated so the both die
4192                          * at the same time.
4193                          *
4194                          * If I return assoc, I have to bump up its reference
4195                          * count to keep with the ipsa_t reference count
4196                          * semantics.
4197                          */
4198                         IPSA_REFHOLD(assoc);
4199                         retval = assoc;
4200                 }
4201                 sadb_expire_assoc(pfkey_q, assoc);
4202                 assoc->ipsa_hardexpiretime = current + reap_delay;
4203         } else if (assoc->ipsa_softexpiretime != 0 &&
4204             assoc->ipsa_softexpiretime <= current &&
4205             assoc->ipsa_state < IPSA_STATE_DYING) {
4206                 /*
4207                  * Send EXPIRE message to PF_KEY.  May wish to pawn
4208                  * this off on another non-interrupt thread.
4209                  */
4210                 assoc->ipsa_state = IPSA_STATE_DYING;
4211                 if (assoc->ipsa_haspeer) {
4212                         /*
4213                          * If the SA has a peer, update the peer's state
4214                          * on SOFT_EXPIRE, this is mostly to prevent two
4215                          * expire messages from effectively the same SA.
4216                          *
4217                          * Don't care about paired SA's, then can (and should)
4218                          * be able to soft expire at different times.
4219                          *
4220                          * If I return assoc, I have to bump up its
4221                          * reference count to keep with the ipsa_t reference
4222                          * count semantics.
4223                          */
4224                         IPSA_REFHOLD(assoc);
4225                         retval = assoc;
4226                 }
4227                 sadb_expire_assoc(pfkey_q, assoc);
4228         } else if (assoc->ipsa_idletime != 0 &&
4229             assoc->ipsa_idleexpiretime <= current) {
4230                 if (assoc->ipsa_state == IPSA_STATE_ACTIVE_ELSEWHERE) {
4231                         assoc->ipsa_state = IPSA_STATE_IDLE;
4232                 }
4233 
4234                 /*
4235                  * Need to handle Mature case
4236                  */
4237                 if (assoc->ipsa_state == IPSA_STATE_MATURE) {
4238                         sadb_expire_assoc(pfkey_q, assoc);
4239                 }
4240         } else {
4241                 /* Check idle time activities. */
4242                 dropped_mutex = sadb_idle_activities(assoc,
4243                     current - assoc->ipsa_lastuse, inbound);
4244         }
4245 
4246         if (!dropped_mutex)
4247                 mutex_exit(&assoc->ipsa_lock);
4248         return (retval);
4249 }
4250 
4251 /*
4252  * Called by a consumer protocol to do ther dirty work of reaping dead
4253  * Security Associations and outstanding acquire records.
4254  *
4255  * NOTE: sadb_age_assoc() marks expired SA's as DEAD but only removed
4256  * SA's that are already marked DEAD, so expired SA's are only reaped
4257  * the second time sadb_ager() runs.
4258  */
4259 void
4260 sadb_ager(sadb_t *sp, queue_t *pfkey_q, int reap_delay, netstack_t *ns)
4261 {
4262         int i;
4263         isaf_t *bucket;
4264         ipsa_t *assoc, *spare;
4265         iacqf_t *acqlist;
4266         ipsacq_t *acqrec, *spareacq;
4267         templist_t *haspeerlist, *newbie;
4268         /* Snapshot current time now. */
4269         time_t current = gethrestime_sec();
4270         haspeerlist = NULL;
4271 
4272         /*
4273          * Do my dirty work.  This includes aging real entries, aging
4274          * larvals, and aging outstanding ACQUIREs.
4275          *
4276          * I hope I don't tie up resources for too long.
4277          */
4278 
4279         /* Age acquires. */
4280 
4281         for (i = 0; i < sp->sdb_hashsize; i++) {
4282                 acqlist = &sp->sdb_acq[i];
4283                 mutex_enter(&acqlist->iacqf_lock);
4284                 for (acqrec = acqlist->iacqf_ipsacq; acqrec != NULL;
4285                     acqrec = spareacq) {
4286                         spareacq = acqrec->ipsacq_next;
4287                         if (current > acqrec->ipsacq_expire)
4288                                 sadb_destroy_acquire(acqrec, ns);
4289                 }
4290                 mutex_exit(&acqlist->iacqf_lock);
4291         }
4292 
4293         /* Age inbound associations. */
4294         for (i = 0; i < sp->sdb_hashsize; i++) {
4295                 bucket = &(sp->sdb_if[i]);
4296                 mutex_enter(&bucket->isaf_lock);
4297                 for (assoc = bucket->isaf_ipsa; assoc != NULL;
4298                     assoc = spare) {
4299                         spare = assoc->ipsa_next;
4300                         if (sadb_age_assoc(bucket, pfkey_q, assoc, current,
4301                             reap_delay, B_TRUE) != NULL) {
4302                                 /*
4303                                  * Put SA's which have a peer or SA's which
4304                                  * are paired on a list for processing after
4305                                  * all the hash tables have been walked.
4306                                  *
4307                                  * sadb_age_assoc() increments the refcnt,
4308                                  * effectively doing an IPSA_REFHOLD().
4309                                  */
4310                                 newbie = kmem_alloc(sizeof (*newbie),
4311                                     KM_NOSLEEP);
4312                                 if (newbie == NULL) {
4313                                         /*
4314                                          * Don't forget to REFRELE().
4315                                          */
4316                                         IPSA_REFRELE(assoc);
4317                                         continue;       /* for loop... */
4318                                 }
4319                                 newbie->next = haspeerlist;
4320                                 newbie->ipsa = assoc;
4321                                 haspeerlist = newbie;
4322                         }
4323                 }
4324                 mutex_exit(&bucket->isaf_lock);
4325         }
4326 
4327         age_pair_peer_list(haspeerlist, sp, B_FALSE);
4328         haspeerlist = NULL;
4329 
4330         /* Age outbound associations. */
4331         for (i = 0; i < sp->sdb_hashsize; i++) {
4332                 bucket = &(sp->sdb_of[i]);
4333                 mutex_enter(&bucket->isaf_lock);
4334                 for (assoc = bucket->isaf_ipsa; assoc != NULL;
4335                     assoc = spare) {
4336                         spare = assoc->ipsa_next;
4337                         if (sadb_age_assoc(bucket, pfkey_q, assoc, current,
4338                             reap_delay, B_FALSE) != NULL) {
4339                                 /*
4340                                  * sadb_age_assoc() increments the refcnt,
4341                                  * effectively doing an IPSA_REFHOLD().
4342                                  */
4343                                 newbie = kmem_alloc(sizeof (*newbie),
4344                                     KM_NOSLEEP);
4345                                 if (newbie == NULL) {
4346                                         /*
4347                                          * Don't forget to REFRELE().
4348                                          */
4349                                         IPSA_REFRELE(assoc);
4350                                         continue;       /* for loop... */
4351                                 }
4352                                 newbie->next = haspeerlist;
4353                                 newbie->ipsa = assoc;
4354                                 haspeerlist = newbie;
4355                         }
4356                 }
4357                 mutex_exit(&bucket->isaf_lock);
4358         }
4359 
4360         age_pair_peer_list(haspeerlist, sp, B_TRUE);
4361 
4362         /*
4363          * Run a GC pass to clean out dead identities.
4364          */
4365         ipsid_gc(ns);
4366 }
4367 
4368 /*
4369  * Figure out when to reschedule the ager.
4370  */
4371 timeout_id_t
4372 sadb_retimeout(hrtime_t begin, queue_t *pfkey_q, void (*ager)(void *),
4373     void *agerarg, uint_t *intp, uint_t intmax, short mid)
4374 {
4375         hrtime_t end = gethrtime();
4376         uint_t interval = *intp;        /* "interval" is in ms. */
4377 
4378         /*
4379          * See how long this took.  If it took too long, increase the
4380          * aging interval.
4381          */
4382         if ((end - begin) > MSEC2NSEC(interval)) {
4383                 if (interval >= intmax) {
4384                         /* XXX Rate limit this?  Or recommend flush? */
4385                         (void) strlog(mid, 0, 0, SL_ERROR | SL_WARN,
4386                             "Too many SA's to age out in %d msec.\n",
4387                             intmax);
4388                 } else {
4389                         /* Double by shifting by one bit. */
4390                         interval <<= 1;
4391                         interval = min(interval, intmax);
4392                 }
4393         } else if ((end - begin) <= (MSEC2NSEC(interval) / 2) &&
4394             interval > SADB_AGE_INTERVAL_DEFAULT) {
4395                 /*
4396                  * If I took less than half of the interval, then I should
4397                  * ratchet the interval back down.  Never automatically
4398                  * shift below the default aging interval.
4399                  *
4400                  * NOTE:This even overrides manual setting of the age
4401                  *      interval using NDD to lower the setting past the
4402                  *      default.  In other words, if you set the interval
4403                  *      lower than the default, and your SADB gets too big,
4404                  *      the interval will only self-lower back to the default.
4405                  */
4406                 /* Halve by shifting one bit. */
4407                 interval >>= 1;
4408                 interval = max(interval, SADB_AGE_INTERVAL_DEFAULT);
4409         }
4410         *intp = interval;
4411         return (qtimeout(pfkey_q, ager, agerarg,
4412             drv_usectohz(interval * (MICROSEC / MILLISEC))));
4413 }
4414 
4415 
4416 /*
4417  * Update the lifetime values of an SA.  This is the path an SADB_UPDATE
4418  * message takes when updating a MATURE or DYING SA.
4419  */
4420 static void
4421 sadb_update_lifetimes(ipsa_t *assoc, sadb_lifetime_t *hard,
4422     sadb_lifetime_t *soft, sadb_lifetime_t *idle, boolean_t outbound)
4423 {
4424         mutex_enter(&assoc->ipsa_lock);
4425 
4426         /*
4427          * XXX RFC 2367 mentions how an SADB_EXT_LIFETIME_CURRENT can be
4428          * passed in during an update message.  We currently don't handle
4429          * these.
4430          */
4431 
4432         if (hard != NULL) {
4433                 if (hard->sadb_lifetime_bytes != 0)
4434                         assoc->ipsa_hardbyteslt = hard->sadb_lifetime_bytes;
4435                 if (hard->sadb_lifetime_usetime != 0)
4436                         assoc->ipsa_harduselt = hard->sadb_lifetime_usetime;
4437                 if (hard->sadb_lifetime_addtime != 0)
4438                         assoc->ipsa_hardaddlt = hard->sadb_lifetime_addtime;
4439                 if (assoc->ipsa_hardaddlt != 0) {
4440                         assoc->ipsa_hardexpiretime =
4441                             assoc->ipsa_addtime + assoc->ipsa_hardaddlt;
4442                 }
4443                 if (assoc->ipsa_harduselt != 0 &&
4444                     assoc->ipsa_flags & IPSA_F_USED) {
4445                         UPDATE_EXPIRE(assoc, harduselt, hardexpiretime);
4446                 }
4447                 if (hard->sadb_lifetime_allocations != 0)
4448                         assoc->ipsa_hardalloc = hard->sadb_lifetime_allocations;
4449         }
4450 
4451         if (soft != NULL) {
4452                 if (soft->sadb_lifetime_bytes != 0) {
4453                         if (soft->sadb_lifetime_bytes >
4454                             assoc->ipsa_hardbyteslt) {
4455                                 assoc->ipsa_softbyteslt =
4456                                     assoc->ipsa_hardbyteslt;
4457                         } else {
4458                                 assoc->ipsa_softbyteslt =
4459                                     soft->sadb_lifetime_bytes;
4460                         }
4461                 }
4462                 if (soft->sadb_lifetime_usetime != 0) {
4463                         if (soft->sadb_lifetime_usetime >
4464                             assoc->ipsa_harduselt) {
4465                                 assoc->ipsa_softuselt =
4466                                     assoc->ipsa_harduselt;
4467                         } else {
4468                                 assoc->ipsa_softuselt =
4469                                     soft->sadb_lifetime_usetime;
4470                         }
4471                 }
4472                 if (soft->sadb_lifetime_addtime != 0) {
4473                         if (soft->sadb_lifetime_addtime >
4474                             assoc->ipsa_hardexpiretime) {
4475                                 assoc->ipsa_softexpiretime =
4476                                     assoc->ipsa_hardexpiretime;
4477                         } else {
4478                                 assoc->ipsa_softaddlt =
4479                                     soft->sadb_lifetime_addtime;
4480                         }
4481                 }
4482                 if (assoc->ipsa_softaddlt != 0) {
4483                         assoc->ipsa_softexpiretime =
4484                             assoc->ipsa_addtime + assoc->ipsa_softaddlt;
4485                 }
4486                 if (assoc->ipsa_softuselt != 0 &&
4487                     assoc->ipsa_flags & IPSA_F_USED) {
4488                         UPDATE_EXPIRE(assoc, softuselt, softexpiretime);
4489                 }
4490                 if (outbound && assoc->ipsa_softexpiretime != 0) {
4491                         if (assoc->ipsa_state == IPSA_STATE_MATURE)
4492                                 lifetime_fuzz(assoc);
4493                 }
4494 
4495                 if (soft->sadb_lifetime_allocations != 0)
4496                         assoc->ipsa_softalloc = soft->sadb_lifetime_allocations;
4497         }
4498 
4499         if (idle != NULL) {
4500                 time_t current = gethrestime_sec();
4501                 if ((assoc->ipsa_idleexpiretime <= current) &&
4502                     (assoc->ipsa_idleaddlt == idle->sadb_lifetime_addtime)) {
4503                         assoc->ipsa_idleexpiretime =
4504                             current + assoc->ipsa_idleaddlt;
4505                 }
4506                 if (idle->sadb_lifetime_addtime != 0)
4507                         assoc->ipsa_idleaddlt = idle->sadb_lifetime_addtime;
4508                 if (idle->sadb_lifetime_usetime != 0)
4509                         assoc->ipsa_idleuselt = idle->sadb_lifetime_usetime;
4510                 if (assoc->ipsa_idleaddlt != 0) {
4511                         assoc->ipsa_idleexpiretime =
4512                             current + idle->sadb_lifetime_addtime;
4513                         assoc->ipsa_idletime = idle->sadb_lifetime_addtime;
4514                 }
4515                 if (assoc->ipsa_idleuselt != 0) {
4516                         if (assoc->ipsa_idletime != 0) {
4517                                 assoc->ipsa_idletime = min(assoc->ipsa_idletime,
4518                                     assoc->ipsa_idleuselt);
4519                         assoc->ipsa_idleexpiretime =
4520                             current + assoc->ipsa_idletime;
4521                         } else {
4522                                 assoc->ipsa_idleexpiretime =
4523                                     current + assoc->ipsa_idleuselt;
4524                                 assoc->ipsa_idletime = assoc->ipsa_idleuselt;
4525                         }
4526                 }
4527         }
4528         mutex_exit(&assoc->ipsa_lock);
4529 }
4530 
4531 static int
4532 sadb_update_state(ipsa_t *assoc, uint_t new_state, mblk_t **ipkt_lst)
4533 {
4534         int rcode = 0;
4535         time_t current = gethrestime_sec();
4536 
4537         mutex_enter(&assoc->ipsa_lock);
4538 
4539         switch (new_state) {
4540         case SADB_X_SASTATE_ACTIVE_ELSEWHERE:
4541                 if (assoc->ipsa_state == SADB_X_SASTATE_IDLE) {
4542                         assoc->ipsa_state = IPSA_STATE_ACTIVE_ELSEWHERE;
4543                         assoc->ipsa_idleexpiretime =
4544                             current + assoc->ipsa_idletime;
4545                 }
4546                 break;
4547         case SADB_X_SASTATE_IDLE:
4548                 if (assoc->ipsa_state == SADB_X_SASTATE_ACTIVE_ELSEWHERE) {
4549                         assoc->ipsa_state = IPSA_STATE_IDLE;
4550                         assoc->ipsa_idleexpiretime =
4551                             current + assoc->ipsa_idletime;
4552                 } else {
4553                         rcode = EINVAL;
4554                 }
4555                 break;
4556 
4557         case SADB_X_SASTATE_ACTIVE:
4558                 if (assoc->ipsa_state != SADB_X_SASTATE_IDLE) {
4559                         rcode = EINVAL;
4560                         break;
4561                 }
4562                 assoc->ipsa_state = IPSA_STATE_MATURE;
4563                 assoc->ipsa_idleexpiretime = current + assoc->ipsa_idletime;
4564 
4565                 if (ipkt_lst == NULL) {
4566                         break;
4567                 }
4568 
4569                 if (assoc->ipsa_bpkt_head != NULL) {
4570                         *ipkt_lst = assoc->ipsa_bpkt_head;
4571                         assoc->ipsa_bpkt_head = assoc->ipsa_bpkt_tail = NULL;
4572                         assoc->ipsa_mblkcnt = 0;
4573                 } else {
4574                         *ipkt_lst = NULL;
4575                 }
4576                 break;
4577         default:
4578                 rcode = EINVAL;
4579                 break;
4580         }
4581 
4582         mutex_exit(&assoc->ipsa_lock);
4583         return (rcode);
4584 }
4585 
4586 /*
4587  * Check a proposed KMC update for sanity.
4588  */
4589 static int
4590 sadb_check_kmc(ipsa_query_t *sq, ipsa_t *sa, int *diagnostic)
4591 {
4592         uint32_t kmp = sq->kmp;
4593         uint32_t kmc = sq->kmc;
4594 
4595         if (sa == NULL)
4596                 return (0);
4597 
4598         if (sa->ipsa_state == IPSA_STATE_DEAD)
4599                 return (ESRCH); /* DEAD == Not there, in this case. */
4600 
4601         if ((kmp != 0) && ((sa->ipsa_kmp != 0) || (sa->ipsa_kmp != kmp))) {
4602                 *diagnostic = SADB_X_DIAGNOSTIC_DUPLICATE_KMP;
4603                 return (EINVAL);
4604         }
4605 
4606         if ((kmc != 0) && ((sa->ipsa_kmc != 0) || (sa->ipsa_kmc != kmc))) {
4607                 *diagnostic = SADB_X_DIAGNOSTIC_DUPLICATE_KMC;
4608                 return (EINVAL);
4609         }
4610 
4611         return (0);
4612 }
4613 
4614 /*
4615  * Actually update the KMC info.
4616  */
4617 static void
4618 sadb_update_kmc(ipsa_query_t *sq, ipsa_t *sa)
4619 {
4620         uint32_t kmp = sq->kmp;
4621         uint32_t kmc = sq->kmc;
4622 
4623         if (kmp != 0)
4624                 sa->ipsa_kmp = kmp;
4625         if (kmc != 0)
4626                 sa->ipsa_kmc = kmc;
4627 }
4628 
4629 /*
4630  * Common code to update an SA.
4631  */
4632 
4633 int
4634 sadb_update_sa(mblk_t *mp, keysock_in_t *ksi, mblk_t **ipkt_lst,
4635     sadbp_t *spp, int *diagnostic, queue_t *pfkey_q,
4636     int (*add_sa_func)(mblk_t *, keysock_in_t *, int *, netstack_t *),
4637     netstack_t *ns, uint8_t sadb_msg_type)
4638 {
4639         sadb_key_t *akey = (sadb_key_t *)ksi->ks_in_extv[SADB_EXT_KEY_AUTH];
4640         sadb_key_t *ekey = (sadb_key_t *)ksi->ks_in_extv[SADB_EXT_KEY_ENCRYPT];
4641         sadb_x_replay_ctr_t *replext =
4642             (sadb_x_replay_ctr_t *)ksi->ks_in_extv[SADB_X_EXT_REPLAY_VALUE];
4643         sadb_lifetime_t *soft =
4644             (sadb_lifetime_t *)ksi->ks_in_extv[SADB_EXT_LIFETIME_SOFT];
4645         sadb_lifetime_t *hard =
4646             (sadb_lifetime_t *)ksi->ks_in_extv[SADB_EXT_LIFETIME_HARD];
4647         sadb_lifetime_t *idle =
4648             (sadb_lifetime_t *)ksi->ks_in_extv[SADB_X_EXT_LIFETIME_IDLE];
4649         sadb_x_pair_t *pair_ext =
4650             (sadb_x_pair_t *)ksi->ks_in_extv[SADB_X_EXT_PAIR];
4651         ipsa_t *echo_target = NULL;
4652         ipsap_t ipsapp;
4653         ipsa_query_t sq;
4654         time_t current = gethrestime_sec();
4655 
4656         sq.spp = spp;           /* XXX param */
4657         int error = sadb_form_query(ksi, IPSA_Q_SRC|IPSA_Q_DST|IPSA_Q_SA,
4658             IPSA_Q_SRC|IPSA_Q_DST|IPSA_Q_SA|IPSA_Q_INBOUND|IPSA_Q_OUTBOUND,
4659             &sq, diagnostic);
4660 
4661         if (error != 0)
4662                 return (error);
4663 
4664         error = get_ipsa_pair(&sq, &ipsapp, diagnostic);
4665         if (error != 0)
4666                 return (error);
4667 
4668         if (ipsapp.ipsap_psa_ptr == NULL && ipsapp.ipsap_sa_ptr != NULL) {
4669                 if (ipsapp.ipsap_sa_ptr->ipsa_state == IPSA_STATE_LARVAL) {
4670                         /*
4671                          * REFRELE the target and let the add_sa_func()
4672                          * deal with updating a larval SA.
4673                          */
4674                         destroy_ipsa_pair(&ipsapp);
4675                         return (add_sa_func(mp, ksi, diagnostic, ns));
4676                 }
4677         }
4678 
4679         /*
4680          * At this point we have an UPDATE to a MATURE SA. There should
4681          * not be any keying material present.
4682          */
4683         if (akey != NULL) {
4684                 *diagnostic = SADB_X_DIAGNOSTIC_AKEY_PRESENT;
4685                 error = EINVAL;
4686                 goto bail;
4687         }
4688         if (ekey != NULL) {
4689                 *diagnostic = SADB_X_DIAGNOSTIC_EKEY_PRESENT;
4690                 error = EINVAL;
4691                 goto bail;
4692         }
4693 
4694         if (sq.assoc->sadb_sa_state == SADB_X_SASTATE_ACTIVE_ELSEWHERE) {
4695                 if (ipsapp.ipsap_sa_ptr != NULL &&
4696                     ipsapp.ipsap_sa_ptr->ipsa_state == IPSA_STATE_IDLE) {
4697                         if ((error = sadb_update_state(ipsapp.ipsap_sa_ptr,
4698                             sq.assoc->sadb_sa_state, NULL)) != 0) {
4699                                 *diagnostic = SADB_X_DIAGNOSTIC_BAD_SASTATE;
4700                                 goto bail;
4701                         }
4702                 }
4703                 if (ipsapp.ipsap_psa_ptr != NULL &&
4704                     ipsapp.ipsap_psa_ptr->ipsa_state == IPSA_STATE_IDLE) {
4705                         if ((error = sadb_update_state(ipsapp.ipsap_psa_ptr,
4706                             sq.assoc->sadb_sa_state, NULL)) != 0) {
4707                                 *diagnostic = SADB_X_DIAGNOSTIC_BAD_SASTATE;
4708                                 goto bail;
4709                         }
4710                 }
4711         }
4712         if (sq.assoc->sadb_sa_state == SADB_X_SASTATE_ACTIVE) {
4713                 if (ipsapp.ipsap_sa_ptr != NULL) {
4714                         error = sadb_update_state(ipsapp.ipsap_sa_ptr,
4715                             sq.assoc->sadb_sa_state,
4716                             (ipsapp.ipsap_sa_ptr->ipsa_flags &
4717                             IPSA_F_INBOUND) ? ipkt_lst : NULL);
4718                         if (error) {
4719                                 *diagnostic = SADB_X_DIAGNOSTIC_BAD_SASTATE;
4720                                 goto bail;
4721                         }
4722                 }
4723                 if (ipsapp.ipsap_psa_ptr != NULL) {
4724                         error = sadb_update_state(ipsapp.ipsap_psa_ptr,
4725                             sq.assoc->sadb_sa_state,
4726                             (ipsapp.ipsap_psa_ptr->ipsa_flags &
4727                             IPSA_F_INBOUND) ? ipkt_lst : NULL);
4728                         if (error) {
4729                                 *diagnostic = SADB_X_DIAGNOSTIC_BAD_SASTATE;
4730                                 goto bail;
4731                         }
4732                 }
4733                 sadb_pfkey_echo(pfkey_q, mp, (sadb_msg_t *)mp->b_cont->b_rptr,
4734                     ksi, echo_target);
4735                 goto bail;
4736         }
4737 
4738         /*
4739          * Reality checks for updates of active associations.
4740          * Sundry first-pass UPDATE-specific reality checks.
4741          * Have to do the checks here, because it's after the add_sa code.
4742          * XXX STATS : logging/stats here?
4743          */
4744 
4745         if (!((sq.assoc->sadb_sa_state == SADB_SASTATE_MATURE) ||
4746             (sq.assoc->sadb_sa_state == SADB_X_SASTATE_ACTIVE_ELSEWHERE))) {
4747                 *diagnostic = SADB_X_DIAGNOSTIC_BAD_SASTATE;
4748                 error = EINVAL;
4749                 goto bail;
4750         }
4751         if (sq.assoc->sadb_sa_flags & ~spp->s_updateflags) {
4752                 *diagnostic = SADB_X_DIAGNOSTIC_BAD_SAFLAGS;
4753                 error = EINVAL;
4754                 goto bail;
4755         }
4756         if (ksi->ks_in_extv[SADB_EXT_LIFETIME_CURRENT] != NULL) {
4757                 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_LIFETIME;
4758                 error = EOPNOTSUPP;
4759                 goto bail;
4760         }
4761 
4762         if ((*diagnostic = sadb_hardsoftchk(hard, soft, idle)) != 0) {
4763                 error = EINVAL;
4764                 goto bail;
4765         }
4766 
4767         if ((*diagnostic = sadb_labelchk(ksi)) != 0)
4768                 return (EINVAL);
4769 
4770         error = sadb_check_kmc(&sq, ipsapp.ipsap_sa_ptr, diagnostic);
4771         if (error != 0)
4772                 goto bail;
4773 
4774         error = sadb_check_kmc(&sq, ipsapp.ipsap_psa_ptr, diagnostic);
4775         if (error != 0)
4776                 goto bail;
4777 
4778 
4779         if (ipsapp.ipsap_sa_ptr != NULL) {
4780                 /*
4781                  * Do not allow replay value change for MATURE or LARVAL SA.
4782                  */
4783 
4784                 if ((replext != NULL) &&
4785                     ((ipsapp.ipsap_sa_ptr->ipsa_state == IPSA_STATE_LARVAL) ||
4786                     (ipsapp.ipsap_sa_ptr->ipsa_state == IPSA_STATE_MATURE))) {
4787                         *diagnostic = SADB_X_DIAGNOSTIC_BAD_SASTATE;
4788                         error = EINVAL;
4789                         goto bail;
4790                 }
4791         }
4792 
4793 
4794         if (ipsapp.ipsap_sa_ptr != NULL) {
4795                 sadb_update_lifetimes(ipsapp.ipsap_sa_ptr, hard, soft,
4796                     idle, B_TRUE);
4797                 sadb_update_kmc(&sq, ipsapp.ipsap_sa_ptr);
4798                 if ((replext != NULL) &&
4799                     (ipsapp.ipsap_sa_ptr->ipsa_replay_wsize != 0)) {
4800                         /*
4801                          * If an inbound SA, update the replay counter
4802                          * and check off all the other sequence number
4803                          */
4804                         if (ksi->ks_in_dsttype == KS_IN_ADDR_ME) {
4805                                 if (!sadb_replay_check(ipsapp.ipsap_sa_ptr,
4806                                     replext->sadb_x_rc_replay32)) {
4807                                         *diagnostic =
4808                                             SADB_X_DIAGNOSTIC_INVALID_REPLAY;
4809                                         error = EINVAL;
4810                                         goto bail;
4811                                 }
4812                                 mutex_enter(&ipsapp.ipsap_sa_ptr->ipsa_lock);
4813                                 ipsapp.ipsap_sa_ptr->ipsa_idleexpiretime =
4814                                     current +
4815                                     ipsapp.ipsap_sa_ptr->ipsa_idletime;
4816                                 mutex_exit(&ipsapp.ipsap_sa_ptr->ipsa_lock);
4817                         } else {
4818                                 mutex_enter(&ipsapp.ipsap_sa_ptr->ipsa_lock);
4819                                 ipsapp.ipsap_sa_ptr->ipsa_replay =
4820                                     replext->sadb_x_rc_replay32;
4821                                 ipsapp.ipsap_sa_ptr->ipsa_idleexpiretime =
4822                                     current +
4823                                     ipsapp.ipsap_sa_ptr->ipsa_idletime;
4824                                 mutex_exit(&ipsapp.ipsap_sa_ptr->ipsa_lock);
4825                         }
4826                 }
4827         }
4828 
4829         if (sadb_msg_type == SADB_X_UPDATEPAIR) {
4830                 if (ipsapp.ipsap_psa_ptr != NULL) {
4831                         sadb_update_lifetimes(ipsapp.ipsap_psa_ptr, hard, soft,
4832                             idle, B_FALSE);
4833                         sadb_update_kmc(&sq, ipsapp.ipsap_psa_ptr);
4834                 } else {
4835                         *diagnostic = SADB_X_DIAGNOSTIC_PAIR_SA_NOTFOUND;
4836                         error = ESRCH;
4837                         goto bail;
4838                 }
4839         }
4840 
4841         if (pair_ext != NULL)
4842                 error = update_pairing(&ipsapp, &sq, ksi, diagnostic);
4843 
4844         if (error == 0)
4845                 sadb_pfkey_echo(pfkey_q, mp, (sadb_msg_t *)mp->b_cont->b_rptr,
4846                     ksi, echo_target);
4847 bail:
4848 
4849         destroy_ipsa_pair(&ipsapp);
4850 
4851         return (error);
4852 }
4853 
4854 
4855 static int
4856 update_pairing(ipsap_t *ipsapp, ipsa_query_t *sq, keysock_in_t *ksi,
4857     int *diagnostic)
4858 {
4859         sadb_sa_t *assoc = (sadb_sa_t *)ksi->ks_in_extv[SADB_EXT_SA];
4860         sadb_x_pair_t *pair_ext =
4861             (sadb_x_pair_t *)ksi->ks_in_extv[SADB_X_EXT_PAIR];
4862         int error = 0;
4863         ipsap_t oipsapp;
4864         boolean_t undo_pair = B_FALSE;
4865         uint32_t ipsa_flags;
4866 
4867         if (pair_ext->sadb_x_pair_spi == 0 || pair_ext->sadb_x_pair_spi ==
4868             assoc->sadb_sa_spi) {
4869                 *diagnostic = SADB_X_DIAGNOSTIC_PAIR_INAPPROPRIATE;
4870                 return (EINVAL);
4871         }
4872 
4873         /*
4874          * Assume for now that the spi value provided in the SADB_UPDATE
4875          * message was valid, update the SA with its pair spi value.
4876          * If the spi turns out to be bogus or the SA no longer exists
4877          * then this will be detected when the reverse update is made
4878          * below.
4879          */
4880         mutex_enter(&ipsapp->ipsap_sa_ptr->ipsa_lock);
4881         ipsapp->ipsap_sa_ptr->ipsa_flags |= IPSA_F_PAIRED;
4882         ipsapp->ipsap_sa_ptr->ipsa_otherspi = pair_ext->sadb_x_pair_spi;
4883         mutex_exit(&ipsapp->ipsap_sa_ptr->ipsa_lock);
4884 
4885         /*
4886          * After updating the ipsa_otherspi element of the SA, get_ipsa_pair()
4887          * should now return pointers to the SA *AND* its pair, if this is not
4888          * the case, the "otherspi" either did not exist or was deleted. Also
4889          * check that "otherspi" is not already paired. If everything looks
4890          * good, complete the update. IPSA_REFRELE the first pair_pointer
4891          * after this update to ensure its not deleted until we are done.
4892          */
4893         error = get_ipsa_pair(sq, &oipsapp, diagnostic);
4894         if (error != 0) {
4895                 /*
4896                  * This should never happen, calling function still has
4897                  * IPSA_REFHELD on the SA we just updated.
4898                  */
4899                 return (error); /* XXX EINVAL instead of ESRCH? */
4900         }
4901 
4902         if (oipsapp.ipsap_psa_ptr == NULL) {
4903                 *diagnostic = SADB_X_DIAGNOSTIC_PAIR_INAPPROPRIATE;
4904                 error = EINVAL;
4905                 undo_pair = B_TRUE;
4906         } else {
4907                 ipsa_flags = oipsapp.ipsap_psa_ptr->ipsa_flags;
4908                 if ((oipsapp.ipsap_psa_ptr->ipsa_state == IPSA_STATE_DEAD) ||
4909                     (oipsapp.ipsap_psa_ptr->ipsa_state == IPSA_STATE_DYING)) {
4910                         /* Its dead Jim! */
4911                         *diagnostic = SADB_X_DIAGNOSTIC_PAIR_INAPPROPRIATE;
4912                         undo_pair = B_TRUE;
4913                 } else if ((ipsa_flags & (IPSA_F_OUTBOUND | IPSA_F_INBOUND)) ==
4914                     (IPSA_F_OUTBOUND | IPSA_F_INBOUND)) {
4915                         /* This SA is in both hashtables. */
4916                         *diagnostic = SADB_X_DIAGNOSTIC_PAIR_INAPPROPRIATE;
4917                         undo_pair = B_TRUE;
4918                 } else if (ipsa_flags & IPSA_F_PAIRED) {
4919                         /* This SA is already paired with another. */
4920                         *diagnostic = SADB_X_DIAGNOSTIC_PAIR_ALREADY;
4921                         undo_pair = B_TRUE;
4922                 }
4923         }
4924 
4925         if (undo_pair) {
4926                 /* The pair SA does not exist. */
4927                 mutex_enter(&ipsapp->ipsap_sa_ptr->ipsa_lock);
4928                 ipsapp->ipsap_sa_ptr->ipsa_flags &= ~IPSA_F_PAIRED;
4929                 ipsapp->ipsap_sa_ptr->ipsa_otherspi = 0;
4930                 mutex_exit(&ipsapp->ipsap_sa_ptr->ipsa_lock);
4931         } else {
4932                 mutex_enter(&oipsapp.ipsap_psa_ptr->ipsa_lock);
4933                 oipsapp.ipsap_psa_ptr->ipsa_otherspi = assoc->sadb_sa_spi;
4934                 oipsapp.ipsap_psa_ptr->ipsa_flags |= IPSA_F_PAIRED;
4935                 mutex_exit(&oipsapp.ipsap_psa_ptr->ipsa_lock);
4936         }
4937 
4938         destroy_ipsa_pair(&oipsapp);
4939         return (error);
4940 }
4941 
4942 /*
4943  * The following functions deal with ACQUIRE LISTS.  An ACQUIRE list is
4944  * a list of outstanding SADB_ACQUIRE messages.  If ipsec_getassocbyconn() fails
4945  * for an outbound datagram, that datagram is queued up on an ACQUIRE record,
4946  * and an SADB_ACQUIRE message is sent up.  Presumably, a user-space key
4947  * management daemon will process the ACQUIRE, use a SADB_GETSPI to reserve
4948  * an SPI value and a larval SA, then SADB_UPDATE the larval SA, and ADD the
4949  * other direction's SA.
4950  */
4951 
4952 /*
4953  * Check the ACQUIRE lists.  If there's an existing ACQUIRE record,
4954  * grab it, lock it, and return it.  Otherwise return NULL.
4955  *
4956  * XXX MLS number of arguments getting unwieldy here
4957  */
4958 static ipsacq_t *
4959 sadb_checkacquire(iacqf_t *bucket, ipsec_action_t *ap, ipsec_policy_t *pp,
4960     uint32_t *src, uint32_t *dst, uint32_t *isrc, uint32_t *idst,
4961     uint64_t unique_id, ts_label_t *tsl)
4962 {
4963         ipsacq_t *walker;
4964         sa_family_t fam;
4965         uint32_t blank_address[4] = {0, 0, 0, 0};
4966 
4967         ASSERT(MUTEX_HELD(&bucket->iacqf_lock));
4968 
4969         if (isrc == NULL) {
4970                 ASSERT(idst == NULL);
4971                 isrc = idst = blank_address;
4972         }
4973 
4974         /*
4975          * Scan list for duplicates.  Check for UNIQUE, src/dest, policy.
4976          *
4977          * XXX May need search for duplicates based on other things too!
4978          */
4979         for (walker = bucket->iacqf_ipsacq; walker != NULL;
4980             walker = walker->ipsacq_next) {
4981                 mutex_enter(&walker->ipsacq_lock);
4982                 fam = walker->ipsacq_addrfam;
4983                 if (IPSA_ARE_ADDR_EQUAL(dst, walker->ipsacq_dstaddr, fam) &&
4984                     IPSA_ARE_ADDR_EQUAL(src, walker->ipsacq_srcaddr, fam) &&
4985                     ip_addr_match((uint8_t *)isrc, walker->ipsacq_innersrcpfx,
4986                     (in6_addr_t *)walker->ipsacq_innersrc) &&
4987                     ip_addr_match((uint8_t *)idst, walker->ipsacq_innerdstpfx,
4988                     (in6_addr_t *)walker->ipsacq_innerdst) &&
4989                     (ap == walker->ipsacq_act) &&
4990                     (pp == walker->ipsacq_policy) &&
4991                     /* XXX do deep compares of ap/pp? */
4992                     (unique_id == walker->ipsacq_unique_id) &&
4993                     (ipsec_label_match(tsl, walker->ipsacq_tsl)))
4994                         break;                  /* everything matched */
4995                 mutex_exit(&walker->ipsacq_lock);
4996         }
4997 
4998         return (walker);
4999 }
5000 
5001 /*
5002  * Take a pointers to mblk_t (packet for which we need to acquire an SA) and
5003  * ip_xmit_attr_t (transmit attributes used to generate or retrieve acquire
5004  * record) and two booleans need_ah and need_esp, one but not both of which
5005  * must be true. Acquire records are stored in hash buckets, and we assume
5006  * bucket contains addrs of all of the same length. If this is a new acquire
5007  * record, we generate an acquire samsg to send to protocol keysock layer,
5008  * which assumes ownership from there. If we run into problems along the way,
5009  * we generate errors if possible and drop packets if need be. Before sending
5010  * to keysock, we simply unlock the acquire record and let the ager deal with
5011  * releasing locks and freeing resources.
5012  *
5013  * This code is called by the IP stack when trying to send a packet for which
5014  * all necessary SAs can't be found to include in ip_xmit_attr_t. Be aware of
5015  * the following case: you need both ESP and AH and have SAs for neither. In
5016  * that case both need_esp and need_ah are true, but we go with need_esp, as
5017  * ESP will call us back for an AH acquire if it's successful and the AH SA
5018  * still missing. It can also be that the packet needs both, but an SA already
5019  * exists for one, in which case only the missing one will be flagged as
5020  * needed, although the ipsec_action_t has want flags for both.
5021  */
5022 void
5023 sadb_acquire(mblk_t *datamp, ip_xmit_attr_t *ixa, boolean_t need_ah,
5024     boolean_t need_esp)
5025 {
5026         mblk_t          *asyncmp, *regular, *extended, *prop_m, *eprop_m;
5027         sadbp_t *spp;
5028         sadb_t *sp;
5029         ipsacq_t *newbie;
5030         iacqf_t *bucket;
5031         ipha_t *ipha = (ipha_t *)datamp->b_rptr;
5032         ip6_t *ip6h = (ip6_t *)datamp->b_rptr;
5033         uint32_t        seq, *src, *dst, *isrc, *idst;
5034         ipsec_policy_t *pp = ixa->ixa_ipsec_policy;
5035         ipsec_action_t *ap = ixa->ixa_ipsec_action;
5036         sa_family_t af;
5037         int             hashoffset, sens_len;
5038         uint64_t unique_id = 0;
5039         uint_t          propsize, epropsize, combs_limit;
5040         uint8_t         *start, *end;
5041         sadb_msg_t      *samsg;
5042         sadb_prop_t     *prop, *eprop;
5043         ipsec_selector_t sel;
5044         boolean_t tunnel_mode = (ixa->ixa_flags & IXAF_IPSEC_TUNNEL) != 0;
5045         ts_label_t      *tsl = NULL;
5046         netstack_t      *ns = ixa->ixa_ipst->ips_netstack;
5047         ipsec_stack_t   *ipss = ns->netstack_ipsec;
5048         sadb_sens_t     *sens = NULL;
5049         ipsecesp_stack_t *espstack = ns->netstack_ipsecesp;
5050         ipsecah_stack_t *ahstack = ns->netstack_ipsecah;
5051         queue_t         *q;
5052 
5053         ASSERT(need_ah || need_esp);
5054         ASSERT((ap != NULL) || (pp != NULL));
5055 
5056         spp = need_esp ? &espstack->esp_sadb : &ahstack->ah_sadb;
5057         sp = (ixa->ixa_flags & IXAF_IS_IPV4) ? &spp->s_v4 : &spp->s_v6;
5058 
5059         if (is_system_labeled())
5060                 tsl = ixa->ixa_tsl;
5061 
5062         if (ap == NULL)
5063                 ap = pp->ipsp_act;
5064         ASSERT(ap != NULL);
5065 
5066         if (ap->ipa_act.ipa_apply.ipp_use_unique || tunnel_mode)
5067                 unique_id = SA_FORM_UNIQUE_ID(ixa);
5068 
5069         /*
5070          * Set up an ACQUIRE record.
5071          *
5072          * Immediately, make sure the ACQUIRE sequence number doesn't slip
5073          * below the lowest point allowed in the kernel.  (In other words,
5074          * make sure the high bit on the sequence number is set.)
5075          */
5076         seq = keysock_next_seq(ns) | IACQF_LOWEST_SEQ;
5077 
5078         if (IPH_HDR_VERSION(ipha) == IP_VERSION) {
5079                 src = (uint32_t *)&ipha->ipha_src;
5080                 dst = (uint32_t *)&ipha->ipha_dst;
5081                 af = AF_INET;
5082                 ip6h = NULL;
5083                 hashoffset = OUTBOUND_HASH_V4(sp, ipha->ipha_dst);
5084                 ASSERT(ixa->ixa_flags & IXAF_IS_IPV4);
5085         } else {
5086                 ASSERT(IPH_HDR_VERSION(ipha) == IPV6_VERSION);
5087                 src = (uint32_t *)&ip6h->ip6_src;
5088                 dst = (uint32_t *)&ip6h->ip6_dst;
5089                 af = AF_INET6;
5090                 ipha = NULL;
5091                 hashoffset = OUTBOUND_HASH_V6(sp, ip6h->ip6_dst);
5092                 ASSERT(!(ixa->ixa_flags & IXAF_IS_IPV4));
5093         }
5094 
5095         if (tunnel_mode) {
5096                 if (pp == NULL) {
5097                         /*
5098                          * Tunnel mode with no policy pointer means this is a
5099                          * reflected ICMP (like a ECHO REQUEST) that came in
5100                          * with self-encapsulated protection.  Until we better
5101                          * support this, drop the packet.
5102                          */
5103                         ip_drop_packet(datamp, B_FALSE, NULL,
5104                             DROPPER(ipss, ipds_spd_got_selfencap),
5105                             &ipss->ipsec_spd_dropper);
5106                         return;
5107                 }
5108                 /* Snag inner addresses. */
5109                 isrc = ixa->ixa_ipsec_insrc;
5110                 idst = ixa->ixa_ipsec_indst;
5111         } else {
5112                 isrc = idst = NULL;
5113         }
5114 
5115         /*
5116          * Check bucket for existing matching entry. If so, grab it. On match
5117          * sadb_checkacquire returns locked newbie.
5118          */
5119         bucket = &(sp->sdb_acq[hashoffset]);
5120         mutex_enter(&bucket->iacqf_lock);
5121         newbie = sadb_checkacquire(bucket, ap, pp, src, dst, isrc, idst,
5122             unique_id, tsl);
5123 
5124         /* If not found, initialize a new one and insert into chain. */
5125         if (newbie == NULL) {
5126                 newbie = kmem_zalloc(sizeof (*newbie), KM_NOSLEEP);
5127                 if (newbie == NULL) {
5128                         mutex_exit(&bucket->iacqf_lock);
5129                         ip_drop_packet(datamp, B_FALSE, NULL,
5130                             DROPPER(ipss, ipds_sadb_acquire_nomem),
5131                             &ipss->ipsec_sadb_dropper);
5132                         return;
5133                 }
5134                 newbie->ipsacq_policy = pp;
5135                 if (pp != NULL) {
5136                         IPPOL_REFHOLD(pp);
5137                 }
5138                 IPACT_REFHOLD(ap);
5139                 newbie->ipsacq_act = ap;
5140                 newbie->ipsacq_linklock = &bucket->iacqf_lock;
5141                 newbie->ipsacq_next = bucket->iacqf_ipsacq;
5142                 newbie->ipsacq_ptpn = &bucket->iacqf_ipsacq;
5143                 if (newbie->ipsacq_next != NULL)
5144                         newbie->ipsacq_next->ipsacq_ptpn = &newbie->ipsacq_next;
5145 
5146                 bucket->iacqf_ipsacq = newbie;
5147                 mutex_init(&newbie->ipsacq_lock, NULL, MUTEX_DEFAULT, NULL);
5148                 mutex_enter(&newbie->ipsacq_lock);
5149         }
5150 
5151         /*
5152          * XXX MLS does it actually help us to drop the bucket lock here?
5153          * we have inserted a half-built, locked acquire record into the
5154          * bucket.  any competing thread will now be able to lock the bucket
5155          * to scan it, but will immediately pile up on the new acquire
5156          * record's lock; I don't think we gain anything here other than to
5157          * disperse blame for lock contention.
5158          *
5159          * we might be able to dispense with acquire record locks entirely..
5160          * just use the bucket locks..
5161          */
5162         mutex_exit(&bucket->iacqf_lock);
5163 
5164         /*
5165          * This assert looks silly for now, but we may need to enter newbie's
5166          * mutex during a search. Confirms we got locked newbie from
5167          * sadb_checkacquire.
5168          */
5169         ASSERT(MUTEX_HELD(&newbie->ipsacq_lock));
5170 
5171         /* Make ip_xmit_attr_t into message we can queue, link packet data. */
5172         asyncmp = ip_xmit_attr_to_mblk(ixa);
5173         if (asyncmp != NULL)
5174                 linkb(asyncmp, datamp);
5175 
5176         /* Bump appropriate discard stat & free datamp if allocation failed. */
5177         if (asyncmp == NULL) {
5178                 if (ixa->ixa_flags & IXAF_IS_IPV4) {
5179                         BUMP_MIB(&ixa->ixa_ipst->ips_ip_mib,
5180                             ipIfStatsOutDiscards);
5181                 } else {
5182                         BUMP_MIB(&ixa->ixa_ipst->ips_ip6_mib,
5183                             ipIfStatsOutDiscards);
5184                 }
5185                 ip_drop_output("No memory for asyncmp", datamp, NULL);
5186                 freemsg(datamp);
5187         } else if (newbie->ipsacq_numpackets == 0) { /* Pkt queue forms here. */
5188                 newbie->ipsacq_mp = asyncmp;
5189                 newbie->ipsacq_numpackets = 1;
5190                 newbie->ipsacq_expire = gethrestime_sec();
5191                 /* Extended ACQUIRE with AH+ESP uses ESP's timeout */
5192                 newbie->ipsacq_expire += *spp->s_acquire_timeout;
5193                 newbie->ipsacq_seq = seq;
5194                 newbie->ipsacq_addrfam = af;
5195 
5196                 newbie->ipsacq_srcport = ixa->ixa_ipsec_src_port;
5197                 newbie->ipsacq_dstport = ixa->ixa_ipsec_dst_port;
5198                 newbie->ipsacq_icmp_type = ixa->ixa_ipsec_icmp_type;
5199                 newbie->ipsacq_icmp_code = ixa->ixa_ipsec_icmp_code;
5200                 if (tunnel_mode) {
5201                         newbie->ipsacq_inneraddrfam = ixa->ixa_ipsec_inaf;
5202                         newbie->ipsacq_proto = ixa->ixa_ipsec_inaf == AF_INET6 ?
5203                             IPPROTO_IPV6 : IPPROTO_ENCAP;
5204                         newbie->ipsacq_innersrcpfx = ixa->ixa_ipsec_insrcpfx;
5205                         newbie->ipsacq_innerdstpfx = ixa->ixa_ipsec_indstpfx;
5206                         IPSA_COPY_ADDR(newbie->ipsacq_innersrc,
5207                             ixa->ixa_ipsec_insrc, ixa->ixa_ipsec_inaf);
5208                         IPSA_COPY_ADDR(newbie->ipsacq_innerdst,
5209                             ixa->ixa_ipsec_indst, ixa->ixa_ipsec_inaf);
5210                 } else {
5211                         newbie->ipsacq_proto = ixa->ixa_ipsec_proto;
5212                 }
5213                 newbie->ipsacq_unique_id = unique_id;
5214 
5215                 if (tsl != NULL) {
5216                         label_hold(tsl);
5217                         newbie->ipsacq_tsl = tsl;
5218                 }
5219         } else { /* Attempt to join packet queue as b_next. */
5220                 mblk_t *lastone = newbie->ipsacq_mp;
5221 
5222                 while (lastone->b_next != NULL)
5223                         lastone = lastone->b_next;
5224                 lastone->b_next = asyncmp;
5225                 /* Queue maxed: set counter to max, unchain, free & drop pkt */
5226                 if (newbie->ipsacq_numpackets++ == ipsacq_maxpackets) {
5227                         newbie->ipsacq_numpackets = ipsacq_maxpackets;
5228                         lastone = newbie->ipsacq_mp;
5229                         newbie->ipsacq_mp = lastone->b_next;
5230                         lastone->b_next = NULL;
5231 
5232                         lastone = ip_xmit_attr_free_mblk(lastone);
5233                         ip_drop_packet(lastone, B_FALSE, NULL,
5234                             DROPPER(ipss, ipds_sadb_acquire_toofull),
5235                             &ipss->ipsec_sadb_dropper);
5236                 } else { /* Successfully queued */
5237                         IP_ACQUIRE_STAT(ipss, qhiwater,
5238                             newbie->ipsacq_numpackets);
5239                 }
5240         }
5241 
5242         /*
5243          * Reset addresses.  Set them to the most recently added mblk chain,
5244          * so that the address pointers in the acquire record will point
5245          * at an mblk still attached to the acquire list.
5246          */
5247 
5248         newbie->ipsacq_srcaddr = src;
5249         newbie->ipsacq_dstaddr = dst;
5250 
5251         /*
5252          * Sequence number mismatch or previously populated packet queue means
5253          * we retrieved an already-pending ACQUIRE record and needn't repeat
5254          * ourself. Unlock and return.
5255          */
5256         if (newbie->ipsacq_seq != seq || newbie->ipsacq_numpackets > 1)
5257                 goto unlock_acqrec;
5258 
5259         /*
5260          * Even if we fail before sending to keysock, starting with a NULL
5261          * queue pointer, if gets this far, it counts as an acquire request.
5262          */
5263         if (need_esp) {
5264                 ESP_BUMP_STAT(espstack, acquire_requests);
5265                 q = espstack->esp_pfkey_q;
5266         } else {
5267                 AH_BUMP_STAT(ahstack, acquire_requests);
5268                 q = ahstack->ah_pfkey_q;
5269         }
5270 
5271         if (q == NULL)
5272                 goto unlock_acqrec;
5273 
5274         /* Initializes keysock M_CTL message for regular acquire. */
5275         regular = sadb_keysock_out(0);
5276         if (regular == NULL)
5277                 goto unlock_acqrec;
5278 
5279         /*
5280          * Check keysock stack to make sure we don't have extended register
5281          * pending. If not, have keysock initialize M_CTL msg for extended
5282          * acquire. If pending, set extended to NULL so we ignore it hereafter.
5283          */
5284         if (keysock_extended_reg(ns)) {
5285                 extended = sadb_keysock_out(0);
5286                 if (extended == NULL)
5287                         goto bail_and_free_regular;
5288         } else {
5289                 extended = NULL;
5290         }
5291 
5292         if (tsl != NULL) {
5293                 /*
5294                  * XXX MLS correct condition here?
5295                  * XXX MLS other credential attributes in acquire?
5296                  * XXX malloc failure?  don't fall back to original?
5297                  */
5298                 sens = sadb_make_sens_ext(tsl, &sens_len);
5299 
5300                 if (sens == NULL)
5301                         goto bail_extended;
5302         }
5303         /* re-initialize selector using ixa and ipha */
5304         bzero(&sel, sizeof (sel));
5305         sel.ips_isv4 = (ixa->ixa_flags & IXAF_IS_IPV4) != 0;
5306         if (tunnel_mode) {
5307                 sel.ips_protocol = (ixa->ixa_ipsec_inaf == AF_INET) ?
5308                     IPPROTO_ENCAP : IPPROTO_IPV6;
5309         } else {
5310                 sel.ips_protocol = ixa->ixa_ipsec_proto;
5311                 sel.ips_local_port = ixa->ixa_ipsec_src_port;
5312                 sel.ips_remote_port = ixa->ixa_ipsec_dst_port;
5313         }
5314         sel.ips_icmp_type = ixa->ixa_ipsec_icmp_type;
5315         sel.ips_icmp_code = ixa->ixa_ipsec_icmp_code;
5316         sel.ips_is_icmp_inv_acq = 0;
5317         if (af == AF_INET) {
5318                 sel.ips_local_addr_v4 = ipha->ipha_src;
5319                 sel.ips_remote_addr_v4 = ipha->ipha_dst;
5320         } else {
5321                 sel.ips_local_addr_v6 = ip6h->ip6_src;
5322                 sel.ips_remote_addr_v6 = ip6h->ip6_dst;
5323         }
5324 
5325         /* Tack message containing sadb_msg_t onto keysock regular M_CTL */
5326         regular->b_cont = sadb_construct_acqmsg(newbie, &sel, ap, pp, ns, sens,
5327             need_esp, tunnel_mode, B_FALSE, B_FALSE); /* regular, no props */
5328         /* We have to do this, no matter the result of previous call */
5329         if (sens != NULL)
5330                 kmem_free(sens, sens_len);
5331 
5332         if (regular->b_cont == NULL)
5333                 goto bail_extended;
5334 
5335         /*
5336          * If there's no extended pending, duplicate regular samsg, tacking it
5337          * on as the b_cont of the keysock-generated extended M_CTL.
5338          */
5339         if (extended != NULL) {
5340                 extended->b_cont = dupb(regular->b_cont);
5341                 if (extended->b_cont == NULL)
5342                         goto bail_extended;
5343         }
5344 
5345         rw_enter(&ipss->ipsec_alg_lock, RW_READER);
5346         CALC_COMBS(combs_limit, ipss, need_esp);
5347         propsize = sizeof (sadb_prop_t) + (combs_limit * sizeof (sadb_comb_t));
5348 
5349         if ((prop_m = allocb(propsize, BPRI_HI)) == NULL)
5350                 goto bail_and_unlock;
5351 
5352         if (extended != NULL) {
5353                 epropsize = sizeof (sadb_prop_t)
5354                     + (combs_limit * sizeof (sadb_x_ecomb_t));
5355                 if ((eprop_m = allocb(epropsize, BPRI_HI)) == NULL)
5356                         goto bail_and_unlock;
5357         }
5358 
5359         prop = (sadb_prop_t *)prop_m->b_rptr;
5360         sadb_insert_prop(prop, ap, ns, combs_limit, need_esp);
5361         if (prop == NULL) {
5362                 goto bail_and_unlock;
5363         /* 0 length prop is error, mark regular samsg a dud, & freeb prop_m */
5364         } else {
5365                 samsg = (sadb_msg_t *)regular->b_cont->b_rptr;
5366 
5367                 if (prop->sadb_prop_len == 0) {
5368                         ERRNO_SAMSG(samsg, ENOENT);
5369                         freeb(prop_m);
5370                 }
5371                 samsg->sadb_msg_len += prop->sadb_prop_len;
5372                 prop_m->b_wptr += SADB_64TO8(prop->sadb_prop_len);
5373                 regular->b_cont->b_cont = prop_m;
5374         }
5375 
5376         if (extended != NULL) {
5377                 start = (uint8_t *)eprop_m->b_rptr;
5378                 end = start + epropsize;
5379                 eprop =
5380                     (sadb_prop_t *)sadb_construct_eprop(ap, pp, ns, start, end);
5381                 if (eprop == NULL)
5382                         goto bail_and_unlock;
5383                 /* If 0 ecombs, mark extended samsg a dud, and freeb eprop_m */
5384                 else {
5385                         samsg = (sadb_msg_t *)extended->b_cont->b_rptr;
5386 
5387                         if (eprop->sadb_x_prop_numecombs == 0) {
5388                                 ERRNO_SAMSG(samsg, ENOENT);
5389                                 freeb(eprop_m);
5390                         }
5391                         samsg->sadb_msg_len += eprop->sadb_prop_len;
5392                         eprop_m->b_wptr += SADB_64TO8(eprop->sadb_prop_len);
5393                         extended->b_cont->b_cont = eprop_m;
5394                 }
5395         }
5396 
5397         rw_exit(&ipss->ipsec_alg_lock);
5398         mutex_exit(&newbie->ipsacq_lock);
5399 
5400         if (extended != NULL)
5401                 putnext(q, extended);
5402         putnext(q, regular);
5403         return;
5404 
5405 /* We used a lot of b_cont mblk chaining, so we need to use freemsg. */
5406 bail_and_unlock:
5407         rw_exit(&ipss->ipsec_alg_lock);
5408 bail_extended:
5409         if (extended != NULL)
5410                 freemsg(extended);
5411 bail_and_free_regular:
5412         freemsg(regular);
5413 unlock_acqrec:
5414         mutex_exit(&newbie->ipsacq_lock);
5415 }
5416 
5417 /*
5418  * Unlink and free an acquire record.
5419  */
5420 void
5421 sadb_destroy_acquire(ipsacq_t *acqrec, netstack_t *ns)
5422 {
5423         mblk_t          *mp;
5424         ipsec_stack_t   *ipss = ns->netstack_ipsec;
5425 
5426         ASSERT(MUTEX_HELD(acqrec->ipsacq_linklock));
5427 
5428         /* XXX Should references be released before mutex is acquired? */
5429         if (acqrec->ipsacq_policy != NULL) {
5430                 IPPOL_REFRELE(acqrec->ipsacq_policy);
5431         }
5432         if (acqrec->ipsacq_act != NULL) {
5433                 IPACT_REFRELE(acqrec->ipsacq_act);
5434         }
5435 
5436         /* Unlink */
5437         *(acqrec->ipsacq_ptpn) = acqrec->ipsacq_next;
5438         if (acqrec->ipsacq_next != NULL)
5439                 acqrec->ipsacq_next->ipsacq_ptpn = acqrec->ipsacq_ptpn;
5440 
5441         if (acqrec->ipsacq_tsl != NULL) {
5442                 label_rele(acqrec->ipsacq_tsl);
5443                 acqrec->ipsacq_tsl = NULL;
5444         }
5445 
5446         /*
5447          * Free hanging mp's.
5448          *
5449          * XXX Instead of freemsg(), perhaps use IPSEC_REQ_FAILED.
5450          */
5451 
5452         mutex_enter(&acqrec->ipsacq_lock);
5453         while (acqrec->ipsacq_mp != NULL) {
5454                 mp = acqrec->ipsacq_mp;
5455                 acqrec->ipsacq_mp = mp->b_next;
5456                 mp->b_next = NULL;
5457                 /* Freeing the async message */
5458                 mp = ip_xmit_attr_free_mblk(mp);
5459                 ip_drop_packet(mp, B_FALSE, NULL,
5460                     DROPPER(ipss, ipds_sadb_acquire_timeout),
5461                     &ipss->ipsec_sadb_dropper);
5462         }
5463         mutex_exit(&acqrec->ipsacq_lock);
5464 
5465         /* Free */
5466         mutex_destroy(&acqrec->ipsacq_lock);
5467         kmem_free(acqrec, sizeof (*acqrec));
5468 }
5469 
5470 /*
5471  * Destroy an acquire list fanout.
5472  */
5473 static void
5474 sadb_destroy_acqlist(iacqf_t **listp, uint_t numentries, boolean_t forever,
5475     netstack_t *ns)
5476 {
5477         int i;
5478         iacqf_t *list = *listp;
5479 
5480         if (list == NULL)
5481                 return;
5482 
5483         for (i = 0; i < numentries; i++) {
5484                 mutex_enter(&(list[i].iacqf_lock));
5485                 while (list[i].iacqf_ipsacq != NULL)
5486                         sadb_destroy_acquire(list[i].iacqf_ipsacq, ns);
5487                 mutex_exit(&(list[i].iacqf_lock));
5488                 if (forever)
5489                         mutex_destroy(&(list[i].iacqf_lock));
5490         }
5491 
5492         if (forever) {
5493                 *listp = NULL;
5494                 kmem_free(list, numentries * sizeof (*list));
5495         }
5496 }
5497 
5498 /*
5499  * Create an algorithm descriptor for an extended ACQUIRE.  Filter crypto
5500  * framework's view of reality vs. IPsec's.  EF's wins, BTW.
5501  */
5502 static uint8_t *
5503 sadb_new_algdesc(const uint8_t *start, const uint8_t *end,
5504     sadb_x_ecomb_t *ecomb, uint8_t satype, uint8_t algtype,
5505     uint8_t alg, uint16_t minbits, uint16_t maxbits, ipsec_stack_t *ipss)
5506 {
5507         uint8_t *cur = (uint8_t *)start;
5508         ipsec_alginfo_t *algp;
5509         sadb_x_algdesc_t *algdesc = (sadb_x_algdesc_t *)cur;
5510 
5511         ASSERT(RW_READ_HELD(&ipss->ipsec_alg_lock));
5512 
5513         cur += sizeof (*algdesc);
5514         if (cur >= end)
5515                 return (NULL);
5516 
5517         ecomb->sadb_x_ecomb_numalgs++;
5518 
5519         /*
5520          * Normalize vs. crypto framework's limits.  This way, you can specify
5521          * a stronger policy, and when the framework loads a stronger version,
5522          * you can just keep plowing w/o rewhacking your SPD.
5523          */
5524         algp = ipss->ipsec_alglists[(algtype == SADB_X_ALGTYPE_AUTH) ?
5525             IPSEC_ALG_AUTH : IPSEC_ALG_ENCR][alg];
5526         if (algp == NULL)
5527                 return (NULL);  /* Algorithm doesn't exist.  Fail gracefully. */
5528         if (minbits < algp->alg_ef_minbits)
5529                 minbits = algp->alg_ef_minbits;
5530         if (maxbits > algp->alg_ef_maxbits)
5531                 maxbits = algp->alg_ef_maxbits;
5532 
5533         algdesc->sadb_x_algdesc_reserved = SADB_8TO1(algp->alg_saltlen);
5534         algdesc->sadb_x_algdesc_satype = satype;
5535         algdesc->sadb_x_algdesc_algtype = algtype;
5536         algdesc->sadb_x_algdesc_alg = alg;
5537         algdesc->sadb_x_algdesc_minbits = minbits;
5538         algdesc->sadb_x_algdesc_maxbits = maxbits;
5539 
5540         return (cur);
5541 }
5542 
5543 /*
5544  * Use buffer defined by byte-aligned pointers start and end to convert
5545  * ipsec_action_t pointer act into an ecomb, using alg data hanging off of
5546  * netstack_t pointer ns. Return NULL rather than overrun buffer, otherwise
5547  * pointer to end of ecomb (which should be exact size of buffer).
5548  */
5549 static uint8_t *
5550 sadb_action_to_ecomb(const uint8_t *start, const uint8_t *end,
5551     const ipsec_action_t *act, netstack_t *ns)
5552 {
5553         uint8_t *cur = (uint8_t *)start;
5554         sadb_x_ecomb_t *ecomb = (sadb_x_ecomb_t *)cur;
5555         ipsec_prot_t *ipp;
5556         ipsec_stack_t *ipss = ns->netstack_ipsec;
5557 
5558         ASSERT(RW_READ_HELD(&ipss->ipsec_alg_lock));
5559         ASSERT(act->ipa_act.ipa_type == IPSEC_ACT_APPLY);
5560 
5561         cur += sizeof (*ecomb);
5562         if (cur >= end)
5563                 return (NULL);
5564 
5565         ipp = &((ipsec_action_t *)act)->ipa_act.ipa_apply;
5566 
5567         ecomb->sadb_x_ecomb_numalgs = 0;
5568         ecomb->sadb_x_ecomb_reserved = 0;
5569         ecomb->sadb_x_ecomb_reserved2 = 0;
5570         /*
5571          * No limits on allocations, since we really don't support that
5572          * concept currently.
5573          */
5574         ecomb->sadb_x_ecomb_soft_allocations = 0;
5575         ecomb->sadb_x_ecomb_hard_allocations = 0;
5576 
5577         /*
5578          * XXX TBD: Policy or global parameters will eventually be
5579          * able to fill in some of these.
5580          */
5581         ecomb->sadb_x_ecomb_flags = 0;
5582         ecomb->sadb_x_ecomb_soft_bytes = 0;
5583         ecomb->sadb_x_ecomb_hard_bytes = 0;
5584         ecomb->sadb_x_ecomb_soft_addtime = 0;
5585         ecomb->sadb_x_ecomb_hard_addtime = 0;
5586         ecomb->sadb_x_ecomb_soft_usetime = 0;
5587         ecomb->sadb_x_ecomb_hard_usetime = 0;
5588 
5589         if (ipp->ipp_use_ah) {
5590                 cur = sadb_new_algdesc(cur, end, ecomb,
5591                     SADB_SATYPE_AH, SADB_X_ALGTYPE_AUTH, ipp->ipp_auth_alg,
5592                     ipp->ipp_ah_minbits, ipp->ipp_ah_maxbits, ipss);
5593                 if (cur == NULL)
5594                         return (NULL);
5595                 ipsecah_fill_defs(ecomb, ns);
5596         }
5597 
5598         if (ipp->ipp_use_esp) {
5599                 if (ipp->ipp_use_espa) {
5600                         cur = sadb_new_algdesc(cur, end, ecomb,
5601                             SADB_SATYPE_ESP, SADB_X_ALGTYPE_AUTH,
5602                             ipp->ipp_esp_auth_alg,
5603                             ipp->ipp_espa_minbits,
5604                             ipp->ipp_espa_maxbits, ipss);
5605                         if (cur == NULL)
5606                                 return (NULL);
5607                 }
5608 
5609                 cur = sadb_new_algdesc(cur, end, ecomb,
5610                     SADB_SATYPE_ESP, SADB_X_ALGTYPE_CRYPT,
5611                     ipp->ipp_encr_alg,
5612                     ipp->ipp_espe_minbits,
5613                     ipp->ipp_espe_maxbits, ipss);
5614                 if (cur == NULL)
5615                         return (NULL);
5616                 /* Fill in lifetimes if and only if AH didn't already... */
5617                 if (!ipp->ipp_use_ah)
5618                         ipsecesp_fill_defs(ecomb, ns);
5619         }
5620 
5621         return (cur);
5622 }
5623 
5624 #include <sys/tsol/label_macro.h> /* XXX should not need this */
5625 
5626 /*
5627  * From a cred_t, construct a sensitivity label extension
5628  *
5629  * We send up a fixed-size sensitivity label bitmap, and are perhaps
5630  * overly chummy with the underlying data structures here.
5631  */
5632 
5633 /* ARGSUSED */
5634 int
5635 sadb_sens_len_from_label(ts_label_t *tsl)
5636 {
5637         int baselen = sizeof (sadb_sens_t) + _C_LEN * 4;
5638         return (roundup(baselen, sizeof (uint64_t)));
5639 }
5640 
5641 void
5642 sadb_sens_from_label(sadb_sens_t *sens, int exttype, ts_label_t *tsl,
5643     int senslen)
5644 {
5645         uint8_t *bitmap;
5646         bslabel_t *sl;
5647 
5648         /* LINTED */
5649         ASSERT((_C_LEN & 1) == 0);
5650         ASSERT((senslen & 7) == 0);
5651 
5652         sl = label2bslabel(tsl);
5653 
5654         sens->sadb_sens_exttype = exttype;
5655         sens->sadb_sens_len = SADB_8TO64(senslen);
5656 
5657         sens->sadb_sens_dpd = tsl->tsl_doi;
5658         sens->sadb_sens_sens_level = LCLASS(sl);
5659         sens->sadb_sens_integ_level = 0; /* TBD */
5660         sens->sadb_sens_sens_len = _C_LEN >> 1;
5661         sens->sadb_sens_integ_len = 0; /* TBD */
5662         sens->sadb_x_sens_flags = 0;
5663 
5664         bitmap = (uint8_t *)(sens + 1);
5665         bcopy(&(((_bslabel_impl_t *)sl)->compartments), bitmap, _C_LEN * 4);
5666 }
5667 
5668 static sadb_sens_t *
5669 sadb_make_sens_ext(ts_label_t *tsl, int *len)
5670 {
5671         /* XXX allocation failure? */
5672         int sens_len = sadb_sens_len_from_label(tsl);
5673 
5674         sadb_sens_t *sens = kmem_alloc(sens_len, KM_SLEEP);
5675 
5676         sadb_sens_from_label(sens, SADB_EXT_SENSITIVITY, tsl, sens_len);
5677 
5678         *len = sens_len;
5679 
5680         return (sens);
5681 }
5682 
5683 /*
5684  * Okay, how do we report errors/invalid labels from this?
5685  * With a special designated "not a label" cred_t ?
5686  */
5687 /* ARGSUSED */
5688 ts_label_t *
5689 sadb_label_from_sens(sadb_sens_t *sens, uint64_t *bitmap)
5690 {
5691         int bitmap_len = SADB_64TO8(sens->sadb_sens_sens_len);
5692         bslabel_t sl;
5693         ts_label_t *tsl;
5694 
5695         if (sens->sadb_sens_integ_level != 0)
5696                 return (NULL);
5697         if (sens->sadb_sens_integ_len != 0)
5698                 return (NULL);
5699         if (bitmap_len > _C_LEN * 4)
5700                 return (NULL);
5701 
5702         bsllow(&sl);
5703         LCLASS_SET((_bslabel_impl_t *)&sl, sens->sadb_sens_sens_level);
5704         bcopy(bitmap, &((_bslabel_impl_t *)&sl)->compartments,
5705             bitmap_len);
5706 
5707         tsl = labelalloc(&sl, sens->sadb_sens_dpd, KM_NOSLEEP);
5708         if (tsl == NULL)
5709                 return (NULL);
5710 
5711         if (sens->sadb_x_sens_flags & SADB_X_SENS_UNLABELED)
5712                 tsl->tsl_flags |= TSLF_UNLABELED;
5713         return (tsl);
5714 }
5715 
5716 /* End XXX label-library-leakage */
5717 
5718 /*
5719  * Takes a pointer to sadb_prop_t (what we're initializing), ipsec_action_t
5720  * (first action in chain we need to walk of actions for each alg
5721  * combination), netstack_ns (contains pointers to alg properties and
5722  * per-protocol settings), a combs_limit integer (maximum applicable
5723  * combinations derived from per-protcol netstack_t alg array), and need_esp
5724  * boolean_t. We distinguish between two error cases: we exceed combs_limit,
5725  * which should only be a kernel bug (ipsec_alg_lock is our shepherd), or we
5726  * have an alg ID with a NULL netstack member or member with the valid bit
5727  * flipped, both of which indicate the needs to reset state, which we flag by
5728  * returning no combs. We return NULL if we exceed combs_limit and zero-length
5729  * prop if we run into an alg that can't be transferred into the prop.
5730  */
5731 static void
5732 sadb_insert_prop(sadb_prop_t *prop, const ipsec_action_t *ap, netstack_t *ns,
5733     uint_t combs_limit, boolean_t need_esp)
5734 {
5735         sadb_comb_t     *comb = (sadb_comb_t *)(prop + 1);
5736         ipsec_action_t  *act = (ipsec_action_t *)ap;
5737         ipsec_prot_t    *prot;
5738         ipsecah_stack_t *ahstack = ns->netstack_ipsecah;
5739         ipsecesp_stack_t *espstack = ns->netstack_ipsecesp;
5740         ipsec_stack_t   *ipss = ns->netstack_ipsec;
5741         boolean_t       need_ah = !need_esp;
5742 
5743         ASSERT(RW_READ_HELD(&ipss->ipsec_alg_lock));
5744         ASSERT((need_esp && ap->ipa_want_esp) || (need_ah && ap->ipa_want_ah));
5745 
5746         prop->sadb_prop_exttype = SADB_EXT_PROPOSAL;
5747         prop->sadb_prop_len = SADB_8TO64(sizeof (sadb_prop_t));
5748         *(uint32_t *)(&prop->sadb_prop_replay) = 0; /* Quick zero-out! */
5749         prop->sadb_prop_replay = need_esp ?
5750             espstack->ipsecesp_replay_size : ahstack->ipsecah_replay_size;
5751 
5752         /* Prioritize a proposal, preserving policy order. */
5753         for (; act != NULL; act = act->ipa_next) {
5754                 ipsec_alginfo_t *aalg = NULL;
5755                 ipsec_alginfo_t *ealg = NULL;
5756 
5757                 if ((act->ipa_act.ipa_type != IPSEC_POLICY_APPLY) ||
5758                     (need_esp && !act->ipa_act.ipa_apply.ipp_use_esp) ||
5759                     (need_ah && !act->ipa_act.ipa_apply.ipp_use_ah))
5760                         continue;
5761 
5762                 if (--combs_limit == 0) {
5763                         prop = NULL;
5764                         return;
5765                 }
5766 
5767                 prot = &act->ipa_act.ipa_apply;
5768 
5769                 /*
5770                  * Alg ID 0 is none/any, which is valid only for ESP without
5771                  * message integrity (ipp_esp_auth_alg). NULL encryption ESP
5772                  * uses a distinct alg, non-zero ID.
5773                  */
5774                 if ((need_esp && prot->ipp_esp_auth_alg != 0) || need_ah) {
5775                         ASSERT(need_esp || (prot->ipp_auth_alg > 0));
5776                         aalg = ipss->ipsec_alglists[IPSEC_ALG_AUTH][need_esp ?
5777                             prot->ipp_esp_auth_alg : prot->ipp_auth_alg];
5778                         if (aalg == NULL || !ALG_VALID(aalg))
5779                                 goto failure;
5780                 }
5781 
5782                 if (need_esp) {
5783                         ASSERT(prot->ipp_encr_alg > 0);
5784                         ealg = ipss->ipsec_alglists[IPSEC_ALG_ENCR]
5785                             [prot->ipp_encr_alg];
5786                         if (ealg == NULL || !ALG_VALID(ealg))
5787                                 goto failure;
5788                 }
5789 
5790                 comb->sadb_comb_flags = 0;
5791                 comb->sadb_comb_reserved = 0;
5792 
5793                 if (ealg != NULL) {
5794                         comb->sadb_comb_encrypt = ealg->alg_id;
5795                         comb->sadb_comb_encrypt_minbits =
5796                             MAX(prot->ipp_espe_minbits, ealg->alg_ef_minbits);
5797                         comb->sadb_comb_encrypt_maxbits =
5798                             MIN(prot->ipp_espe_maxbits, ealg->alg_ef_maxbits);
5799                 } else {
5800                         comb->sadb_comb_encrypt = 0;
5801                         comb->sadb_comb_encrypt_minbits = 0;
5802                         comb->sadb_comb_encrypt_maxbits = 0;
5803                 }
5804 
5805                 if (aalg != NULL) {
5806                         uint16_t minbits, maxbits;
5807                         minbits = need_esp ?
5808                             prot->ipp_espa_minbits : prot->ipp_ah_minbits;
5809                         maxbits = need_esp ?
5810                             prot->ipp_espa_maxbits : prot->ipp_ah_maxbits;
5811                         comb->sadb_comb_auth = aalg->alg_id;
5812                         comb->sadb_comb_auth_minbits =
5813                             MAX(minbits, aalg->alg_ef_minbits);
5814                         comb->sadb_comb_auth_maxbits =
5815                             MIN(maxbits, aalg->alg_ef_maxbits);
5816                 } else {
5817                         comb->sadb_comb_auth = 0;
5818                         comb->sadb_comb_auth_minbits = 0;
5819                         comb->sadb_comb_auth_maxbits = 0;
5820                 }
5821 
5822                 /*
5823                  * The following may be based on algorithm properties, but in
5824                  * the meantime, we just pick some good, sensible numbers.
5825                  * Key mgmt. can (and perhaps should) be the place to finalize
5826                  * such decisions.
5827                  */
5828 
5829                 /* 0 == unlimited == unsupported */
5830                 comb->sadb_comb_soft_allocations = 0;
5831                 comb->sadb_comb_hard_allocations = 0;
5832 
5833                 /* These may want to come from policy rule. */
5834                 if (need_esp) {
5835                         comb->sadb_comb_soft_bytes =
5836                             espstack->ipsecesp_default_soft_bytes;
5837                         comb->sadb_comb_hard_bytes =
5838                             espstack->ipsecesp_default_hard_bytes;
5839                         comb->sadb_comb_soft_addtime =
5840                             espstack->ipsecesp_default_soft_addtime;
5841                         comb->sadb_comb_hard_addtime =
5842                             espstack->ipsecesp_default_hard_addtime;
5843                         comb->sadb_comb_soft_usetime =
5844                             espstack->ipsecesp_default_soft_usetime;
5845                         comb->sadb_comb_hard_usetime =
5846                             espstack->ipsecesp_default_hard_usetime;
5847                 } else {
5848                         comb->sadb_comb_soft_bytes =
5849                             ahstack->ipsecah_default_soft_bytes;
5850                         comb->sadb_comb_hard_bytes =
5851                             ahstack->ipsecah_default_hard_bytes;
5852                         comb->sadb_comb_soft_addtime =
5853                             ahstack->ipsecah_default_soft_addtime;
5854                         comb->sadb_comb_hard_addtime =
5855                             ahstack->ipsecah_default_hard_addtime;
5856                         comb->sadb_comb_soft_usetime =
5857                             ahstack->ipsecah_default_soft_usetime;
5858                         comb->sadb_comb_hard_usetime =
5859                             ahstack->ipsecah_default_hard_usetime;
5860                 }
5861 
5862                 prop->sadb_prop_len += SADB_8TO64(sizeof (*comb));
5863                 comb++;
5864         }
5865 
5866         return;
5867 
5868 failure:
5869         prop->sadb_prop_len = 0;
5870 }
5871 
5872 /*
5873  * Construct extended properties using ipsec_action_t, ipsec_policy_t, and
5874  * netstack_t pointers. Byte-aligned pointers cur and end are used for bounds
5875  * checking here and in called code. We don't set length if numecombs is 0, so
5876  * callers must check this for error handling.
5877  */
5878 static uint8_t *
5879 sadb_construct_eprop(const ipsec_action_t *act, const ipsec_policy_t *pp,
5880     netstack_t *ns, const uint8_t *start, const uint8_t *end)
5881 {
5882         uint8_t         *cur = (uint8_t *)start;
5883         sadb_prop_t     *eprop = (sadb_prop_t *)cur;
5884         ipsec_action_t  *an, *ap = (ipsec_action_t *)act;
5885         ipsec_stack_t   *ipss = ns->netstack_ipsec;
5886 
5887         ASSERT(RW_READ_HELD(&ipss->ipsec_alg_lock));
5888 
5889         cur += sizeof (*eprop);
5890         if (cur > end)
5891                 return (NULL);
5892 
5893         eprop->sadb_prop_exttype = SADB_X_EXT_EPROP;
5894         eprop->sadb_x_prop_ereserved = 0;
5895         eprop->sadb_x_prop_numecombs = 0;
5896         eprop->sadb_prop_replay = 32;        /* default */
5897 
5898         for (; ap != NULL; ap = an) {
5899                 /*
5900                  * XXX Don't walk past first ap if there's no pp. Not clear on
5901                  * the rationale for this, but it's what extended path did.
5902                  */
5903                 an = (pp != NULL) ? ap->ipa_next : NULL;
5904 
5905                 if (ap->ipa_act.ipa_type != IPSEC_ACT_APPLY)
5906                         continue;
5907 
5908                 if (ap->ipa_act.ipa_apply.ipp_replay_depth) {
5909                         eprop->sadb_prop_replay =
5910                             ap->ipa_act.ipa_apply.ipp_replay_depth;
5911                 }
5912 
5913                 cur = sadb_action_to_ecomb(cur, end, ap, ns);
5914                 if (cur == NULL)
5915                         return (NULL);
5916                 eprop->sadb_x_prop_numecombs++;
5917         }
5918 
5919         /*
5920          * This is an error. We return what we've got of eprops, caller needs
5921          * to check for condition and pass it further up (e.g. by error samsg).
5922          */
5923         if (eprop->sadb_x_prop_numecombs == 0)
5924                 return (cur);
5925 
5926         eprop->sadb_prop_len = SADB_8TO64(cur - (uint8_t *)start);
5927 
5928         return (cur);
5929 bail:
5930         return (NULL);
5931 }
5932 
5933 /*
5934  * Convert ipsec_policy_t and ipsec_action_t pointers to kmc extension. Byte-
5935  * aligned cur and end pointers used for bounds checking. sadb_x_kmcext_t
5936  * handling encapsulated in sadb_make_kmc_ext. Returns new value for cur,
5937  * NULL on failure.
5938  * We encapsulate for recursion since we have to walk ipsec_action_t.
5939  */
5940 static uint8_t *
5941 sadb_policy_to_kmcext(const ipsec_policy_t *pp, const ipsec_action_t *act,
5942     const uint8_t *start, const uint8_t *end)
5943 {
5944         uint8_t         *cur = (uint8_t *)start;
5945         ipsec_action_t  *an, *ap = (ipsec_action_t *)act;
5946         uint32_t        kmp = 0, kmc = 0;
5947 
5948         for (; ap != NULL; ap = an) {
5949                 an = (pp != NULL) ? ap->ipa_next : NULL;
5950 
5951                 /*
5952                  * Skip non-IPsec policies
5953                  */
5954                 if (ap->ipa_act.ipa_type != IPSEC_ACT_APPLY)
5955                         continue;
5956 
5957                 if (ap->ipa_act.ipa_apply.ipp_km_proto)
5958                         kmp = ap->ipa_act.ipa_apply.ipp_km_proto;
5959                 if (ap->ipa_act.ipa_apply.ipp_km_cookie)
5960                         kmc = ap->ipa_act.ipa_apply.ipp_km_cookie;
5961         }
5962 
5963         if ((kmp != 0) || (kmc != 0))
5964                 cur = sadb_make_kmc_ext(cur, end, kmp, kmc);
5965 
5966         return (cur);
5967 }
5968 
5969 /*
5970  * Prepare the SADB_ACQUIRE message proper, which should be a b_cont to a
5971  * keysock registered M_CTL message. Takes a pointer to ipsacq_t (optional
5972  * acquire record for which we're sending message), ipsec_selector_t,
5973  * ipsec_action_t, ipsec_policy_t, netstack_t, and sense (required for called
5974  * to generate the message), and booleans for need_esp, tunnel_mode,
5975  * extended, and with_prop (all of these should be self-explanatory). Because
5976  * extended messages set satype to SADB_SATYPE_UNSPEC, extended-only callers
5977  * can fudge need_esp.
5978  */
5979 static mblk_t *
5980 sadb_construct_acqmsg(ipsacq_t *acqrec, ipsec_selector_t *sel,
5981     ipsec_action_t *ap, ipsec_policy_t *pp, netstack_t *ns, sadb_sens_t *sens,
5982     boolean_t need_esp, boolean_t tunnel_mode, boolean_t extended,
5983     boolean_t with_prop)
5984 {
5985         uint_t          combs_limit, allocsize;
5986         uint8_t         *cur, *end;
5987         sadb_msg_t      *samsg;
5988         sadb_prop_t     *prop, *eprop;
5989         mblk_t          *mp;
5990         int             satype = extended ? SADB_SATYPE_UNSPEC
5991             : (need_esp ? SADB_SATYPE_ESP : SADB_SATYPE_AH);
5992         ipsec_stack_t   *ipss = ns->netstack_ipsec;
5993 
5994         ASSERT((acqrec == NULL) || (MUTEX_HELD(&acqrec->ipsacq_lock)));
5995         ASSERT(ap != NULL);
5996         ASSERT((pp == NULL) || (pp->ipsp_refs != 0));
5997         ASSERT((ap == NULL) || (ap->ipa_refs != 0));
5998 
5999         /*
6000          * Set the limit used to size [e]prop [e]combs array to as many
6001          * algorithms as defined on the netstack (must hold ipsec_alg_lock
6002          * from here to when done reading off netstack for [e]prop
6003          * formation). need_esp may be fudged, so be generous to extended.
6004          */
6005         if (with_prop) {
6006                 if (extended)
6007                         need_esp = B_TRUE;
6008                 rw_enter(&ipss->ipsec_alg_lock, RW_READER);
6009                 CALC_COMBS(combs_limit, ipss, need_esp);
6010         }
6011 
6012         /*
6013          * If this code is right, we may not need cur & end for bounds
6014          * checking, but we'll keep normal runtime checks until that statement
6015          * looks credible rather than merely plausible, at which point checks
6016          * can be moved to ASSERTs. sens is variably sized but already
6017          * set. kmc is fixed size. Pointers into message are byte-aligned, so
6018          * we're generally depending on all structures used in this
6019          * calculation to be so, too (in fact, all sadb_*_t types used here
6020          * are 64-bit aligned per PF_KEY requirements).
6021          */
6022         allocsize = sizeof (sadb_msg_t) + sizeof (sadb_prop_t);
6023         allocsize += ((tunnel_mode) ? 4 : 2) * (sizeof (sadb_address_t)
6024             + SADB_SOCKADDR_SIZE);
6025         if (sens != NULL)
6026                 allocsize += SADB_64TO8(sens->sadb_sens_len);
6027         allocsize += sizeof (sadb_x_kmc_t);
6028         /* If we need props, size combs/combs array using combs_limit */
6029         if (with_prop)
6030                 allocsize += combs_limit * (extended ?
6031                     sizeof (sadb_x_ecomb_t) : sizeof (sadb_comb_t));
6032 
6033         ASSERT((allocsize & 0x7) == 0);
6034 
6035         mp = allocb(allocsize, BPRI_HI);
6036         if (mp == NULL)
6037                 goto unlock_and_fail;
6038 
6039         cur = mp->b_rptr;
6040         end = cur + allocsize;
6041 
6042         samsg = (sadb_msg_t *)cur;
6043         INITIALIZE_SAMSG(samsg, SADB_ACQUIRE);
6044         samsg->sadb_msg_satype = satype;
6045         samsg->sadb_msg_pid = 0;
6046         samsg->sadb_msg_seq = (acqrec != NULL) ? acqrec->ipsacq_seq : 0;
6047 
6048         /* CALC_COMBS asserts on zero limit; broken config still possible */
6049         if (with_prop && (combs_limit == 0)) {
6050                 ERRNO_SAMSG(samsg, ENOENT);
6051                 goto unlock_and_bail;
6052         }
6053 
6054         cur += sizeof (sadb_msg_t);
6055 
6056         cur = sadb_sel_to_addrexts(sel, pp, ap, cur, end, tunnel_mode);
6057         if (cur == NULL)
6058                 goto unlock_and_fail;
6059 
6060         if (with_prop) {
6061                 if (extended) {
6062                         cur = sadb_construct_eprop(ap, pp, ns, cur, end);
6063                         if (cur == NULL)
6064                                 goto unlock_and_fail;
6065 
6066                         eprop = (sadb_prop_t *)cur;
6067                         if (eprop->sadb_x_prop_numecombs == 0) {
6068                                 ERRNO_SAMSG(samsg, ENOENT);
6069                                 goto unlock_and_bail;
6070                         }
6071                 } else {
6072                         prop = (sadb_prop_t *)cur;
6073 
6074                         sadb_insert_prop(prop, ap, ns, combs_limit, need_esp);
6075                         if (prop == NULL) {
6076                                 goto unlock_and_fail;
6077                         } else if (prop->sadb_prop_len == 0) {
6078                                 ERRNO_SAMSG(samsg, ENOENT);
6079                                 goto unlock_and_bail;
6080                         }
6081 
6082                         cur += SADB_64TO8(prop->sadb_prop_len);
6083                 }
6084 
6085                 rw_exit(&ipss->ipsec_alg_lock);
6086         }
6087 
6088         if (sens != NULL) {
6089                 uint8_t *sensext = cur;
6090                 int senslen = SADB_64TO8(sens->sadb_sens_len);
6091 
6092                 cur += senslen;
6093                 if (cur > end)
6094                         goto freeb_bail;
6095                 bcopy(sens, sensext, senslen);
6096         }
6097 
6098         cur = sadb_policy_to_kmcext(pp, ap, cur, end);
6099         if (cur == NULL)
6100                 goto freeb_bail;
6101 
6102         samsg->sadb_msg_len = SADB_8TO64(cur - mp->b_rptr);
6103         mp->b_wptr = cur;
6104 
6105         return (mp);
6106 
6107 freeb_bail:
6108         /* This message isn't chained, so we can freeb. */
6109         freeb(mp);
6110         return (NULL);
6111 unlock_and_bail:
6112         if (with_prop)
6113                 rw_exit(&ipss->ipsec_alg_lock);
6114         return (mp);
6115 unlock_and_fail:
6116         if (with_prop)
6117                 rw_exit(&ipss->ipsec_alg_lock);
6118         return (NULL);
6119 }
6120 
6121 /*
6122  * Given an SADB_GETSPI message, find an appropriately ranged SA and
6123  * allocate an SA.  If there are message improprieties, return (ipsa_t *)-1.
6124  * If there was a memory allocation error, return NULL.  (Assume NULL !=
6125  * (ipsa_t *)-1).
6126  *
6127  * master_spi is passed in host order.
6128  */
6129 ipsa_t *
6130 sadb_getspi(keysock_in_t *ksi, uint32_t master_spi, int *diagnostic,
6131     netstack_t *ns, uint_t sa_type)
6132 {
6133         sadb_address_t *src =
6134             (sadb_address_t *)ksi->ks_in_extv[SADB_EXT_ADDRESS_SRC],
6135             *dst = (sadb_address_t *)ksi->ks_in_extv[SADB_EXT_ADDRESS_DST];
6136         sadb_spirange_t *range =
6137             (sadb_spirange_t *)ksi->ks_in_extv[SADB_EXT_SPIRANGE];
6138         struct sockaddr_in *ssa, *dsa;
6139         struct sockaddr_in6 *ssa6, *dsa6;
6140         uint32_t *srcaddr, *dstaddr;
6141         sa_family_t af;
6142         uint32_t add, min, max;
6143         uint8_t protocol =
6144             (sa_type == SADB_SATYPE_AH) ? IPPROTO_AH : IPPROTO_ESP;
6145 
6146         if (src == NULL) {
6147                 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_SRC;
6148                 return ((ipsa_t *)-1);
6149         }
6150         if (dst == NULL) {
6151                 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_DST;
6152                 return ((ipsa_t *)-1);
6153         }
6154         if (range == NULL) {
6155                 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_RANGE;
6156                 return ((ipsa_t *)-1);
6157         }
6158 
6159         min = ntohl(range->sadb_spirange_min);
6160         max = ntohl(range->sadb_spirange_max);
6161         dsa = (struct sockaddr_in *)(dst + 1);
6162         dsa6 = (struct sockaddr_in6 *)dsa;
6163 
6164         ssa = (struct sockaddr_in *)(src + 1);
6165         ssa6 = (struct sockaddr_in6 *)ssa;
6166         ASSERT(dsa->sin_family == ssa->sin_family);
6167 
6168         srcaddr = ALL_ZEROES_PTR;
6169         af = dsa->sin_family;
6170         switch (af) {
6171         case AF_INET:
6172                 if (src != NULL)
6173                         srcaddr = (uint32_t *)(&ssa->sin_addr);
6174                 dstaddr = (uint32_t *)(&dsa->sin_addr);
6175                 break;
6176         case AF_INET6:
6177                 if (src != NULL)
6178                         srcaddr = (uint32_t *)(&ssa6->sin6_addr);
6179                 dstaddr = (uint32_t *)(&dsa6->sin6_addr);
6180                 break;
6181         default:
6182                 *diagnostic = SADB_X_DIAGNOSTIC_BAD_DST_AF;
6183                 return ((ipsa_t *)-1);
6184         }
6185 
6186         if (master_spi < min || master_spi > max) {
6187                 /* Return a random value in the range. */
6188                 if (cl_inet_getspi) {
6189                         cl_inet_getspi(ns->netstack_stackid, protocol,
6190                             (uint8_t *)&add, sizeof (add), NULL);
6191                 } else {
6192                         (void) random_get_pseudo_bytes((uint8_t *)&add,
6193                             sizeof (add));
6194                 }
6195                 master_spi = min + (add % (max - min + 1));
6196         }
6197 
6198         /*
6199          * Since master_spi is passed in host order, we need to htonl() it
6200          * for the purposes of creating a new SA.
6201          */
6202         return (sadb_makelarvalassoc(htonl(master_spi), srcaddr, dstaddr, af,
6203             ns));
6204 }
6205 
6206 /*
6207  *
6208  * Locate an ACQUIRE and nuke it.  If I have an samsg that's larger than the
6209  * base header, just ignore it.  Otherwise, lock down the whole ACQUIRE list
6210  * and scan for the sequence number in question.  I may wish to accept an
6211  * address pair with it, for easier searching.
6212  *
6213  * Caller frees the message, so we don't have to here.
6214  *
6215  * NOTE:        The pfkey_q parameter may be used in the future for ACQUIRE
6216  *              failures.
6217  */
6218 /* ARGSUSED */
6219 void
6220 sadb_in_acquire(sadb_msg_t *samsg, sadbp_t *sp, queue_t *pfkey_q,
6221     netstack_t *ns)
6222 {
6223         int i;
6224         ipsacq_t *acqrec;
6225         iacqf_t *bucket;
6226 
6227         /*
6228          * I only accept the base header for this!
6229          * Though to be honest, requiring the dst address would help
6230          * immensely.
6231          *
6232          * XXX  There are already cases where I can get the dst address.
6233          */
6234         if (samsg->sadb_msg_len > SADB_8TO64(sizeof (*samsg)))
6235                 return;
6236 
6237         /*
6238          * Using the samsg->sadb_msg_seq, find the ACQUIRE record, delete it,
6239          * (and in the future send a message to IP with the appropriate error
6240          * number).
6241          *
6242          * Q: Do I want to reject if pid != 0?
6243          */
6244 
6245         for (i = 0; i < sp->s_v4.sdb_hashsize; i++) {
6246                 bucket = &sp->s_v4.sdb_acq[i];
6247                 mutex_enter(&bucket->iacqf_lock);
6248                 for (acqrec = bucket->iacqf_ipsacq; acqrec != NULL;
6249                     acqrec = acqrec->ipsacq_next) {
6250                         if (samsg->sadb_msg_seq == acqrec->ipsacq_seq)
6251                                 break;  /* for acqrec... loop. */
6252                 }
6253                 if (acqrec != NULL)
6254                         break;  /* for i = 0... loop. */
6255 
6256                 mutex_exit(&bucket->iacqf_lock);
6257         }
6258 
6259         if (acqrec == NULL) {
6260                 for (i = 0; i < sp->s_v6.sdb_hashsize; i++) {
6261                         bucket = &sp->s_v6.sdb_acq[i];
6262                         mutex_enter(&bucket->iacqf_lock);
6263                         for (acqrec = bucket->iacqf_ipsacq; acqrec != NULL;
6264                             acqrec = acqrec->ipsacq_next) {
6265                                 if (samsg->sadb_msg_seq == acqrec->ipsacq_seq)
6266                                         break;  /* for acqrec... loop. */
6267                         }
6268                         if (acqrec != NULL)
6269                                 break;  /* for i = 0... loop. */
6270 
6271                         mutex_exit(&bucket->iacqf_lock);
6272                 }
6273         }
6274 
6275 
6276         if (acqrec == NULL)
6277                 return;
6278 
6279         /*
6280          * What do I do with the errno and IP?  I may need mp's services a
6281          * little more.  See sadb_destroy_acquire() for future directions
6282          * beyond free the mblk chain on the acquire record.
6283          */
6284 
6285         ASSERT(&bucket->iacqf_lock == acqrec->ipsacq_linklock);
6286         sadb_destroy_acquire(acqrec, ns);
6287         /* Have to exit mutex here, because of breaking out of for loop. */
6288         mutex_exit(&bucket->iacqf_lock);
6289 }
6290 
6291 /*
6292  * The following functions work with the replay windows of an SA.  They assume
6293  * the ipsa->ipsa_replay_arr is an array of uint64_t, and that the bit vector
6294  * represents the highest sequence number packet received, and back
6295  * (ipsa->ipsa_replay_wsize) packets.
6296  */
6297 
6298 /*
6299  * Is the replay bit set?
6300  */
6301 static boolean_t
6302 ipsa_is_replay_set(ipsa_t *ipsa, uint32_t offset)
6303 {
6304         uint64_t bit = (uint64_t)1 << (uint64_t)(offset & 63);
6305 
6306         return ((bit & ipsa->ipsa_replay_arr[offset >> 6]) ? B_TRUE : B_FALSE);
6307 }
6308 
6309 /*
6310  * Shift the bits of the replay window over.
6311  */
6312 static void
6313 ipsa_shift_replay(ipsa_t *ipsa, uint32_t shift)
6314 {
6315         int i;
6316         int jump = ((shift - 1) >> 6) + 1;
6317 
6318         if (shift == 0)
6319                 return;
6320 
6321         for (i = (ipsa->ipsa_replay_wsize - 1) >> 6; i >= 0; i--) {
6322                 if (i + jump <= (ipsa->ipsa_replay_wsize - 1) >> 6) {
6323                         ipsa->ipsa_replay_arr[i + jump] |=
6324                             ipsa->ipsa_replay_arr[i] >> (64 - (shift & 63));
6325                 }
6326                 ipsa->ipsa_replay_arr[i] <<= shift;
6327         }
6328 }
6329 
6330 /*
6331  * Set a bit in the bit vector.
6332  */
6333 static void
6334 ipsa_set_replay(ipsa_t *ipsa, uint32_t offset)
6335 {
6336         uint64_t bit = (uint64_t)1 << (uint64_t)(offset & 63);
6337 
6338         ipsa->ipsa_replay_arr[offset >> 6] |= bit;
6339 }
6340 
6341 #define SADB_MAX_REPLAY_VALUE 0xffffffff
6342 
6343 /*
6344  * Assume caller has NOT done ntohl() already on seq.  Check to see
6345  * if replay sequence number "seq" has been seen already.
6346  */
6347 boolean_t
6348 sadb_replay_check(ipsa_t *ipsa, uint32_t seq)
6349 {
6350         boolean_t rc;
6351         uint32_t diff;
6352 
6353         if (ipsa->ipsa_replay_wsize == 0)
6354                 return (B_TRUE);
6355 
6356         /*
6357          * NOTE:  I've already checked for 0 on the wire in sadb_replay_peek().
6358          */
6359 
6360         /* Convert sequence number into host order before holding the mutex. */
6361         seq = ntohl(seq);
6362 
6363         mutex_enter(&ipsa->ipsa_lock);
6364 
6365         /* Initialize inbound SA's ipsa_replay field to last one received. */
6366         if (ipsa->ipsa_replay == 0)
6367                 ipsa->ipsa_replay = 1;
6368 
6369         if (seq > ipsa->ipsa_replay) {
6370                 /*
6371                  * I have received a new "highest value received".  Shift
6372                  * the replay window over.
6373                  */
6374                 diff = seq - ipsa->ipsa_replay;
6375                 if (diff < ipsa->ipsa_replay_wsize) {
6376                         /* In replay window, shift bits over. */
6377                         ipsa_shift_replay(ipsa, diff);
6378                 } else {
6379                         /* WAY FAR AHEAD, clear bits and start again. */
6380                         bzero(ipsa->ipsa_replay_arr,
6381                             sizeof (ipsa->ipsa_replay_arr));
6382                 }
6383                 ipsa_set_replay(ipsa, 0);
6384                 ipsa->ipsa_replay = seq;
6385                 rc = B_TRUE;
6386                 goto done;
6387         }
6388         diff = ipsa->ipsa_replay - seq;
6389         if (diff >= ipsa->ipsa_replay_wsize || ipsa_is_replay_set(ipsa, diff)) {
6390                 rc = B_FALSE;
6391                 goto done;
6392         }
6393         /* Set this packet as seen. */
6394         ipsa_set_replay(ipsa, diff);
6395 
6396         rc = B_TRUE;
6397 done:
6398         mutex_exit(&ipsa->ipsa_lock);
6399         return (rc);
6400 }
6401 
6402 /*
6403  * "Peek" and see if we should even bother going through the effort of
6404  * running an authentication check on the sequence number passed in.
6405  * this takes into account packets that are below the replay window,
6406  * and collisions with already replayed packets.  Return B_TRUE if it
6407  * is okay to proceed, B_FALSE if this packet should be dropped immediately.
6408  * Assume same byte-ordering as sadb_replay_check.
6409  */
6410 boolean_t
6411 sadb_replay_peek(ipsa_t *ipsa, uint32_t seq)
6412 {
6413         boolean_t rc = B_FALSE;
6414         uint32_t diff;
6415 
6416         if (ipsa->ipsa_replay_wsize == 0)
6417                 return (B_TRUE);
6418 
6419         /*
6420          * 0 is 0, regardless of byte order... :)
6421          *
6422          * If I get 0 on the wire (and there is a replay window) then the
6423          * sender most likely wrapped.  This ipsa may need to be marked or
6424          * something.
6425          */
6426         if (seq == 0)
6427                 return (B_FALSE);
6428 
6429         seq = ntohl(seq);
6430         mutex_enter(&ipsa->ipsa_lock);
6431         if (seq < ipsa->ipsa_replay - ipsa->ipsa_replay_wsize &&
6432             ipsa->ipsa_replay >= ipsa->ipsa_replay_wsize)
6433                 goto done;
6434 
6435         /*
6436          * If I've hit 0xffffffff, then quite honestly, I don't need to
6437          * bother with formalities.  I'm not accepting any more packets
6438          * on this SA.
6439          */
6440         if (ipsa->ipsa_replay == SADB_MAX_REPLAY_VALUE) {
6441                 /*
6442                  * Since we're already holding the lock, update the
6443                  * expire time ala. sadb_replay_delete() and return.
6444                  */
6445                 ipsa->ipsa_hardexpiretime = (time_t)1;
6446                 goto done;
6447         }
6448 
6449         if (seq <= ipsa->ipsa_replay) {
6450                 /*
6451                  * This seq is in the replay window.  I'm not below it,
6452                  * because I already checked for that above!
6453                  */
6454                 diff = ipsa->ipsa_replay - seq;
6455                 if (ipsa_is_replay_set(ipsa, diff))
6456                         goto done;
6457         }
6458         /* Else return B_TRUE, I'm going to advance the window. */
6459 
6460         rc = B_TRUE;
6461 done:
6462         mutex_exit(&ipsa->ipsa_lock);
6463         return (rc);
6464 }
6465 
6466 /*
6467  * Delete a single SA.
6468  *
6469  * For now, use the quick-and-dirty trick of making the association's
6470  * hard-expire lifetime (time_t)1, ensuring deletion by the *_ager().
6471  */
6472 void
6473 sadb_replay_delete(ipsa_t *assoc)
6474 {
6475         mutex_enter(&assoc->ipsa_lock);
6476         assoc->ipsa_hardexpiretime = (time_t)1;
6477         mutex_exit(&assoc->ipsa_lock);
6478 }
6479 
6480 /*
6481  * Special front-end to ipsec_rl_strlog() dealing with SA failure.
6482  * this is designed to take only a format string with "* %x * %s *", so
6483  * that "spi" is printed first, then "addr" is converted using inet_pton().
6484  *
6485  * This is abstracted out to save the stack space for only when inet_pton()
6486  * is called.  Make sure "spi" is in network order; it usually is when this
6487  * would get called.
6488  */
6489 void
6490 ipsec_assocfailure(short mid, short sid, char level, ushort_t sl, char *fmt,
6491     uint32_t spi, void *addr, int af, netstack_t *ns)
6492 {
6493         char buf[INET6_ADDRSTRLEN];
6494 
6495         ASSERT(af == AF_INET6 || af == AF_INET);
6496 
6497         ipsec_rl_strlog(ns, mid, sid, level, sl, fmt, ntohl(spi),
6498             inet_ntop(af, addr, buf, sizeof (buf)));
6499 }
6500 
6501 /*
6502  * Fills in a reference to the policy, if any, from the conn, in *ppp
6503  * If found, we hold a reference to the policy, caller must release.
6504  */
6505 static void
6506 ipsec_conn_pol(ipsec_selector_t *sel, conn_t *connp, ipsec_policy_t **ppp)
6507 {
6508         ipsec_policy_t  *pp;
6509         ipsec_latch_t   *ipl = connp->conn_latch;
6510 
6511         /* Use policy pointer already on conn_t if it's there. */
6512         if ((ipl != NULL) && (connp->conn_ixa->ixa_ipsec_policy != NULL)) {
6513                 pp = connp->conn_ixa->ixa_ipsec_policy;
6514                 IPPOL_REFHOLD(pp);
6515         } else { /* otherwise query SPD */
6516                 /* This holds a reference for us if successful) */
6517                 pp = ipsec_find_policy(IPSEC_TYPE_OUTBOUND, connp, sel,
6518                     connp->conn_netstack);
6519         }
6520         *ppp = pp;
6521 }
6522 
6523 /*
6524  * Takes ipsec_selector_t (for attributes to query), ipsec_policy_t (what we're
6525  * trying to find), and ip_stack_t (contains udp fanout we need to query). If we
6526  * find a matching connection, we return its policy settings.
6527  */
6528 static void
6529 ipsec_udp_pol(ipsec_selector_t *sel, ipsec_policy_t **ppp, ip_stack_t *ipst)
6530 {
6531         connf_t *connfp;
6532         conn_t *connp = NULL;
6533         ipsec_selector_t portonly;
6534 
6535         ASSERT(*ppp == NULL);
6536 
6537         bzero((void *)&portonly, sizeof (portonly));
6538 
6539         if (sel->ips_local_port == 0)
6540                 return;
6541 
6542         connfp = &ipst->ips_ipcl_udp_fanout[IPCL_UDP_HASH(sel->ips_local_port,
6543             ipst)];
6544         mutex_enter(&connfp->connf_lock);
6545 
6546         if (sel->ips_isv4) {
6547                 connp = connfp->connf_head;
6548                 while (connp != NULL) {
6549                         if (IPCL_UDP_MATCH(connp, sel->ips_local_port,
6550                             sel->ips_local_addr_v4, sel->ips_remote_port,
6551                             sel->ips_remote_addr_v4))
6552                                 break;
6553                         connp = connp->conn_next;
6554                 }
6555 
6556                 if (connp == NULL) {
6557                         /* Try port-only match in IPv6. */
6558                         portonly.ips_local_port = sel->ips_local_port;
6559                         sel = &portonly;
6560                 }
6561         }
6562 
6563         if (connp == NULL) {
6564                 connp = connfp->connf_head;
6565                 while (connp != NULL) {
6566                         if (IPCL_UDP_MATCH_V6(connp, sel->ips_local_port,
6567                             sel->ips_local_addr_v6, sel->ips_remote_port,
6568                             sel->ips_remote_addr_v6))
6569                                 break;
6570                         connp = connp->conn_next;
6571                 }
6572 
6573                 if (connp == NULL) {
6574                         mutex_exit(&connfp->connf_lock);
6575                         return;
6576                 }
6577         }
6578 
6579         CONN_INC_REF(connp);
6580         mutex_exit(&connfp->connf_lock);
6581 
6582         ipsec_conn_pol(sel, connp, ppp);
6583         CONN_DEC_REF(connp);
6584 }
6585 
6586 /*
6587  * Takes ipsec_selector_t (connection attributes to form query) and ip_stack_t
6588  * (contains bind fanout we need to query) pointers to look up existing TCP
6589  * listener, returned via conn_t pointer. We return NULL on failure.
6590  * We increment reference count on match, caller must decrement.
6591  */
6592 static conn_t *
6593 ipsec_find_listen_conn(ipsec_selector_t *sel, ip_stack_t *ipst)
6594 {
6595         connf_t *connfp;
6596         conn_t *connp = NULL;
6597         const in6_addr_t *v6addrmatch = &sel->ips_local_addr_v6;
6598 
6599         /* XXX Sure about the second part? */
6600         ASSERT(sel->ips_local_port != 0 && ipst != NULL);
6601 
6602         connfp = &ipst->ips_ipcl_bind_fanout[
6603             IPCL_BIND_HASH(sel->ips_local_port, ipst)];
6604         mutex_enter(&connfp->connf_lock);
6605 
6606         if (sel->ips_isv4) {
6607                 connp = connfp->connf_head;
6608                 while (connp != NULL) {
6609                         if (IPCL_BIND_MATCH(connp, IPPROTO_TCP,
6610                             sel->ips_local_addr_v4, sel->ips_local_port))
6611                                 break;
6612                         connp = connp->conn_next;
6613                 }
6614 
6615                 if (connp == NULL) {
6616                         /* Match to all-zeroes. */
6617                         v6addrmatch = &ipv6_all_zeros;
6618                 }
6619         }
6620 
6621         if (connp == NULL) {
6622                 connp = connfp->connf_head;
6623                 while (connp != NULL) {
6624                         if (IPCL_BIND_MATCH_V6(connp, IPPROTO_TCP,
6625                             *v6addrmatch, sel->ips_local_port))
6626                                 break;
6627                         connp = connp->conn_next;
6628                 }
6629 
6630                 if (connp == NULL) {
6631                         mutex_exit(&connfp->connf_lock);
6632                         return (NULL);
6633                 }
6634         }
6635 
6636         CONN_INC_REF(connp);
6637         mutex_exit(&connfp->connf_lock);
6638         return (connp);
6639 }
6640 
6641 /*
6642  * Given ipsec_selector_t (contains attributes to query, ipsec_policy_t (what we
6643  * need to find), and ip_stack_t pointer (contains connection state to query),
6644  * find a matching TCP connection or listener and return its policy pointer.
6645  */
6646 static void
6647 ipsec_tcp_pol(ipsec_selector_t *sel, ipsec_policy_t **ppp, ip_stack_t *ipst)
6648 {
6649         connf_t         *connfp;
6650         conn_t          *connp;
6651         uint32_t        ports;
6652         uint16_t        *pptr = (uint16_t *)&ports;
6653 
6654         ASSERT(sel->ips_local_port != 0 && *ppp == NULL);
6655 
6656         /*
6657          * Find TCP state in the following order:
6658          * 1.) Connected conns. (walk ipst connection fanout)
6659          * 2.) Listeners.
6660          *
6661          * Even though #2 will be the common case for inbound traffic, only
6662          * following this order insures correctness.
6663          */
6664 
6665 
6666         /*
6667          * pptr makes an array of port values, 0 for fport, 1 for lport.  SRC is
6668          * the local one here. Connection lookup macros want this instead of
6669          * selector port members.
6670          */
6671         pptr[0] = sel->ips_remote_port;
6672         pptr[1] = sel->ips_local_port;
6673 
6674         connfp = &ipst->ips_ipcl_conn_fanout[
6675             IPCL_CONN_HASH(sel->ips_remote_addr_v4, ports, ipst)];
6676         mutex_enter(&connfp->connf_lock);
6677         connp = connfp->connf_head;
6678 
6679         if (sel->ips_isv4) {
6680                 while (connp != NULL) {
6681                         if (IPCL_CONN_MATCH(connp, IPPROTO_TCP,
6682                             sel->ips_remote_addr_v4, sel->ips_local_addr_v4,
6683                             ports))
6684                                 break;
6685                         connp = connp->conn_next;
6686                 }
6687         } else {
6688                 while (connp != NULL) {
6689                         if (IPCL_CONN_MATCH_V6(connp, IPPROTO_TCP,
6690                             sel->ips_remote_addr_v6, sel->ips_local_addr_v6,
6691                             ports))
6692                                 break;
6693                         connp = connp->conn_next;
6694                 }
6695         }
6696 
6697         if (connp != NULL) {
6698                 CONN_INC_REF(connp);
6699                 mutex_exit(&connfp->connf_lock);
6700         } else {
6701                 mutex_exit(&connfp->connf_lock);
6702 
6703                 /* Try the listen hash. If found, comes with incremented ref. */
6704                 if ((connp = ipsec_find_listen_conn(sel, ipst)) == NULL)
6705                         return;
6706         }
6707 
6708         ipsec_conn_pol(sel, connp, ppp);
6709         CONN_DEC_REF(connp);
6710 }
6711 
6712 /*
6713  * Given ipsec_selector_t (connection attributes to form query), ipsec_policy_t
6714  * (populate with match), and ip_stack_t (connection state to query) pointers,
6715  * call into sctp to find an existing connection and return its policy.
6716  */
6717 static void
6718 ipsec_sctp_pol(ipsec_selector_t *sel, ipsec_policy_t **ppp, ip_stack_t *ipst)
6719 {
6720         conn_t          *connp;
6721         uint32_t        ports;
6722         uint16_t        *pptr = (uint16_t *)&ports;
6723 
6724         ASSERT(sel->ips_local_port != 0 && *ppp == NULL);
6725 
6726         /*
6727          * Find SCP state in the following order:
6728          * 1.) Connected conns.
6729          * 2.) Listeners.
6730          *
6731          * Even though #2 will be the common case for inbound traffic, only
6732          * following this order insures correctness.
6733          */
6734 
6735         /*
6736          * pptr makes an array of port values, 0 for fport, 1 for lport.  SRC is
6737          * the local one here. Connection lookup macros want this instead of
6738          * selector port members.
6739          */
6740         pptr[0] = sel->ips_remote_port;
6741         pptr[1] = sel->ips_local_port;
6742 
6743         /*
6744          * For labeled systems, there's no need to check the
6745          * label here.  It's known to be good as we checked
6746          * before allowing the connection to become bound.
6747          */
6748         if (sel->ips_isv4) {
6749                 in6_addr_t      src, dst;
6750 
6751                 IN6_IPADDR_TO_V4MAPPED(sel->ips_remote_addr_v4, &dst);
6752                 IN6_IPADDR_TO_V4MAPPED(sel->ips_local_addr_v4, &src);
6753                 connp = sctp_find_conn(&dst, &src, ports, ALL_ZONES,
6754                     0, ipst->ips_netstack->netstack_sctp);
6755         } else {
6756                 connp = sctp_find_conn(&sel->ips_remote_addr_v6,
6757                     &sel->ips_local_addr_v6, ports, ALL_ZONES,
6758                     0, ipst->ips_netstack->netstack_sctp);
6759         }
6760         if (connp == NULL)
6761                 return;
6762         ipsec_conn_pol(sel, connp, ppp);
6763         CONN_DEC_REF(connp);
6764 }
6765 
6766 /*
6767  * Takes ipsec_selector_t (what we're forming), two sadb_address_t (address
6768  * extentions needed to create selector), and diagnostic (what, if anything,
6769  * went wrong in PF_KEY terms) pointers, returns int (0 or errno).
6770  * NOTE:  For right now, this function (and ipsec_selector_t for that matter),
6771  * ignore prefix lengths in the address extension.  Since we match on first-
6772  * entered policies, this shouldn't matter.  Also, since we normalize prefix-
6773  * set addresses to mask out the lower bits, we should get a suitable search
6774  * key for the SPD anyway.  This is the function to change if the assumption
6775  * about suitable search keys is wrong.
6776  */
6777 static int
6778 ipsec_get_inverse_acquire_sel(ipsec_selector_t *sel, sadb_address_t *srcext,
6779     sadb_address_t *dstext, int *diagnostic)
6780 {
6781         struct sockaddr_in *src, *dst;
6782         struct sockaddr_in6 *src6, *dst6;
6783 
6784         *diagnostic = 0;
6785 
6786         bzero(sel, sizeof (*sel));
6787         sel->ips_protocol = srcext->sadb_address_proto;
6788         dst = (struct sockaddr_in *)(dstext + 1);
6789         if (dst->sin_family == AF_INET6) {
6790                 dst6 = (struct sockaddr_in6 *)dst;
6791                 src6 = (struct sockaddr_in6 *)(srcext + 1);
6792                 if (src6->sin6_family != AF_INET6) {
6793                         *diagnostic = SADB_X_DIAGNOSTIC_AF_MISMATCH;
6794                         return (EINVAL);
6795                 }
6796                 sel->ips_remote_addr_v6 = dst6->sin6_addr;
6797                 sel->ips_local_addr_v6 = src6->sin6_addr;
6798                 if (sel->ips_protocol == IPPROTO_ICMPV6) {
6799                         sel->ips_is_icmp_inv_acq = 1;
6800                 } else {
6801                         sel->ips_remote_port = dst6->sin6_port;
6802                         sel->ips_local_port = src6->sin6_port;
6803                 }
6804                 sel->ips_isv4 = B_FALSE;
6805         } else {
6806                 src = (struct sockaddr_in *)(srcext + 1);
6807                 if (src->sin_family != AF_INET) {
6808                         *diagnostic = SADB_X_DIAGNOSTIC_AF_MISMATCH;
6809                         return (EINVAL);
6810                 }
6811                 sel->ips_remote_addr_v4 = dst->sin_addr.s_addr;
6812                 sel->ips_local_addr_v4 = src->sin_addr.s_addr;
6813                 if (sel->ips_protocol == IPPROTO_ICMP) {
6814                         sel->ips_is_icmp_inv_acq = 1;
6815                 } else {
6816                         sel->ips_remote_port = dst->sin_port;
6817                         sel->ips_local_port = src->sin_port;
6818                 }
6819                 sel->ips_isv4 = B_TRUE;
6820         }
6821         return (0);
6822 }
6823 
6824 /*
6825  * We're passed pointers to ipsec_selector (inner info needed to form query),
6826  * ipsec_policy_t (what we're trying to populate), a pair of sadb_address_t
6827  * (extentions needed to reset selector), ipsec_tun_pol_t (tunnel policy that
6828  * may already be populated from previous SPD query), and integer (error detail
6829  * in PF_KEY2 terms, always 0). Return 0 or errno.
6830  * Caller may have fudged inner selector, so we need to reset it via if we have
6831  * to reuse it.
6832  */
6833 static int
6834 ipsec_tun_pol(ipsec_selector_t *sel, ipsec_policy_t **ppp,
6835     sadb_address_t *innsrcext, sadb_address_t *inndstext, ipsec_tun_pol_t *itp,
6836     int *diagnostic)
6837 {
6838         int err;
6839         ipsec_policy_head_t *polhead;
6840 
6841         ASSERT(*ppp == NULL);
6842 
6843         *diagnostic = 0;
6844 
6845         /* Check for inner selectors and act appropriately */
6846         if (innsrcext != NULL) {
6847                 ASSERT(inndstext != NULL); /* Need a pair */
6848                 /*
6849                  * If inner packet selectors, we must have negotiated tunnel and
6850                  * active policy already. If the tunnel has transport-mode
6851                  * policy set on it or no policy at all, fail.
6852                  */
6853                 if ((itp == NULL) ||
6854                     (itp->itp_flags & (ITPF_P_ACTIVE | ITPF_P_TUNNEL)) !=
6855                     (ITPF_P_ACTIVE | ITPF_P_TUNNEL)) {
6856                         return (ENOENT);
6857                 } else {
6858                         /*
6859                          * If we got a sane policy back from the SPD, reset the
6860                          * possibly fudged selector for subsequent operations.
6861                          */
6862                         if ((err = ipsec_get_inverse_acquire_sel(sel,
6863                                     innsrcext, inndstext, diagnostic)) != 0)
6864                                 return (err);
6865                 }
6866         } else { /* No inner selectors present */
6867 
6868                 /*
6869                  * Transport mode negotiation with no tunnel policy configured
6870                  * - return to indicate a global policy check is needed.
6871                  */
6872                 if ((itp == NULL) || !(itp->itp_flags & ITPF_P_ACTIVE)) {
6873                         return (0);
6874                 } else if (itp->itp_flags & ITPF_P_TUNNEL) {
6875                         /* Tunnel mode set with no inner selectors. */
6876                         return (ENOENT);
6877                 }
6878                 /*
6879                  * Else, this is a tunnel policy configured with ifconfig(1m)
6880                  * or "negotiate transport" with ipsecconf(1m).  We have an
6881                  * itp with policy set based on any match, so don't bother
6882                  * changing fields in "sel".
6883                  */
6884         }
6885 
6886         ASSERT(itp != NULL);
6887         polhead = itp->itp_policy;
6888         ASSERT(polhead != NULL);
6889         rw_enter(&polhead->iph_lock, RW_READER);
6890         *ppp = ipsec_find_policy_head(NULL, polhead, IPSEC_TYPE_INBOUND, sel);
6891         rw_exit(&polhead->iph_lock);
6892 
6893         /*
6894          * Don't default to global if we didn't find a matching policy entry.
6895          * Instead, send ENOENT, just like if we hit a transport-mode tunnel.
6896          */
6897         if (*ppp == NULL)
6898                 return (ENOENT);
6899 
6900         return (0);
6901 }
6902 
6903 /*
6904  * Takes ipsec_selector_t (data to form query), ipsec_policy_t (what we need
6905  * to populate), and ip_stack_t (contains state data to query) pointers. This is
6906  * a generic protocol look-up function to find a relevant connection that can be
6907  * converted in a policy.
6908  * XXX For sctp conn_faddr is the primary address, hence this is of limited
6909  * use for sctp. Do we care, given sctp has its own lookup?
6910  */
6911 static void
6912 ipsec_oth_pol(ipsec_selector_t *sel, ipsec_policy_t **ppp,
6913     ip_stack_t *ipst)
6914 {
6915         boolean_t       isv4 = sel->ips_isv4;
6916         connf_t         *connfp;
6917         conn_t          *connp;
6918 
6919         ASSERT(*ppp == NULL);
6920 
6921         if (isv4) {
6922                 connfp = &ipst->ips_ipcl_proto_fanout_v4[sel->ips_protocol];
6923         } else {
6924                 connfp = &ipst->ips_ipcl_proto_fanout_v6[sel->ips_protocol];
6925         }
6926 
6927         mutex_enter(&connfp->connf_lock);
6928         for (connp = connfp->connf_head; connp != NULL;
6929             connp = connp->conn_next) {
6930                 if (isv4) {
6931                         if ((connp->conn_laddr_v4 == INADDR_ANY ||
6932                             connp->conn_laddr_v4 == sel->ips_local_addr_v4) &&
6933                             (connp->conn_faddr_v4 == INADDR_ANY ||
6934                             connp->conn_faddr_v4 == sel->ips_remote_addr_v4))
6935                                 break;
6936                 } else {
6937                         if ((IN6_IS_ADDR_UNSPECIFIED(&connp->conn_laddr_v6) ||
6938                             IN6_ARE_ADDR_EQUAL(&connp->conn_laddr_v6,
6939                             &sel->ips_local_addr_v6)) &&
6940                             (IN6_IS_ADDR_UNSPECIFIED(&connp->conn_faddr_v6) ||
6941                             IN6_ARE_ADDR_EQUAL(&connp->conn_faddr_v6,
6942                             &sel->ips_remote_addr_v6)))
6943                                 break;
6944                 }
6945         }
6946         if (connp == NULL) {
6947                 mutex_exit(&connfp->connf_lock);
6948                 return;
6949         }
6950 
6951         CONN_INC_REF(connp);
6952         mutex_exit(&connfp->connf_lock);
6953 
6954         ipsec_conn_pol(sel, connp, ppp);
6955         CONN_DEC_REF(connp);
6956 }
6957 
6958 /*
6959  * This code is called from keysock to handle inverse acquire messages.  We
6960  * are passed a pointer to sadb_msg_t, a fixed-size array of sadb_ext_t, and a
6961  * netstack_t pointer and return a mblk_t pointer, in which we attempt to
6962  * construct a return acquire message. In case of errors, we return a NULL
6963  * pointer and populate samsg->sadb_msg_errno and samsg->sadb_msg_diagnostic,
6964  * which is handled as an error at the keysock layer. Otherwise keysock does a
6965  * passup with our message.
6966  * Caller performs basic sanity checks such as NULL external addresses and
6967  * only one of two inner addrs being NULL. Remaining checks happen here.
6968  *
6969  * XXX MLS: key management supplies a label which we just reflect back up
6970  * again.  clearly we need to involve the label in the rest of the checks.
6971  */
6972 mblk_t *
6973 ipsec_construct_inverse_acquire(sadb_msg_t *samsg, sadb_ext_t *extv[],
6974     netstack_t *ns)
6975 {
6976         int err;
6977         int diagnostic;
6978         sadb_address_t *srcext = (sadb_address_t *)extv[SADB_EXT_ADDRESS_SRC],
6979             *dstext = (sadb_address_t *)extv[SADB_EXT_ADDRESS_DST],
6980             *innsrcext = (sadb_address_t *)extv[SADB_X_EXT_ADDRESS_INNER_SRC],
6981             *inndstext = (sadb_address_t *)extv[SADB_X_EXT_ADDRESS_INNER_DST];
6982         sadb_sens_t *sens = (sadb_sens_t *)extv[SADB_EXT_SENSITIVITY];
6983         struct sockaddr_in6 *src, *dst;
6984         struct sockaddr_in6 *isrc, *idst;
6985         ipsec_tun_pol_t *itp = NULL;
6986         ipsec_policy_t *pp = NULL;
6987         ipsec_selector_t sel, isel;
6988         mblk_t *retmp;
6989         ip_stack_t      *ipst = ns->netstack_ip;
6990         sadb_msg_t *retmsg;
6991         ipsec_action_t *ap;
6992         boolean_t tunnel_mode = B_FALSE;
6993 
6994         /* Normalize addresses */
6995         if (sadb_addrcheck(NULL, (mblk_t *)samsg, (sadb_ext_t *)srcext, 0, ns)
6996             == KS_IN_ADDR_UNKNOWN) {
6997                 err = EINVAL;
6998                 diagnostic = SADB_X_DIAGNOSTIC_BAD_SRC;
6999                 goto bail;
7000         }
7001         src = (struct sockaddr_in6 *)(srcext + 1);
7002         if (sadb_addrcheck(NULL, (mblk_t *)samsg, (sadb_ext_t *)dstext, 0, ns)
7003             == KS_IN_ADDR_UNKNOWN) {
7004                 err = EINVAL;
7005                 diagnostic = SADB_X_DIAGNOSTIC_BAD_DST;
7006                 goto bail;
7007         }
7008         dst = (struct sockaddr_in6 *)(dstext + 1);
7009         if (src->sin6_family != dst->sin6_family) {
7010                 err = EINVAL;
7011                 diagnostic = SADB_X_DIAGNOSTIC_AF_MISMATCH;
7012                 goto bail;
7013         }
7014 
7015         /* Check for tunnel mode and act appropriately */
7016         /*
7017          * Note: keysock_inverse_acquire catches unbalanced extensions and
7018          * makes them into keysock_error calls, so ASSERTs here to confirm.
7019          */
7020         if (innsrcext != NULL) {
7021                 ASSERT(inndstext != NULL);
7022                 if (sadb_addrcheck(NULL, (mblk_t *)samsg,
7023                     (sadb_ext_t *)innsrcext, 0, ns) == KS_IN_ADDR_UNKNOWN) {
7024                         err = EINVAL;
7025                         diagnostic = SADB_X_DIAGNOSTIC_MALFORMED_INNER_SRC;
7026                         goto bail;
7027                 }
7028                 isrc = (struct sockaddr_in6 *)(innsrcext + 1);
7029                 if (sadb_addrcheck(NULL, (mblk_t *)samsg,
7030                     (sadb_ext_t *)inndstext, 0, ns) == KS_IN_ADDR_UNKNOWN) {
7031                         err = EINVAL;
7032                         diagnostic = SADB_X_DIAGNOSTIC_MALFORMED_INNER_DST;
7033                         goto bail;
7034                 }
7035                 idst = (struct sockaddr_in6 *)(inndstext + 1);
7036                 if (isrc->sin6_family != idst->sin6_family) {
7037                         err = EINVAL;
7038                         diagnostic = SADB_X_DIAGNOSTIC_INNER_AF_MISMATCH;
7039                         goto bail;
7040                 }
7041                 if (isrc->sin6_family != AF_INET &&
7042                     isrc->sin6_family != AF_INET6) {
7043                         err = EINVAL;
7044                         diagnostic = SADB_X_DIAGNOSTIC_BAD_INNER_SRC_AF;
7045                         goto bail;
7046                 }
7047                 tunnel_mode = B_TRUE;
7048         } else
7049                 ASSERT(inndstext == NULL);
7050 
7051         /* Convert address extensions into outer selector */
7052         err = ipsec_get_inverse_acquire_sel(&sel, srcext, dstext, &diagnostic);
7053         if (err != 0)
7054                 goto bail;
7055 
7056         /* Sanity-check newfound outer selector for tunnel mode mismatches */
7057         if (tunnel_mode &&
7058             ((isrc->sin6_family == AF_INET &&
7059             sel.ips_protocol != IPPROTO_ENCAP && sel.ips_protocol != 0) ||
7060             (isrc->sin6_family == AF_INET6 &&
7061             sel.ips_protocol != IPPROTO_IPV6 && sel.ips_protocol != 0))) {
7062                 err = EPROTOTYPE;
7063                 goto bail;
7064         }
7065 
7066         /*
7067          * Okay, we have the addresses and other selector information.
7068          * If our selector is for a protocol on top of IP, we make protocol-
7069          * specific queries that work through useful state (e.g. connections or
7070          * listeners). If we get something back, a reference to it will already
7071          * be held, and we need to release that reference.
7072          */
7073         switch (sel.ips_protocol) {
7074         case IPPROTO_TCP:
7075                 ipsec_tcp_pol(&sel, &pp, ipst);
7076                 break;
7077         case IPPROTO_UDP:
7078                 ipsec_udp_pol(&sel, &pp, ipst);
7079                 break;
7080         case IPPROTO_SCTP:
7081                 ipsec_sctp_pol(&sel, &pp, ipst);
7082                 break;
7083         case IPPROTO_ENCAP:
7084         case IPPROTO_IPV6:
7085                 /*
7086                  * These cases are IPv6 in IP or IP in IP. Revert to querying
7087                  * SPD for tunnel policy, since there's no higher-level protocol
7088                  * or stack state to assist. Assume sel.ips_remote_addr_* has
7089                  * right address at exact position.
7090                  */
7091                 itp = itp_get_byaddr((uint32_t *)(&sel.ips_local_addr_v6),
7092                     (uint32_t *)(&sel.ips_remote_addr_v6), src->sin6_family,
7093                     ipst);
7094 
7095                 if (innsrcext == NULL) {
7096                         /*
7097                          * Transport-mode tunnel, make sure we fake out isel
7098                          * to contain something based on the outer protocol.
7099                          */
7100                         bzero(&isel, sizeof (isel));
7101                         isel.ips_isv4 = (sel.ips_protocol == IPPROTO_ENCAP);
7102                         /* XXX does this make tunnel_mode true? */
7103                 } /* Else isel is initialized by ipsec_tun_pol(). */
7104                 err = ipsec_tun_pol(&isel, &pp, innsrcext, inndstext, itp,
7105                     &diagnostic);
7106                 /*
7107                  * NOTE:  isel isn't used for now, but in RFC 430x IPsec, it
7108                  * may be.
7109                  */
7110                 if (err != 0)
7111                         goto bail;
7112                 break;
7113         default: /* Fall through to generic lookup */
7114                 ipsec_oth_pol(&sel, &pp, ipst);
7115                 break;
7116         }
7117 
7118         /*
7119          * If we didn't find a matching conn_t or other policy head (pp retains
7120          * initial NULL value), attempt to revert to the global policy.
7121          */
7122         if (pp == NULL) {
7123                 pp = ipsec_find_policy(IPSEC_TYPE_OUTBOUND, NULL, &sel, ns);
7124                 if (pp == NULL) {
7125                         /* There's no global policy. */
7126                         err = ENOENT;
7127                         diagnostic = 0;
7128                         goto bail;
7129                 }
7130         }
7131 
7132         /*
7133          * Now that we have a policy entry/widget, construct an ACQUIRE
7134          * message based on that, fix fields where appropriate,
7135          * and return the message.
7136          */
7137         ap = pp->ipsp_act;
7138         ASSERT(ap != NULL);
7139 
7140         if (ap != NULL)
7141                 IPACT_REFHOLD(ap);
7142 
7143         retmp = sadb_construct_acqmsg(NULL, &sel, ap, pp, ns, sens, 0,
7144             tunnel_mode, B_TRUE, B_TRUE);
7145         if (retmp == NULL)
7146                 goto nomem_bail;
7147 
7148         retmsg = (sadb_msg_t *)retmp->b_rptr;
7149         retmsg->sadb_msg_seq = samsg->sadb_msg_seq;
7150         retmsg->sadb_msg_pid = samsg->sadb_msg_pid;
7151 
7152         if (pp != NULL)
7153                 IPPOL_REFRELE(pp);
7154         if (ap != NULL)
7155                 IPACT_REFRELE(ap);
7156 
7157         return (retmp);
7158 
7159 nomem_bail:
7160         if (pp != NULL)
7161                 IPPOL_REFRELE(pp);
7162         if (ap != NULL)
7163                 IPACT_REFRELE(ap);
7164         ASSERT(err == 0 && diagnostic == 0);
7165         err = ENOMEM;
7166 bail:
7167         if (itp != NULL) {
7168                 ITP_REFRELE(itp, ns);
7169         }
7170         /*
7171          * Write error info into original message, as we may not have resources
7172          * for a proper reply.
7173          */
7174         samsg->sadb_msg_errno = (uint8_t)err;
7175         samsg->sadb_x_msg_diagnostic = (uint16_t)diagnostic;
7176         return (retmp);
7177 }
7178 
7179 /*
7180  * ipsa_lpkt is a one-element queue, only manipulated by the next two
7181  * functions.  They have to hold the ipsa_lock because of potential races
7182  * between key management using SADB_UPDATE, and inbound packets that may
7183  * queue up on the larval SA (hence the 'l' in "lpkt").
7184  */
7185 
7186 /*
7187  * sadb_set_lpkt:
7188  *
7189  * Returns the passed-in packet if the SA is no longer larval.
7190  *
7191  * Returns NULL if the SA is larval, and needs to be swapped into the SA for
7192  * processing after an SADB_UPDATE.
7193  */
7194 mblk_t *
7195 sadb_set_lpkt(ipsa_t *ipsa, mblk_t *npkt, ip_recv_attr_t *ira)
7196 {
7197         mblk_t          *opkt;
7198 
7199         mutex_enter(&ipsa->ipsa_lock);
7200         opkt = ipsa->ipsa_lpkt;
7201         if (ipsa->ipsa_state == IPSA_STATE_LARVAL) {
7202                 /*
7203                  * Consume npkt and place it in the LARVAL SA's inbound
7204                  * packet slot.
7205                  */
7206                 mblk_t  *attrmp;
7207 
7208                 attrmp = ip_recv_attr_to_mblk(ira);
7209                 if (attrmp == NULL) {
7210                         ill_t *ill = ira->ira_ill;
7211 
7212                         BUMP_MIB(ill->ill_ip_mib, ipIfStatsInDiscards);
7213                         ip_drop_input("ipIfStatsInDiscards", npkt, ill);
7214                         freemsg(npkt);
7215                         opkt = NULL;
7216                 } else {
7217                         ASSERT(attrmp->b_cont == NULL);
7218                         attrmp->b_cont = npkt;
7219                         ipsa->ipsa_lpkt = attrmp;
7220                 }
7221                 npkt = NULL;
7222         } else {
7223                 /*
7224                  * If not larval, we lost the race.  NOTE: ipsa_lpkt may still
7225                  * have been non-NULL in the non-larval case, because of
7226                  * inbound packets arriving prior to sadb_common_add()
7227                  * transferring the SA completely out of larval state, but
7228                  * after lpkt was grabbed by the AH/ESP-specific add routines.
7229                  * We should clear the old ipsa_lpkt in this case to make sure
7230                  * that it doesn't linger on the now-MATURE IPsec SA, or get
7231                  * picked up as an out-of-order packet.
7232                  */
7233                 ipsa->ipsa_lpkt = NULL;
7234         }
7235         mutex_exit(&ipsa->ipsa_lock);
7236 
7237         if (opkt != NULL) {
7238                 ipsec_stack_t   *ipss;
7239 
7240                 ipss = ira->ira_ill->ill_ipst->ips_netstack->netstack_ipsec;
7241                 opkt = ip_recv_attr_free_mblk(opkt);
7242                 ip_drop_packet(opkt, B_TRUE, ira->ira_ill,
7243                     DROPPER(ipss, ipds_sadb_inlarval_replace),
7244                     &ipss->ipsec_sadb_dropper);
7245         }
7246         return (npkt);
7247 }
7248 
7249 /*
7250  * sadb_clear_lpkt: Atomically clear ipsa->ipsa_lpkt and return the
7251  * previous value.
7252  */
7253 mblk_t *
7254 sadb_clear_lpkt(ipsa_t *ipsa)
7255 {
7256         mblk_t *opkt;
7257 
7258         mutex_enter(&ipsa->ipsa_lock);
7259         opkt = ipsa->ipsa_lpkt;
7260         ipsa->ipsa_lpkt = NULL;
7261         mutex_exit(&ipsa->ipsa_lock);
7262         return (opkt);
7263 }
7264 
7265 /*
7266  * Buffer a packet that's in IDLE state as set by Solaris Clustering.
7267  */
7268 void
7269 sadb_buf_pkt(ipsa_t *ipsa, mblk_t *bpkt, ip_recv_attr_t *ira)
7270 {
7271         netstack_t      *ns = ira->ira_ill->ill_ipst->ips_netstack;
7272         ipsec_stack_t   *ipss = ns->netstack_ipsec;
7273         in6_addr_t *srcaddr = (in6_addr_t *)(&ipsa->ipsa_srcaddr);
7274         in6_addr_t *dstaddr = (in6_addr_t *)(&ipsa->ipsa_dstaddr);
7275         mblk_t          *mp;
7276 
7277         ASSERT(ipsa->ipsa_state == IPSA_STATE_IDLE);
7278 
7279         if (cl_inet_idlesa == NULL) {
7280                 ip_drop_packet(bpkt, B_TRUE, ira->ira_ill,
7281                     DROPPER(ipss, ipds_sadb_inidle_overflow),
7282                     &ipss->ipsec_sadb_dropper);
7283                 return;
7284         }
7285 
7286         cl_inet_idlesa(ns->netstack_stackid,
7287             (ipsa->ipsa_type == SADB_SATYPE_AH) ? IPPROTO_AH : IPPROTO_ESP,
7288             ipsa->ipsa_spi, ipsa->ipsa_addrfam, *srcaddr, *dstaddr, NULL);
7289 
7290         mp = ip_recv_attr_to_mblk(ira);
7291         if (mp == NULL) {
7292                 ip_drop_packet(bpkt, B_TRUE, ira->ira_ill,
7293                     DROPPER(ipss, ipds_sadb_inidle_overflow),
7294                     &ipss->ipsec_sadb_dropper);
7295                 return;
7296         }
7297         linkb(mp, bpkt);
7298 
7299         mutex_enter(&ipsa->ipsa_lock);
7300         ipsa->ipsa_mblkcnt++;
7301         if (ipsa->ipsa_bpkt_head == NULL) {
7302                 ipsa->ipsa_bpkt_head = ipsa->ipsa_bpkt_tail = bpkt;
7303         } else {
7304                 ipsa->ipsa_bpkt_tail->b_next = bpkt;
7305                 ipsa->ipsa_bpkt_tail = bpkt;
7306                 if (ipsa->ipsa_mblkcnt > SADB_MAX_IDLEPKTS) {
7307                         mblk_t *tmp;
7308 
7309                         tmp = ipsa->ipsa_bpkt_head;
7310                         ipsa->ipsa_bpkt_head = ipsa->ipsa_bpkt_head->b_next;
7311                         tmp = ip_recv_attr_free_mblk(tmp);
7312                         ip_drop_packet(tmp, B_TRUE, NULL,
7313                             DROPPER(ipss, ipds_sadb_inidle_overflow),
7314                             &ipss->ipsec_sadb_dropper);
7315                         ipsa->ipsa_mblkcnt --;
7316                 }
7317         }
7318         mutex_exit(&ipsa->ipsa_lock);
7319 }
7320 
7321 /*
7322  * Stub function that taskq_dispatch() invokes to take the mblk (in arg)
7323  * and put into STREAMS again.
7324  */
7325 void
7326 sadb_clear_buf_pkt(void *ipkt)
7327 {
7328         mblk_t  *tmp, *buf_pkt;
7329         ip_recv_attr_t  iras;
7330 
7331         buf_pkt = (mblk_t *)ipkt;
7332 
7333         while (buf_pkt != NULL) {
7334                 mblk_t *data_mp;
7335 
7336                 tmp = buf_pkt->b_next;
7337                 buf_pkt->b_next = NULL;
7338 
7339                 data_mp = buf_pkt->b_cont;
7340                 buf_pkt->b_cont = NULL;
7341                 if (!ip_recv_attr_from_mblk(buf_pkt, &iras)) {
7342                         /* The ill or ip_stack_t disappeared on us. */
7343                         ip_drop_input("ip_recv_attr_from_mblk", data_mp, NULL);
7344                         freemsg(data_mp);
7345                 } else {
7346                         ip_input_post_ipsec(data_mp, &iras);
7347                 }
7348                 ira_cleanup(&iras, B_TRUE);
7349                 buf_pkt = tmp;
7350         }
7351 }
7352 /*
7353  * Walker callback used by sadb_alg_update() to free/create crypto
7354  * context template when a crypto software provider is removed or
7355  * added.
7356  */
7357 
7358 struct sadb_update_alg_state {
7359         ipsec_algtype_t alg_type;
7360         uint8_t alg_id;
7361         boolean_t is_added;
7362         boolean_t async_auth;
7363         boolean_t async_encr;
7364 };
7365 
7366 static void
7367 sadb_alg_update_cb(isaf_t *head, ipsa_t *entry, void *cookie)
7368 {
7369         struct sadb_update_alg_state *update_state =
7370             (struct sadb_update_alg_state *)cookie;
7371         crypto_ctx_template_t *ctx_tmpl = NULL;
7372 
7373         ASSERT(MUTEX_HELD(&head->isaf_lock));
7374 
7375         if (entry->ipsa_state == IPSA_STATE_LARVAL)
7376                 return;
7377 
7378         mutex_enter(&entry->ipsa_lock);
7379 
7380         if ((entry->ipsa_encr_alg != SADB_EALG_NONE && entry->ipsa_encr_alg !=
7381             SADB_EALG_NULL && update_state->async_encr) ||
7382             (entry->ipsa_auth_alg != SADB_AALG_NONE &&
7383             update_state->async_auth)) {
7384                 entry->ipsa_flags |= IPSA_F_ASYNC;
7385         } else {
7386                 entry->ipsa_flags &= ~IPSA_F_ASYNC;
7387         }
7388 
7389         switch (update_state->alg_type) {
7390         case IPSEC_ALG_AUTH:
7391                 if (entry->ipsa_auth_alg == update_state->alg_id)
7392                         ctx_tmpl = &entry->ipsa_authtmpl;
7393                 break;
7394         case IPSEC_ALG_ENCR:
7395                 if (entry->ipsa_encr_alg == update_state->alg_id)
7396                         ctx_tmpl = &entry->ipsa_encrtmpl;
7397                 break;
7398         default:
7399                 ctx_tmpl = NULL;
7400         }
7401 
7402         if (ctx_tmpl == NULL) {
7403                 mutex_exit(&entry->ipsa_lock);
7404                 return;
7405         }
7406 
7407         /*
7408          * The context template of the SA may be affected by the change
7409          * of crypto provider.
7410          */
7411         if (update_state->is_added) {
7412                 /* create the context template if not already done */
7413                 if (*ctx_tmpl == NULL) {
7414                         (void) ipsec_create_ctx_tmpl(entry,
7415                             update_state->alg_type);
7416                 }
7417         } else {
7418                 /*
7419                  * The crypto provider was removed. If the context template
7420                  * exists but it is no longer valid, free it.
7421                  */
7422                 if (*ctx_tmpl != NULL)
7423                         ipsec_destroy_ctx_tmpl(entry, update_state->alg_type);
7424         }
7425 
7426         mutex_exit(&entry->ipsa_lock);
7427 }
7428 
7429 /*
7430  * Invoked by IP when an software crypto provider has been updated, or if
7431  * the crypto synchrony changes.  The type and id of the corresponding
7432  * algorithm is passed as argument.  The type is set to ALL in the case of
7433  * a synchrony change.
7434  *
7435  * is_added is B_TRUE if the provider was added, B_FALSE if it was
7436  * removed. The function updates the SADB and free/creates the
7437  * context templates associated with SAs if needed.
7438  */
7439 
7440 #define SADB_ALG_UPDATE_WALK(sadb, table) \
7441     sadb_walker((sadb).table, (sadb).sdb_hashsize, sadb_alg_update_cb, \
7442         &update_state)
7443 
7444 void
7445 sadb_alg_update(ipsec_algtype_t alg_type, uint8_t alg_id, boolean_t is_added,
7446     netstack_t *ns)
7447 {
7448         struct sadb_update_alg_state update_state;
7449         ipsecah_stack_t *ahstack = ns->netstack_ipsecah;
7450         ipsecesp_stack_t        *espstack = ns->netstack_ipsecesp;
7451         ipsec_stack_t *ipss = ns->netstack_ipsec;
7452 
7453         update_state.alg_type = alg_type;
7454         update_state.alg_id = alg_id;
7455         update_state.is_added = is_added;
7456         update_state.async_auth = ipss->ipsec_algs_exec_mode[IPSEC_ALG_AUTH] ==
7457             IPSEC_ALGS_EXEC_ASYNC;
7458         update_state.async_encr = ipss->ipsec_algs_exec_mode[IPSEC_ALG_ENCR] ==
7459             IPSEC_ALGS_EXEC_ASYNC;
7460 
7461         if (alg_type == IPSEC_ALG_AUTH || alg_type == IPSEC_ALG_ALL) {
7462                 /* walk the AH tables only for auth. algorithm changes */
7463                 SADB_ALG_UPDATE_WALK(ahstack->ah_sadb.s_v4, sdb_of);
7464                 SADB_ALG_UPDATE_WALK(ahstack->ah_sadb.s_v4, sdb_if);
7465                 SADB_ALG_UPDATE_WALK(ahstack->ah_sadb.s_v6, sdb_of);
7466                 SADB_ALG_UPDATE_WALK(ahstack->ah_sadb.s_v6, sdb_if);
7467         }
7468 
7469         /* walk the ESP tables */
7470         SADB_ALG_UPDATE_WALK(espstack->esp_sadb.s_v4, sdb_of);
7471         SADB_ALG_UPDATE_WALK(espstack->esp_sadb.s_v4, sdb_if);
7472         SADB_ALG_UPDATE_WALK(espstack->esp_sadb.s_v6, sdb_of);
7473         SADB_ALG_UPDATE_WALK(espstack->esp_sadb.s_v6, sdb_if);
7474 }
7475 
7476 /*
7477  * Creates a context template for the specified SA. This function
7478  * is called when an SA is created and when a context template needs
7479  * to be created due to a change of software provider.
7480  */
7481 int
7482 ipsec_create_ctx_tmpl(ipsa_t *sa, ipsec_algtype_t alg_type)
7483 {
7484         ipsec_alginfo_t *alg;
7485         crypto_mechanism_t mech;
7486         crypto_key_t *key;
7487         crypto_ctx_template_t *sa_tmpl;
7488         int rv;
7489         ipsec_stack_t   *ipss = sa->ipsa_netstack->netstack_ipsec;
7490 
7491         ASSERT(RW_READ_HELD(&ipss->ipsec_alg_lock));
7492         ASSERT(MUTEX_HELD(&sa->ipsa_lock));
7493 
7494         /* get pointers to the algorithm info, context template, and key */
7495         switch (alg_type) {
7496         case IPSEC_ALG_AUTH:
7497                 key = &sa->ipsa_kcfauthkey;
7498                 sa_tmpl = &sa->ipsa_authtmpl;
7499                 alg = ipss->ipsec_alglists[alg_type][sa->ipsa_auth_alg];
7500                 break;
7501         case IPSEC_ALG_ENCR:
7502                 key = &sa->ipsa_kcfencrkey;
7503                 sa_tmpl = &sa->ipsa_encrtmpl;
7504                 alg = ipss->ipsec_alglists[alg_type][sa->ipsa_encr_alg];
7505                 break;
7506         default:
7507                 alg = NULL;
7508         }
7509 
7510         if (alg == NULL || !ALG_VALID(alg))
7511                 return (EINVAL);
7512 
7513         /* initialize the mech info structure for the framework */
7514         ASSERT(alg->alg_mech_type != CRYPTO_MECHANISM_INVALID);
7515         mech.cm_type = alg->alg_mech_type;
7516         mech.cm_param = NULL;
7517         mech.cm_param_len = 0;
7518 
7519         /* create a new context template */
7520         rv = crypto_create_ctx_template(&mech, key, sa_tmpl, KM_NOSLEEP);
7521 
7522         /*
7523          * CRYPTO_MECH_NOT_SUPPORTED can be returned if only hardware
7524          * providers are available for that mechanism. In that case
7525          * we don't fail, and will generate the context template from
7526          * the framework callback when a software provider for that
7527          * mechanism registers.
7528          *
7529          * The context template is assigned the special value
7530          * IPSEC_CTX_TMPL_ALLOC if the allocation failed due to a
7531          * lack of memory. No attempt will be made to use
7532          * the context template if it is set to this value.
7533          */
7534         if (rv == CRYPTO_HOST_MEMORY) {
7535                 *sa_tmpl = IPSEC_CTX_TMPL_ALLOC;
7536         } else if (rv != CRYPTO_SUCCESS) {
7537                 *sa_tmpl = NULL;
7538                 if (rv != CRYPTO_MECH_NOT_SUPPORTED)
7539                         return (EINVAL);
7540         }
7541 
7542         return (0);
7543 }
7544 
7545 /*
7546  * Destroy the context template of the specified algorithm type
7547  * of the specified SA. Must be called while holding the SA lock.
7548  */
7549 void
7550 ipsec_destroy_ctx_tmpl(ipsa_t *sa, ipsec_algtype_t alg_type)
7551 {
7552         ASSERT(MUTEX_HELD(&sa->ipsa_lock));
7553 
7554         if (alg_type == IPSEC_ALG_AUTH) {
7555                 if (sa->ipsa_authtmpl == IPSEC_CTX_TMPL_ALLOC)
7556                         sa->ipsa_authtmpl = NULL;
7557                 else if (sa->ipsa_authtmpl != NULL) {
7558                         crypto_destroy_ctx_template(sa->ipsa_authtmpl);
7559                         sa->ipsa_authtmpl = NULL;
7560                 }
7561         } else {
7562                 ASSERT(alg_type == IPSEC_ALG_ENCR);
7563                 if (sa->ipsa_encrtmpl == IPSEC_CTX_TMPL_ALLOC)
7564                         sa->ipsa_encrtmpl = NULL;
7565                 else if (sa->ipsa_encrtmpl != NULL) {
7566                         crypto_destroy_ctx_template(sa->ipsa_encrtmpl);
7567                         sa->ipsa_encrtmpl = NULL;
7568                 }
7569         }
7570 }
7571 
7572 /*
7573  * Use the kernel crypto framework to check the validity of a key received
7574  * via keysock. Returns 0 if the key is OK, -1 otherwise.
7575  */
7576 int
7577 ipsec_check_key(crypto_mech_type_t mech_type, sadb_key_t *sadb_key,
7578     boolean_t is_auth, int *diag)
7579 {
7580         crypto_mechanism_t mech;
7581         crypto_key_t crypto_key;
7582         int crypto_rc;
7583 
7584         mech.cm_type = mech_type;
7585         mech.cm_param = NULL;
7586         mech.cm_param_len = 0;
7587 
7588         crypto_key.ck_format = CRYPTO_KEY_RAW;
7589         crypto_key.ck_data = sadb_key + 1;
7590         crypto_key.ck_length = sadb_key->sadb_key_bits;
7591 
7592         crypto_rc = crypto_key_check(&mech, &crypto_key);
7593 
7594         switch (crypto_rc) {
7595         case CRYPTO_SUCCESS:
7596                 return (0);
7597         case CRYPTO_MECHANISM_INVALID:
7598         case CRYPTO_MECH_NOT_SUPPORTED:
7599                 *diag = is_auth ? SADB_X_DIAGNOSTIC_BAD_AALG :
7600                     SADB_X_DIAGNOSTIC_BAD_EALG;
7601                 break;
7602         case CRYPTO_KEY_SIZE_RANGE:
7603                 *diag = is_auth ? SADB_X_DIAGNOSTIC_BAD_AKEYBITS :
7604                     SADB_X_DIAGNOSTIC_BAD_EKEYBITS;
7605                 break;
7606         case CRYPTO_WEAK_KEY:
7607                 *diag = is_auth ? SADB_X_DIAGNOSTIC_WEAK_AKEY :
7608                     SADB_X_DIAGNOSTIC_WEAK_EKEY;
7609                 break;
7610         }
7611 
7612         return (-1);
7613 }
7614 
7615 /*
7616  * Whack options in the outer IP header when ipsec changes the outer label
7617  *
7618  * This is inelegant and really could use refactoring.
7619  */
7620 mblk_t *
7621 sadb_whack_label_v4(mblk_t *mp, ipsa_t *assoc, kstat_named_t *counter,
7622     ipdropper_t *dropper)
7623 {
7624         int delta;
7625         int plen;
7626         dblk_t *db;
7627         int hlen;
7628         uint8_t *opt_storage = assoc->ipsa_opt_storage;
7629         ipha_t *ipha = (ipha_t *)mp->b_rptr;
7630 
7631         plen = ntohs(ipha->ipha_length);
7632 
7633         delta = tsol_remove_secopt(ipha, MBLKL(mp));
7634         mp->b_wptr += delta;
7635         plen += delta;
7636 
7637         /* XXX XXX code copied from tsol_check_label */
7638 
7639         /* Make sure we have room for the worst-case addition */
7640         hlen = IPH_HDR_LENGTH(ipha) + opt_storage[IPOPT_OLEN];
7641         hlen = (hlen + 3) & ~3;
7642         if (hlen > IP_MAX_HDR_LENGTH)
7643                 hlen = IP_MAX_HDR_LENGTH;
7644         hlen -= IPH_HDR_LENGTH(ipha);
7645 
7646         db = mp->b_datap;
7647         if ((db->db_ref != 1) || (mp->b_wptr + hlen > db->db_lim)) {
7648                 int copylen;
7649                 mblk_t *new_mp;
7650 
7651                 /* allocate enough to be meaningful, but not *too* much */
7652                 copylen = MBLKL(mp);
7653                 if (copylen > 256)
7654                         copylen = 256;
7655                 new_mp = allocb_tmpl(hlen + copylen +
7656                     (mp->b_rptr - mp->b_datap->db_base), mp);
7657 
7658                 if (new_mp == NULL) {
7659                         ip_drop_packet(mp, B_FALSE, NULL, counter,  dropper);
7660                         return (NULL);
7661                 }
7662 
7663                 /* keep the bias */
7664                 new_mp->b_rptr += mp->b_rptr - mp->b_datap->db_base;
7665                 new_mp->b_wptr = new_mp->b_rptr + copylen;
7666                 bcopy(mp->b_rptr, new_mp->b_rptr, copylen);
7667                 new_mp->b_cont = mp;
7668                 if ((mp->b_rptr += copylen) >= mp->b_wptr) {
7669                         new_mp->b_cont = mp->b_cont;
7670                         freeb(mp);
7671                 }
7672                 mp = new_mp;
7673                 ipha = (ipha_t *)mp->b_rptr;
7674         }
7675 
7676         delta = tsol_prepend_option(assoc->ipsa_opt_storage, ipha, MBLKL(mp));
7677 
7678         ASSERT(delta != -1);
7679 
7680         plen += delta;
7681         mp->b_wptr += delta;
7682 
7683         /*
7684          * Paranoia
7685          */
7686         db = mp->b_datap;
7687 
7688         ASSERT3P(mp->b_wptr, <=, db->db_lim);
7689         ASSERT3P(mp->b_rptr, <=, db->db_lim);
7690 
7691         ASSERT3P(mp->b_wptr, >=, db->db_base);
7692         ASSERT3P(mp->b_rptr, >=, db->db_base);
7693         /* End paranoia */
7694 
7695         ipha->ipha_length = htons(plen);
7696 
7697         return (mp);
7698 }
7699 
7700 mblk_t *
7701 sadb_whack_label_v6(mblk_t *mp, ipsa_t *assoc, kstat_named_t *counter,
7702     ipdropper_t *dropper)
7703 {
7704         int delta;
7705         int plen;
7706         dblk_t *db;
7707         int hlen;
7708         uint8_t *opt_storage = assoc->ipsa_opt_storage;
7709         uint_t sec_opt_len; /* label option length not including type, len */
7710         ip6_t *ip6h = (ip6_t *)mp->b_rptr;
7711 
7712         plen = ntohs(ip6h->ip6_plen);
7713 
7714         delta = tsol_remove_secopt_v6(ip6h, MBLKL(mp));
7715         mp->b_wptr += delta;
7716         plen += delta;
7717 
7718         /* XXX XXX code copied from tsol_check_label_v6 */
7719         /*
7720          * Make sure we have room for the worst-case addition. Add 2 bytes for
7721          * the hop-by-hop ext header's next header and length fields. Add
7722          * another 2 bytes for the label option type, len and then round
7723          * up to the next 8-byte multiple.
7724          */
7725         sec_opt_len = opt_storage[1];
7726 
7727         db = mp->b_datap;
7728         hlen = (4 + sec_opt_len + 7) & ~7;
7729 
7730         if ((db->db_ref != 1) || (mp->b_wptr + hlen > db->db_lim)) {
7731                 int copylen;
7732                 mblk_t *new_mp;
7733                 uint16_t hdr_len;
7734 
7735                 hdr_len = ip_hdr_length_v6(mp, ip6h);
7736                 /*
7737                  * Allocate enough to be meaningful, but not *too* much.
7738                  * Also all the IPv6 extension headers must be in the same mblk
7739                  */
7740                 copylen = MBLKL(mp);
7741                 if (copylen > 256)
7742                         copylen = 256;
7743                 if (copylen < hdr_len)
7744                         copylen = hdr_len;
7745                 new_mp = allocb_tmpl(hlen + copylen +
7746                     (mp->b_rptr - mp->b_datap->db_base), mp);
7747                 if (new_mp == NULL) {
7748                         ip_drop_packet(mp, B_FALSE, NULL, counter,  dropper);
7749                         return (NULL);
7750                 }
7751 
7752                 /* keep the bias */
7753                 new_mp->b_rptr += mp->b_rptr - mp->b_datap->db_base;
7754                 new_mp->b_wptr = new_mp->b_rptr + copylen;
7755                 bcopy(mp->b_rptr, new_mp->b_rptr, copylen);
7756                 new_mp->b_cont = mp;
7757                 if ((mp->b_rptr += copylen) >= mp->b_wptr) {
7758                         new_mp->b_cont = mp->b_cont;
7759                         freeb(mp);
7760                 }
7761                 mp = new_mp;
7762                 ip6h = (ip6_t *)mp->b_rptr;
7763         }
7764 
7765         delta = tsol_prepend_option_v6(assoc->ipsa_opt_storage,
7766             ip6h, MBLKL(mp));
7767 
7768         ASSERT(delta != -1);
7769 
7770         plen += delta;
7771         mp->b_wptr += delta;
7772 
7773         /*
7774          * Paranoia
7775          */
7776         db = mp->b_datap;
7777 
7778         ASSERT3P(mp->b_wptr, <=, db->db_lim);
7779         ASSERT3P(mp->b_rptr, <=, db->db_lim);
7780 
7781         ASSERT3P(mp->b_wptr, >=, db->db_base);
7782         ASSERT3P(mp->b_rptr, >=, db->db_base);
7783         /* End paranoia */
7784 
7785         ip6h->ip6_plen = htons(plen);
7786 
7787         return (mp);
7788 }
7789 
7790 /* Whack the labels and update ip_xmit_attr_t as needed */
7791 mblk_t *
7792 sadb_whack_label(mblk_t *mp, ipsa_t *assoc, ip_xmit_attr_t *ixa,
7793     kstat_named_t *counter, ipdropper_t *dropper)
7794 {
7795         int adjust;
7796         int iplen;
7797 
7798         if (ixa->ixa_flags & IXAF_IS_IPV4) {
7799                 ipha_t          *ipha = (ipha_t *)mp->b_rptr;
7800 
7801                 ASSERT(IPH_HDR_VERSION(ipha) == IPV4_VERSION);
7802                 iplen = ntohs(ipha->ipha_length);
7803                 mp = sadb_whack_label_v4(mp, assoc, counter, dropper);
7804                 if (mp == NULL)
7805                         return (NULL);
7806 
7807                 ipha = (ipha_t *)mp->b_rptr;
7808                 ASSERT(IPH_HDR_VERSION(ipha) == IPV4_VERSION);
7809                 adjust = (int)ntohs(ipha->ipha_length) - iplen;
7810         } else {
7811                 ip6_t           *ip6h = (ip6_t *)mp->b_rptr;
7812 
7813                 ASSERT(IPH_HDR_VERSION(ip6h) == IPV6_VERSION);
7814                 iplen = ntohs(ip6h->ip6_plen);
7815                 mp = sadb_whack_label_v6(mp, assoc, counter, dropper);
7816                 if (mp == NULL)
7817                         return (NULL);
7818 
7819                 ip6h = (ip6_t *)mp->b_rptr;
7820                 ASSERT(IPH_HDR_VERSION(ip6h) == IPV6_VERSION);
7821                 adjust = (int)ntohs(ip6h->ip6_plen) - iplen;
7822         }
7823         ixa->ixa_pktlen += adjust;
7824         ixa->ixa_ip_hdr_length += adjust;
7825         return (mp);
7826 }
7827 
7828 /*
7829  * If this is an outgoing SA then add some fuzz to the
7830  * SOFT EXPIRE time. The reason for this is to stop
7831  * peers trying to renegotiate SOFT expiring SA's at
7832  * the same time. The amount of fuzz needs to be at
7833  * least 8 seconds which is the typical interval
7834  * sadb_ager(), although this is only a guide as it
7835  * selftunes.
7836  */
7837 static void
7838 lifetime_fuzz(ipsa_t *assoc)
7839 {
7840         uint8_t rnd;
7841 
7842         if (assoc->ipsa_softaddlt == 0)
7843                 return;
7844 
7845         (void) random_get_pseudo_bytes(&rnd, sizeof (rnd));
7846         rnd = (rnd & 0xF) + 8;
7847         assoc->ipsa_softexpiretime -= rnd;
7848         assoc->ipsa_softaddlt -= rnd;
7849 }
7850 
7851 static void
7852 destroy_ipsa_pair(ipsap_t *ipsapp)
7853 {
7854         /*
7855          * Because of the multi-line macro nature of IPSA_REFRELE, keep
7856          * them in { }.
7857          */
7858         if (ipsapp->ipsap_sa_ptr != NULL) {
7859                 IPSA_REFRELE(ipsapp->ipsap_sa_ptr);
7860         }
7861         if (ipsapp->ipsap_psa_ptr != NULL) {
7862                 IPSA_REFRELE(ipsapp->ipsap_psa_ptr);
7863         }
7864         init_ipsa_pair(ipsapp);
7865 }
7866 
7867 static void
7868 init_ipsa_pair(ipsap_t *ipsapp)
7869 {
7870         ipsapp->ipsap_bucket = NULL;
7871         ipsapp->ipsap_sa_ptr = NULL;
7872         ipsapp->ipsap_pbucket = NULL;
7873         ipsapp->ipsap_psa_ptr = NULL;
7874 }
7875 
7876 /*
7877  * The sadb_ager() function walks through the hash tables of SA's and ages
7878  * them, if the SA expires as a result, its marked as DEAD and will be reaped
7879  * the next time sadb_ager() runs. SA's which are paired or have a peer (same
7880  * SA appears in both the inbound and outbound tables because its not possible
7881  * to determine its direction) are placed on a list when they expire. This is
7882  * to ensure that pair/peer SA's are reaped at the same time, even if they
7883  * expire at different times.
7884  *
7885  * This function is called twice by sadb_ager(), one after processing the
7886  * inbound table, then again after processing the outbound table.
7887  */
7888 void
7889 age_pair_peer_list(templist_t *haspeerlist, sadb_t *sp, boolean_t outbound)
7890 {
7891         templist_t *listptr;
7892         int outhash;
7893         isaf_t *bucket;
7894         boolean_t haspeer;
7895         ipsa_t *peer_assoc, *dying;
7896         /*
7897          * Haspeer cases will contain both IPv4 and IPv6.  This code
7898          * is address independent.
7899          */
7900         while (haspeerlist != NULL) {
7901                 /* "dying" contains the SA that has a peer. */
7902                 dying = haspeerlist->ipsa;
7903                 haspeer = (dying->ipsa_haspeer);
7904                 listptr = haspeerlist;
7905                 haspeerlist = listptr->next;
7906                 kmem_free(listptr, sizeof (*listptr));
7907                 /*
7908                  * Pick peer bucket based on addrfam.
7909                  */
7910                 if (outbound) {
7911                         if (haspeer)
7912                                 bucket = INBOUND_BUCKET(sp, dying->ipsa_spi);
7913                         else
7914                                 bucket = INBOUND_BUCKET(sp,
7915                                     dying->ipsa_otherspi);
7916                 } else { /* inbound */
7917                         if (haspeer) {
7918                                 if (dying->ipsa_addrfam == AF_INET6) {
7919                                         outhash = OUTBOUND_HASH_V6(sp,
7920                                             *((in6_addr_t *)&dying->
7921                                             ipsa_dstaddr));
7922                                 } else {
7923                                         outhash = OUTBOUND_HASH_V4(sp,
7924                                             *((ipaddr_t *)&dying->
7925                                             ipsa_dstaddr));
7926                                 }
7927                         } else if (dying->ipsa_addrfam == AF_INET6) {
7928                                 outhash = OUTBOUND_HASH_V6(sp,
7929                                     *((in6_addr_t *)&dying->
7930                                     ipsa_srcaddr));
7931                         } else {
7932                                 outhash = OUTBOUND_HASH_V4(sp,
7933                                     *((ipaddr_t *)&dying->
7934                                     ipsa_srcaddr));
7935                         }
7936                         bucket = &(sp->sdb_of[outhash]);
7937                 }
7938 
7939                 mutex_enter(&bucket->isaf_lock);
7940                 /*
7941                  * "haspeer" SA's have the same src/dst address ordering,
7942                  * "paired" SA's have the src/dst addresses reversed.
7943                  */
7944                 if (haspeer) {
7945                         peer_assoc = ipsec_getassocbyspi(bucket,
7946                             dying->ipsa_spi, dying->ipsa_srcaddr,
7947                             dying->ipsa_dstaddr, dying->ipsa_addrfam);
7948                 } else {
7949                         peer_assoc = ipsec_getassocbyspi(bucket,
7950                             dying->ipsa_otherspi, dying->ipsa_dstaddr,
7951                             dying->ipsa_srcaddr, dying->ipsa_addrfam);
7952                 }
7953 
7954                 mutex_exit(&bucket->isaf_lock);
7955                 if (peer_assoc != NULL) {
7956                         mutex_enter(&peer_assoc->ipsa_lock);
7957                         mutex_enter(&dying->ipsa_lock);
7958                         if (!haspeer) {
7959                                 /*
7960                                  * Only SA's which have a "peer" or are
7961                                  * "paired" end up on this list, so this
7962                                  * must be a "paired" SA, update the flags
7963                                  * to break the pair.
7964                                  */
7965                                 peer_assoc->ipsa_otherspi = 0;
7966                                 peer_assoc->ipsa_flags &= ~IPSA_F_PAIRED;
7967                                 dying->ipsa_otherspi = 0;
7968                                 dying->ipsa_flags &= ~IPSA_F_PAIRED;
7969                         }
7970                         if (haspeer || outbound) {
7971                                 /*
7972                                  * Update the state of the "inbound" SA when
7973                                  * the "outbound" SA has expired. Don't update
7974                                  * the "outbound" SA when the "inbound" SA
7975                                  * SA expires because setting the hard_addtime
7976                                  * below will cause this to happen.
7977                                  */
7978                                 peer_assoc->ipsa_state = dying->ipsa_state;
7979                         }
7980                         if (dying->ipsa_state == IPSA_STATE_DEAD)
7981                                 peer_assoc->ipsa_hardexpiretime = 1;
7982 
7983                         mutex_exit(&dying->ipsa_lock);
7984                         mutex_exit(&peer_assoc->ipsa_lock);
7985                         IPSA_REFRELE(peer_assoc);
7986                 }
7987                 IPSA_REFRELE(dying);
7988         }
7989 }
7990 
7991 /*
7992  * Ensure that the IV used for CCM mode never repeats. The IV should
7993  * only be updated by this function. Also check to see if the IV
7994  * is about to wrap and generate a SOFT Expire. This function is only
7995  * called for outgoing packets, the IV for incomming packets is taken
7996  * from the wire. If the outgoing SA needs to be expired, update
7997  * the matching incomming SA.
7998  */
7999 boolean_t
8000 update_iv(uint8_t *iv_ptr, queue_t *pfkey_q, ipsa_t *assoc,
8001     ipsecesp_stack_t *espstack)
8002 {
8003         boolean_t rc = B_TRUE;
8004         isaf_t *inbound_bucket;
8005         sadb_t *sp;
8006         ipsa_t *pair_sa = NULL;
8007         int sa_new_state = 0;
8008 
8009         /* For non counter modes, the IV is random data. */
8010         if (!(assoc->ipsa_flags & IPSA_F_COUNTERMODE)) {
8011                 (void) random_get_pseudo_bytes(iv_ptr, assoc->ipsa_iv_len);
8012                 return (rc);
8013         }
8014 
8015         mutex_enter(&assoc->ipsa_lock);
8016 
8017         (*assoc->ipsa_iv)++;
8018 
8019         if (*assoc->ipsa_iv == assoc->ipsa_iv_hardexpire) {
8020                 sa_new_state = IPSA_STATE_DEAD;
8021                 rc = B_FALSE;
8022         } else if (*assoc->ipsa_iv == assoc->ipsa_iv_softexpire) {
8023                 if (assoc->ipsa_state != IPSA_STATE_DYING) {
8024                         /*
8025                          * This SA may have already been expired when its
8026                          * PAIR_SA expired.
8027                          */
8028                         sa_new_state = IPSA_STATE_DYING;
8029                 }
8030         }
8031         if (sa_new_state) {
8032                 /*
8033                  * If there is a state change, we need to update this SA
8034                  * and its "pair", we can find the bucket for the "pair" SA
8035                  * while holding the ipsa_t mutex, but we won't actually
8036                  * update anything untill the ipsa_t mutex has been released
8037                  * for _this_ SA.
8038                  */
8039                 assoc->ipsa_state = sa_new_state;
8040                 if (assoc->ipsa_addrfam == AF_INET6) {
8041                         sp = &espstack->esp_sadb.s_v6;
8042                 } else {
8043                         sp = &espstack->esp_sadb.s_v4;
8044                 }
8045                 inbound_bucket = INBOUND_BUCKET(sp, assoc->ipsa_otherspi);
8046                 sadb_expire_assoc(pfkey_q, assoc);
8047         }
8048         if (rc == B_TRUE)
8049                 bcopy(assoc->ipsa_iv, iv_ptr, assoc->ipsa_iv_len);
8050 
8051         mutex_exit(&assoc->ipsa_lock);
8052 
8053         if (sa_new_state) {
8054                 /* Find the inbound SA, need to lock hash bucket. */
8055                 mutex_enter(&inbound_bucket->isaf_lock);
8056                 pair_sa = ipsec_getassocbyspi(inbound_bucket,
8057                     assoc->ipsa_otherspi, assoc->ipsa_dstaddr,
8058                     assoc->ipsa_srcaddr, assoc->ipsa_addrfam);
8059                 mutex_exit(&inbound_bucket->isaf_lock);
8060                 if (pair_sa != NULL) {
8061                         mutex_enter(&pair_sa->ipsa_lock);
8062                         pair_sa->ipsa_state = sa_new_state;
8063                         mutex_exit(&pair_sa->ipsa_lock);
8064                         IPSA_REFRELE(pair_sa);
8065                 }
8066         }
8067 
8068         return (rc);
8069 }
8070 
8071 void
8072 ccm_params_init(ipsa_t *assoc, uchar_t *esph, uint_t data_len, uchar_t *iv_ptr,
8073     ipsa_cm_mech_t *cm_mech, crypto_data_t *crypto_data)
8074 {
8075         uchar_t *nonce;
8076         crypto_mechanism_t *combined_mech;
8077         CK_AES_CCM_PARAMS *params;
8078 
8079         combined_mech = (crypto_mechanism_t *)cm_mech;
8080         params = (CK_AES_CCM_PARAMS *)(combined_mech + 1);
8081         nonce = (uchar_t *)(params + 1);
8082         params->ulMACSize = assoc->ipsa_mac_len;
8083         params->ulNonceSize = assoc->ipsa_nonce_len;
8084         params->ulAuthDataSize = sizeof (esph_t);
8085         params->ulDataSize = data_len;
8086         params->nonce = nonce;
8087         params->authData = esph;
8088 
8089         cm_mech->combined_mech.cm_type = assoc->ipsa_emech.cm_type;
8090         cm_mech->combined_mech.cm_param_len = sizeof (CK_AES_CCM_PARAMS);
8091         cm_mech->combined_mech.cm_param = (caddr_t)params;
8092         /* See gcm_params_init() for comments. */
8093         bcopy(assoc->ipsa_nonce, nonce, assoc->ipsa_saltlen);
8094         nonce += assoc->ipsa_saltlen;
8095         bcopy(iv_ptr, nonce, assoc->ipsa_iv_len);
8096         crypto_data->cd_miscdata = NULL;
8097 }
8098 
8099 /* ARGSUSED */
8100 void
8101 cbc_params_init(ipsa_t *assoc, uchar_t *esph, uint_t data_len, uchar_t *iv_ptr,
8102     ipsa_cm_mech_t *cm_mech, crypto_data_t *crypto_data)
8103 {
8104         cm_mech->combined_mech.cm_type = assoc->ipsa_emech.cm_type;
8105         cm_mech->combined_mech.cm_param_len = 0;
8106         cm_mech->combined_mech.cm_param = NULL;
8107         crypto_data->cd_miscdata = (char *)iv_ptr;
8108 }
8109 
8110 /* ARGSUSED */
8111 void
8112 gcm_params_init(ipsa_t *assoc, uchar_t *esph, uint_t data_len, uchar_t *iv_ptr,
8113     ipsa_cm_mech_t *cm_mech, crypto_data_t *crypto_data)
8114 {
8115         uchar_t *nonce;
8116         crypto_mechanism_t *combined_mech;
8117         CK_AES_GCM_PARAMS *params;
8118 
8119         combined_mech = (crypto_mechanism_t *)cm_mech;
8120         params = (CK_AES_GCM_PARAMS *)(combined_mech + 1);
8121         nonce = (uchar_t *)(params + 1);
8122 
8123         params->pIv = nonce;
8124         params->ulIvLen = assoc->ipsa_nonce_len;
8125         params->ulIvBits = SADB_8TO1(assoc->ipsa_nonce_len);
8126         params->pAAD = esph;
8127         params->ulAADLen = sizeof (esph_t);
8128         params->ulTagBits = SADB_8TO1(assoc->ipsa_mac_len);
8129 
8130         cm_mech->combined_mech.cm_type = assoc->ipsa_emech.cm_type;
8131         cm_mech->combined_mech.cm_param_len = sizeof (CK_AES_GCM_PARAMS);
8132         cm_mech->combined_mech.cm_param = (caddr_t)params;
8133         /*
8134          * Create the nonce, which is made up of the salt and the IV.
8135          * Copy the salt from the SA and the IV from the packet.
8136          * For inbound packets we copy the IV from the packet because it
8137          * was set by the sending system, for outbound packets we copy the IV
8138          * from the packet because the IV in the SA may be changed by another
8139          * thread, the IV in the packet was created while holding a mutex.
8140          */
8141         bcopy(assoc->ipsa_nonce, nonce, assoc->ipsa_saltlen);
8142         nonce += assoc->ipsa_saltlen;
8143         bcopy(iv_ptr, nonce, assoc->ipsa_iv_len);
8144         crypto_data->cd_miscdata = NULL;
8145 }