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 
  26 #include <sys/types.h>
  27 #include <sys/stream.h>
  28 #include <sys/strsubr.h>
  29 #include <sys/sunddi.h>
  30 #include <sys/ddi.h>
  31 #include <sys/strlog.h>
  32 
  33 #include <inet/common.h>
  34 #include <inet/mib2.h>
  35 #include <inet/ip.h>
  36 #include <inet/ip6.h>
  37 
  38 #include <net/pfkeyv2.h>
  39 #include <inet/sadb.h>
  40 #include <inet/ipsec_impl.h>
  41 #include <inet/ipdrop.h>
  42 #include <inet/ipsecesp.h>
  43 #include <inet/ipsecah.h>
  44 #include <sys/kstat.h>
  45 
  46 /*
  47  * Returns B_TRUE if the identities in the SA match the identities
  48  * in the "latch" structure.
  49  */
  50 
  51 static boolean_t
  52 ipsec_match_outbound_ids(ipsec_latch_t *ipl, ipsa_t *sa)
  53 {
  54         ASSERT(ipl->ipl_ids_latched == B_TRUE);
  55         return ipsid_equal(ipl->ipl_local_cid, sa->ipsa_src_cid) &&
  56             ipsid_equal(ipl->ipl_remote_cid, sa->ipsa_dst_cid);
  57 }
  58 
  59 /* l1 is packet label; l2 is SA label */
  60 boolean_t
  61 ipsec_label_match(ts_label_t *l1, ts_label_t *l2)
  62 {
  63         if (!is_system_labeled())
  64                 return (B_TRUE);
  65 
  66         /*
  67          * Check for NULL label.  Unlabeled SA (l2) always matches;
  68          * unlabeled user with labeled  SA always fails
  69          */
  70         if (l2 == NULL)
  71                 return (B_TRUE);
  72 
  73         if (l1 == NULL)
  74                 return (B_FALSE);
  75 
  76         /* Simple IPsec MLS policy: labels must be equal */
  77         /* In future will need bit in policy saying whether this is the case */
  78 
  79         /*
  80          * label_equal() checks DOI and label contents.  We should be
  81          * good to go with this check.
  82          */
  83         return (label_equal(l1, l2));
  84 }
  85 
  86 
  87 /*
  88  * Look up a security association based on the unique ID generated by IP and
  89  * transport or tunnel information, such as ports and upper-layer protocol,
  90  * and the inner and outer address(es).  Used for uniqueness testing and
  91  * outbound packets.  The outer source address may be ignored.
  92  *
  93  * I expect an SA hash bucket, and that its per-bucket mutex is held.
  94  * The SA ptr I return will have its reference count incremented by one.
  95  */
  96 ipsa_t *
  97 ipsec_getassocbyconn(isaf_t *bucket, ip_xmit_attr_t *ixa, uint32_t *src,
  98     uint32_t *dst, sa_family_t af, uint8_t protocol, ts_label_t *tsl)
  99 {
 100         ipsa_t *retval, *candidate;
 101         ipsec_action_t *candact;
 102         boolean_t need_unique;
 103         boolean_t tunnel_mode = (ixa->ixa_flags & IXAF_IPSEC_TUNNEL);
 104         uint64_t unique_id;
 105         uint32_t old_flags, excludeflags;
 106         ipsec_policy_t *pp = ixa->ixa_ipsec_policy;
 107         ipsec_action_t *actlist = ixa->ixa_ipsec_action;
 108         ipsec_action_t *act;
 109         ipsec_latch_t *ipl = ixa->ixa_ipsec_latch;
 110         ipsa_ref_t *ipr = NULL;
 111         sa_family_t inaf = ixa->ixa_ipsec_inaf;
 112         uint32_t *insrc = ixa->ixa_ipsec_insrc;
 113         uint32_t *indst = ixa->ixa_ipsec_indst;
 114         uint8_t insrcpfx = ixa->ixa_ipsec_insrcpfx;
 115         uint8_t indstpfx = ixa->ixa_ipsec_indstpfx;
 116 
 117         ASSERT(MUTEX_HELD(&bucket->isaf_lock));
 118 
 119         /*
 120          * Caller must set ip_xmit_attr_t structure such that we know
 121          * whether this is tunnel mode or transport mode based on
 122          * IXAF_IPSEC_TUNNEL.  If this flag is set, we assume that
 123          * there are valid inner src and destination addresses to compare.
 124          */
 125 
 126         /*
 127          * Fast path: do we have a latch structure, is it for this bucket,
 128          * and does the generation number match?  If so, refhold and return.
 129          */
 130 
 131         if (ipl != NULL) {
 132                 ASSERT((protocol == IPPROTO_AH) || (protocol == IPPROTO_ESP));
 133                 ipr = &ixa->ixa_ipsec_ref[protocol - IPPROTO_ESP];
 134 
 135                 retval = ipr->ipsr_sa;
 136 
 137                 /*
 138                  * NOTE: The isaf_gen check (incremented upon
 139                  * sadb_unlinkassoc()) protects against retval being a freed
 140                  * SA.  (We're exploiting short-circuit evaluation.)
 141                  */
 142                 if ((bucket == ipr->ipsr_bucket) &&
 143                     (bucket->isaf_gen == ipr->ipsr_gen) &&
 144                     (retval->ipsa_state != IPSA_STATE_DEAD) &&
 145                     !(retval->ipsa_flags & IPSA_F_CINVALID)) {
 146                         IPSA_REFHOLD(retval);
 147                         return (retval);
 148                 }
 149         }
 150 
 151         ASSERT((pp != NULL) || (actlist != NULL));
 152         if (actlist == NULL)
 153                 actlist = pp->ipsp_act;
 154         ASSERT(actlist != NULL);
 155 
 156         need_unique = actlist->ipa_want_unique;
 157         unique_id = SA_FORM_UNIQUE_ID(ixa);
 158 
 159         /*
 160          * Precompute mask for SA flags comparison: If we need a
 161          * unique SA and an SA has already been used, or if the SA has
 162          * a unique value which doesn't match, we aren't interested in
 163          * the SA..
 164          */
 165 
 166         excludeflags = IPSA_F_UNIQUE;
 167         if (need_unique)
 168                 excludeflags |= IPSA_F_USED;
 169 
 170         /*
 171          * Walk the hash bucket, matching on:
 172          *
 173          * - unique_id
 174          * - destination
 175          * - source
 176          * - algorithms
 177          * - inner dst
 178          * - inner src
 179          * - <MORE TBD>
 180          *
 181          * Make sure that wildcard sources are inserted at the end of the hash
 182          * bucket.
 183          *
 184          * DEFINITIONS: A _shared_ SA is one with unique_id == 0 and USED.
 185          *              An _unused_ SA is one with unique_id == 0 and not USED.
 186          *              A _unique_ SA is one with unique_id != 0 and USED.
 187          *              An SA with unique_id != 0 and not USED never happens.
 188          */
 189 
 190         candidate = NULL;
 191 
 192         for (retval = bucket->isaf_ipsa; retval != NULL;
 193             retval = retval->ipsa_next) {
 194                 ASSERT((candidate == NULL) ||
 195                     MUTEX_HELD(&candidate->ipsa_lock));
 196 
 197                 /*
 198                  * Q: Should I lock this SA?
 199                  * A: For now, yes.  I change and use too many fields in here
 200                  *    (e.g. unique_id) that I may be racing with other threads.
 201                  *    Also, the refcnt needs to be bumped up.
 202                  */
 203 
 204                 mutex_enter(&retval->ipsa_lock);
 205 
 206                 /* My apologies for the use of goto instead of continue. */
 207 
 208                 /* Outer destination address */
 209                 if (!IPSA_ARE_ADDR_EQUAL(dst, retval->ipsa_dstaddr, af))
 210                         goto next_ipsa; /* Destination mismatch. */
 211 
 212                 /* Outer source address */
 213                 if (!IPSA_ARE_ADDR_EQUAL(src, retval->ipsa_srcaddr, af) &&
 214                     !IPSA_IS_ADDR_UNSPEC(retval->ipsa_srcaddr, af))
 215                         goto next_ipsa; /* Specific source and not matched. */
 216 
 217                 if (tunnel_mode) {
 218                         /* Check tunnel mode */
 219                         if (!(retval->ipsa_flags & IPSA_F_TUNNEL))
 220                                 goto next_ipsa; /* Not tunnel mode SA */
 221 
 222                         /* Inner destination address */
 223                         if (!IPSA_IS_ADDR_UNSPEC(retval->ipsa_innerdst, inaf)) {
 224                                 if (!ip_addr_match((uint8_t *)indst,
 225                                     min(indstpfx, retval->ipsa_innerdstpfx),
 226                                     (in6_addr_t *)retval->ipsa_innerdst))
 227                                         goto next_ipsa; /* not matched. */
 228                         }
 229 
 230                         /* Inner source address */
 231                         if (!IPSA_IS_ADDR_UNSPEC(retval->ipsa_innersrc, inaf)) {
 232                                 if (!ip_addr_match((uint8_t *)insrc,
 233                                     min(insrcpfx, retval->ipsa_innersrcpfx),
 234                                     (in6_addr_t *)retval->ipsa_innersrc))
 235                                         goto next_ipsa; /* not matched. */
 236                         }
 237                 } else {
 238                         /* Check transport mode */
 239                         if (retval->ipsa_flags & IPSA_F_TUNNEL)
 240                                 goto next_ipsa; /* Not transport mode SA */
 241 
 242                         /*
 243                          * TODO - If we ever do RFC 3884's dream of transport-
 244                          * mode SAs with inner IP address selectors, we need
 245                          * to put some code here.
 246                          */
 247                 }
 248 
 249                 /*
 250                  * XXX should be able to use cached/latched action
 251                  * to dodge this loop
 252                  */
 253                 for (act = actlist; act != NULL; act = act->ipa_next) {
 254                         ipsec_act_t *ap = &act->ipa_act;
 255                         if (ap->ipa_type != IPSEC_POLICY_APPLY)
 256                                 continue;
 257 
 258                         /*
 259                          * XXX ugly.  should be better way to do this test
 260                          */
 261                         if (protocol == IPPROTO_AH) {
 262                                 if (!(ap->ipa_apply.ipp_use_ah))
 263                                         continue;
 264                                 if (ap->ipa_apply.ipp_auth_alg !=
 265                                     retval->ipsa_auth_alg)
 266                                         continue;
 267                                 if (ap->ipa_apply.ipp_ah_minbits >
 268                                     retval->ipsa_authkeybits)
 269                                         continue;
 270                         } else {
 271                                 if (!(ap->ipa_apply.ipp_use_esp))
 272                                         continue;
 273 
 274                                 if ((ap->ipa_apply.ipp_encr_alg !=
 275                                     retval->ipsa_encr_alg))
 276                                         continue;
 277 
 278                                 if (ap->ipa_apply.ipp_espe_minbits >
 279                                     retval->ipsa_encrkeybits)
 280                                         continue;
 281 
 282                                 if (ap->ipa_apply.ipp_esp_auth_alg != 0) {
 283                                         if (ap->ipa_apply.ipp_esp_auth_alg !=
 284                                             retval->ipsa_auth_alg)
 285                                                 continue;
 286                                         if (ap->ipa_apply.ipp_espa_minbits >
 287                                             retval->ipsa_authkeybits)
 288                                                 continue;
 289                                 }
 290                         }
 291 
 292                         /*
 293                          * Check key mgmt proto, cookie
 294                          */
 295                         if ((ap->ipa_apply.ipp_km_proto != 0) &&
 296                             (retval->ipsa_kmp != 0) &&
 297                             (ap->ipa_apply.ipp_km_proto != retval->ipsa_kmp))
 298                                 continue;
 299 
 300                         if ((ap->ipa_apply.ipp_km_cookie != 0) &&
 301                             (retval->ipsa_kmc != 0) &&
 302                             (ap->ipa_apply.ipp_km_cookie != retval->ipsa_kmc))
 303                                 continue;
 304 
 305                         break;
 306                 }
 307                 if (act == NULL)
 308                         goto next_ipsa; /* nothing matched */
 309 
 310                 /*
 311                  * Do identities match?
 312                  */
 313                 if (ipl && ipl->ipl_ids_latched &&
 314                     !ipsec_match_outbound_ids(ipl, retval))
 315                         goto next_ipsa;
 316 
 317                 /*
 318                  * Do labels match?
 319                  */
 320                 if (!ipsec_label_match(tsl, retval->ipsa_tsl))
 321                         goto next_ipsa;
 322 
 323                 /*
 324                  * At this point, we know that we have at least a match on:
 325                  *
 326                  * - dest
 327                  * - source (if source is specified, i.e. non-zeroes)
 328                  * - inner dest (if specified)
 329                  * - inner source (if specified)
 330                  * - auth alg (if auth alg is specified, i.e. non-zero)
 331                  * - encrypt. alg (if encrypt. alg is specified, i.e. non-zero)
 332                  * and we know that the SA keylengths are appropriate.
 333                  *
 334                  * (Keep in mind known-src SAs are hit before zero-src SAs,
 335                  * thanks to sadb_insertassoc().)
 336                  * If we need a unique asssociation, optimally we have
 337                  * ipsa_unique_id == unique_id, otherwise NOT USED
 338                  * is held in reserve (stored in candidate).
 339                  *
 340                  * For those stored in candidate, take best-match (i.e. given
 341                  * a choice, candidate should have non-zero ipsa_src).
 342                  */
 343 
 344                 /*
 345                  * If SA has a unique value which matches, we're all set...
 346                  * "key management knows best"
 347                  */
 348                 if ((retval->ipsa_flags & IPSA_F_UNIQUE) &&
 349                     ((unique_id & retval->ipsa_unique_mask) ==
 350                     retval->ipsa_unique_id))
 351                         break;
 352 
 353                 /*
 354                  * If we need a unique SA and this SA has already been used,
 355                  * or if the SA has a unique value which doesn't match,
 356                  * this isn't for us.
 357                  */
 358 
 359                 if (retval->ipsa_flags & excludeflags)
 360                         goto next_ipsa;
 361 
 362 
 363                 /*
 364                  * I found a candidate..
 365                  */
 366                 if (candidate == NULL) {
 367                         /*
 368                          * and didn't already have one..
 369                          */
 370                         candidate = retval;
 371                         candact = act;
 372                         continue;
 373                 } else {
 374                         /*
 375                          * If candidate's source address is zero and
 376                          * the current match (i.e. retval) address is
 377                          * not zero, we have a better candidate..
 378                          */
 379                         if (IPSA_IS_ADDR_UNSPEC(candidate->ipsa_srcaddr, af) &&
 380                             !IPSA_IS_ADDR_UNSPEC(retval->ipsa_srcaddr, af)) {
 381                                 mutex_exit(&candidate->ipsa_lock);
 382                                 candidate = retval;
 383                                 candact = act;
 384                                 continue;
 385                         }
 386                 }
 387 next_ipsa:
 388                 mutex_exit(&retval->ipsa_lock);
 389         }
 390         ASSERT((retval == NULL) || MUTEX_HELD(&retval->ipsa_lock));
 391         ASSERT((candidate == NULL) || MUTEX_HELD(&candidate->ipsa_lock));
 392         ASSERT((retval == NULL) || (act != NULL));
 393         ASSERT((candidate == NULL) || (candact != NULL));
 394 
 395         /* Let caller react to a lookup failure when it gets NULL. */
 396         if (retval == NULL && candidate == NULL)
 397                 return (NULL);
 398 
 399         if (retval == NULL) {
 400                 ASSERT(MUTEX_HELD(&candidate->ipsa_lock));
 401                 retval = candidate;
 402                 act = candact;
 403         } else if (candidate != NULL) {
 404                 mutex_exit(&candidate->ipsa_lock);
 405         }
 406         ASSERT(MUTEX_HELD(&retval->ipsa_lock));
 407         ASSERT(act != NULL);
 408 
 409         /*
 410          * Even though I hold the mutex, since the reference counter is an
 411          * atomic operation, I really have to use the IPSA_REFHOLD macro.
 412          */
 413         IPSA_REFHOLD(retval);
 414 
 415         /*
 416          * This association is no longer unused.
 417          */
 418         old_flags = retval->ipsa_flags;
 419         retval->ipsa_flags |= IPSA_F_USED;
 420 
 421         /*
 422          * Cache a reference to this SA for the fast path.
 423          */
 424         if (ipr != NULL) {
 425                 ipr->ipsr_bucket = bucket;
 426                 ipr->ipsr_gen = bucket->isaf_gen;
 427                 ipr->ipsr_sa = retval;
 428                 /* I'm now caching, so the cache-invalid flag goes away! */
 429                 retval->ipsa_flags &= ~IPSA_F_CINVALID;
 430         }
 431         /*
 432          * Latch various things while we're here..
 433          */
 434         if (ipl != NULL) {
 435                 if (!ipl->ipl_ids_latched) {
 436                         ipsec_latch_ids(ipl,
 437                             retval->ipsa_src_cid, retval->ipsa_dst_cid);
 438                 }
 439                 if (ixa->ixa_ipsec_action == NULL) {
 440                         IPACT_REFHOLD(act);
 441                         ixa->ixa_ipsec_action = act;
 442                 }
 443         }
 444 
 445         /*
 446          * Set the uniqueness only first time.
 447          */
 448         if (need_unique && !(old_flags & IPSA_F_USED)) {
 449                 if (retval->ipsa_unique_id == 0) {
 450                         ASSERT((retval->ipsa_flags & IPSA_F_UNIQUE) == 0);
 451                         /*
 452                          * From now on, only this src, dst[ports, addr],
 453                          * proto, should use it.
 454                          */
 455                         retval->ipsa_flags |= IPSA_F_UNIQUE;
 456                         retval->ipsa_unique_id = unique_id;
 457                         retval->ipsa_unique_mask = SA_UNIQUE_MASK(
 458                             ixa->ixa_ipsec_src_port, ixa->ixa_ipsec_dst_port,
 459                             protocol, 0);
 460                 }
 461 
 462                 /*
 463                  * Set the source address and adjust the hash
 464                  * buckets only if src_addr is zero.
 465                  */
 466                 if (IPSA_IS_ADDR_UNSPEC(retval->ipsa_srcaddr, af)) {
 467                         /*
 468                          * sadb_unlinkassoc() will decrement the refcnt.  Bump
 469                          * up when we have the lock so that we don't have to
 470                          * acquire locks when we come back from
 471                          * sadb_insertassoc().
 472                          *
 473                          * We don't need to bump the bucket's gen since
 474                          * we aren't moving to a new bucket.
 475                          */
 476                         IPSA_REFHOLD(retval);
 477                         IPSA_COPY_ADDR(retval->ipsa_srcaddr, src, af);
 478                         mutex_exit(&retval->ipsa_lock);
 479                         sadb_unlinkassoc(retval);
 480                         /*
 481                          * Since the bucket lock is held, we know
 482                          * sadb_insertassoc() will succeed.
 483                          */
 484 #ifdef DEBUG
 485                         if (sadb_insertassoc(retval, bucket) != 0) {
 486                                 cmn_err(CE_PANIC,
 487                                     "sadb_insertassoc() failed in "
 488                                     "ipsec_getassocbyconn().\n");
 489                         }
 490 #else   /* non-DEBUG */
 491                         (void) sadb_insertassoc(retval, bucket);
 492 #endif  /* DEBUG */
 493                         return (retval);
 494                 }
 495         }
 496         mutex_exit(&retval->ipsa_lock);
 497 
 498         return (retval);
 499 }
 500 
 501 /*
 502  * Look up a security association based on the security parameters index (SPI)
 503  * and address(es).  This is used for inbound packets and general SA lookups
 504  * (even in outbound SA tables).  The source address may be ignored.  Return
 505  * NULL if no association is available.  If an SA is found, return it, with
 506  * its refcnt incremented.  The caller must REFRELE after using the SA.
 507  * The hash bucket must be locked down before calling.
 508  */
 509 ipsa_t *
 510 ipsec_getassocbyspi(isaf_t *bucket, uint32_t spi, uint32_t *src, uint32_t *dst,
 511     sa_family_t af)
 512 {
 513         ipsa_t *retval;
 514 
 515         ASSERT(MUTEX_HELD(&bucket->isaf_lock));
 516 
 517         /*
 518          * Walk the hash bucket, matching exactly on SPI, then destination,
 519          * then source.
 520          *
 521          * Per-SA locking doesn't need to happen, because I'm only matching
 522          * on addresses.  Addresses are only changed during insertion/deletion
 523          * from the hash bucket.  Since the hash bucket lock is held, we don't
 524          * need to worry about addresses changing.
 525          */
 526 
 527         for (retval = bucket->isaf_ipsa; retval != NULL;
 528             retval = retval->ipsa_next) {
 529                 if (retval->ipsa_spi != spi)
 530                         continue;
 531                 if (!IPSA_ARE_ADDR_EQUAL(dst, retval->ipsa_dstaddr, af))
 532                         continue;
 533 
 534                 /*
 535                  * Assume that wildcard source addresses are inserted at the
 536                  * end of the hash bucket.  (See sadb_insertassoc().)
 537                  * The following check for source addresses is a weak form
 538                  * of access control/source identity verification.  If an
 539                  * SA has a source address, I only match an all-zeroes
 540                  * source address, or that particular one.  If the SA has
 541                  * an all-zeroes source, then I match regardless.
 542                  *
 543                  * There is a weakness here in that a packet with all-zeroes
 544                  * for an address will match regardless of the source address
 545                  * stored in the packet.
 546                  *
 547                  * Note that port-level packet selectors, if present,
 548                  * are checked in ipsec_check_ipsecin_unique().
 549                  */
 550                 if (IPSA_ARE_ADDR_EQUAL(src, retval->ipsa_srcaddr, af) ||
 551                     IPSA_IS_ADDR_UNSPEC(retval->ipsa_srcaddr, af) ||
 552                     IPSA_IS_ADDR_UNSPEC(src, af))
 553                         break;
 554         }
 555 
 556         if (retval != NULL) {
 557                 /*
 558                  * Just refhold the return value.  The caller will then
 559                  * make the appropriate calls to set the USED flag.
 560                  */
 561                 IPSA_REFHOLD(retval);
 562         }
 563 
 564         return (retval);
 565 }
 566 
 567 boolean_t
 568 ipsec_outbound_sa(mblk_t *data_mp, ip_xmit_attr_t *ixa, uint_t proto)
 569 {
 570         ipaddr_t dst;
 571         uint32_t *dst_ptr, *src_ptr;
 572         isaf_t *bucket;
 573         ipsa_t *assoc;
 574         ip_pkt_t ipp;
 575         in6_addr_t dst6;
 576         ipsa_t **sa;
 577         sadbp_t *sadbp;
 578         sadb_t *sp;
 579         sa_family_t af;
 580         ip_stack_t      *ipst = ixa->ixa_ipst;
 581         netstack_t      *ns = ipst->ips_netstack;
 582 
 583         ASSERT(ixa->ixa_flags & IXAF_IPSEC_SECURE);
 584 
 585         if (proto == IPPROTO_ESP) {
 586                 ipsecesp_stack_t        *espstack;
 587 
 588                 espstack = ns->netstack_ipsecesp;
 589                 sa = &ixa->ixa_ipsec_esp_sa;
 590                 sadbp = &espstack->esp_sadb;
 591         } else {
 592                 ipsecah_stack_t *ahstack;
 593 
 594                 ASSERT(proto == IPPROTO_AH);
 595                 ahstack = ns->netstack_ipsecah;
 596                 sa = &ixa->ixa_ipsec_ah_sa;
 597                 sadbp = &ahstack->ah_sadb;
 598         }
 599 
 600         ASSERT(*sa == NULL);
 601 
 602         if (ixa->ixa_flags & IXAF_IS_IPV4) {
 603                 ipha_t *ipha = (ipha_t *)data_mp->b_rptr;
 604 
 605                 ASSERT(IPH_HDR_VERSION(ipha) == IPV4_VERSION);
 606                 dst = ip_get_dst(ipha);
 607                 sp = &sadbp->s_v4;
 608                 af = AF_INET;
 609 
 610                 /*
 611                  * NOTE:Getting the outbound association is considerably
 612                  *      painful.  ipsec_getassocbyconn() will require more
 613                  *      parameters as policy implementations mature.
 614                  */
 615                 bucket = OUTBOUND_BUCKET_V4(sp, dst);
 616                 src_ptr = (uint32_t *)&ipha->ipha_src;
 617                 dst_ptr = (uint32_t *)&dst;
 618         } else {
 619                 ip6_t *ip6h = (ip6_t *)data_mp->b_rptr;
 620 
 621                 ASSERT(IPH_HDR_VERSION(ip6h) == IPV6_VERSION);
 622                 dst6 = ip_get_dst_v6(ip6h, data_mp, NULL);
 623                 af = AF_INET6;
 624 
 625                 bzero(&ipp, sizeof (ipp));
 626                 sp = &sadbp->s_v6;
 627 
 628                 /* Same NOTE: applies here! */
 629                 bucket = OUTBOUND_BUCKET_V6(sp, dst6);
 630                 src_ptr = (uint32_t *)&ip6h->ip6_src;
 631                 dst_ptr = (uint32_t *)&dst6;
 632         }
 633 
 634         mutex_enter(&bucket->isaf_lock);
 635         assoc = ipsec_getassocbyconn(bucket, ixa, src_ptr, dst_ptr, af,
 636             proto, ixa->ixa_tsl);
 637         mutex_exit(&bucket->isaf_lock);
 638 
 639         if (assoc == NULL)
 640                 return (B_FALSE);
 641 
 642         if (assoc->ipsa_state == IPSA_STATE_DEAD) {
 643                 IPSA_REFRELE(assoc);
 644                 return (B_FALSE);
 645         }
 646 
 647         ASSERT(assoc->ipsa_state != IPSA_STATE_LARVAL);
 648 
 649         *sa = assoc;
 650         return (B_TRUE);
 651 }
 652 
 653 /*
 654  * Inbound IPsec SA selection.
 655  * Can return a pulled up mblk.
 656  * When it returns non-NULL ahp is updated
 657  */
 658 mblk_t *
 659 ipsec_inbound_ah_sa(mblk_t *mp, ip_recv_attr_t *ira, ah_t **ahp)
 660 {
 661         ipha_t *ipha;
 662         ipsa_t  *assoc;
 663         ah_t *ah;
 664         isaf_t *hptr;
 665         boolean_t isv6;
 666         ip6_t *ip6h;
 667         int ah_offset;
 668         uint32_t *src_ptr, *dst_ptr;
 669         int pullup_len;
 670         sadb_t *sp;
 671         sa_family_t af;
 672         netstack_t      *ns = ira->ira_ill->ill_ipst->ips_netstack;
 673         ipsec_stack_t   *ipss = ns->netstack_ipsec;
 674         ipsecah_stack_t *ahstack = ns->netstack_ipsecah;
 675 
 676         IP_AH_BUMP_STAT(ipss, in_requests);
 677 
 678         isv6 = !(ira->ira_flags & IRAF_IS_IPV4);
 679         if (isv6) {
 680                 ip6h = (ip6_t *)mp->b_rptr;
 681                 ah_offset = ipsec_ah_get_hdr_size_v6(mp, B_TRUE);
 682         } else {
 683                 ipha = (ipha_t *)mp->b_rptr;
 684                 ASSERT(ipha->ipha_protocol == IPPROTO_AH);
 685                 ah_offset = ipha->ipha_version_and_hdr_length -
 686                     (uint8_t)((IP_VERSION << 4));
 687                 ah_offset <<= 2;
 688         }
 689 
 690         /*
 691          * We assume that the IP header is pulled up until
 692          * the options. We need to see whether we have the
 693          * AH header in the same mblk or not.
 694          */
 695         pullup_len = ah_offset + sizeof (ah_t);
 696         if (mp->b_rptr + pullup_len > mp->b_wptr) {
 697                 if (!pullupmsg(mp, pullup_len)) {
 698                         ipsec_rl_strlog(ns, ip_mod_info.mi_idnum, 0, 0,
 699                             SL_WARN | SL_ERROR,
 700                             "ipsec_inbound_ah_sa: Small AH header\n");
 701                         IP_AH_BUMP_STAT(ipss, in_discards);
 702                         ip_drop_packet(mp, B_TRUE, ira->ira_ill,
 703                             DROPPER(ipss, ipds_ah_bad_length),
 704                             &ipss->ipsec_dropper);
 705                         return (NULL);
 706                 }
 707                 if (isv6)
 708                         ip6h = (ip6_t *)mp->b_rptr;
 709                 else
 710                         ipha = (ipha_t *)mp->b_rptr;
 711         }
 712 
 713         ah = (ah_t *)(mp->b_rptr + ah_offset);
 714 
 715         if (isv6) {
 716                 src_ptr = (uint32_t *)&ip6h->ip6_src;
 717                 dst_ptr = (uint32_t *)&ip6h->ip6_dst;
 718                 sp = &ahstack->ah_sadb.s_v6;
 719                 af = AF_INET6;
 720         } else {
 721                 src_ptr = (uint32_t *)&ipha->ipha_src;
 722                 dst_ptr = (uint32_t *)&ipha->ipha_dst;
 723                 sp = &ahstack->ah_sadb.s_v4;
 724                 af = AF_INET;
 725         }
 726 
 727         hptr = INBOUND_BUCKET(sp, ah->ah_spi);
 728         mutex_enter(&hptr->isaf_lock);
 729         assoc = ipsec_getassocbyspi(hptr, ah->ah_spi, src_ptr, dst_ptr, af);
 730         mutex_exit(&hptr->isaf_lock);
 731 
 732         if (assoc == NULL || assoc->ipsa_state == IPSA_STATE_DEAD ||
 733             assoc->ipsa_state == IPSA_STATE_ACTIVE_ELSEWHERE) {
 734                 IP_AH_BUMP_STAT(ipss, lookup_failure);
 735                 IP_AH_BUMP_STAT(ipss, in_discards);
 736                 ipsecah_in_assocfailure(mp, 0,
 737                     SL_ERROR | SL_CONSOLE | SL_WARN,
 738                     "ipsec_inbound_ah_sa: No association found for "
 739                     "spi 0x%x, dst addr %s\n",
 740                     ah->ah_spi, dst_ptr, af, ira);
 741                 if (assoc != NULL) {
 742                         IPSA_REFRELE(assoc);
 743                 }
 744                 return (NULL);
 745         }
 746 
 747         if (assoc->ipsa_state == IPSA_STATE_LARVAL) {
 748                 /* Not fully baked; swap the packet under a rock until then */
 749 
 750                 mp = sadb_set_lpkt(assoc, mp, ira);
 751                 if (mp == NULL) {
 752                         IPSA_REFRELE(assoc);
 753                         return (NULL);
 754                 }
 755                 /* Looks like the SA is no longer LARVAL. */
 756         }
 757 
 758         /* Are the IPsec fields initialized at all? */
 759         if (!(ira->ira_flags & IRAF_IPSEC_SECURE)) {
 760                 ira->ira_ipsec_action = NULL;
 761                 ira->ira_ipsec_ah_sa = NULL;
 762                 ira->ira_ipsec_esp_sa = NULL;
 763         }
 764 
 765         /*
 766          * Save a reference to the association so that it can
 767          * be retrieved after execution. We free any AH SA reference
 768          * already there (innermost SA "wins". The reference to
 769          * the SA will also be used later when doing the policy checks.
 770          */
 771         if (ira->ira_ipsec_ah_sa != NULL) {
 772                 IPSA_REFRELE(ira->ira_ipsec_ah_sa);
 773         }
 774         ira->ira_flags |= IRAF_IPSEC_SECURE;
 775         ira->ira_ipsec_ah_sa = assoc;
 776 
 777         *ahp = ah;
 778         return (mp);
 779 }
 780 
 781 /*
 782  * Can return a pulled up mblk.
 783  * When it returns non-NULL esphp is updated
 784  */
 785 mblk_t *
 786 ipsec_inbound_esp_sa(mblk_t *data_mp, ip_recv_attr_t *ira, esph_t **esphp)
 787 {
 788         mblk_t *placeholder;
 789         uint32_t *src_ptr, *dst_ptr;
 790         ipha_t *ipha;
 791         ip6_t *ip6h;
 792         esph_t *esph;
 793         ipsa_t *ipsa;
 794         isaf_t *bucket;
 795         uint_t preamble;
 796         sa_family_t af;
 797         boolean_t isv6;
 798         sadb_t *sp;
 799         netstack_t      *ns = ira->ira_ill->ill_ipst->ips_netstack;
 800         ipsec_stack_t   *ipss = ns->netstack_ipsec;
 801         ipsecesp_stack_t *espstack = ns->netstack_ipsecesp;
 802 
 803         IP_ESP_BUMP_STAT(ipss, in_requests);
 804 
 805         isv6 = !(ira->ira_flags & IRAF_IS_IPV4);
 806         if (isv6) {
 807                 ip6h = (ip6_t *)data_mp->b_rptr;
 808         } else {
 809                 ipha = (ipha_t *)data_mp->b_rptr;
 810         }
 811 
 812         /*
 813          * Put all data into one mblk if it's not there already.
 814          * XXX This is probably bad long-term.  Figure out better ways of doing
 815          * this.  Much of the inbound path depends on all of the data being
 816          * in one mblk.
 817          *
 818          * XXX Jumbogram issues will have to be dealt with here.
 819          * If the plen is 0, we'll have to scan for a HBH header with the
 820          * actual packet length.
 821          */
 822         if (data_mp->b_datap->db_ref > 1 ||
 823             (data_mp->b_wptr - data_mp->b_rptr) < ira->ira_pktlen) {
 824                 placeholder = msgpullup(data_mp, -1);
 825                 if (placeholder == NULL) {
 826                         IP_ESP_BUMP_STAT(ipss, in_discards);
 827                         ip_drop_packet(data_mp, B_TRUE, ira->ira_ill,
 828                             DROPPER(ipss, ipds_esp_nomem),
 829                             &ipss->ipsec_dropper);
 830                         return (NULL);
 831                 } else {
 832                         /* Reset packet with new pulled up mblk. */
 833                         freemsg(data_mp);
 834                         data_mp = placeholder;
 835                 }
 836         }
 837 
 838         /*
 839          * Find the ESP header, point the address pointers at the appropriate
 840          * IPv4/IPv6 places.
 841          */
 842         if (isv6) {
 843                 ip6h = (ip6_t *)data_mp->b_rptr;
 844                 src_ptr = (uint32_t *)&ip6h->ip6_src;
 845                 dst_ptr = (uint32_t *)&ip6h->ip6_dst;
 846                 if (ip6h->ip6_nxt != IPPROTO_ESP) {
 847                         /* There are options that need to be processed. */
 848                         preamble = ip_hdr_length_v6(data_mp, ip6h);
 849                 } else {
 850                         preamble = sizeof (ip6_t);
 851                 }
 852 
 853                 sp = &espstack->esp_sadb.s_v6;
 854                 af = AF_INET6;
 855         } else {
 856                 ipha = (ipha_t *)data_mp->b_rptr;
 857                 src_ptr = (uint32_t *)&ipha->ipha_src;
 858                 dst_ptr = (uint32_t *)&ipha->ipha_dst;
 859                 preamble = IPH_HDR_LENGTH(ipha);
 860 
 861                 sp = &espstack->esp_sadb.s_v4;
 862                 af = AF_INET;
 863         }
 864 
 865         esph = (esph_t *)(data_mp->b_rptr + preamble);
 866 
 867         /* Since hash is common on inbound (SPI value), hash here. */
 868         bucket = INBOUND_BUCKET(sp, esph->esph_spi);
 869         mutex_enter(&bucket->isaf_lock);
 870         ipsa = ipsec_getassocbyspi(bucket, esph->esph_spi, src_ptr, dst_ptr,
 871             af);
 872         mutex_exit(&bucket->isaf_lock);
 873 
 874         if (ipsa == NULL || ipsa->ipsa_state == IPSA_STATE_DEAD ||
 875             ipsa->ipsa_state == IPSA_STATE_ACTIVE_ELSEWHERE) {
 876                 /*  This is a loggable error!  AUDIT ME! */
 877                 IP_ESP_BUMP_STAT(ipss, lookup_failure);
 878                 IP_ESP_BUMP_STAT(ipss, in_discards);
 879                 ipsecesp_in_assocfailure(data_mp, 0,
 880                     SL_ERROR | SL_CONSOLE | SL_WARN,
 881                     "ipsec_inbound_esp_sa: No association found for "
 882                     "spi 0x%x, dst addr %s\n",
 883                     esph->esph_spi, dst_ptr, af, ira);
 884                 if (ipsa != NULL) {
 885                         IPSA_REFRELE(ipsa);
 886                 }
 887                 return (NULL);
 888         }
 889 
 890         if (ipsa->ipsa_state == IPSA_STATE_LARVAL) {
 891                 /* Not fully baked; swap the packet under a rock until then */
 892 
 893                 data_mp = sadb_set_lpkt(ipsa, data_mp, ira);
 894                 if (data_mp == NULL) {
 895                         IPSA_REFRELE(ipsa);
 896                         return (NULL);
 897                 }
 898                 /* Looks like the SA is no longer LARVAL. */
 899         }
 900 
 901         /* Are the IPsec fields initialized at all? */
 902         if (!(ira->ira_flags & IRAF_IPSEC_SECURE)) {
 903                 ira->ira_ipsec_action = NULL;
 904                 ira->ira_ipsec_ah_sa = NULL;
 905                 ira->ira_ipsec_esp_sa = NULL;
 906         }
 907 
 908         /*
 909          * Save a reference to the association so that it can
 910          * be retrieved after execution. We free any AH SA reference
 911          * already there (innermost SA "wins". The reference to
 912          * the SA will also be used later when doing the policy checks.
 913          */
 914         if (ira->ira_ipsec_esp_sa != NULL) {
 915                 IPSA_REFRELE(ira->ira_ipsec_esp_sa);
 916         }
 917         ira->ira_flags |= IRAF_IPSEC_SECURE;
 918         ira->ira_ipsec_esp_sa = ipsa;
 919 
 920         *esphp = esph;
 921         return (data_mp);
 922 }