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