Print this page
C. Fraire's code review fixes
8529 Extended and regular SADB_ACQUIREs should share address extension code
Portions contributed by: Bayard Bell <buffer.g.overflow@gmail.com>


   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  * Copyright (c) 2012 Nexenta Systems, Inc. All rights reserved.

  25  */
  26 
  27 #include <sys/types.h>
  28 #include <sys/stream.h>
  29 #include <sys/stropts.h>
  30 #include <sys/strsubr.h>
  31 #include <sys/errno.h>
  32 #include <sys/ddi.h>
  33 #include <sys/debug.h>
  34 #include <sys/cmn_err.h>
  35 #include <sys/stream.h>
  36 #include <sys/strlog.h>
  37 #include <sys/kmem.h>
  38 #include <sys/sunddi.h>
  39 #include <sys/tihdr.h>
  40 #include <sys/atomic.h>
  41 #include <sys/socket.h>
  42 #include <sys/sysmacros.h>
  43 #include <sys/crypto/common.h>
  44 #include <sys/crypto/api.h>


  57 #include <inet/sadb.h>
  58 #include <inet/ipsec_impl.h>
  59 #include <inet/ipsecah.h>
  60 #include <inet/ipsecesp.h>
  61 #include <sys/random.h>
  62 #include <sys/dlpi.h>
  63 #include <sys/strsun.h>
  64 #include <sys/strsubr.h>
  65 #include <inet/ip_if.h>
  66 #include <inet/ipdrop.h>
  67 #include <inet/ipclassifier.h>
  68 #include <inet/sctp_ip.h>
  69 #include <sys/tsol/tnet.h>
  70 
  71 /*
  72  * This source file contains Security Association Database (SADB) common
  73  * routines.  They are linked in with the AH module.  Since AH has no chance
  74  * of falling under export control, it was safe to link it in there.
  75  */
  76 
  77 static mblk_t *sadb_extended_acquire(ipsec_selector_t *, ipsec_policy_t *,
  78     ipsec_action_t *, boolean_t, uint32_t, uint32_t, sadb_sens_t *,
  79     netstack_t *);
  80 static ipsa_t *sadb_torch_assoc(isaf_t *, ipsa_t *);
  81 static void sadb_destroy_acqlist(iacqf_t **, uint_t, boolean_t,
  82                             netstack_t *);
  83 static void sadb_destroy(sadb_t *, netstack_t *);
  84 static mblk_t *sadb_sa2msg(ipsa_t *, sadb_msg_t *);
  85 static ts_label_t *sadb_label_from_sens(sadb_sens_t *, uint64_t *);
  86 static sadb_sens_t *sadb_make_sens_ext(ts_label_t *tsl, int *len);
  87 
  88 static time_t sadb_add_time(time_t, uint64_t);
  89 static void lifetime_fuzz(ipsa_t *);
  90 static void age_pair_peer_list(templist_t *, sadb_t *, boolean_t);
  91 static int get_ipsa_pair(ipsa_query_t *, ipsap_t *, int *);
  92 static void init_ipsa_pair(ipsap_t *);
  93 static void destroy_ipsa_pair(ipsap_t *);
  94 static int update_pairing(ipsap_t *, ipsa_query_t *, keysock_in_t *, int *);
  95 static void ipsa_set_replay(ipsa_t *ipsa, uint32_t offset);
  96 
  97 /*
  98  * ipsacq_maxpackets is defined here to make it tunable
  99  * from /etc/system.
 100  */
 101 extern uint64_t ipsacq_maxpackets;
 102 
 103 #define SET_EXPIRE(sa, delta, exp) {                            \
 104         if (((sa)->ipsa_ ## delta) != 0) {                           \
 105                 (sa)->ipsa_ ## exp = sadb_add_time((sa)->ipsa_addtime,    \
 106                         (sa)->ipsa_ ## delta);                               \


4827                 fam = walker->ipsacq_addrfam;
4828                 if (IPSA_ARE_ADDR_EQUAL(dst, walker->ipsacq_dstaddr, fam) &&
4829                     IPSA_ARE_ADDR_EQUAL(src, walker->ipsacq_srcaddr, fam) &&
4830                     ip_addr_match((uint8_t *)isrc, walker->ipsacq_innersrcpfx,
4831                     (in6_addr_t *)walker->ipsacq_innersrc) &&
4832                     ip_addr_match((uint8_t *)idst, walker->ipsacq_innerdstpfx,
4833                     (in6_addr_t *)walker->ipsacq_innerdst) &&
4834                     (ap == walker->ipsacq_act) &&
4835                     (pp == walker->ipsacq_policy) &&
4836                     /* XXX do deep compares of ap/pp? */
4837                     (unique_id == walker->ipsacq_unique_id) &&
4838                     (ipsec_label_match(tsl, walker->ipsacq_tsl)))
4839                         break;                  /* everything matched */
4840                 mutex_exit(&walker->ipsacq_lock);
4841         }
4842 
4843         return (walker);
4844 }
4845 
4846 /*





































































































































































































































































































































































































































































































































































4847  * For this mblk, insert a new acquire record.  Assume bucket contains addrs
4848  * of all of the same length.  Give up (and drop) if memory
4849  * cannot be allocated for a new one; otherwise, invoke callback to
4850  * send the acquire up..
4851  *
4852  * In cases where we need both AH and ESP, add the SA to the ESP ACQUIRE
4853  * list.  The ah_add_sa_finish() routines can look at the packet's attached
4854  * attributes and handle this case specially.
4855  */
4856 void
4857 sadb_acquire(mblk_t *datamp, ip_xmit_attr_t *ixa, boolean_t need_ah,
4858     boolean_t need_esp)
4859 {
4860         mblk_t  *asyncmp;
4861         sadbp_t *spp;
4862         sadb_t *sp;
4863         ipsacq_t *newbie;
4864         iacqf_t *bucket;
4865         mblk_t *extended;
4866         ipha_t *ipha = (ipha_t *)datamp->b_rptr;
4867         ip6_t *ip6h = (ip6_t *)datamp->b_rptr;
4868         uint32_t *src, *dst, *isrc, *idst;
4869         ipsec_policy_t *pp = ixa->ixa_ipsec_policy;
4870         ipsec_action_t *ap = ixa->ixa_ipsec_action;
4871         sa_family_t af;
4872         int hashoffset;
4873         uint32_t seq;
4874         uint64_t unique_id = 0;
4875         ipsec_selector_t sel;
4876         boolean_t tunnel_mode = (ixa->ixa_flags & IXAF_IPSEC_TUNNEL) != 0;
4877         ts_label_t      *tsl = NULL;
4878         netstack_t      *ns = ixa->ixa_ipst->ips_netstack;
4879         ipsec_stack_t   *ipss = ns->netstack_ipsec;
4880         sadb_sens_t     *sens = NULL;
4881         int             sens_len;


4882 
4883         ASSERT((pp != NULL) || (ap != NULL));
4884 
4885         ASSERT(need_ah != NULL || need_esp != NULL);
4886 
4887         /* Assign sadb pointers */
4888         if (need_esp) { /* ESP for AH+ESP */
4889                 ipsecesp_stack_t *espstack = ns->netstack_ipsecesp;
4890 

4891                 spp = &espstack->esp_sadb;
4892         } else {
4893                 ipsecah_stack_t *ahstack = ns->netstack_ipsecah;
4894 
4895                 spp = &ahstack->ah_sadb;
4896         }
4897         sp = (ixa->ixa_flags & IXAF_IS_IPV4) ? &spp->s_v4 : &spp->s_v6;
4898 
4899         if (is_system_labeled())
4900                 tsl = ixa->ixa_tsl;


4901 
4902         if (ap == NULL)
4903                 ap = pp->ipsp_act;
4904 
4905         ASSERT(ap != NULL);
4906 
4907         if (ap->ipa_act.ipa_apply.ipp_use_unique || tunnel_mode)
4908                 unique_id = SA_FORM_UNIQUE_ID(ixa);
4909 
4910         /*
4911          * Set up an ACQUIRE record.
4912          *
4913          * Immediately, make sure the ACQUIRE sequence number doesn't slip
4914          * below the lowest point allowed in the kernel.  (In other words,
4915          * make sure the high bit on the sequence number is set.)
4916          */
4917 
4918         seq = keysock_next_seq(ns) | IACQF_LOWEST_SEQ;
4919 
4920         if (IPH_HDR_VERSION(ipha) == IP_VERSION) {
4921                 src = (uint32_t *)&ipha->ipha_src;
4922                 dst = (uint32_t *)&ipha->ipha_dst;
4923                 af = AF_INET;
4924                 hashoffset = OUTBOUND_HASH_V4(sp, ipha->ipha_dst);


5014          * Make the ip_xmit_attr_t into something we can queue.
5015          * If no memory it frees datamp.
5016          */
5017         asyncmp = ip_xmit_attr_to_mblk(ixa);
5018         if (asyncmp != NULL)
5019                 linkb(asyncmp, datamp);
5020 
5021         /* Queue up packet.  Use b_next. */
5022 
5023         if (asyncmp == NULL) {
5024                 /* Statistics for allocation failure */
5025                 if (ixa->ixa_flags & IXAF_IS_IPV4) {
5026                         BUMP_MIB(&ixa->ixa_ipst->ips_ip_mib,
5027                             ipIfStatsOutDiscards);
5028                 } else {
5029                         BUMP_MIB(&ixa->ixa_ipst->ips_ip6_mib,
5030                             ipIfStatsOutDiscards);
5031                 }
5032                 ip_drop_output("No memory for asyncmp", datamp, NULL);
5033                 freemsg(datamp);







5034         } else if (newbie->ipsacq_numpackets == 0) {
5035                 /* First one. */
5036                 newbie->ipsacq_mp = asyncmp;
5037                 newbie->ipsacq_numpackets = 1;
5038                 newbie->ipsacq_expire = gethrestime_sec();
5039                 /*
5040                  * Extended ACQUIRE with both AH+ESP will use ESP's timeout
5041                  * value.
5042                  */
5043                 newbie->ipsacq_expire += *spp->s_acquire_timeout;
5044                 newbie->ipsacq_seq = seq;
5045                 newbie->ipsacq_addrfam = af;
5046 
5047                 newbie->ipsacq_srcport = ixa->ixa_ipsec_src_port;
5048                 newbie->ipsacq_dstport = ixa->ixa_ipsec_dst_port;
5049                 newbie->ipsacq_icmp_type = ixa->ixa_ipsec_icmp_type;
5050                 newbie->ipsacq_icmp_code = ixa->ixa_ipsec_icmp_code;
5051                 if (tunnel_mode) {
5052                         newbie->ipsacq_inneraddrfam = ixa->ixa_ipsec_inaf;
5053                         newbie->ipsacq_proto = ixa->ixa_ipsec_inaf == AF_INET6 ?
5054                             IPPROTO_IPV6 : IPPROTO_ENCAP;
5055                         newbie->ipsacq_innersrcpfx = ixa->ixa_ipsec_insrcpfx;
5056                         newbie->ipsacq_innerdstpfx = ixa->ixa_ipsec_indstpfx;
5057                         IPSA_COPY_ADDR(newbie->ipsacq_innersrc,
5058                             ixa->ixa_ipsec_insrc, ixa->ixa_ipsec_inaf);
5059                         IPSA_COPY_ADDR(newbie->ipsacq_innerdst,
5060                             ixa->ixa_ipsec_indst, ixa->ixa_ipsec_inaf);
5061                 } else {
5062                         newbie->ipsacq_proto = ixa->ixa_ipsec_proto;
5063                 }
5064                 newbie->ipsacq_unique_id = unique_id;
5065 
5066                 if (ixa->ixa_tsl != NULL) {
5067                         label_hold(ixa->ixa_tsl);
5068                         newbie->ipsacq_tsl = ixa->ixa_tsl;
5069                 }
5070         } else {
5071                 /* Scan to the end of the list & insert. */
5072                 mblk_t *lastone = newbie->ipsacq_mp;
5073 
5074                 while (lastone->b_next != NULL)
5075                         lastone = lastone->b_next;
5076                 lastone->b_next = asyncmp;
5077                 if (newbie->ipsacq_numpackets++ == ipsacq_maxpackets) {
5078                         newbie->ipsacq_numpackets = ipsacq_maxpackets;
5079                         lastone = newbie->ipsacq_mp;
5080                         newbie->ipsacq_mp = lastone->b_next;
5081                         lastone->b_next = NULL;
5082 
5083                         /* Freeing the async message */
5084                         lastone = ip_xmit_attr_free_mblk(lastone);
5085                         ip_drop_packet(lastone, B_FALSE, NULL,
5086                             DROPPER(ipss, ipds_sadb_acquire_toofull),
5087                             &ipss->ipsec_sadb_dropper);
5088                 } else {


5093 
5094         /*
5095          * Reset addresses.  Set them to the most recently added mblk chain,
5096          * so that the address pointers in the acquire record will point
5097          * at an mblk still attached to the acquire list.
5098          */
5099 
5100         newbie->ipsacq_srcaddr = src;
5101         newbie->ipsacq_dstaddr = dst;
5102 
5103         /*
5104          * If the acquire record has more than one queued packet, we've
5105          * already sent an ACQUIRE, and don't need to repeat ourself.
5106          */
5107         if (newbie->ipsacq_seq != seq || newbie->ipsacq_numpackets > 1) {
5108                 /* I have an acquire outstanding already! */
5109                 mutex_exit(&newbie->ipsacq_lock);
5110                 return;
5111         }
5112 
5113         if (!keysock_extended_reg(ns))
5114                 goto punt_extended;


5115         /*
5116          * Construct an extended ACQUIRE.  There are logging
5117          * opportunities here in failure cases.




5118          */








5119         bzero(&sel, sizeof (sel));
5120         sel.ips_isv4 = (ixa->ixa_flags & IXAF_IS_IPV4) != 0;
5121         if (tunnel_mode) {
5122                 sel.ips_protocol = (ixa->ixa_ipsec_inaf == AF_INET) ?
5123                     IPPROTO_ENCAP : IPPROTO_IPV6;
5124         } else {
5125                 sel.ips_protocol = ixa->ixa_ipsec_proto;
5126                 sel.ips_local_port = ixa->ixa_ipsec_src_port;
5127                 sel.ips_remote_port = ixa->ixa_ipsec_dst_port;
5128         }
5129         sel.ips_icmp_type = ixa->ixa_ipsec_icmp_type;
5130         sel.ips_icmp_code = ixa->ixa_ipsec_icmp_code;
5131         sel.ips_is_icmp_inv_acq = 0;
5132         if (af == AF_INET) {
5133                 sel.ips_local_addr_v4 = ipha->ipha_src;
5134                 sel.ips_remote_addr_v4 = ipha->ipha_dst;
5135         } else {
5136                 sel.ips_local_addr_v6 = ip6h->ip6_src;
5137                 sel.ips_remote_addr_v6 = ip6h->ip6_dst;
5138         }
5139 
5140         extended = sadb_keysock_out(0);
5141         if (extended == NULL)
5142                 goto punt_extended;
5143 
5144         if (ixa->ixa_tsl != NULL) {
5145                 /*
5146                  * XXX MLS correct condition here?
5147                  * XXX MLS other credential attributes in acquire?
5148                  * XXX malloc failure?  don't fall back to original?











5149                  */
5150                 sens = sadb_make_sens_ext(ixa->ixa_tsl, &sens_len);
5151 
5152                 if (sens == NULL) {
5153                         freeb(extended);
5154                         goto punt_extended;
5155                 }
5156         }
5157 
5158         extended->b_cont = sadb_extended_acquire(&sel, pp, ap, tunnel_mode,
5159             seq, 0, sens, ns);

5160 
5161         if (sens != NULL)
5162                 kmem_free(sens, sens_len);


5163 
5164         if (extended->b_cont == NULL) {
5165                 freeb(extended);
5166                 goto punt_extended;
5167         }




5168 



5169         /*
5170          * Send an ACQUIRE message (and possible an extended ACQUIRE) based on
5171          * this new record.  The send-acquire callback assumes that acqrec is
5172          * already locked.
5173          */
5174         (*spp->s_acqfn)(newbie, extended, ns);




































5175         return;
5176 
5177 punt_extended:
5178         (*spp->s_acqfn)(newbie, NULL, ns);







5179 }
5180 
5181 /*
5182  * Unlink and free an acquire record.
5183  */
5184 void
5185 sadb_destroy_acquire(ipsacq_t *acqrec, netstack_t *ns)
5186 {
5187         mblk_t          *mp;
5188         ipsec_stack_t   *ipss = ns->netstack_ipsec;
5189 
5190         ASSERT(MUTEX_HELD(acqrec->ipsacq_linklock));
5191 
5192         if (acqrec->ipsacq_policy != NULL) {
5193                 IPPOL_REFRELE(acqrec->ipsacq_policy);
5194         }
5195         if (acqrec->ipsacq_act != NULL) {
5196                 IPACT_REFRELE(acqrec->ipsacq_act);
5197         }
5198 


5412         /* LINTED */
5413         ASSERT((_C_LEN & 1) == 0);
5414         ASSERT((senslen & 7) == 0);
5415 
5416         sl = label2bslabel(tsl);
5417 
5418         sens->sadb_sens_exttype = exttype;
5419         sens->sadb_sens_len = SADB_8TO64(senslen);
5420 
5421         sens->sadb_sens_dpd = tsl->tsl_doi;
5422         sens->sadb_sens_sens_level = LCLASS(sl);
5423         sens->sadb_sens_integ_level = 0; /* TBD */
5424         sens->sadb_sens_sens_len = _C_LEN >> 1;
5425         sens->sadb_sens_integ_len = 0; /* TBD */
5426         sens->sadb_x_sens_flags = 0;
5427 
5428         bitmap = (uint8_t *)(sens + 1);
5429         bcopy(&(((_bslabel_impl_t *)sl)->compartments), bitmap, _C_LEN * 4);
5430 }
5431 
5432 static sadb_sens_t *
5433 sadb_make_sens_ext(ts_label_t *tsl, int *len)
5434 {
5435         /* XXX allocation failure? */
5436         int sens_len = sadb_sens_len_from_label(tsl);
5437 
5438         sadb_sens_t *sens = kmem_alloc(sens_len, KM_SLEEP);
5439 
5440         sadb_sens_from_label(sens, SADB_EXT_SENSITIVITY, tsl, sens_len);
5441 
5442         *len = sens_len;
5443 
5444         return (sens);
5445 }
5446 
5447 /*
5448  * Okay, how do we report errors/invalid labels from this?
5449  * With a special designated "not a label" cred_t ?
5450  */
5451 /* ARGSUSED */
5452 ts_label_t *
5453 sadb_label_from_sens(sadb_sens_t *sens, uint64_t *bitmap)
5454 {
5455         int bitmap_len = SADB_64TO8(sens->sadb_sens_sens_len);
5456         bslabel_t sl;
5457         ts_label_t *tsl;
5458 
5459         if (sens->sadb_sens_integ_level != 0)
5460                 return (NULL);
5461         if (sens->sadb_sens_integ_len != 0)
5462                 return (NULL);
5463         if (bitmap_len > _C_LEN * 4)
5464                 return (NULL);
5465 
5466         bsllow(&sl);
5467         LCLASS_SET((_bslabel_impl_t *)&sl, sens->sadb_sens_sens_level);
5468         bcopy(bitmap, &((_bslabel_impl_t *)&sl)->compartments,
5469             bitmap_len);
5470 
5471         tsl = labelalloc(&sl, sens->sadb_sens_dpd, KM_NOSLEEP);
5472         if (tsl == NULL)
5473                 return (NULL);
5474 
5475         if (sens->sadb_x_sens_flags & SADB_X_SENS_UNLABELED)
5476                 tsl->tsl_flags |= TSLF_UNLABELED;
5477         return (tsl);
5478 }
5479 
5480 /* End XXX label-library-leakage */
5481 
5482 /*
5483  * Construct an extended ACQUIRE message based on a selector and the resulting
5484  * IPsec action.
5485  *
5486  * NOTE: This is used by both inverse ACQUIRE and actual ACQUIRE
5487  * generation. As a consequence, expect this function to evolve
5488  * rapidly.
5489  */
5490 static mblk_t *
5491 sadb_extended_acquire(ipsec_selector_t *sel, ipsec_policy_t *pol,
5492     ipsec_action_t *act, boolean_t tunnel_mode, uint32_t seq, uint32_t pid,
5493     sadb_sens_t *sens, netstack_t *ns)
5494 {
5495         mblk_t *mp;
5496         sadb_msg_t *samsg;
5497         uint8_t *start, *cur, *end;
5498         uint32_t *saddrptr, *daddrptr;
5499         sa_family_t af;
5500         sadb_prop_t *eprop;
5501         ipsec_action_t *ap, *an;
5502         ipsec_selkey_t *ipsl;
5503         uint8_t proto, pfxlen;
5504         uint16_t lport, rport;
5505         uint32_t kmp, kmc;
5506 
5507         /*
5508          * Find the action we want sooner rather than later..
5509          */
5510         an = NULL;
5511         if (pol == NULL) {
5512                 ap = act;
5513         } else {
5514                 ap = pol->ipsp_act;
5515 
5516                 if (ap != NULL)
5517                         an = ap->ipa_next;
5518         }
5519 
5520         /*
5521          * Just take a swag for the allocation for now.  We can always
5522          * alter it later.
5523          */
5524 #define SADB_EXTENDED_ACQUIRE_SIZE      4096
5525         mp = allocb(SADB_EXTENDED_ACQUIRE_SIZE, BPRI_HI);
5526         if (mp == NULL)
5527                 return (NULL);
5528 
5529         start = mp->b_rptr;
5530         end = start + SADB_EXTENDED_ACQUIRE_SIZE;
5531 
5532         cur = start;
5533 
5534         samsg = (sadb_msg_t *)cur;
5535         cur += sizeof (*samsg);
5536 
5537         samsg->sadb_msg_version = PF_KEY_V2;
5538         samsg->sadb_msg_type = SADB_ACQUIRE;
5539         samsg->sadb_msg_errno = 0;
5540         samsg->sadb_msg_reserved = 0;
5541         samsg->sadb_msg_satype = 0;
5542         samsg->sadb_msg_seq = seq;
5543         samsg->sadb_msg_pid = pid;
5544 
5545         if (tunnel_mode) {
5546                 /*
5547                  * Form inner address extensions based NOT on the inner
5548                  * selectors (i.e. the packet data), but on the policy's
5549                  * selector key (i.e. the policy's selector information).
5550                  *
5551                  * NOTE:  The position of IPv4 and IPv6 addresses is the
5552                  * same in ipsec_selkey_t (unless the compiler does very
5553                  * strange things with unions, consult your local C language
5554                  * lawyer for details).
5555                  */
5556                 ASSERT(pol != NULL);
5557 
5558                 ipsl = &(pol->ipsp_sel->ipsl_key);
5559                 if (ipsl->ipsl_valid & IPSL_IPV4) {
5560                         af = AF_INET;
5561                         ASSERT(sel->ips_protocol == IPPROTO_ENCAP);
5562                         ASSERT(!(ipsl->ipsl_valid & IPSL_IPV6));
5563                 } else {
5564                         af = AF_INET6;
5565                         ASSERT(sel->ips_protocol == IPPROTO_IPV6);
5566                         ASSERT(ipsl->ipsl_valid & IPSL_IPV6);
5567                 }
5568 
5569                 if (ipsl->ipsl_valid & IPSL_LOCAL_ADDR) {
5570                         saddrptr = (uint32_t *)(&ipsl->ipsl_local);
5571                         pfxlen = ipsl->ipsl_local_pfxlen;
5572                 } else {
5573                         saddrptr = (uint32_t *)(&ipv6_all_zeros);
5574                         pfxlen = 0;
5575                 }
5576                 /* XXX What about ICMP type/code? */
5577                 lport = (ipsl->ipsl_valid & IPSL_LOCAL_PORT) ?
5578                     ipsl->ipsl_lport : 0;
5579                 proto = (ipsl->ipsl_valid & IPSL_PROTOCOL) ?
5580                     ipsl->ipsl_proto : 0;
5581 
5582                 cur = sadb_make_addr_ext(cur, end, SADB_X_EXT_ADDRESS_INNER_SRC,
5583                     af, saddrptr, lport, proto, pfxlen);
5584                 if (cur == NULL) {
5585                         freeb(mp);
5586                         return (NULL);
5587                 }
5588 
5589                 if (ipsl->ipsl_valid & IPSL_REMOTE_ADDR) {
5590                         daddrptr = (uint32_t *)(&ipsl->ipsl_remote);
5591                         pfxlen = ipsl->ipsl_remote_pfxlen;
5592                 } else {
5593                         daddrptr = (uint32_t *)(&ipv6_all_zeros);
5594                         pfxlen = 0;
5595                 }
5596                 /* XXX What about ICMP type/code? */
5597                 rport = (ipsl->ipsl_valid & IPSL_REMOTE_PORT) ?
5598                     ipsl->ipsl_rport : 0;
5599 
5600                 cur = sadb_make_addr_ext(cur, end, SADB_X_EXT_ADDRESS_INNER_DST,
5601                     af, daddrptr, rport, proto, pfxlen);
5602                 if (cur == NULL) {
5603                         freeb(mp);
5604                         return (NULL);
5605                 }
5606                 /*
5607                  * TODO  - if we go to 3408's dream of transport mode IP-in-IP
5608                  * _with_ inner-packet address selectors, we'll need to further
5609                  * distinguish tunnel mode here.  For now, having inner
5610                  * addresses and/or ports is sufficient.
5611                  *
5612                  * Meanwhile, whack proto/ports to reflect IP-in-IP for the
5613                  * outer addresses.
5614                  */
5615                 proto = sel->ips_protocol;   /* Either _ENCAP or _IPV6 */
5616                 lport = rport = 0;
5617         } else if ((ap != NULL) && (!ap->ipa_want_unique)) {
5618                 proto = 0;
5619                 lport = 0;
5620                 rport = 0;
5621                 if (pol != NULL) {
5622                         ipsl = &(pol->ipsp_sel->ipsl_key);
5623                         if (ipsl->ipsl_valid & IPSL_PROTOCOL)
5624                                 proto = ipsl->ipsl_proto;
5625                         if (ipsl->ipsl_valid & IPSL_REMOTE_PORT)
5626                                 rport = ipsl->ipsl_rport;
5627                         if (ipsl->ipsl_valid & IPSL_LOCAL_PORT)
5628                                 lport = ipsl->ipsl_lport;
5629                 }
5630         } else {
5631                 proto = sel->ips_protocol;
5632                 lport = sel->ips_local_port;
5633                 rport = sel->ips_remote_port;
5634         }
5635 
5636         af = sel->ips_isv4 ? AF_INET : AF_INET6;
5637 
5638         /*
5639          * NOTE:  The position of IPv4 and IPv6 addresses is the same in
5640          * ipsec_selector_t.
5641          */
5642         cur = sadb_make_addr_ext(cur, end, SADB_EXT_ADDRESS_SRC, af,
5643             (uint32_t *)(&sel->ips_local_addr_v6), lport, proto, 0);
5644 
5645         if (cur == NULL) {
5646                 freeb(mp);
5647                 return (NULL);
5648         }
5649 
5650         cur = sadb_make_addr_ext(cur, end, SADB_EXT_ADDRESS_DST, af,
5651             (uint32_t *)(&sel->ips_remote_addr_v6), rport, proto, 0);
5652 
5653         if (cur == NULL) {
5654                 freeb(mp);
5655                 return (NULL);
5656         }
5657 
5658         if (sens != NULL) {
5659                 uint8_t *sensext = cur;
5660                 int senslen = SADB_64TO8(sens->sadb_sens_len);
5661 
5662                 cur += senslen;
5663                 if (cur > end) {
5664                         freeb(mp);
5665                         return (NULL);
5666                 }
5667                 bcopy(sens, sensext, senslen);
5668         }
5669 
5670         /*
5671          * This section will change a lot as policy evolves.
5672          * For now, it'll be relatively simple.
5673          */
5674         eprop = (sadb_prop_t *)cur;
5675         cur += sizeof (*eprop);
5676         if (cur > end) {
5677                 /* no space left */
5678                 freeb(mp);
5679                 return (NULL);
5680         }
5681 
5682         eprop->sadb_prop_exttype = SADB_X_EXT_EPROP;
5683         eprop->sadb_x_prop_ereserved = 0;
5684         eprop->sadb_x_prop_numecombs = 0;
5685         eprop->sadb_prop_replay = 32;        /* default */
5686 
5687         kmc = kmp = 0;
5688 
5689         for (; ap != NULL; ap = an) {
5690                 an = (pol != NULL) ? ap->ipa_next : NULL;
5691 
5692                 /*
5693                  * Skip non-IPsec policies
5694                  */
5695                 if (ap->ipa_act.ipa_type != IPSEC_ACT_APPLY)
5696                         continue;
5697 
5698                 if (ap->ipa_act.ipa_apply.ipp_km_proto)
5699                         kmp = ap->ipa_act.ipa_apply.ipp_km_proto;
5700                 if (ap->ipa_act.ipa_apply.ipp_km_cookie)
5701                         kmc = ap->ipa_act.ipa_apply.ipp_km_cookie;
5702                 if (ap->ipa_act.ipa_apply.ipp_replay_depth) {
5703                         eprop->sadb_prop_replay =
5704                             ap->ipa_act.ipa_apply.ipp_replay_depth;
5705                 }
5706 
5707                 cur = sadb_action_to_ecomb(cur, end, ap, ns);
5708                 if (cur == NULL) { /* no space */
5709                         freeb(mp);
5710                         return (NULL);
5711                 }
5712                 eprop->sadb_x_prop_numecombs++;
5713         }
5714 
5715         if (eprop->sadb_x_prop_numecombs == 0) {
5716                 /*
5717                  * This will happen if we fail to find a policy
5718                  * allowing for IPsec processing.
5719                  * Construct an error message.
5720                  */
5721                 samsg->sadb_msg_len = SADB_8TO64(sizeof (*samsg));
5722                 samsg->sadb_msg_errno = ENOENT;
5723                 samsg->sadb_x_msg_diagnostic = 0;
5724                 return (mp);
5725         }
5726 
5727         if ((kmp != 0) || (kmc != 0)) {
5728                 cur = sadb_make_kmc_ext(cur, end, kmp, kmc);
5729                 if (cur == NULL) {
5730                         freeb(mp);
5731                         return (NULL);
5732                 }
5733         }
5734 
5735         eprop->sadb_prop_len = SADB_8TO64(cur - (uint8_t *)eprop);
5736         samsg->sadb_msg_len = SADB_8TO64(cur - start);
5737         mp->b_wptr = cur;
5738 
5739         return (mp);
5740 }
5741 
5742 /*
5743  * Generic setup of an RFC 2367 ACQUIRE message.  Caller sets satype.
5744  *
5745  * NOTE: This function acquires alg_lock as a side-effect if-and-only-if we
5746  * succeed (i.e. return non-NULL).  Caller MUST release it.  This is to
5747  * maximize code consolidation while preventing algorithm changes from messing
5748  * with the callers finishing touches on the ACQUIRE itself.
5749  */
5750 mblk_t *
5751 sadb_setup_acquire(ipsacq_t *acqrec, uint8_t satype, ipsec_stack_t *ipss)
5752 {
5753         uint_t allocsize;
5754         mblk_t *pfkeymp, *msgmp;
5755         sa_family_t af;
5756         uint8_t *cur, *end;
5757         sadb_msg_t *samsg;
5758         uint16_t sport_typecode;
5759         uint16_t dport_typecode;
5760         uint8_t check_proto;
5761         boolean_t tunnel_mode = (acqrec->ipsacq_inneraddrfam != 0);
5762 
5763         ASSERT(MUTEX_HELD(&acqrec->ipsacq_lock));
5764 
5765         pfkeymp = sadb_keysock_out(0);
5766         if (pfkeymp == NULL)
5767                 return (NULL);
5768 
5769         /*
5770          * First, allocate a basic ACQUIRE message
5771          */
5772         allocsize = sizeof (sadb_msg_t) + sizeof (sadb_address_t) +
5773             sizeof (sadb_address_t) + sizeof (sadb_prop_t);
5774 
5775         /* Make sure there's enough to cover both AF_INET and AF_INET6. */
5776         allocsize += 2 * sizeof (struct sockaddr_in6);
5777 
5778         rw_enter(&ipss->ipsec_alg_lock, RW_READER);
5779         /* NOTE:  The lock is now held through to this function's return. */
5780         allocsize += ipss->ipsec_nalgs[IPSEC_ALG_AUTH] *
5781             ipss->ipsec_nalgs[IPSEC_ALG_ENCR] * sizeof (sadb_comb_t);
5782 
5783         if (tunnel_mode) {
5784                 /* Tunnel mode! */
5785                 allocsize += 2 * sizeof (sadb_address_t);
5786                 /* Enough to cover both AF_INET and AF_INET6. */
5787                 allocsize += 2 * sizeof (struct sockaddr_in6);
5788         }
5789 
5790         msgmp = allocb(allocsize, BPRI_HI);
5791         if (msgmp == NULL) {
5792                 freeb(pfkeymp);
5793                 rw_exit(&ipss->ipsec_alg_lock);
5794                 return (NULL);
5795         }
5796 
5797         pfkeymp->b_cont = msgmp;
5798         cur = msgmp->b_rptr;
5799         end = cur + allocsize;
5800         samsg = (sadb_msg_t *)cur;
5801         cur += sizeof (sadb_msg_t);
5802 
5803         af = acqrec->ipsacq_addrfam;
5804         switch (af) {
5805         case AF_INET:
5806                 check_proto = IPPROTO_ICMP;
5807                 break;
5808         case AF_INET6:
5809                 check_proto = IPPROTO_ICMPV6;
5810                 break;
5811         default:
5812                 /* This should never happen unless we have kernel bugs. */
5813                 cmn_err(CE_WARN,
5814                     "sadb_setup_acquire:  corrupt ACQUIRE record.\n");
5815                 ASSERT(0);
5816                 rw_exit(&ipss->ipsec_alg_lock);
5817                 return (NULL);
5818         }
5819 
5820         samsg->sadb_msg_version = PF_KEY_V2;
5821         samsg->sadb_msg_type = SADB_ACQUIRE;
5822         samsg->sadb_msg_satype = satype;
5823         samsg->sadb_msg_errno = 0;
5824         samsg->sadb_msg_pid = 0;
5825         samsg->sadb_msg_reserved = 0;
5826         samsg->sadb_msg_seq = acqrec->ipsacq_seq;
5827 
5828         ASSERT(MUTEX_HELD(&acqrec->ipsacq_lock));
5829 
5830         if ((acqrec->ipsacq_proto == check_proto) || tunnel_mode) {
5831                 sport_typecode = dport_typecode = 0;
5832         } else {
5833                 sport_typecode = acqrec->ipsacq_srcport;
5834                 dport_typecode = acqrec->ipsacq_dstport;
5835         }
5836 
5837         cur = sadb_make_addr_ext(cur, end, SADB_EXT_ADDRESS_SRC, af,
5838             acqrec->ipsacq_srcaddr, sport_typecode, acqrec->ipsacq_proto, 0);
5839 
5840         cur = sadb_make_addr_ext(cur, end, SADB_EXT_ADDRESS_DST, af,
5841             acqrec->ipsacq_dstaddr, dport_typecode, acqrec->ipsacq_proto, 0);
5842 
5843         if (tunnel_mode) {
5844                 sport_typecode = acqrec->ipsacq_srcport;
5845                 dport_typecode = acqrec->ipsacq_dstport;
5846                 cur = sadb_make_addr_ext(cur, end, SADB_X_EXT_ADDRESS_INNER_SRC,
5847                     acqrec->ipsacq_inneraddrfam, acqrec->ipsacq_innersrc,
5848                     sport_typecode, acqrec->ipsacq_inner_proto,
5849                     acqrec->ipsacq_innersrcpfx);
5850                 cur = sadb_make_addr_ext(cur, end, SADB_X_EXT_ADDRESS_INNER_DST,
5851                     acqrec->ipsacq_inneraddrfam, acqrec->ipsacq_innerdst,
5852                     dport_typecode, acqrec->ipsacq_inner_proto,
5853                     acqrec->ipsacq_innerdstpfx);
5854         }
5855 
5856         /* XXX Insert identity information here. */
5857 
5858         /* XXXMLS Insert sensitivity information here. */
5859 
5860         if (cur != NULL)
5861                 samsg->sadb_msg_len = SADB_8TO64(cur - msgmp->b_rptr);
5862         else
5863                 rw_exit(&ipss->ipsec_alg_lock);
5864 
5865         return (pfkeymp);
5866 }
5867 
5868 /*
5869  * Given an SADB_GETSPI message, find an appropriately ranged SA and
5870  * allocate an SA.  If there are message improprieties, return (ipsa_t *)-1.
5871  * If there was a memory allocation error, return NULL.  (Assume NULL !=
5872  * (ipsa_t *)-1).
5873  *
5874  * master_spi is passed in host order.
5875  */
5876 ipsa_t *
5877 sadb_getspi(keysock_in_t *ksi, uint32_t master_spi, int *diagnostic,
5878     netstack_t *ns, uint_t sa_type)
5879 {
5880         sadb_address_t *src =
5881             (sadb_address_t *)ksi->ks_in_extv[SADB_EXT_ADDRESS_SRC],
5882             *dst = (sadb_address_t *)ksi->ks_in_extv[SADB_EXT_ADDRESS_DST];
5883         sadb_spirange_t *range =
5884             (sadb_spirange_t *)ksi->ks_in_extv[SADB_EXT_SPIRANGE];
5885         struct sockaddr_in *ssa, *dsa;
5886         struct sockaddr_in6 *ssa6, *dsa6;
5887         uint32_t *srcaddr, *dstaddr;
5888         sa_family_t af;


6839                 break;
6840         default:
6841                 ipsec_oth_pol(&sel, &pp, ipst);
6842                 break;
6843         }
6844 
6845         /*
6846          * If we didn't find a matching conn_t or other policy head, take a
6847          * look in the global policy.
6848          */
6849         if (pp == NULL) {
6850                 pp = ipsec_find_policy(IPSEC_TYPE_OUTBOUND, NULL, &sel, ns);
6851                 if (pp == NULL) {
6852                         /* There's no global policy. */
6853                         err = ENOENT;
6854                         diagnostic = 0;
6855                         goto bail;
6856                 }
6857         }
6858 
6859         /*
6860          * Now that we have a policy entry/widget, construct an ACQUIRE
6861          * message based on that, fix fields where appropriate,
6862          * and return the message.
6863          */
6864         retmp = sadb_extended_acquire(&sel, pp, NULL,
6865             (itp != NULL && (itp->itp_flags & ITPF_P_TUNNEL)),
6866             samsg->sadb_msg_seq, samsg->sadb_msg_pid, sens, ns);




















6867         if (pp != NULL) {
6868                 IPPOL_REFRELE(pp);
6869         }
6870         ASSERT(err == 0 && diagnostic == 0);
6871         if (retmp == NULL)
6872                 err = ENOMEM;
6873 bail:
6874         if (itp != NULL) {
6875                 ITP_REFRELE(itp, ns);
6876         }
6877         samsg->sadb_msg_errno = (uint8_t)err;
6878         samsg->sadb_x_msg_diagnostic = (uint16_t)diagnostic;
6879         return (retmp);
6880 }
6881 
6882 /*
6883  * ipsa_lpkt is a one-element queue, only manipulated by the next two
6884  * functions.  They have to hold the ipsa_lock because of potential races
6885  * between key management using SADB_UPDATE, and inbound packets that may
6886  * queue up on the larval SA (hence the 'l' in "lpkt").




   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  * Copyright (c) 2012 Nexenta Systems, Inc. All rights reserved.
  25  * Copyright (c) 2017 Joyent, Inc.
  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>


  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 uint8_t *sadb_action_to_ecomb(uint8_t *, uint8_t *, ipsec_action_t *,

  79     netstack_t *);
  80 static ipsa_t *sadb_torch_assoc(isaf_t *, ipsa_t *);
  81 static void sadb_destroy_acqlist(iacqf_t **, uint_t, boolean_t,
  82                             netstack_t *);
  83 static void sadb_destroy(sadb_t *, netstack_t *);
  84 static mblk_t *sadb_sa2msg(ipsa_t *, sadb_msg_t *);
  85 static ts_label_t *sadb_label_from_sens(sadb_sens_t *, uint64_t *);

  86 
  87 static time_t sadb_add_time(time_t, uint64_t);
  88 static void lifetime_fuzz(ipsa_t *);
  89 static void age_pair_peer_list(templist_t *, sadb_t *, boolean_t);
  90 static int get_ipsa_pair(ipsa_query_t *, ipsap_t *, int *);
  91 static void init_ipsa_pair(ipsap_t *);
  92 static void destroy_ipsa_pair(ipsap_t *);
  93 static int update_pairing(ipsap_t *, ipsa_query_t *, keysock_in_t *, int *);
  94 static void ipsa_set_replay(ipsa_t *ipsa, uint32_t offset);
  95 
  96 /*
  97  * ipsacq_maxpackets is defined here to make it tunable
  98  * from /etc/system.
  99  */
 100 extern uint64_t ipsacq_maxpackets;
 101 
 102 #define SET_EXPIRE(sa, delta, exp) {                            \
 103         if (((sa)->ipsa_ ## delta) != 0) {                           \
 104                 (sa)->ipsa_ ## exp = sadb_add_time((sa)->ipsa_addtime,    \
 105                         (sa)->ipsa_ ## delta);                               \


4826                 fam = walker->ipsacq_addrfam;
4827                 if (IPSA_ARE_ADDR_EQUAL(dst, walker->ipsacq_dstaddr, fam) &&
4828                     IPSA_ARE_ADDR_EQUAL(src, walker->ipsacq_srcaddr, fam) &&
4829                     ip_addr_match((uint8_t *)isrc, walker->ipsacq_innersrcpfx,
4830                     (in6_addr_t *)walker->ipsacq_innersrc) &&
4831                     ip_addr_match((uint8_t *)idst, walker->ipsacq_innerdstpfx,
4832                     (in6_addr_t *)walker->ipsacq_innerdst) &&
4833                     (ap == walker->ipsacq_act) &&
4834                     (pp == walker->ipsacq_policy) &&
4835                     /* XXX do deep compares of ap/pp? */
4836                     (unique_id == walker->ipsacq_unique_id) &&
4837                     (ipsec_label_match(tsl, walker->ipsacq_tsl)))
4838                         break;                  /* everything matched */
4839                 mutex_exit(&walker->ipsacq_lock);
4840         }
4841 
4842         return (walker);
4843 }
4844 
4845 /*
4846  * Generate an SADB_ACQUIRE base message mblk, including KEYSOCK_OUT metadata.
4847  * In other words, this will return, upon success, a two-mblk chain.
4848  */
4849 static inline mblk_t *
4850 sadb_acquire_msg_base(minor_t serial, uint8_t satype, uint32_t seq, pid_t pid)
4851 {
4852         mblk_t *mp;
4853         sadb_msg_t *samsg;
4854 
4855         mp = sadb_keysock_out(serial);
4856         if (mp == NULL)
4857                 return (NULL);
4858         mp->b_cont = allocb(sizeof (sadb_msg_t), BPRI_HI);
4859         if (mp->b_cont == NULL) {
4860                 freeb(mp);
4861                 return (NULL);
4862         }
4863 
4864         samsg = (sadb_msg_t *)mp->b_cont->b_rptr;
4865         mp->b_cont->b_wptr += sizeof (*samsg);
4866         samsg->sadb_msg_version = PF_KEY_V2;
4867         samsg->sadb_msg_type = SADB_ACQUIRE;
4868         samsg->sadb_msg_errno = 0;
4869         samsg->sadb_msg_reserved = 0;
4870         samsg->sadb_msg_satype = satype;
4871         samsg->sadb_msg_seq = seq;
4872         samsg->sadb_msg_pid = pid;
4873 
4874         return (mp);
4875 }
4876 
4877 /*
4878  * Generate address and TX/MLS sensitivity label PF_KEY extensions that are
4879  * common to both regular and extended ACQUIREs.
4880  */
4881 static mblk_t *
4882 sadb_acquire_msg_common(ipsec_selector_t *sel, ipsec_policy_t *pp,
4883     ipsec_action_t *ap, boolean_t tunnel_mode, ts_label_t *tsl,
4884     sadb_sens_t *sens)
4885 {
4886         size_t len;
4887         mblk_t *mp;
4888         uint8_t *start, *cur, *end;
4889         uint32_t *saddrptr, *daddrptr;
4890         sa_family_t af;
4891         ipsec_action_t *oldap;
4892         ipsec_selkey_t *ipsl;
4893         uint8_t proto, pfxlen;
4894         uint16_t lport, rport;
4895         int senslen = 0;
4896 
4897         /*
4898          * Get action pointer set if it isn't already.
4899          */
4900         oldap = ap;
4901         if (pp != NULL) {
4902                 ap = pp->ipsp_act;
4903                 if (ap == NULL)
4904                         ap = oldap;
4905         }
4906 
4907         /*
4908          * Biggest-case scenario:
4909          * 4x (sadb_address_t + struct sockaddr_in6)
4910          *      (src, dst, isrc, idst)
4911          *      (COMING SOON, 6x, because of triggering-packet contents.)
4912          * sadb_x_kmc_t
4913          * sadb_sens_t
4914          * And wiggle room for label bitvectors.  Luckily there are
4915          * programmatic ways to find it.
4916          */
4917         len = 4 * (sizeof (sadb_address_t) + sizeof (struct sockaddr_in6));
4918 
4919         /* Figure out full and proper length of sensitivity labels. */
4920         if (sens != NULL) {
4921                 ASSERT(tsl == NULL);
4922                 senslen = SADB_64TO8(sens->sadb_sens_len);
4923         } else if (tsl != NULL) {
4924                 senslen = sadb_sens_len_from_label(tsl);
4925         }
4926 #ifdef DEBUG
4927         else {
4928                 ASSERT(senslen == 0);
4929         }
4930 #endif /* DEBUG */
4931         len += senslen;
4932 
4933         mp = allocb(len, BPRI_HI);
4934         if (mp == NULL)
4935                 return (NULL);
4936 
4937         start = mp->b_rptr;
4938         end = start + len;
4939         cur = start;
4940 
4941         /*
4942          * Address extensions first, from most-recently-defined to least.
4943          * (This should immediately trigger surprise or verify robustness on
4944          * older apps, like in.iked.)
4945          */
4946         if (tunnel_mode) {
4947                 /*
4948                  * Form inner address extensions based NOT on the inner
4949                  * selectors (i.e. the packet data), but on the policy's
4950                  * selector key (i.e. the policy's selector information).
4951                  *
4952                  * NOTE:  The position of IPv4 and IPv6 addresses is the
4953                  * same in ipsec_selkey_t (unless the compiler does very
4954                  * strange things with unions, consult your local C language
4955                  * lawyer for details).
4956                  */
4957                 ASSERT(pp != NULL);
4958 
4959                 ipsl = &(pp->ipsp_sel->ipsl_key);
4960                 if (ipsl->ipsl_valid & IPSL_IPV4) {
4961                         af = AF_INET;
4962                         ASSERT(sel->ips_protocol == IPPROTO_ENCAP);
4963                         ASSERT(!(ipsl->ipsl_valid & IPSL_IPV6));
4964                 } else {
4965                         af = AF_INET6;
4966                         ASSERT(sel->ips_protocol == IPPROTO_IPV6);
4967                         ASSERT(ipsl->ipsl_valid & IPSL_IPV6);
4968                 }
4969 
4970                 if (ipsl->ipsl_valid & IPSL_LOCAL_ADDR) {
4971                         saddrptr = (uint32_t *)(&ipsl->ipsl_local);
4972                         pfxlen = ipsl->ipsl_local_pfxlen;
4973                 } else {
4974                         saddrptr = (uint32_t *)(&ipv6_all_zeros);
4975                         pfxlen = 0;
4976                 }
4977                 /* XXX What about ICMP type/code? */
4978                 lport = (ipsl->ipsl_valid & IPSL_LOCAL_PORT) ?
4979                     ipsl->ipsl_lport : 0;
4980                 proto = (ipsl->ipsl_valid & IPSL_PROTOCOL) ?
4981                     ipsl->ipsl_proto : 0;
4982 
4983                 cur = sadb_make_addr_ext(cur, end, SADB_X_EXT_ADDRESS_INNER_SRC,
4984                     af, saddrptr, lport, proto, pfxlen);
4985                 if (cur == NULL) {
4986                         freeb(mp);
4987                         return (NULL);
4988                 }
4989 
4990                 if (ipsl->ipsl_valid & IPSL_REMOTE_ADDR) {
4991                         daddrptr = (uint32_t *)(&ipsl->ipsl_remote);
4992                         pfxlen = ipsl->ipsl_remote_pfxlen;
4993                 } else {
4994                         daddrptr = (uint32_t *)(&ipv6_all_zeros);
4995                         pfxlen = 0;
4996                 }
4997                 /* XXX What about ICMP type/code? */
4998                 rport = (ipsl->ipsl_valid & IPSL_REMOTE_PORT) ?
4999                     ipsl->ipsl_rport : 0;
5000 
5001                 cur = sadb_make_addr_ext(cur, end, SADB_X_EXT_ADDRESS_INNER_DST,
5002                     af, daddrptr, rport, proto, pfxlen);
5003                 if (cur == NULL) {
5004                         freeb(mp);
5005                         return (NULL);
5006                 }
5007                 /*
5008                  * TODO  - if we go to 3884's dream of transport mode IP-in-IP
5009                  * _with_ inner-packet address selectors, we'll need to further
5010                  * distinguish tunnel mode here.  For now, having inner
5011                  * addresses and/or ports is sufficient.
5012                  *
5013                  * Meanwhile, whack proto/ports to reflect IP-in-IP for the
5014                  * outer addresses.
5015                  */
5016                 proto = sel->ips_protocol;   /* Either _ENCAP or _IPV6 */
5017                 lport = rport = 0;
5018         } else if ((ap != NULL) && (!ap->ipa_want_unique)) {
5019                 /*
5020                  * For cases when the policy calls out specific ports (or not).
5021                  */
5022                 proto = 0;
5023                 lport = 0;
5024                 rport = 0;
5025                 if (pp != NULL) {
5026                         ipsl = &(pp->ipsp_sel->ipsl_key);
5027                         if (ipsl->ipsl_valid & IPSL_PROTOCOL)
5028                                 proto = ipsl->ipsl_proto;
5029                         if (ipsl->ipsl_valid & IPSL_REMOTE_PORT)
5030                                 rport = ipsl->ipsl_rport;
5031                         if (ipsl->ipsl_valid & IPSL_LOCAL_PORT)
5032                                 lport = ipsl->ipsl_lport;
5033                 }
5034         } else {
5035                 /*
5036                  * For require-unique-SA policies.
5037                  */
5038                 proto = sel->ips_protocol;
5039                 lport = sel->ips_local_port;
5040                 rport = sel->ips_remote_port;
5041         }
5042 
5043         /*
5044          * Regular addresses.  These are outer-packet ones for tunnel mode.
5045          * Or for transport mode, the regulard address & port information.
5046          */
5047         af = sel->ips_isv4 ? AF_INET : AF_INET6;
5048 
5049         /*
5050          * NOTE:  The position of IPv4 and IPv6 addresses is the same in
5051          * ipsec_selector_t.
5052          */
5053         cur = sadb_make_addr_ext(cur, end, SADB_EXT_ADDRESS_SRC, af,
5054             (uint32_t *)(&sel->ips_local_addr_v6), lport, proto, 0);
5055         if (cur == NULL) {
5056                 freeb(mp);
5057                 return (NULL);
5058         }
5059 
5060         cur = sadb_make_addr_ext(cur, end, SADB_EXT_ADDRESS_DST, af,
5061             (uint32_t *)(&sel->ips_remote_addr_v6), rport, proto, 0);
5062         if (cur == NULL) {
5063                 freeb(mp);
5064                 return (NULL);
5065         }
5066 
5067         /*
5068          * If present, generate a sensitivity label.
5069          */
5070         if (cur + senslen > end) {
5071                 freeb(mp);
5072                 return (NULL);
5073         }
5074         if (sens != NULL) {
5075                 /* Explicit sadb_sens_t, usually from inverse-ACQUIRE. */
5076                 bcopy(sens, cur, senslen);
5077         } else if (tsl != NULL) {
5078                 /* Generate sadb_sens_t from ACQUIRE source. */
5079                 sadb_sens_from_label((sadb_sens_t *)cur, SADB_EXT_SENSITIVITY,
5080                     tsl, senslen);
5081         }
5082 #ifdef DEBUG
5083         else {
5084                 ASSERT(senslen == 0);
5085         }
5086 #endif /* DEBUG */
5087         cur += senslen;
5088         mp->b_wptr = cur;
5089 
5090         return (mp);
5091 }
5092 
5093 /*
5094  * Generate a regular ACQUIRE's proposal extension and KMC information..
5095  */
5096 static mblk_t *
5097 sadb_acquire_prop(ipsec_action_t *ap, netstack_t *ns, boolean_t do_esp)
5098 {
5099         ipsec_stack_t *ipss = ns->netstack_ipsec;
5100         ipsecesp_stack_t *espstack = ns->netstack_ipsecesp;
5101         ipsecah_stack_t *ahstack = ns->netstack_ipsecah;
5102         mblk_t *mp = NULL;
5103         sadb_prop_t *prop;
5104         sadb_comb_t *comb;
5105         ipsec_action_t *walker;
5106         int ncombs, allocsize, ealgid, aalgid, aminbits, amaxbits, eminbits,
5107             emaxbits, replay;
5108         uint64_t softbytes, hardbytes, softaddtime, hardaddtime, softusetime,
5109             hardusetime;
5110         uint32_t kmc = 0, kmp = 0;
5111 
5112         /*
5113          * Since it's an rwlock read, AND writing to the IPsec algorithms is
5114          * rare, just acquire it once up top, and drop it upon return.
5115          */
5116         rw_enter(&ipss->ipsec_alg_lock, RW_READER);
5117         if (do_esp) {
5118                 uint64_t num_aalgs, num_ealgs;
5119 
5120                 if (espstack->esp_kstats == NULL)
5121                         goto bail;
5122 
5123                 num_aalgs = ipss->ipsec_nalgs[IPSEC_ALG_AUTH];
5124                 num_ealgs = ipss->ipsec_nalgs[IPSEC_ALG_ENCR];
5125                 if (num_ealgs == 0)
5126                         goto bail;      /* IPsec not loaded yet, apparently. */
5127                 num_aalgs++;    /* No-auth or self-auth-crypto ESP. */
5128 
5129                 /* Use netstack's maximum loaded algorithms... */
5130                 ncombs = num_ealgs * num_aalgs;
5131                 replay =  espstack->ipsecesp_replay_size;
5132         } else {
5133                 if (ahstack->ah_kstats == NULL)
5134                         goto bail;
5135 
5136                 ncombs = ipss->ipsec_nalgs[IPSEC_ALG_AUTH];
5137 
5138                 if (ncombs == 0)
5139                         goto bail;      /* IPsec not loaded yet, apparently. */
5140                 replay =  ahstack->ipsecah_replay_size;
5141         }
5142 
5143         allocsize = sizeof (*prop) + ncombs * sizeof (*comb) +
5144             sizeof (sadb_x_kmc_t);
5145         mp = allocb(allocsize, BPRI_HI);
5146         if (mp == NULL)
5147                 goto bail;
5148         prop = (sadb_prop_t *)mp->b_rptr;
5149         mp->b_wptr += sizeof (*prop);
5150         comb = (sadb_comb_t *)mp->b_wptr;
5151         /* Decrement allocsize, if it goes to or below 0, stop. */
5152         allocsize -= sizeof (*prop);
5153         prop->sadb_prop_exttype = SADB_EXT_PROPOSAL;
5154         prop->sadb_prop_len = SADB_8TO64(sizeof (*prop));
5155         *(uint32_t *)(&prop->sadb_prop_replay) = 0;      /* Quick zero-out! */
5156         prop->sadb_prop_replay = replay;
5157 
5158         /*
5159          * Based upon algorithm properties, and what-not, prioritize a
5160          * proposal, based on the ordering of the ESP algorithms in the
5161          * alternatives in the policy rule or socket that was placed
5162          * in the acquire record.
5163          *
5164          * For each action in policy list
5165          *   Add combination.
5166          *   I should not hit it, but if I've hit limit, return.
5167          */
5168 
5169         for (walker = ap; walker != NULL; walker = walker->ipa_next) {
5170                 ipsec_alginfo_t *ealg, *aalg;
5171                 ipsec_prot_t *prot;
5172 
5173                 if (walker->ipa_act.ipa_type != IPSEC_POLICY_APPLY)
5174                         continue;
5175 
5176                 prot = &walker->ipa_act.ipa_apply;
5177                 if (walker->ipa_act.ipa_apply.ipp_km_proto != 0)
5178                         kmp = walker->ipa_act.ipa_apply.ipp_km_proto;
5179                 if (walker->ipa_act.ipa_apply.ipp_km_cookie != 0)
5180                         kmc = walker->ipa_act.ipa_apply.ipp_km_cookie;
5181                 if (walker->ipa_act.ipa_apply.ipp_replay_depth) {
5182                         prop->sadb_prop_replay =
5183                             walker->ipa_act.ipa_apply.ipp_replay_depth;
5184                 }
5185 
5186                 if (do_esp) {
5187                         if (!prot->ipp_use_esp)
5188                                 continue;
5189 
5190                         if (prot->ipp_esp_auth_alg != 0) {
5191                                 aalg = ipss->ipsec_alglists[IPSEC_ALG_AUTH]
5192                                     [prot->ipp_esp_auth_alg];
5193                                 if (aalg == NULL || !ALG_VALID(aalg))
5194                                         continue;
5195                         } else
5196                                 aalg = NULL;
5197 
5198                         ASSERT(prot->ipp_encr_alg > 0);
5199                         ealg = ipss->ipsec_alglists[IPSEC_ALG_ENCR]
5200                             [prot->ipp_encr_alg];
5201                         if (ealg == NULL || !ALG_VALID(ealg))
5202                                 continue;
5203 
5204                         /*
5205                          * These may want to come from policy rule..
5206                          */
5207                         softbytes = espstack->ipsecesp_default_soft_bytes;
5208                         hardbytes = espstack->ipsecesp_default_hard_bytes;
5209                         softaddtime = espstack->ipsecesp_default_soft_addtime;
5210                         hardaddtime = espstack->ipsecesp_default_hard_addtime;
5211                         softusetime = espstack->ipsecesp_default_soft_usetime;
5212                         hardusetime = espstack->ipsecesp_default_hard_usetime;
5213                 } else {
5214                         if (!prot->ipp_use_ah)
5215                                 continue;
5216                         ealg = NULL;
5217                         aalg = ipss->ipsec_alglists[IPSEC_ALG_AUTH]
5218                             [prot->ipp_auth_alg];
5219                         if (aalg == NULL || !ALG_VALID(aalg))
5220                                 continue;
5221 
5222                         /*
5223                          * These may want to come from policy rule..
5224                          */
5225                         softbytes = ahstack->ipsecah_default_soft_bytes;
5226                         hardbytes = ahstack->ipsecah_default_hard_bytes;
5227                         softaddtime = ahstack->ipsecah_default_soft_addtime;
5228                         hardaddtime = ahstack->ipsecah_default_hard_addtime;
5229                         softusetime = ahstack->ipsecah_default_soft_usetime;
5230                         hardusetime = ahstack->ipsecah_default_hard_usetime;
5231                 }
5232 
5233                 if (ealg == NULL) {
5234                         ealgid = eminbits = emaxbits = 0;
5235                 } else {
5236                         ealgid = ealg->alg_id;
5237                         eminbits =
5238                             MAX(prot->ipp_espe_minbits, ealg->alg_ef_minbits);
5239                         emaxbits =
5240                             MIN(prot->ipp_espe_maxbits, ealg->alg_ef_maxbits);
5241                 }
5242 
5243                 if (aalg == NULL) {
5244                         aalgid = aminbits = amaxbits = 0;
5245                 } else {
5246                         aalgid = aalg->alg_id;
5247                         aminbits = MAX(prot->ipp_espa_minbits,
5248                             aalg->alg_ef_minbits);
5249                         amaxbits = MIN(prot->ipp_espa_maxbits,
5250                             aalg->alg_ef_maxbits);
5251                 }
5252 
5253                 comb->sadb_comb_flags = 0;
5254                 comb->sadb_comb_reserved = 0;
5255                 comb->sadb_comb_encrypt = ealgid;
5256                 comb->sadb_comb_encrypt_minbits = eminbits;
5257                 comb->sadb_comb_encrypt_maxbits = emaxbits;
5258                 comb->sadb_comb_auth = aalgid;
5259                 comb->sadb_comb_auth_minbits = aminbits;
5260                 comb->sadb_comb_auth_maxbits = amaxbits;
5261                 comb->sadb_comb_soft_allocations = 0;
5262                 comb->sadb_comb_hard_allocations = 0;
5263                 comb->sadb_comb_soft_bytes = softbytes;
5264                 comb->sadb_comb_hard_bytes = hardbytes;
5265                 comb->sadb_comb_soft_addtime = softaddtime;
5266                 comb->sadb_comb_hard_addtime = hardaddtime;
5267                 comb->sadb_comb_soft_usetime = softusetime;
5268                 comb->sadb_comb_hard_usetime = hardusetime;
5269 
5270                 prop->sadb_prop_len += SADB_8TO64(sizeof (*comb));
5271                 mp->b_wptr += sizeof (*comb);
5272                 allocsize -= sizeof (*comb);
5273                 /* Should never dip BELOW sizeof (KM cookie extension). */
5274                 ASSERT3S(allocsize, >=, sizeof (sadb_x_kmc_t));
5275                 if (allocsize <= sizeof (sadb_x_kmc_t))
5276                         break;  /* out of space.. */
5277                 comb++;
5278         }
5279 
5280         /* Don't include KMC extension if there's no room. */
5281         if (((kmp != 0) || (kmc != 0)) && allocsize >= sizeof (sadb_x_kmc_t)) {
5282                 if (sadb_make_kmc_ext(mp->b_wptr,
5283                     mp->b_wptr + sizeof (sadb_x_kmc_t), kmp, kmc) == NULL) {
5284                         freeb(mp);
5285                         mp = NULL;
5286                         goto bail;
5287                 }
5288                 mp->b_wptr += sizeof (sadb_x_kmc_t);
5289                 prop->sadb_prop_len += SADB_8TO64(sizeof (sadb_x_kmc_t));
5290         }
5291 
5292 bail:
5293         rw_exit(&ipss->ipsec_alg_lock);
5294         return (mp);
5295 }
5296 
5297 /*
5298  * Generate an extended ACQUIRE's extended-proposal extension.
5299  */
5300 /* ARGSUSED */
5301 static mblk_t *
5302 sadb_acquire_extended_prop(ipsec_action_t *ap, netstack_t *ns)
5303 {
5304         sadb_prop_t *eprop;
5305         uint8_t *cur, *end;
5306         mblk_t *mp;
5307         int allocsize, numecombs = 0, numalgdescs = 0;
5308         uint32_t kmc = 0, kmp = 0, replay = 0;
5309         ipsec_action_t *walker;
5310 
5311         allocsize = sizeof (*eprop);
5312 
5313         /*
5314          * Going to walk through the action list twice.  Once for allocation
5315          * measurement, and once for actual construction.
5316          */
5317         for (walker = ap; walker != NULL; walker = walker->ipa_next) {
5318                 ipsec_prot_t *ipp;
5319 
5320                 /*
5321                  * Skip non-IPsec policies
5322                  */
5323                 if (walker->ipa_act.ipa_type != IPSEC_ACT_APPLY)
5324                         continue;
5325 
5326                 ipp = &walker->ipa_act.ipa_apply;
5327 
5328                 if (walker->ipa_act.ipa_apply.ipp_km_proto)
5329                         kmp = ipp->ipp_km_proto;
5330                 if (walker->ipa_act.ipa_apply.ipp_km_cookie)
5331                         kmc = ipp->ipp_km_cookie;
5332                 if (walker->ipa_act.ipa_apply.ipp_replay_depth)
5333                         replay = ipp->ipp_replay_depth;
5334 
5335                 if (ipp->ipp_use_ah)
5336                         numalgdescs++;
5337                 if (ipp->ipp_use_esp) {
5338                         numalgdescs++;
5339                         if (ipp->ipp_use_espa)
5340                                 numalgdescs++;
5341                 }
5342 
5343                 numecombs++;
5344         }
5345         ASSERT(numecombs > 0);
5346 
5347         allocsize += numecombs * sizeof (sadb_x_ecomb_t) +
5348             numalgdescs * sizeof (sadb_x_algdesc_t) + sizeof (sadb_x_kmc_t);
5349         mp = allocb(allocsize, BPRI_HI);
5350         if (mp == NULL)
5351                 return (NULL);
5352         eprop = (sadb_prop_t *)mp->b_rptr;
5353         end = mp->b_rptr + allocsize;
5354         cur = mp->b_rptr + sizeof (*eprop);
5355 
5356         eprop->sadb_prop_exttype = SADB_X_EXT_EPROP;
5357         eprop->sadb_x_prop_ereserved = 0;
5358         eprop->sadb_x_prop_numecombs = 0;
5359         *(uint32_t *)(&eprop->sadb_prop_replay) = 0;     /* Quick zero-out! */
5360         /* Pick ESP's replay default if need be. */
5361         eprop->sadb_prop_replay = (replay == 0) ?
5362             ns->netstack_ipsecesp->ipsecesp_replay_size : replay;
5363 
5364         /* This time, walk through and actually allocate. */
5365         for (walker = ap; walker != NULL; walker = walker->ipa_next) {
5366                 /*
5367                  * Skip non-IPsec policies
5368                  */
5369                 if (walker->ipa_act.ipa_type != IPSEC_ACT_APPLY)
5370                         continue;
5371                 cur = sadb_action_to_ecomb(cur, end, walker, ns);
5372                 if (cur == NULL) {
5373                         /* NOTE: inverse-ACQUIRE should note this as ENOMEM. */
5374                         freeb(mp);
5375                         return (NULL);
5376                 }
5377                 eprop->sadb_x_prop_numecombs++;
5378         }
5379 
5380         ASSERT(end - cur >= sizeof (sadb_x_kmc_t));
5381         if ((kmp != 0) || (kmc != 0)) {
5382                 cur = sadb_make_kmc_ext(cur, end, kmp, kmc);
5383                 if (cur == NULL) {
5384                         freeb(mp);
5385                         return (NULL);
5386                 }
5387         }
5388         mp->b_wptr = cur;
5389         eprop->sadb_prop_len = SADB_8TO64(cur - mp->b_rptr);
5390 
5391         return (mp);
5392 }
5393 
5394 /*
5395  * For this mblk, insert a new acquire record.  Assume bucket contains addrs
5396  * of all of the same length.  Give up (and drop) if memory
5397  * cannot be allocated for a new one; otherwise, invoke callback to
5398  * send the acquire up..
5399  *
5400  * In cases where we need both AH and ESP, add the SA to the ESP ACQUIRE
5401  * list.  The ah_add_sa_finish() routines can look at the packet's attached
5402  * attributes and handle this case specially.
5403  */
5404 void
5405 sadb_acquire(mblk_t *datamp, ip_xmit_attr_t *ixa, boolean_t need_ah,
5406     boolean_t need_esp)
5407 {
5408         mblk_t  *asyncmp, *regular, *extended, *common, *prop, *eprop;
5409         sadbp_t *spp;
5410         sadb_t *sp;
5411         ipsacq_t *newbie;
5412         iacqf_t *bucket;

5413         ipha_t *ipha = (ipha_t *)datamp->b_rptr;
5414         ip6_t *ip6h = (ip6_t *)datamp->b_rptr;
5415         uint32_t *src, *dst, *isrc, *idst;
5416         ipsec_policy_t *pp = ixa->ixa_ipsec_policy;
5417         ipsec_action_t *ap = ixa->ixa_ipsec_action;
5418         sa_family_t af;
5419         int hashoffset;
5420         uint32_t seq;
5421         uint64_t unique_id = 0;

5422         boolean_t tunnel_mode = (ixa->ixa_flags & IXAF_IPSEC_TUNNEL) != 0;
5423         ts_label_t      *tsl;
5424         netstack_t      *ns = ixa->ixa_ipst->ips_netstack;
5425         ipsec_stack_t   *ipss = ns->netstack_ipsec;
5426         ipsecesp_stack_t *espstack = ns->netstack_ipsecesp;
5427         ipsecah_stack_t *ahstack = ns->netstack_ipsecah;
5428         ipsec_selector_t sel;
5429         queue_t *q;
5430 
5431         ASSERT((pp != NULL) || (ap != NULL));
5432 
5433         ASSERT(need_ah || need_esp);
5434 
5435         /* Assign sadb pointers */
5436         if (need_esp) {
5437                 /*
5438                  * ESP happens first if we need both AH and ESP.
5439                  */
5440                 spp = &espstack->esp_sadb;
5441         } else {


5442                 spp = &ahstack->ah_sadb;
5443         }
5444         sp = (ixa->ixa_flags & IXAF_IS_IPV4) ? &spp->s_v4 : &spp->s_v6;
5445 
5446         if (is_system_labeled())
5447                 tsl = ixa->ixa_tsl;
5448         else
5449                 tsl = NULL;
5450 
5451         if (ap == NULL)
5452                 ap = pp->ipsp_act;

5453         ASSERT(ap != NULL);
5454 
5455         if (ap->ipa_act.ipa_apply.ipp_use_unique || tunnel_mode)
5456                 unique_id = SA_FORM_UNIQUE_ID(ixa);
5457 
5458         /*
5459          * Set up an ACQUIRE record.
5460          *
5461          * Immediately, make sure the ACQUIRE sequence number doesn't slip
5462          * below the lowest point allowed in the kernel.  (In other words,
5463          * make sure the high bit on the sequence number is set.)
5464          */
5465 
5466         seq = keysock_next_seq(ns) | IACQF_LOWEST_SEQ;
5467 
5468         if (IPH_HDR_VERSION(ipha) == IP_VERSION) {
5469                 src = (uint32_t *)&ipha->ipha_src;
5470                 dst = (uint32_t *)&ipha->ipha_dst;
5471                 af = AF_INET;
5472                 hashoffset = OUTBOUND_HASH_V4(sp, ipha->ipha_dst);


5562          * Make the ip_xmit_attr_t into something we can queue.
5563          * If no memory it frees datamp.
5564          */
5565         asyncmp = ip_xmit_attr_to_mblk(ixa);
5566         if (asyncmp != NULL)
5567                 linkb(asyncmp, datamp);
5568 
5569         /* Queue up packet.  Use b_next. */
5570 
5571         if (asyncmp == NULL) {
5572                 /* Statistics for allocation failure */
5573                 if (ixa->ixa_flags & IXAF_IS_IPV4) {
5574                         BUMP_MIB(&ixa->ixa_ipst->ips_ip_mib,
5575                             ipIfStatsOutDiscards);
5576                 } else {
5577                         BUMP_MIB(&ixa->ixa_ipst->ips_ip6_mib,
5578                             ipIfStatsOutDiscards);
5579                 }
5580                 ip_drop_output("No memory for asyncmp", datamp, NULL);
5581                 freemsg(datamp);
5582                 /*
5583                  * The acquire record will be freed quickly if it's new
5584                  * (ipsacq_expire == 0), and will proceed as if no packet
5585                  * showed up if not.
5586                  */
5587                 mutex_exit(&newbie->ipsacq_lock);
5588                 return;
5589         } else if (newbie->ipsacq_numpackets == 0) {
5590                 /* First one. */
5591                 newbie->ipsacq_mp = asyncmp;
5592                 newbie->ipsacq_numpackets = 1;
5593                 newbie->ipsacq_expire = gethrestime_sec();
5594                 /*
5595                  * Extended ACQUIRE with both AH+ESP will use ESP's timeout
5596                  * value.
5597                  */
5598                 newbie->ipsacq_expire += *spp->s_acquire_timeout;
5599                 newbie->ipsacq_seq = seq;
5600                 newbie->ipsacq_addrfam = af;
5601 
5602                 newbie->ipsacq_srcport = ixa->ixa_ipsec_src_port;
5603                 newbie->ipsacq_dstport = ixa->ixa_ipsec_dst_port;
5604                 newbie->ipsacq_icmp_type = ixa->ixa_ipsec_icmp_type;
5605                 newbie->ipsacq_icmp_code = ixa->ixa_ipsec_icmp_code;
5606                 if (tunnel_mode) {
5607                         newbie->ipsacq_inneraddrfam = ixa->ixa_ipsec_inaf;
5608                         newbie->ipsacq_proto = ixa->ixa_ipsec_inaf == AF_INET6 ?
5609                             IPPROTO_IPV6 : IPPROTO_ENCAP;
5610                         newbie->ipsacq_innersrcpfx = ixa->ixa_ipsec_insrcpfx;
5611                         newbie->ipsacq_innerdstpfx = ixa->ixa_ipsec_indstpfx;
5612                         IPSA_COPY_ADDR(newbie->ipsacq_innersrc,
5613                             ixa->ixa_ipsec_insrc, ixa->ixa_ipsec_inaf);
5614                         IPSA_COPY_ADDR(newbie->ipsacq_innerdst,
5615                             ixa->ixa_ipsec_indst, ixa->ixa_ipsec_inaf);
5616                 } else {
5617                         newbie->ipsacq_proto = ixa->ixa_ipsec_proto;
5618                 }
5619                 newbie->ipsacq_unique_id = unique_id;
5620 
5621                 if (tsl != NULL) {
5622                         label_hold(tsl);
5623                         newbie->ipsacq_tsl = tsl;
5624                 }
5625         } else {
5626                 /* Scan to the end of the list & insert. */
5627                 mblk_t *lastone = newbie->ipsacq_mp;
5628 
5629                 while (lastone->b_next != NULL)
5630                         lastone = lastone->b_next;
5631                 lastone->b_next = asyncmp;
5632                 if (newbie->ipsacq_numpackets++ == ipsacq_maxpackets) {
5633                         newbie->ipsacq_numpackets = ipsacq_maxpackets;
5634                         lastone = newbie->ipsacq_mp;
5635                         newbie->ipsacq_mp = lastone->b_next;
5636                         lastone->b_next = NULL;
5637 
5638                         /* Freeing the async message */
5639                         lastone = ip_xmit_attr_free_mblk(lastone);
5640                         ip_drop_packet(lastone, B_FALSE, NULL,
5641                             DROPPER(ipss, ipds_sadb_acquire_toofull),
5642                             &ipss->ipsec_sadb_dropper);
5643                 } else {


5648 
5649         /*
5650          * Reset addresses.  Set them to the most recently added mblk chain,
5651          * so that the address pointers in the acquire record will point
5652          * at an mblk still attached to the acquire list.
5653          */
5654 
5655         newbie->ipsacq_srcaddr = src;
5656         newbie->ipsacq_dstaddr = dst;
5657 
5658         /*
5659          * If the acquire record has more than one queued packet, we've
5660          * already sent an ACQUIRE, and don't need to repeat ourself.
5661          */
5662         if (newbie->ipsacq_seq != seq || newbie->ipsacq_numpackets > 1) {
5663                 /* I have an acquire outstanding already! */
5664                 mutex_exit(&newbie->ipsacq_lock);
5665                 return;
5666         }
5667 
5668         if (need_esp) {
5669                 ESP_BUMP_STAT(espstack, acquire_requests);
5670                 q = espstack->esp_pfkey_q;
5671         } else {
5672                 /*
5673                  * Two cases get us here:
5674                  * 1.) AH-only policy.
5675                  *
5676                  * 2.) A continuation of an AH+ESP policy, and this is the
5677                  * post-ESP, AH-needs-to-send-a-regular-ACQUIRE case.
5678                  * (i.e. called from esp_do_outbound_ah().)
5679                  */
5680                 AH_BUMP_STAT(ahstack, acquire_requests);
5681                 q = ahstack->ah_pfkey_q;
5682         }
5683 
5684         /*
5685          * Get selectors and other policy-expression bits needed for an
5686          * ACQUIRE.
5687          */
5688         bzero(&sel, sizeof (sel));
5689         sel.ips_isv4 = (ixa->ixa_flags & IXAF_IS_IPV4) != 0;
5690         if (tunnel_mode) {
5691                 sel.ips_protocol = (ixa->ixa_ipsec_inaf == AF_INET) ?
5692                     IPPROTO_ENCAP : IPPROTO_IPV6;
5693         } else {
5694                 sel.ips_protocol = ixa->ixa_ipsec_proto;
5695                 sel.ips_local_port = ixa->ixa_ipsec_src_port;
5696                 sel.ips_remote_port = ixa->ixa_ipsec_dst_port;
5697         }
5698         sel.ips_icmp_type = ixa->ixa_ipsec_icmp_type;
5699         sel.ips_icmp_code = ixa->ixa_ipsec_icmp_code;
5700         sel.ips_is_icmp_inv_acq = 0;
5701         if (af == AF_INET) {
5702                 sel.ips_local_addr_v4 = ipha->ipha_src;
5703                 sel.ips_remote_addr_v4 = ipha->ipha_dst;
5704         } else {
5705                 sel.ips_local_addr_v6 = ip6h->ip6_src;
5706                 sel.ips_remote_addr_v6 = ip6h->ip6_dst;
5707         }
5708 



5709 

5710         /*
5711          * 1. Generate addresses, kmc, and sensitivity.  These are "common"
5712          * and should be an mblk pointed to by common. TBD -- eventually it
5713          * will include triggering packet contents as more address extensions.
5714          *
5715          * 2. Generate ACQUIRE & KEYSOCK_OUT and single-protocol proposal.
5716          * These are "regular" and "prop".  String regular->b_cont->b_cont =
5717          * common, common->b_cont = prop.
5718          *
5719          * 3. If extended register got turned on, generate EXT_ACQUIRE &
5720          * KEYSOCK_OUT and multi-protocol eprop. These are "extended" and
5721          * "eprop".  String extended->b_cont->b_cont = dupb(common) and
5722          * extended->b_cont->b_cont->b_cont = prop.
5723          *
5724          * 4. Deliver:  putnext(q, regular) and if there, putnext(q, extended).
5725          */

5726 
5727         regular = extended = prop = eprop = NULL;




5728 
5729         common = sadb_acquire_msg_common(&sel, pp, ap, tunnel_mode, tsl, NULL);
5730         if (common == NULL)
5731                 goto bail;
5732 
5733         regular = sadb_acquire_msg_base(0, (need_esp ?
5734             SADB_SATYPE_ESP : SADB_SATYPE_AH), newbie->ipsacq_seq, 0);
5735         if (regular == NULL)
5736                 goto bail;
5737 
5738         /*
5739          * Pardon the boolean cleverness. At least one of need_* must be true.
5740          * If they are equal, it's an AH & ESP policy and ESP needs to go
5741          * first.  If they aren't, just check the contents of need_esp.
5742          */
5743         prop = sadb_acquire_prop(ap, ns, need_esp);
5744         if (prop == NULL)
5745                 goto bail;
5746 
5747         /* Link the parts together. */
5748         regular->b_cont->b_cont = common;
5749         common->b_cont = prop;
5750         /*
5751          * Prop is now linked, so don't freemsg() it if the extended
5752          * construction goes off the rails.

5753          */
5754         prop = NULL;
5755 
5756         ((sadb_msg_t *)(regular->b_cont->b_rptr))->sadb_msg_len =
5757             SADB_8TO64(msgsize(regular->b_cont));
5758 
5759         /*
5760          * If we need an extended ACQUIRE, build it here.
5761          */
5762         if (keysock_extended_reg(ns)) {
5763                 /* NOTE: "common" still points to what we need. */
5764                 extended = sadb_acquire_msg_base(0, 0, newbie->ipsacq_seq, 0);
5765                 if (extended == NULL) {
5766                         common = NULL;
5767                         goto bail;
5768                 }
5769 
5770                 extended->b_cont->b_cont = dupb(common);
5771                 common = NULL;
5772                 if (extended->b_cont->b_cont == NULL)
5773                         goto bail;
5774 
5775                 eprop = sadb_acquire_extended_prop(ap, ns);
5776                 if (eprop == NULL)
5777                         goto bail;
5778                 extended->b_cont->b_cont->b_cont = eprop;
5779 
5780                 ((sadb_msg_t *)(extended->b_cont->b_rptr))->sadb_msg_len =
5781                     SADB_8TO64(msgsize(extended->b_cont));
5782         }
5783 
5784         /* So we don't hold a lock across putnext()... */
5785         mutex_exit(&newbie->ipsacq_lock);
5786 
5787         if (extended != NULL)
5788                 putnext(q, extended);
5789         ASSERT(regular != NULL);
5790         putnext(q, regular);
5791         return;
5792 
5793 bail:
5794         /* Make this acquire record go away quickly... */
5795         newbie->ipsacq_expire = 0;
5796         /* Exploit freemsg(NULL) being legal for fun & profit. */
5797         freemsg(common);
5798         freemsg(prop);
5799         freemsg(extended);
5800         freemsg(regular);
5801         mutex_exit(&newbie->ipsacq_lock);
5802 }
5803 
5804 /*
5805  * Unlink and free an acquire record.
5806  */
5807 void
5808 sadb_destroy_acquire(ipsacq_t *acqrec, netstack_t *ns)
5809 {
5810         mblk_t          *mp;
5811         ipsec_stack_t   *ipss = ns->netstack_ipsec;
5812 
5813         ASSERT(MUTEX_HELD(acqrec->ipsacq_linklock));
5814 
5815         if (acqrec->ipsacq_policy != NULL) {
5816                 IPPOL_REFRELE(acqrec->ipsacq_policy);
5817         }
5818         if (acqrec->ipsacq_act != NULL) {
5819                 IPACT_REFRELE(acqrec->ipsacq_act);
5820         }
5821 


6035         /* LINTED */
6036         ASSERT((_C_LEN & 1) == 0);
6037         ASSERT((senslen & 7) == 0);
6038 
6039         sl = label2bslabel(tsl);
6040 
6041         sens->sadb_sens_exttype = exttype;
6042         sens->sadb_sens_len = SADB_8TO64(senslen);
6043 
6044         sens->sadb_sens_dpd = tsl->tsl_doi;
6045         sens->sadb_sens_sens_level = LCLASS(sl);
6046         sens->sadb_sens_integ_level = 0; /* TBD */
6047         sens->sadb_sens_sens_len = _C_LEN >> 1;
6048         sens->sadb_sens_integ_len = 0; /* TBD */
6049         sens->sadb_x_sens_flags = 0;
6050 
6051         bitmap = (uint8_t *)(sens + 1);
6052         bcopy(&(((_bslabel_impl_t *)sl)->compartments), bitmap, _C_LEN * 4);
6053 }
6054 















6055 /*
6056  * Okay, how do we report errors/invalid labels from this?
6057  * With a special designated "not a label" cred_t ?
6058  */
6059 /* ARGSUSED */
6060 ts_label_t *
6061 sadb_label_from_sens(sadb_sens_t *sens, uint64_t *bitmap)
6062 {
6063         int bitmap_len = SADB_64TO8(sens->sadb_sens_sens_len);
6064         bslabel_t sl;
6065         ts_label_t *tsl;
6066 
6067         if (sens->sadb_sens_integ_level != 0)
6068                 return (NULL);
6069         if (sens->sadb_sens_integ_len != 0)
6070                 return (NULL);
6071         if (bitmap_len > _C_LEN * 4)
6072                 return (NULL);
6073 
6074         bsllow(&sl);
6075         LCLASS_SET((_bslabel_impl_t *)&sl, sens->sadb_sens_sens_level);
6076         bcopy(bitmap, &((_bslabel_impl_t *)&sl)->compartments,
6077             bitmap_len);
6078 
6079         tsl = labelalloc(&sl, sens->sadb_sens_dpd, KM_NOSLEEP);
6080         if (tsl == NULL)
6081                 return (NULL);
6082 
6083         if (sens->sadb_x_sens_flags & SADB_X_SENS_UNLABELED)
6084                 tsl->tsl_flags |= TSLF_UNLABELED;
6085         return (tsl);
6086 }
6087 
6088 /* End XXX label-library-leakage */
6089 
6090 /*


































































































































































































































































































































































































6091  * Given an SADB_GETSPI message, find an appropriately ranged SA and
6092  * allocate an SA.  If there are message improprieties, return (ipsa_t *)-1.
6093  * If there was a memory allocation error, return NULL.  (Assume NULL !=
6094  * (ipsa_t *)-1).
6095  *
6096  * master_spi is passed in host order.
6097  */
6098 ipsa_t *
6099 sadb_getspi(keysock_in_t *ksi, uint32_t master_spi, int *diagnostic,
6100     netstack_t *ns, uint_t sa_type)
6101 {
6102         sadb_address_t *src =
6103             (sadb_address_t *)ksi->ks_in_extv[SADB_EXT_ADDRESS_SRC],
6104             *dst = (sadb_address_t *)ksi->ks_in_extv[SADB_EXT_ADDRESS_DST];
6105         sadb_spirange_t *range =
6106             (sadb_spirange_t *)ksi->ks_in_extv[SADB_EXT_SPIRANGE];
6107         struct sockaddr_in *ssa, *dsa;
6108         struct sockaddr_in6 *ssa6, *dsa6;
6109         uint32_t *srcaddr, *dstaddr;
6110         sa_family_t af;


7061                 break;
7062         default:
7063                 ipsec_oth_pol(&sel, &pp, ipst);
7064                 break;
7065         }
7066 
7067         /*
7068          * If we didn't find a matching conn_t or other policy head, take a
7069          * look in the global policy.
7070          */
7071         if (pp == NULL) {
7072                 pp = ipsec_find_policy(IPSEC_TYPE_OUTBOUND, NULL, &sel, ns);
7073                 if (pp == NULL) {
7074                         /* There's no global policy. */
7075                         err = ENOENT;
7076                         diagnostic = 0;
7077                         goto bail;
7078                 }
7079         }
7080 
7081         ASSERT(pp != NULL);
7082         retmp = sadb_acquire_msg_base(0, 0, samsg->sadb_msg_seq,
7083             samsg->sadb_msg_pid);
7084         if (retmp != NULL) {
7085                 /* Remove KEYSOCK_OUT, because caller constructs it instead. */
7086                 mblk_t *kso = retmp;
7087 
7088                 retmp = retmp->b_cont;
7089                 freeb(kso);
7090                 /* Append addresses... */
7091                 retmp->b_cont = sadb_acquire_msg_common(&sel, pp, NULL,
7092                     (itp != NULL && (itp->itp_flags & ITPF_P_TUNNEL)), NULL,
7093                     sens);
7094                 if (retmp->b_cont == NULL) {
7095                         freemsg(retmp);
7096                         retmp = NULL;
7097                 }
7098                 /* And the policy result. */
7099                 retmp->b_cont->b_cont =
7100                     sadb_acquire_extended_prop(pp->ipsp_act, ns);
7101                 if (retmp->b_cont->b_cont == NULL) {
7102                         freemsg(retmp);
7103                         retmp = NULL;
7104                 }
7105                 ((sadb_msg_t *)retmp->b_rptr)->sadb_msg_len =
7106                     SADB_8TO64(msgsize(retmp));
7107         }
7108 
7109         if (pp != NULL) {
7110                 IPPOL_REFRELE(pp);
7111         }
7112         ASSERT(err == 0 && diagnostic == 0);
7113         if (retmp == NULL)
7114                 err = ENOMEM;
7115 bail:
7116         if (itp != NULL) {
7117                 ITP_REFRELE(itp, ns);
7118         }
7119         samsg->sadb_msg_errno = (uint8_t)err;
7120         samsg->sadb_x_msg_diagnostic = (uint16_t)diagnostic;
7121         return (retmp);
7122 }
7123 
7124 /*
7125  * ipsa_lpkt is a one-element queue, only manipulated by the next two
7126  * functions.  They have to hold the ipsa_lock because of potential races
7127  * between key management using SADB_UPDATE, and inbound packets that may
7128  * queue up on the larval SA (hence the 'l' in "lpkt").