Home | History | Annotate | Download | only in ip
      1      0      stevel /*
      2      0      stevel  * CDDL HEADER START
      3      0      stevel  *
      4      0      stevel  * The contents of this file are subject to the terms of the
      5   2751      danmcd  * Common Development and Distribution License (the "License").
      6   2751      danmcd  * You may not use this file except in compliance with the License.
      7      0      stevel  *
      8      0      stevel  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9      0      stevel  * or http://www.opensolaris.org/os/licensing.
     10      0      stevel  * See the License for the specific language governing permissions
     11      0      stevel  * and limitations under the License.
     12      0      stevel  *
     13      0      stevel  * When distributing Covered Code, include this CDDL HEADER in each
     14      0      stevel  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15      0      stevel  * If applicable, add the following below this CDDL HEADER, with the
     16      0      stevel  * fields enclosed by brackets "[]" replaced with your own identifying
     17      0      stevel  * information: Portions Copyright [yyyy] [name of copyright owner]
     18      0      stevel  *
     19      0      stevel  * CDDL HEADER END
     20      0      stevel  */
     21      0      stevel /*
     22   8704      danmcd  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     23      0      stevel  * Use is subject to license terms.
     24      0      stevel  */
     25      0      stevel 
     26      0      stevel #include <sys/types.h>
     27      0      stevel #include <sys/stream.h>
     28      0      stevel #include <sys/stropts.h>
     29      0      stevel #include <sys/errno.h>
     30      0      stevel #include <sys/strlog.h>
     31      0      stevel #include <sys/tihdr.h>
     32      0      stevel #include <sys/socket.h>
     33      0      stevel #include <sys/ddi.h>
     34      0      stevel #include <sys/sunddi.h>
     35      0      stevel #include <sys/kmem.h>
     36   3448    dh155122 #include <sys/zone.h>
     37      0      stevel #include <sys/sysmacros.h>
     38      0      stevel #include <sys/cmn_err.h>
     39      0      stevel #include <sys/vtrace.h>
     40      0      stevel #include <sys/debug.h>
     41      0      stevel #include <sys/atomic.h>
     42      0      stevel #include <sys/strsun.h>
     43      0      stevel #include <sys/random.h>
     44      0      stevel #include <netinet/in.h>
     45      0      stevel #include <net/if.h>
     46      0      stevel #include <netinet/ip6.h>
     47      0      stevel #include <net/pfkeyv2.h>
     48  10824        Mark #include <net/pfpolicy.h>
     49      0      stevel 
     50      0      stevel #include <inet/common.h>
     51      0      stevel #include <inet/mi.h>
     52      0      stevel #include <inet/nd.h>
     53      0      stevel #include <inet/ip.h>
     54   4987      danmcd #include <inet/ip_impl.h>
     55      0      stevel #include <inet/ip6.h>
     56  11042        Erik #include <inet/ip_if.h>
     57  11042        Erik #include <inet/ip_ndp.h>
     58      0      stevel #include <inet/sadb.h>
     59      0      stevel #include <inet/ipsec_info.h>
     60      0      stevel #include <inet/ipsec_impl.h>
     61      0      stevel #include <inet/ipsecesp.h>
     62      0      stevel #include <inet/ipdrop.h>
     63      0      stevel #include <inet/tcp.h>
     64      0      stevel #include <sys/kstat.h>
     65      0      stevel #include <sys/policy.h>
     66      0      stevel #include <sys/strsun.h>
     67  10934  sommerfeld #include <sys/strsubr.h>
     68      0      stevel #include <inet/udp_impl.h>
     69      0      stevel #include <sys/taskq.h>
     70   3448    dh155122 #include <sys/note.h>
     71  10934  sommerfeld 
     72  10934  sommerfeld #include <sys/tsol/tnet.h>
     73      0      stevel 
     74      0      stevel /*
     75      0      stevel  * Table of ND variables supported by ipsecesp. These are loaded into
     76      0      stevel  * ipsecesp_g_nd in ipsecesp_init_nd.
     77      0      stevel  * All of these are alterable, within the min/max values given, at run time.
     78      0      stevel  */
     79   3448    dh155122 static	ipsecespparam_t	lcl_param_arr[] = {
     80      0      stevel 	/* min	max			value	name */
     81      0      stevel 	{ 0,	3,			0,	"ipsecesp_debug"},
     82      0      stevel 	{ 125,	32000, SADB_AGE_INTERVAL_DEFAULT, "ipsecesp_age_interval"},
     83      0      stevel 	{ 1,	10,			1,	"ipsecesp_reap_delay"},
     84      0      stevel 	{ 1,	SADB_MAX_REPLAY,	64,	"ipsecesp_replay_size"},
     85      0      stevel 	{ 1,	300,			15,	"ipsecesp_acquire_timeout"},
     86      0      stevel 	{ 1,	1800,			90,	"ipsecesp_larval_timeout"},
     87      0      stevel 	/* Default lifetime values for ACQUIRE messages. */
     88      0      stevel 	{ 0,	0xffffffffU,	0,	"ipsecesp_default_soft_bytes"},
     89      0      stevel 	{ 0,	0xffffffffU,	0,	"ipsecesp_default_hard_bytes"},
     90      0      stevel 	{ 0,	0xffffffffU,	24000,	"ipsecesp_default_soft_addtime"},
     91      0      stevel 	{ 0,	0xffffffffU,	28800,	"ipsecesp_default_hard_addtime"},
     92      0      stevel 	{ 0,	0xffffffffU,	0,	"ipsecesp_default_soft_usetime"},
     93      0      stevel 	{ 0,	0xffffffffU,	0,	"ipsecesp_default_hard_usetime"},
     94      0      stevel 	{ 0,	1,		0,	"ipsecesp_log_unknown_spi"},
     95      0      stevel 	{ 0,	2,		1,	"ipsecesp_padding_check"},
     96   4987      danmcd 	{ 0,	600,		20,	"ipsecesp_nat_keepalive_interval"},
     97      0      stevel };
     98   3448    dh155122 #define	ipsecesp_debug	ipsecesp_params[0].ipsecesp_param_value
     99   3448    dh155122 #define	ipsecesp_age_interval ipsecesp_params[1].ipsecesp_param_value
    100   3448    dh155122 #define	ipsecesp_age_int_max	ipsecesp_params[1].ipsecesp_param_max
    101   3448    dh155122 #define	ipsecesp_reap_delay	ipsecesp_params[2].ipsecesp_param_value
    102   3448    dh155122 #define	ipsecesp_replay_size	ipsecesp_params[3].ipsecesp_param_value
    103   3448    dh155122 #define	ipsecesp_acquire_timeout	\
    104   3448    dh155122 	ipsecesp_params[4].ipsecesp_param_value
    105   3448    dh155122 #define	ipsecesp_larval_timeout	\
    106   3448    dh155122 	ipsecesp_params[5].ipsecesp_param_value
    107   3448    dh155122 #define	ipsecesp_default_soft_bytes	\
    108   3448    dh155122 	ipsecesp_params[6].ipsecesp_param_value
    109   3448    dh155122 #define	ipsecesp_default_hard_bytes	\
    110   3448    dh155122 	ipsecesp_params[7].ipsecesp_param_value
    111   3448    dh155122 #define	ipsecesp_default_soft_addtime	\
    112   3448    dh155122 	ipsecesp_params[8].ipsecesp_param_value
    113   3448    dh155122 #define	ipsecesp_default_hard_addtime	\
    114   3448    dh155122 	ipsecesp_params[9].ipsecesp_param_value
    115   3448    dh155122 #define	ipsecesp_default_soft_usetime	\
    116   3448    dh155122 	ipsecesp_params[10].ipsecesp_param_value
    117   3448    dh155122 #define	ipsecesp_default_hard_usetime	\
    118   3448    dh155122 	ipsecesp_params[11].ipsecesp_param_value
    119   3448    dh155122 #define	ipsecesp_log_unknown_spi	\
    120   3448    dh155122 	ipsecesp_params[12].ipsecesp_param_value
    121   3448    dh155122 #define	ipsecesp_padding_check	\
    122   3448    dh155122 	ipsecesp_params[13].ipsecesp_param_value
    123   4987      danmcd /* For ipsecesp_nat_keepalive_interval, see ipsecesp.h. */
    124      0      stevel 
    125      0      stevel #define	esp0dbg(a)	printf a
    126      0      stevel /* NOTE:  != 0 instead of > 0 so lint doesn't complain. */
    127   3448    dh155122 #define	esp1dbg(espstack, a)	if (espstack->ipsecesp_debug != 0) printf a
    128   3448    dh155122 #define	esp2dbg(espstack, a)	if (espstack->ipsecesp_debug > 1) printf a
    129   3448    dh155122 #define	esp3dbg(espstack, a)	if (espstack->ipsecesp_debug > 2) printf a
    130      0      stevel 
    131      0      stevel static int ipsecesp_open(queue_t *, dev_t *, int, int, cred_t *);
    132      0      stevel static int ipsecesp_close(queue_t *);
    133      0      stevel static void ipsecesp_wput(queue_t *, mblk_t *);
    134   3448    dh155122 static void	*ipsecesp_stack_init(netstackid_t stackid, netstack_t *ns);
    135   3448    dh155122 static void	ipsecesp_stack_fini(netstackid_t stackid, void *arg);
    136   3448    dh155122 static void esp_send_acquire(ipsacq_t *, mblk_t *, netstack_t *);
    137      0      stevel 
    138   4987      danmcd static void esp_prepare_udp(netstack_t *, mblk_t *, ipha_t *);
    139  11042        Erik static void esp_outbound_finish(mblk_t *, ip_xmit_attr_t *);
    140  11042        Erik static void esp_inbound_restart(mblk_t *, ip_recv_attr_t *);
    141      0      stevel 
    142   3448    dh155122 static boolean_t esp_register_out(uint32_t, uint32_t, uint_t,
    143  11042        Erik     ipsecesp_stack_t *, cred_t *);
    144      0      stevel static boolean_t esp_strip_header(mblk_t *, boolean_t, uint32_t,
    145   3448    dh155122     kstat_named_t **, ipsecesp_stack_t *);
    146  11042        Erik static mblk_t *esp_submit_req_inbound(mblk_t *, ip_recv_attr_t *,
    147  11042        Erik     ipsa_t *, uint_t);
    148  11042        Erik static mblk_t *esp_submit_req_outbound(mblk_t *, ip_xmit_attr_t *,
    149  11042        Erik     ipsa_t *, uchar_t *, uint_t);
    150   7749  Thejaswini 
    151   3448    dh155122 /* Setable in /etc/system */
    152   3448    dh155122 uint32_t esp_hash_size = IPSEC_DEFAULT_HASH_SIZE;
    153      0      stevel 
    154      0      stevel static struct module_info info = {
    155      0      stevel 	5137, "ipsecesp", 0, INFPSZ, 65536, 1024
    156      0      stevel };
    157      0      stevel 
    158      0      stevel static struct qinit rinit = {
    159  11042        Erik 	(pfi_t)putnext, NULL, ipsecesp_open, ipsecesp_close, NULL, &info,
    160      0      stevel 	NULL
    161      0      stevel };
    162      0      stevel 
    163      0      stevel static struct qinit winit = {
    164      0      stevel 	(pfi_t)ipsecesp_wput, NULL, ipsecesp_open, ipsecesp_close, NULL, &info,
    165      0      stevel 	NULL
    166      0      stevel };
    167      0      stevel 
    168      0      stevel struct streamtab ipsecespinfo = {
    169      0      stevel 	&rinit, &winit, NULL, NULL
    170      0      stevel };
    171      0      stevel 
    172      0      stevel static taskq_t *esp_taskq;
    173      0      stevel 
    174      0      stevel /*
    175      0      stevel  * OTOH, this one is set at open/close, and I'm D_MTQPAIR for now.
    176      0      stevel  *
    177      0      stevel  * Question:	Do I need this, given that all instance's esps->esps_wq point
    178      0      stevel  *		to IP?
    179      0      stevel  *
    180      0      stevel  * Answer:	Yes, because I need to know which queue is BOUND to
    181      0      stevel  *		IPPROTO_ESP
    182      0      stevel  */
    183      0      stevel 
    184      0      stevel /*
    185      0      stevel  * Stats.  This may eventually become a full-blown SNMP MIB once that spec
    186      0      stevel  * stabilizes.
    187      0      stevel  */
    188      0      stevel 
    189   3448    dh155122 typedef struct esp_kstats_s {
    190      0      stevel 	kstat_named_t esp_stat_num_aalgs;
    191      0      stevel 	kstat_named_t esp_stat_good_auth;
    192      0      stevel 	kstat_named_t esp_stat_bad_auth;
    193      0      stevel 	kstat_named_t esp_stat_bad_padding;
    194      0      stevel 	kstat_named_t esp_stat_replay_failures;
    195      0      stevel 	kstat_named_t esp_stat_replay_early_failures;
    196      0      stevel 	kstat_named_t esp_stat_keysock_in;
    197      0      stevel 	kstat_named_t esp_stat_out_requests;
    198      0      stevel 	kstat_named_t esp_stat_acquire_requests;
    199      0      stevel 	kstat_named_t esp_stat_bytes_expired;
    200      0      stevel 	kstat_named_t esp_stat_out_discards;
    201      0      stevel 	kstat_named_t esp_stat_crypto_sync;
    202      0      stevel 	kstat_named_t esp_stat_crypto_async;
    203      0      stevel 	kstat_named_t esp_stat_crypto_failures;
    204      0      stevel 	kstat_named_t esp_stat_num_ealgs;
    205      0      stevel 	kstat_named_t esp_stat_bad_decrypt;
    206   7066      danmcd 	kstat_named_t esp_stat_sa_port_renumbers;
    207      0      stevel } esp_kstats_t;
    208      0      stevel 
    209   3448    dh155122 /*
    210   3448    dh155122  * espstack->esp_kstats is equal to espstack->esp_ksp->ks_data if
    211   3448    dh155122  * kstat_create_netstack for espstack->esp_ksp succeeds, but when it
    212   3448    dh155122  * fails, it will be NULL. Note this is done for all stack instances,
    213   3448    dh155122  * so it *could* fail. hence a non-NULL checking is done for
    214   3448    dh155122  * ESP_BUMP_STAT and ESP_DEBUMP_STAT
    215   3448    dh155122  */
    216   3448    dh155122 #define	ESP_BUMP_STAT(espstack, x)					\
    217   3448    dh155122 do {									\
    218   3448    dh155122 	if (espstack->esp_kstats != NULL)				\
    219   3448    dh155122 		(espstack->esp_kstats->esp_stat_ ## x).value.ui64++;	\
    220   3448    dh155122 _NOTE(CONSTCOND)							\
    221   3448    dh155122 } while (0)
    222      0      stevel 
    223   3448    dh155122 #define	ESP_DEBUMP_STAT(espstack, x)					\
    224   3448    dh155122 do {									\
    225   3448    dh155122 	if (espstack->esp_kstats != NULL)				\
    226   3448    dh155122 		(espstack->esp_kstats->esp_stat_ ## x).value.ui64--;	\
    227   3448    dh155122 _NOTE(CONSTCOND)							\
    228   3448    dh155122 } while (0)
    229      0      stevel 
    230      0      stevel static int	esp_kstat_update(kstat_t *, int);
    231      0      stevel 
    232      0      stevel static boolean_t
    233   3448    dh155122 esp_kstat_init(ipsecesp_stack_t *espstack, netstackid_t stackid)
    234      0      stevel {
    235   3448    dh155122 	espstack->esp_ksp = kstat_create_netstack("ipsecesp", 0, "esp_stat",
    236   3448    dh155122 	    "net", KSTAT_TYPE_NAMED,
    237   3448    dh155122 	    sizeof (esp_kstats_t) / sizeof (kstat_named_t),
    238   3448    dh155122 	    KSTAT_FLAG_PERSISTENT, stackid);
    239      0      stevel 
    240   3448    dh155122 	if (espstack->esp_ksp == NULL || espstack->esp_ksp->ks_data == NULL)
    241      0      stevel 		return (B_FALSE);
    242      0      stevel 
    243   3448    dh155122 	espstack->esp_kstats = espstack->esp_ksp->ks_data;
    244      0      stevel 
    245   3448    dh155122 	espstack->esp_ksp->ks_update = esp_kstat_update;
    246   3448    dh155122 	espstack->esp_ksp->ks_private = (void *)(uintptr_t)stackid;
    247      0      stevel 
    248      0      stevel #define	K64 KSTAT_DATA_UINT64
    249   3448    dh155122 #define	KI(x) kstat_named_init(&(espstack->esp_kstats->esp_stat_##x), #x, K64)
    250      0      stevel 
    251      0      stevel 	KI(num_aalgs);
    252      0      stevel 	KI(num_ealgs);
    253      0      stevel 	KI(good_auth);
    254      0      stevel 	KI(bad_auth);
    255      0      stevel 	KI(bad_padding);
    256      0      stevel 	KI(replay_failures);
    257      0      stevel 	KI(replay_early_failures);
    258      0      stevel 	KI(keysock_in);
    259      0      stevel 	KI(out_requests);
    260      0      stevel 	KI(acquire_requests);
    261      0      stevel 	KI(bytes_expired);
    262      0      stevel 	KI(out_discards);
    263      0      stevel 	KI(crypto_sync);
    264      0      stevel 	KI(crypto_async);
    265      0      stevel 	KI(crypto_failures);
    266      0      stevel 	KI(bad_decrypt);
    267   7066      danmcd 	KI(sa_port_renumbers);
    268      0      stevel 
    269      0      stevel #undef KI
    270      0      stevel #undef K64
    271      0      stevel 
    272   3448    dh155122 	kstat_install(espstack->esp_ksp);
    273      0      stevel 
    274      0      stevel 	return (B_TRUE);
    275      0      stevel }
    276      0      stevel 
    277      0      stevel static int
    278      0      stevel esp_kstat_update(kstat_t *kp, int rw)
    279      0      stevel {
    280      0      stevel 	esp_kstats_t *ekp;
    281   3448    dh155122 	netstackid_t	stackid = (zoneid_t)(uintptr_t)kp->ks_private;
    282   3448    dh155122 	netstack_t	*ns;
    283   3448    dh155122 	ipsec_stack_t	*ipss;
    284      0      stevel 
    285      0      stevel 	if ((kp == NULL) || (kp->ks_data == NULL))
    286      0      stevel 		return (EIO);
    287      0      stevel 
    288      0      stevel 	if (rw == KSTAT_WRITE)
    289      0      stevel 		return (EACCES);
    290      0      stevel 
    291   3448    dh155122 	ns = netstack_find_by_stackid(stackid);
    292   3448    dh155122 	if (ns == NULL)
    293   3448    dh155122 		return (-1);
    294   3448    dh155122 	ipss = ns->netstack_ipsec;
    295   3448    dh155122 	if (ipss == NULL) {
    296   3448    dh155122 		netstack_rele(ns);
    297   3448    dh155122 		return (-1);
    298   3448    dh155122 	}
    299      0      stevel 	ekp = (esp_kstats_t *)kp->ks_data;
    300      0      stevel 
    301   3448    dh155122 	mutex_enter(&ipss->ipsec_alg_lock);
    302   3448    dh155122 	ekp->esp_stat_num_aalgs.value.ui64 =
    303   3448    dh155122 	    ipss->ipsec_nalgs[IPSEC_ALG_AUTH];
    304   3448    dh155122 	ekp->esp_stat_num_ealgs.value.ui64 =
    305   3448    dh155122 	    ipss->ipsec_nalgs[IPSEC_ALG_ENCR];
    306   3448    dh155122 	mutex_exit(&ipss->ipsec_alg_lock);
    307      0      stevel 
    308   3448    dh155122 	netstack_rele(ns);
    309      0      stevel 	return (0);
    310      0      stevel }
    311      0      stevel 
    312      0      stevel #ifdef DEBUG
    313      0      stevel /*
    314      0      stevel  * Debug routine, useful to see pre-encryption data.
    315      0      stevel  */
    316      0      stevel static char *
    317      0      stevel dump_msg(mblk_t *mp)
    318      0      stevel {
    319      0      stevel 	char tmp_str[3], tmp_line[256];
    320      0      stevel 
    321      0      stevel 	while (mp != NULL) {
    322      0      stevel 		unsigned char *ptr;
    323      0      stevel 
    324      0      stevel 		printf("mblk address 0x%p, length %ld, db_ref %d "
    325      0      stevel 		    "type %d, base 0x%p, lim 0x%p\n",
    326      0      stevel 		    (void *) mp, (long)(mp->b_wptr - mp->b_rptr),
    327      0      stevel 		    mp->b_datap->db_ref, mp->b_datap->db_type,
    328      0      stevel 		    (void *)mp->b_datap->db_base, (void *)mp->b_datap->db_lim);
    329      0      stevel 		ptr = mp->b_rptr;
    330      0      stevel 
    331      0      stevel 		tmp_line[0] = '\0';
    332      0      stevel 		while (ptr < mp->b_wptr) {
    333      0      stevel 			uint_t diff;
    334      0      stevel 
    335      0      stevel 			diff = (ptr - mp->b_rptr);
    336      0      stevel 			if (!(diff & 0x1f)) {
    337      0      stevel 				if (strlen(tmp_line) > 0) {
    338      0      stevel 					printf("bytes: %s\n", tmp_line);
    339      0      stevel 					tmp_line[0] = '\0';
    340      0      stevel 				}
    341      0      stevel 			}
    342      0      stevel 			if (!(diff & 0x3))
    343      0      stevel 				(void) strcat(tmp_line, " ");
    344      0      stevel 			(void) sprintf(tmp_str, "%02x", *ptr);
    345      0      stevel 			(void) strcat(tmp_line, tmp_str);
    346      0      stevel 			ptr++;
    347      0      stevel 		}
    348      0      stevel 		if (strlen(tmp_line) > 0)
    349      0      stevel 			printf("bytes: %s\n", tmp_line);
    350      0      stevel 
    351      0      stevel 		mp = mp->b_cont;
    352      0      stevel 	}
    353      0      stevel 
    354      0      stevel 	return ("\n");
    355      0      stevel }
    356      0      stevel 
    357      0      stevel #else /* DEBUG */
    358      0      stevel static char *
    359      0      stevel dump_msg(mblk_t *mp)
    360      0      stevel {
    361      0      stevel 	printf("Find value of mp %p.\n", mp);
    362      0      stevel 	return ("\n");
    363      0      stevel }
    364      0      stevel #endif /* DEBUG */
    365      0      stevel 
    366      0      stevel /*
    367      0      stevel  * Don't have to lock age_interval, as only one thread will access it at
    368      0      stevel  * a time, because I control the one function that does with timeout().
    369      0      stevel  */
    370      0      stevel static void
    371   3448    dh155122 esp_ager(void *arg)
    372      0      stevel {
    373   3448    dh155122 	ipsecesp_stack_t *espstack = (ipsecesp_stack_t *)arg;
    374   3448    dh155122 	netstack_t	*ns = espstack->ipsecesp_netstack;
    375      0      stevel 	hrtime_t begin = gethrtime();
    376      0      stevel 
    377   3448    dh155122 	sadb_ager(&espstack->esp_sadb.s_v4, espstack->esp_pfkey_q,
    378  11042        Erik 	    espstack->ipsecesp_reap_delay, ns);
    379   3448    dh155122 	sadb_ager(&espstack->esp_sadb.s_v6, espstack->esp_pfkey_q,
    380  11042        Erik 	    espstack->ipsecesp_reap_delay, ns);
    381      0      stevel 
    382   3448    dh155122 	espstack->esp_event = sadb_retimeout(begin, espstack->esp_pfkey_q,
    383   3448    dh155122 	    esp_ager, espstack,
    384   3448    dh155122 	    &espstack->ipsecesp_age_interval, espstack->ipsecesp_age_int_max,
    385   3448    dh155122 	    info.mi_idnum);
    386      0      stevel }
    387      0      stevel 
    388      0      stevel /*
    389      0      stevel  * Get an ESP NDD parameter.
    390      0      stevel  */
    391      0      stevel /* ARGSUSED */
    392      0      stevel static int
    393      0      stevel ipsecesp_param_get(q, mp, cp, cr)
    394      0      stevel 	queue_t	*q;
    395      0      stevel 	mblk_t	*mp;
    396      0      stevel 	caddr_t	cp;
    397      0      stevel 	cred_t *cr;
    398      0      stevel {
    399      0      stevel 	ipsecespparam_t	*ipsecesppa = (ipsecespparam_t *)cp;
    400      0      stevel 	uint_t value;
    401   3448    dh155122 	ipsecesp_stack_t	*espstack = (ipsecesp_stack_t *)q->q_ptr;
    402      0      stevel 
    403   3448    dh155122 	mutex_enter(&espstack->ipsecesp_param_lock);
    404      0      stevel 	value = ipsecesppa->ipsecesp_param_value;
    405   3448    dh155122 	mutex_exit(&espstack->ipsecesp_param_lock);
    406      0      stevel 
    407      0      stevel 	(void) mi_mpprintf(mp, "%u", value);
    408      0      stevel 	return (0);
    409      0      stevel }
    410      0      stevel 
    411      0      stevel /*
    412      0      stevel  * This routine sets an NDD variable in a ipsecespparam_t structure.
    413      0      stevel  */
    414      0      stevel /* ARGSUSED */
    415      0      stevel static int
    416      0      stevel ipsecesp_param_set(q, mp, value, cp, cr)
    417      0      stevel 	queue_t	*q;
    418      0      stevel 	mblk_t	*mp;
    419      0      stevel 	char	*value;
    420      0      stevel 	caddr_t	cp;
    421      0      stevel 	cred_t *cr;
    422      0      stevel {
    423      0      stevel 	ulong_t	new_value;
    424      0      stevel 	ipsecespparam_t	*ipsecesppa = (ipsecespparam_t *)cp;
    425   3448    dh155122 	ipsecesp_stack_t	*espstack = (ipsecesp_stack_t *)q->q_ptr;
    426      0      stevel 
    427      0      stevel 	/*
    428      0      stevel 	 * Fail the request if the new value does not lie within the
    429      0      stevel 	 * required bounds.
    430      0      stevel 	 */
    431      0      stevel 	if (ddi_strtoul(value, NULL, 10, &new_value) != 0 ||
    432      0      stevel 	    new_value < ipsecesppa->ipsecesp_param_min ||
    433      0      stevel 	    new_value > ipsecesppa->ipsecesp_param_max) {
    434      0      stevel 		return (EINVAL);
    435      0      stevel 	}
    436      0      stevel 
    437      0      stevel 	/* Set the new value */
    438   3448    dh155122 	mutex_enter(&espstack->ipsecesp_param_lock);
    439      0      stevel 	ipsecesppa->ipsecesp_param_value = new_value;
    440   3448    dh155122 	mutex_exit(&espstack->ipsecesp_param_lock);
    441      0      stevel 	return (0);
    442      0      stevel }
    443      0      stevel 
    444      0      stevel /*
    445      0      stevel  * Using lifetime NDD variables, fill in an extended combination's
    446      0      stevel  * lifetime information.
    447      0      stevel  */
    448      0      stevel void
    449   3448    dh155122 ipsecesp_fill_defs(sadb_x_ecomb_t *ecomb, netstack_t *ns)
    450      0      stevel {
    451   3448    dh155122 	ipsecesp_stack_t	*espstack = ns->netstack_ipsecesp;
    452   3448    dh155122 
    453   3448    dh155122 	ecomb->sadb_x_ecomb_soft_bytes = espstack->ipsecesp_default_soft_bytes;
    454   3448    dh155122 	ecomb->sadb_x_ecomb_hard_bytes = espstack->ipsecesp_default_hard_bytes;
    455   3448    dh155122 	ecomb->sadb_x_ecomb_soft_addtime =
    456   3448    dh155122 	    espstack->ipsecesp_default_soft_addtime;
    457   3448    dh155122 	ecomb->sadb_x_ecomb_hard_addtime =
    458   3448    dh155122 	    espstack->ipsecesp_default_hard_addtime;
    459   3448    dh155122 	ecomb->sadb_x_ecomb_soft_usetime =
    460   3448    dh155122 	    espstack->ipsecesp_default_soft_usetime;
    461   3448    dh155122 	ecomb->sadb_x_ecomb_hard_usetime =
    462   3448    dh155122 	    espstack->ipsecesp_default_hard_usetime;
    463      0      stevel }
    464      0      stevel 
    465      0      stevel /*
    466      0      stevel  * Initialize things for ESP at module load time.
    467      0      stevel  */
    468      0      stevel boolean_t
    469      0      stevel ipsecesp_ddi_init(void)
    470      0      stevel {
    471   3448    dh155122 	esp_taskq = taskq_create("esp_taskq", 1, minclsyspri,
    472   3448    dh155122 	    IPSEC_TASKQ_MIN, IPSEC_TASKQ_MAX, 0);
    473      0      stevel 
    474   3448    dh155122 	/*
    475   3448    dh155122 	 * We want to be informed each time a stack is created or
    476   3448    dh155122 	 * destroyed in the kernel, so we can maintain the
    477   3448    dh155122 	 * set of ipsecesp_stack_t's.
    478   3448    dh155122 	 */
    479   3448    dh155122 	netstack_register(NS_IPSECESP, ipsecesp_stack_init, NULL,
    480   3448    dh155122 	    ipsecesp_stack_fini);
    481   3448    dh155122 
    482   3448    dh155122 	return (B_TRUE);
    483   3448    dh155122 }
    484   3448    dh155122 
    485   3448    dh155122 /*
    486   3448    dh155122  * Walk through the param array specified registering each element with the
    487   3448    dh155122  * named dispatch handler.
    488   3448    dh155122  */
    489   3448    dh155122 static boolean_t
    490   3448    dh155122 ipsecesp_param_register(IDP *ndp, ipsecespparam_t *espp, int cnt)
    491   3448    dh155122 {
    492   3448    dh155122 	for (; cnt-- > 0; espp++) {
    493      0      stevel 		if (espp->ipsecesp_param_name != NULL &&
    494      0      stevel 		    espp->ipsecesp_param_name[0]) {
    495   3448    dh155122 			if (!nd_load(ndp,
    496   3448    dh155122 			    espp->ipsecesp_param_name,
    497      0      stevel 			    ipsecesp_param_get, ipsecesp_param_set,
    498      0      stevel 			    (caddr_t)espp)) {
    499   3448    dh155122 				nd_free(ndp);
    500      0      stevel 				return (B_FALSE);
    501      0      stevel 			}
    502      0      stevel 		}
    503      0      stevel 	}
    504   3448    dh155122 	return (B_TRUE);
    505   3448    dh155122 }
    506   3448    dh155122 /*
    507   3448    dh155122  * Initialize things for ESP for each stack instance
    508   3448    dh155122  */
    509   3448    dh155122 static void *
    510   3448    dh155122 ipsecesp_stack_init(netstackid_t stackid, netstack_t *ns)
    511   3448    dh155122 {
    512   3448    dh155122 	ipsecesp_stack_t	*espstack;
    513   3448    dh155122 	ipsecespparam_t		*espp;
    514      0      stevel 
    515   3448    dh155122 	espstack = (ipsecesp_stack_t *)kmem_zalloc(sizeof (*espstack),
    516   3448    dh155122 	    KM_SLEEP);
    517   3448    dh155122 	espstack->ipsecesp_netstack = ns;
    518      0      stevel 
    519   3448    dh155122 	espp = (ipsecespparam_t *)kmem_alloc(sizeof (lcl_param_arr), KM_SLEEP);
    520   3448    dh155122 	espstack->ipsecesp_params = espp;
    521   3448    dh155122 	bcopy(lcl_param_arr, espp, sizeof (lcl_param_arr));
    522      0      stevel 
    523   3448    dh155122 	(void) ipsecesp_param_register(&espstack->ipsecesp_g_nd, espp,
    524   3448    dh155122 	    A_CNT(lcl_param_arr));
    525      0      stevel 
    526   3448    dh155122 	(void) esp_kstat_init(espstack, stackid);
    527      0      stevel 
    528   3448    dh155122 	espstack->esp_sadb.s_acquire_timeout =
    529   3448    dh155122 	    &espstack->ipsecesp_acquire_timeout;
    530   3448    dh155122 	espstack->esp_sadb.s_acqfn = esp_send_acquire;
    531   3448    dh155122 	sadbp_init("ESP", &espstack->esp_sadb, SADB_SATYPE_ESP, esp_hash_size,
    532   3448    dh155122 	    espstack->ipsecesp_netstack);
    533      0      stevel 
    534   3448    dh155122 	mutex_init(&espstack->ipsecesp_param_lock, NULL, MUTEX_DEFAULT, 0);
    535   3448    dh155122 
    536   3448    dh155122 	ip_drop_register(&espstack->esp_dropper, "IPsec ESP");
    537   3448    dh155122 	return (espstack);
    538      0      stevel }
    539      0      stevel 
    540      0      stevel /*
    541      0      stevel  * Destroy things for ESP at module unload time.
    542      0      stevel  */
    543      0      stevel void
    544      0      stevel ipsecesp_ddi_destroy(void)
    545      0      stevel {
    546   3448    dh155122 	netstack_unregister(NS_IPSECESP);
    547   3448    dh155122 	taskq_destroy(esp_taskq);
    548   3448    dh155122 }
    549      0      stevel 
    550   3448    dh155122 /*
    551   3448    dh155122  * Destroy things for ESP for one stack instance
    552   3448    dh155122  */
    553   3448    dh155122 static void
    554   3448    dh155122 ipsecesp_stack_fini(netstackid_t stackid, void *arg)
    555   3448    dh155122 {
    556   3448    dh155122 	ipsecesp_stack_t *espstack = (ipsecesp_stack_t *)arg;
    557   3448    dh155122 
    558   3448    dh155122 	if (espstack->esp_pfkey_q != NULL) {
    559   3448    dh155122 		(void) quntimeout(espstack->esp_pfkey_q, espstack->esp_event);
    560   3448    dh155122 	}
    561   3448    dh155122 	espstack->esp_sadb.s_acqfn = NULL;
    562   3448    dh155122 	espstack->esp_sadb.s_acquire_timeout = NULL;
    563   3448    dh155122 	sadbp_destroy(&espstack->esp_sadb, espstack->ipsecesp_netstack);
    564   3448    dh155122 	ip_drop_unregister(&espstack->esp_dropper);
    565   3448    dh155122 	mutex_destroy(&espstack->ipsecesp_param_lock);
    566   3448    dh155122 	nd_free(&espstack->ipsecesp_g_nd);
    567   3448    dh155122 
    568   3448    dh155122 	kmem_free(espstack->ipsecesp_params, sizeof (lcl_param_arr));
    569   3448    dh155122 	espstack->ipsecesp_params = NULL;
    570   3448    dh155122 	kstat_delete_netstack(espstack->esp_ksp, stackid);
    571   3448    dh155122 	espstack->esp_ksp = NULL;
    572   3448    dh155122 	espstack->esp_kstats = NULL;
    573   3448    dh155122 	kmem_free(espstack, sizeof (*espstack));
    574      0      stevel }
    575      0      stevel 
    576      0      stevel /*
    577  11042        Erik  * ESP module open routine, which is here for keysock plumbing.
    578  11042        Erik  * Keysock is pushed over {AH,ESP} which is an artifact from the Bad Old
    579  11042        Erik  * Days of export control, and fears that ESP would not be allowed
    580  11042        Erik  * to be shipped at all by default.  Eventually, keysock should
    581  11042        Erik  * either access AH and ESP via modstubs or krtld dependencies, or
    582  11042        Erik  * perhaps be folded in with AH and ESP into a single IPsec/netsec
    583  11042        Erik  * module ("netsec" if PF_KEY provides more than AH/ESP keying tables).
    584      0      stevel  */
    585      0      stevel /* ARGSUSED */
    586      0      stevel static int
    587      0      stevel ipsecesp_open(queue_t *q, dev_t *devp, int flag, int sflag, cred_t *credp)
    588      0      stevel {
    589   3448    dh155122 	netstack_t		*ns;
    590   3448    dh155122 	ipsecesp_stack_t	*espstack;
    591   3448    dh155122 
    592   7118    sommerfe 	if (secpolicy_ip_config(credp, B_FALSE) != 0)
    593      0      stevel 		return (EPERM);
    594      0      stevel 
    595      0      stevel 	if (q->q_ptr != NULL)
    596      0      stevel 		return (0);  /* Re-open of an already open instance. */
    597      0      stevel 
    598      0      stevel 	if (sflag != MODOPEN)
    599      0      stevel 		return (EINVAL);
    600   3448    dh155122 
    601   3448    dh155122 	ns = netstack_find_by_cred(credp);
    602   3448    dh155122 	ASSERT(ns != NULL);
    603   3448    dh155122 	espstack = ns->netstack_ipsecesp;
    604   3448    dh155122 	ASSERT(espstack != NULL);
    605      0      stevel 
    606   3448    dh155122 	q->q_ptr = espstack;
    607   3448    dh155122 	WR(q)->q_ptr = q->q_ptr;
    608      0      stevel 
    609  11042        Erik 	qprocson(q);
    610      0      stevel 	return (0);
    611      0      stevel }
    612      0      stevel 
    613      0      stevel /*
    614      0      stevel  * ESP module close routine.
    615      0      stevel  */
    616      0      stevel static int
    617      0      stevel ipsecesp_close(queue_t *q)
    618      0      stevel {
    619   3448    dh155122 	ipsecesp_stack_t	*espstack = (ipsecesp_stack_t *)q->q_ptr;
    620      0      stevel 
    621      0      stevel 	/*
    622      0      stevel 	 * Clean up q_ptr, if needed.
    623      0      stevel 	 */
    624      0      stevel 	qprocsoff(q);
    625      0      stevel 
    626      0      stevel 	/* Keysock queue check is safe, because of OCEXCL perimeter. */
    627      0      stevel 
    628   3448    dh155122 	if (q == espstack->esp_pfkey_q) {
    629   3448    dh155122 		esp1dbg(espstack,
    630   3448    dh155122 		    ("ipsecesp_close:  Ummm... keysock is closing ESP.\n"));
    631   3448    dh155122 		espstack->esp_pfkey_q = NULL;
    632      0      stevel 		/* Detach qtimeouts. */
    633   3448    dh155122 		(void) quntimeout(q, espstack->esp_event);
    634      0      stevel 	}
    635      0      stevel 
    636   3448    dh155122 	netstack_rele(espstack->ipsecesp_netstack);
    637      0      stevel 	return (0);
    638      0      stevel }
    639      0      stevel 
    640      0      stevel /*
    641      0      stevel  * Add a number of bytes to what the SA has protected so far.  Return
    642      0      stevel  * B_TRUE if the SA can still protect that many bytes.
    643      0      stevel  *
    644      0      stevel  * Caller must REFRELE the passed-in assoc.  This function must REFRELE
    645      0      stevel  * any obtained peer SA.
    646      0      stevel  */
    647      0      stevel static boolean_t
    648      0      stevel esp_age_bytes(ipsa_t *assoc, uint64_t bytes, boolean_t inbound)
    649      0      stevel {
    650      0      stevel 	ipsa_t *inassoc, *outassoc;
    651      0      stevel 	isaf_t *bucket;
    652      0      stevel 	boolean_t inrc, outrc, isv6;
    653      0      stevel 	sadb_t *sp;
    654      0      stevel 	int outhash;
    655   3448    dh155122 	netstack_t		*ns = assoc->ipsa_netstack;
    656   3448    dh155122 	ipsecesp_stack_t	*espstack = ns->netstack_ipsecesp;
    657      0      stevel 
    658      0      stevel 	/* No peer?  No problem! */
    659      0      stevel 	if (!assoc->ipsa_haspeer) {
    660   3448    dh155122 		return (sadb_age_bytes(espstack->esp_pfkey_q, assoc, bytes,
    661      0      stevel 		    B_TRUE));
    662      0      stevel 	}
    663      0      stevel 
    664      0      stevel 	/*
    665      0      stevel 	 * Otherwise, we want to grab both the original assoc and its peer.
    666      0      stevel 	 * There might be a race for this, but if it's a real race, two
    667      0      stevel 	 * expire messages may occur.  We limit this by only sending the
    668      0      stevel 	 * expire message on one of the peers, we'll pick the inbound
    669      0      stevel 	 * arbitrarily.
    670      0      stevel 	 *
    671      0      stevel 	 * If we need tight synchronization on the peer SA, then we need to
    672      0      stevel 	 * reconsider.
    673      0      stevel 	 */
    674      0      stevel 
    675      0      stevel 	/* Use address length to select IPv6/IPv4 */
    676      0      stevel 	isv6 = (assoc->ipsa_addrfam == AF_INET6);
    677   3448    dh155122 	sp = isv6 ? &espstack->esp_sadb.s_v6 : &espstack->esp_sadb.s_v4;
    678      0      stevel 
    679      0      stevel 	if (inbound) {
    680      0      stevel 		inassoc = assoc;
    681      0      stevel 		if (isv6) {
    682    564    sommerfe 			outhash = OUTBOUND_HASH_V6(sp, *((in6_addr_t *)
    683      0      stevel 			    &inassoc->ipsa_dstaddr));
    684      0      stevel 		} else {
    685    564    sommerfe 			outhash = OUTBOUND_HASH_V4(sp, *((ipaddr_t *)
    686   4987      danmcd 			    &inassoc->ipsa_dstaddr));
    687      0      stevel 		}
    688      0      stevel 		bucket = &sp->sdb_of[outhash];
    689      0      stevel 		mutex_enter(&bucket->isaf_lock);
    690      0      stevel 		outassoc = ipsec_getassocbyspi(bucket, inassoc->ipsa_spi,
    691      0      stevel 		    inassoc->ipsa_srcaddr, inassoc->ipsa_dstaddr,
    692      0      stevel 		    inassoc->ipsa_addrfam);
    693      0      stevel 		mutex_exit(&bucket->isaf_lock);
    694      0      stevel 		if (outassoc == NULL) {
    695      0      stevel 			/* Q: Do we wish to set haspeer == B_FALSE? */
    696      0      stevel 			esp0dbg(("esp_age_bytes: "
    697      0      stevel 			    "can't find peer for inbound.\n"));
    698   3448    dh155122 			return (sadb_age_bytes(espstack->esp_pfkey_q, inassoc,
    699      0      stevel 			    bytes, B_TRUE));
    700      0      stevel 		}
    701      0      stevel 	} else {
    702      0      stevel 		outassoc = assoc;
    703    564    sommerfe 		bucket = INBOUND_BUCKET(sp, outassoc->ipsa_spi);
    704      0      stevel 		mutex_enter(&bucket->isaf_lock);
    705      0      stevel 		inassoc = ipsec_getassocbyspi(bucket, outassoc->ipsa_spi,
    706      0      stevel 		    outassoc->ipsa_srcaddr, outassoc->ipsa_dstaddr,
    707      0      stevel 		    outassoc->ipsa_addrfam);
    708      0      stevel 		mutex_exit(&bucket->isaf_lock);
    709      0      stevel 		if (inassoc == NULL) {
    710      0      stevel 			/* Q: Do we wish to set haspeer == B_FALSE? */
    711      0      stevel 			esp0dbg(("esp_age_bytes: "
    712      0      stevel 			    "can't find peer for outbound.\n"));
    713   3448    dh155122 			return (sadb_age_bytes(espstack->esp_pfkey_q, outassoc,
    714      0      stevel 			    bytes, B_TRUE));
    715      0      stevel 		}
    716      0      stevel 	}
    717      0      stevel 
    718   3448    dh155122 	inrc = sadb_age_bytes(espstack->esp_pfkey_q, inassoc, bytes, B_TRUE);
    719   3448    dh155122 	outrc = sadb_age_bytes(espstack->esp_pfkey_q, outassoc, bytes, B_FALSE);
    720      0      stevel 
    721      0      stevel 	/*
    722      0      stevel 	 * REFRELE any peer SA.
    723      0      stevel 	 *
    724      0      stevel 	 * Because of the multi-line macro nature of IPSA_REFRELE, keep
    725      0      stevel 	 * them in { }.
    726      0      stevel 	 */
    727      0      stevel 	if (inbound) {
    728      0      stevel 		IPSA_REFRELE(outassoc);
    729      0      stevel 	} else {
    730      0      stevel 		IPSA_REFRELE(inassoc);
    731      0      stevel 	}
    732      0      stevel 
    733      0      stevel 	return (inrc && outrc);
    734      0      stevel }
    735      0      stevel 
    736      0      stevel /*
    737      0      stevel  * Do incoming NAT-T manipulations for packet.
    738  11042        Erik  * Returns NULL if the mblk chain is consumed.
    739  11042        Erik  */
    740  11042        Erik static mblk_t *
    741      0      stevel esp_fix_natt_checksums(mblk_t *data_mp, ipsa_t *assoc)
    742      0      stevel {
    743      0      stevel 	ipha_t *ipha = (ipha_t *)data_mp->b_rptr;
    744  11042        Erik 	tcpha_t *tcpha;
    745      0      stevel 	udpha_t *udpha;
    746      0      stevel 	/* Initialize to our inbound cksum adjustment... */
    747      0      stevel 	uint32_t sum = assoc->ipsa_inbound_cksum;
    748      0      stevel 
    749      0      stevel 	switch (ipha->ipha_protocol) {
    750      0      stevel 	case IPPROTO_TCP:
    751  11042        Erik 		tcpha = (tcpha_t *)(data_mp->b_rptr +
    752      0      stevel 		    IPH_HDR_LENGTH(ipha));
    753      0      stevel 
    754      0      stevel #define	DOWN_SUM(x) (x) = ((x) & 0xFFFF) +	 ((x) >> 16)
    755  11042        Erik 		sum += ~ntohs(tcpha->tha_sum) & 0xFFFF;
    756      0      stevel 		DOWN_SUM(sum);
    757      0      stevel 		DOWN_SUM(sum);
    758  11042        Erik 		tcpha->tha_sum = ~htons(sum);
    759      0      stevel 		break;
    760      0      stevel 	case IPPROTO_UDP:
    761      0      stevel 		udpha = (udpha_t *)(data_mp->b_rptr + IPH_HDR_LENGTH(ipha));
    762      0      stevel 
    763      0      stevel 		if (udpha->uha_checksum != 0) {
    764      0      stevel 			/* Adujst if the inbound one was not zero. */
    765      0      stevel 			sum += ~ntohs(udpha->uha_checksum) & 0xFFFF;
    766      0      stevel 			DOWN_SUM(sum);
    767      0      stevel 			DOWN_SUM(sum);
    768      0      stevel 			udpha->uha_checksum = ~htons(sum);
    769      0      stevel 			if (udpha->uha_checksum == 0)
    770      0      stevel 				udpha->uha_checksum = 0xFFFF;
    771      0      stevel 		}
    772      0      stevel #undef DOWN_SUM
    773      0      stevel 		break;
    774      0      stevel 	case IPPROTO_IP:
    775      0      stevel 		/*
    776      0      stevel 		 * This case is only an issue for self-encapsulated
    777      0      stevel 		 * packets.  So for now, fall through.
    778      0      stevel 		 */
    779      0      stevel 		break;
    780      0      stevel 	}
    781  11042        Erik 	return (data_mp);
    782      0      stevel }
    783      0      stevel 
    784      0      stevel 
    785      0      stevel /*
    786   3192      danmcd  * Strip ESP header, check padding, and fix IP header.
    787      0      stevel  * Returns B_TRUE on success, B_FALSE if an error occured.
    788      0      stevel  */
    789      0      stevel static boolean_t
    790      0      stevel esp_strip_header(mblk_t *data_mp, boolean_t isv4, uint32_t ivlen,
    791   3448    dh155122     kstat_named_t **counter, ipsecesp_stack_t *espstack)
    792      0      stevel {
    793      0      stevel 	ipha_t *ipha;
    794      0      stevel 	ip6_t *ip6h;
    795      0      stevel 	uint_t divpoint;
    796      0      stevel 	mblk_t *scratch;
    797      0      stevel 	uint8_t nexthdr, padlen;
    798      0      stevel 	uint8_t lastpad;
    799   3448    dh155122 	ipsec_stack_t	*ipss = espstack->ipsecesp_netstack->netstack_ipsec;
    800   3192      danmcd 	uint8_t *lastbyte;
    801      0      stevel 
    802      0      stevel 	/*
    803      0      stevel 	 * Strip ESP data and fix IP header.
    804      0      stevel 	 *
    805      0      stevel 	 * XXX In case the beginning of esp_inbound() changes to not do a
    806      0      stevel 	 * pullup, this part of the code can remain unchanged.
    807      0      stevel 	 */
    808      0      stevel 	if (isv4) {
    809      0      stevel 		ASSERT((data_mp->b_wptr - data_mp->b_rptr) >= sizeof (ipha_t));
    810      0      stevel 		ipha = (ipha_t *)data_mp->b_rptr;
    811      0      stevel 		ASSERT((data_mp->b_wptr - data_mp->b_rptr) >= sizeof (esph_t) +
    812      0      stevel 		    IPH_HDR_LENGTH(ipha));
    813      0      stevel 		divpoint = IPH_HDR_LENGTH(ipha);
    814      0      stevel 	} else {
    815      0      stevel 		ASSERT((data_mp->b_wptr - data_mp->b_rptr) >= sizeof (ip6_t));
    816      0      stevel 		ip6h = (ip6_t *)data_mp->b_rptr;
    817      0      stevel 		divpoint = ip_hdr_length_v6(data_mp, ip6h);
    818      0      stevel 	}
    819      0      stevel 
    820      0      stevel 	scratch = data_mp;
    821      0      stevel 	while (scratch->b_cont != NULL)
    822      0      stevel 		scratch = scratch->b_cont;
    823      0      stevel 
    824      0      stevel 	ASSERT((scratch->b_wptr - scratch->b_rptr) >= 3);
    825      0      stevel 
    826      0      stevel 	/*
    827      0      stevel 	 * "Next header" and padding length are the last two bytes in the
    828      0      stevel 	 * ESP-protected datagram, thus the explicit - 1 and - 2.
    829      0      stevel 	 * lastpad is the last byte of the padding, which can be used for
    830      0      stevel 	 * a quick check to see if the padding is correct.
    831      0      stevel 	 */
    832   3192      danmcd 	lastbyte = scratch->b_wptr - 1;
    833   3192      danmcd 	nexthdr = *lastbyte--;
    834   3192      danmcd 	padlen = *lastbyte--;
    835      0      stevel 
    836      0      stevel 	if (isv4) {
    837      0      stevel 		/* Fix part of the IP header. */
    838      0      stevel 		ipha->ipha_protocol = nexthdr;
    839      0      stevel 		/*
    840      0      stevel 		 * Reality check the padlen.  The explicit - 2 is for the
    841      0      stevel 		 * padding length and the next-header bytes.
    842      0      stevel 		 */
    843      0      stevel 		if (padlen >= ntohs(ipha->ipha_length) - sizeof (ipha_t) - 2 -
    844      0      stevel 		    sizeof (esph_t) - ivlen) {
    845   3448    dh155122 			ESP_BUMP_STAT(espstack, bad_decrypt);
    846   3448    dh155122 			ipsec_rl_strlog(espstack->ipsecesp_netstack,
    847   3448    dh155122 			    info.mi_idnum, 0, 0,
    848   3448    dh155122 			    SL_ERROR | SL_WARN,
    849   3192      danmcd 			    "Corrupt ESP packet (padlen too big).\n");
    850   3448    dh155122 			esp1dbg(espstack, ("padlen (%d) is greater than:\n",
    851   4987      danmcd 			    padlen));
    852   3448    dh155122 			esp1dbg(espstack, ("pkt len(%d) - ip hdr - esp "
    853   3448    dh155122 			    "hdr - ivlen(%d) = %d.\n",
    854   3448    dh155122 			    ntohs(ipha->ipha_length), ivlen,
    855      0      stevel 			    (int)(ntohs(ipha->ipha_length) - sizeof (ipha_t) -
    856   3448    dh155122 			    2 - sizeof (esph_t) - ivlen)));
    857   3448    dh155122 			*counter = DROPPER(ipss, ipds_esp_bad_padlen);
    858      0      stevel 			return (B_FALSE);
    859      0      stevel 		}
    860      0      stevel 
    861      0      stevel 		/*
    862      0      stevel 		 * Fix the rest of the header.  The explicit - 2 is for the
    863      0      stevel 		 * padding length and the next-header bytes.
    864      0      stevel 		 */
    865      0      stevel 		ipha->ipha_length = htons(ntohs(ipha->ipha_length) - padlen -
    866      0      stevel 		    2 - sizeof (esph_t) - ivlen);
    867      0      stevel 		ipha->ipha_hdr_checksum = 0;
    868      0      stevel 		ipha->ipha_hdr_checksum = (uint16_t)ip_csum_hdr(ipha);
    869      0      stevel 	} else {
    870      0      stevel 		if (ip6h->ip6_nxt == IPPROTO_ESP) {
    871      0      stevel 			ip6h->ip6_nxt = nexthdr;
    872      0      stevel 		} else {
    873  11042        Erik 			ip_pkt_t ipp;
    874      0      stevel 
    875      0      stevel 			bzero(&ipp, sizeof (ipp));
    876  11042        Erik 			(void) ip_find_hdr_v6(data_mp, ip6h, B_FALSE, &ipp,
    877  11042        Erik 			    NULL);
    878      0      stevel 			if (ipp.ipp_dstopts != NULL) {
    879      0      stevel 				ipp.ipp_dstopts->ip6d_nxt = nexthdr;
    880      0      stevel 			} else if (ipp.ipp_rthdr != NULL) {
    881      0      stevel 				ipp.ipp_rthdr->ip6r_nxt = nexthdr;
    882      0      stevel 			} else if (ipp.ipp_hopopts != NULL) {
    883      0      stevel 				ipp.ipp_hopopts->ip6h_nxt = nexthdr;
    884      0      stevel 			} else {
    885      0      stevel 				/* Panic a DEBUG kernel. */
    886      0      stevel 				ASSERT(ipp.ipp_hopopts != NULL);
    887      0      stevel 				/* Otherwise, pretend it's IP + ESP. */
    888      0      stevel 				cmn_err(CE_WARN, "ESP IPv6 headers wrong.\n");
    889      0      stevel 				ip6h->ip6_nxt = nexthdr;
    890      0      stevel 			}
    891      0      stevel 		}
    892      0      stevel 
    893      0      stevel 		if (padlen >= ntohs(ip6h->ip6_plen) - 2 - sizeof (esph_t) -
    894      0      stevel 		    ivlen) {
    895   3448    dh155122 			ESP_BUMP_STAT(espstack, bad_decrypt);
    896   3448    dh155122 			ipsec_rl_strlog(espstack->ipsecesp_netstack,
    897   3448    dh155122 			    info.mi_idnum, 0, 0,
    898   3448    dh155122 			    SL_ERROR | SL_WARN,
    899   3192      danmcd 			    "Corrupt ESP packet (v6 padlen too big).\n");
    900   3448    dh155122 			esp1dbg(espstack, ("padlen (%d) is greater than:\n",
    901   4987      danmcd 			    padlen));
    902   4987      danmcd 			esp1dbg(espstack,
    903   4987      danmcd 			    ("pkt len(%u) - ip hdr - esp hdr - ivlen(%d) = "
    904   4987      danmcd 			    "%u.\n", (unsigned)(ntohs(ip6h->ip6_plen)
    905   4987      danmcd 			    + sizeof (ip6_t)), ivlen,
    906   4987      danmcd 			    (unsigned)(ntohs(ip6h->ip6_plen) - 2 -
    907   4987      danmcd 			    sizeof (esph_t) - ivlen)));
    908   3448    dh155122 			*counter = DROPPER(ipss, ipds_esp_bad_padlen);
    909      0      stevel 			return (B_FALSE);
    910      0      stevel 		}
    911      0      stevel 
    912      0      stevel 
    913      0      stevel 		/*
    914      0      stevel 		 * Fix the rest of the header.  The explicit - 2 is for the
    915      0      stevel 		 * padding length and the next-header bytes.  IPv6 is nice,
    916      0      stevel 		 * because there's no hdr checksum!
    917      0      stevel 		 */
    918      0      stevel 		ip6h->ip6_plen = htons(ntohs(ip6h->ip6_plen) - padlen -
    919      0      stevel 		    2 - sizeof (esph_t) - ivlen);
    920      0      stevel 	}
    921      0      stevel 
    922   3448    dh155122 	if (espstack->ipsecesp_padding_check > 0 && padlen > 0) {
    923   3192      danmcd 		/*
    924   3192      danmcd 		 * Weak padding check: compare last-byte to length, they
    925   3192      danmcd 		 * should be equal.
    926   3192      danmcd 		 */
    927   3192      danmcd 		lastpad = *lastbyte--;
    928      0      stevel 
    929   3192      danmcd 		if (padlen != lastpad) {
    930   3448    dh155122 			ipsec_rl_strlog(espstack->ipsecesp_netstack,
    931   3448    dh155122 			    info.mi_idnum, 0, 0, SL_ERROR | SL_WARN,
    932   3192      danmcd 			    "Corrupt ESP packet (lastpad != padlen).\n");
    933   3448    dh155122 			esp1dbg(espstack,
    934   3448    dh155122 			    ("lastpad (%d) not equal to padlen (%d):\n",
    935   3448    dh155122 			    lastpad, padlen));
    936   3448    dh155122 			ESP_BUMP_STAT(espstack, bad_padding);
    937   3448    dh155122 			*counter = DROPPER(ipss, ipds_esp_bad_padding);
    938   3192      danmcd 			return (B_FALSE);
    939   3192      danmcd 		}
    940      0      stevel 
    941      0      stevel 		/*
    942   3192      danmcd 		 * Strong padding check: Check all pad bytes to see that
    943   3192      danmcd 		 * they're ascending.  Go backwards using a descending counter
    944   3192      danmcd 		 * to verify.  padlen == 1 is checked by previous block, so
    945   3192      danmcd 		 * only bother if we've more than 1 byte of padding.
    946   3192      danmcd 		 * Consequently, start the check one byte before the location
    947   3192      danmcd 		 * of "lastpad".
    948      0      stevel 		 */
    949   3448    dh155122 		if (espstack->ipsecesp_padding_check > 1) {
    950   3192      danmcd 			/*
    951   3192      danmcd 			 * This assert may have to become an if and a pullup
    952   3192      danmcd 			 * if we start accepting multi-dblk mblks. For now,
    953   3192      danmcd 			 * though, any packet here will have been pulled up in
    954   3192      danmcd 			 * esp_inbound.
    955   3192      danmcd 			 */
    956   3192      danmcd 			ASSERT(MBLKL(scratch) >= lastpad + 3);
    957      0      stevel 
    958   3192      danmcd 			/*
    959   3192      danmcd 			 * Use "--lastpad" because we already checked the very
    960   3192      danmcd 			 * last pad byte previously.
    961   3192      danmcd 			 */
    962   3192      danmcd 			while (--lastpad != 0) {
    963   3192      danmcd 				if (lastpad != *lastbyte) {
    964   3448    dh155122 					ipsec_rl_strlog(
    965   3448    dh155122 					    espstack->ipsecesp_netstack,
    966   3448    dh155122 					    info.mi_idnum, 0, 0,
    967   3192      danmcd 					    SL_ERROR | SL_WARN, "Corrupt ESP "
    968   3192      danmcd 					    "packet (bad padding).\n");
    969   3448    dh155122 					esp1dbg(espstack,
    970   3448    dh155122 					    ("padding not in correct"
    971   3448    dh155122 					    " format:\n"));
    972   3448    dh155122 					ESP_BUMP_STAT(espstack, bad_padding);
    973   3448    dh155122 					*counter = DROPPER(ipss,
    974   3448    dh155122 					    ipds_esp_bad_padding);
    975   3192      danmcd 					return (B_FALSE);
    976   3192      danmcd 				}
    977   3192      danmcd 				lastbyte--;
    978      0      stevel 			}
    979      0      stevel 		}
    980      0      stevel 	}
    981      0      stevel 
    982      0      stevel 	/* Trim off the padding. */
    983      0      stevel 	ASSERT(data_mp->b_cont == NULL);
    984      0      stevel 	data_mp->b_wptr -= (padlen + 2);
    985      0      stevel 
    986      0      stevel 	/*
    987      0      stevel 	 * Remove the ESP header.
    988      0      stevel 	 *
    989      0      stevel 	 * The above assertions about data_mp's size will make this work.
    990      0      stevel 	 *
    991      0      stevel 	 * XXX  Question:  If I send up and get back a contiguous mblk,
    992      0      stevel 	 * would it be quicker to bcopy over, or keep doing the dupb stuff?
    993      0      stevel 	 * I go with copying for now.
    994      0      stevel 	 */
    995      0      stevel 
    996      0      stevel 	if (IS_P2ALIGNED(data_mp->b_rptr, sizeof (uint32_t)) &&
    997      0      stevel 	    IS_P2ALIGNED(ivlen, sizeof (uint32_t))) {
    998      0      stevel 		uint8_t *start = data_mp->b_rptr;
    999      0      stevel 		uint32_t *src, *dst;
   1000      0      stevel 
   1001      0      stevel 		src = (uint32_t *)(start + divpoint);
   1002      0      stevel 		dst = (uint32_t *)(start + divpoint + sizeof (esph_t) + ivlen);
   1003      0      stevel 
   1004      0      stevel 		ASSERT(IS_P2ALIGNED(dst, sizeof (uint32_t)) &&
   1005      0      stevel 		    IS_P2ALIGNED(src, sizeof (uint32_t)));
   1006      0      stevel 
   1007      0      stevel 		do {
   1008      0      stevel 			src--;
   1009      0      stevel 			dst--;
   1010      0      stevel 			*dst = *src;
   1011      0      stevel 		} while (src != (uint32_t *)start);
   1012      0      stevel 
   1013      0      stevel 		data_mp->b_rptr = (uchar_t *)dst;
   1014      0      stevel 	} else {
   1015      0      stevel 		uint8_t *start = data_mp->b_rptr;
   1016      0      stevel 		uint8_t *src, *dst;
   1017      0      stevel 
   1018      0      stevel 		src = start + divpoint;
   1019      0      stevel 		dst = src + sizeof (esph_t) + ivlen;
   1020      0      stevel 
   1021      0      stevel 		do {
   1022      0      stevel 			src--;
   1023      0      stevel 			dst--;
   1024      0      stevel 			*dst = *src;
   1025      0      stevel 		} while (src != start);
   1026      0      stevel 
   1027      0      stevel 		data_mp->b_rptr = dst;
   1028      0      stevel 	}
   1029      0      stevel 
   1030   3448    dh155122 	esp2dbg(espstack, ("data_mp after inbound ESP adjustment:\n"));
   1031   3448    dh155122 	esp2dbg(espstack, (dump_msg(data_mp)));
   1032      0      stevel 
   1033      0      stevel 	return (B_TRUE);
   1034      0      stevel }
   1035      0      stevel 
   1036      0      stevel /*
   1037      0      stevel  * Updating use times can be tricky business if the ipsa_haspeer flag is
   1038      0      stevel  * set.  This function is called once in an SA's lifetime.
   1039      0      stevel  *
   1040      0      stevel  * Caller has to REFRELE "assoc" which is passed in.  This function has
   1041      0      stevel  * to REFRELE any peer SA that is obtained.
   1042      0      stevel  */
   1043      0      stevel static void
   1044      0      stevel esp_set_usetime(ipsa_t *assoc, boolean_t inbound)
   1045      0      stevel {
   1046      0      stevel 	ipsa_t *inassoc, *outassoc;
   1047      0      stevel 	isaf_t *bucket;
   1048      0      stevel 	sadb_t *sp;
   1049      0      stevel 	int outhash;
   1050      0      stevel 	boolean_t isv6;
   1051   3448    dh155122 	netstack_t		*ns = assoc->ipsa_netstack;
   1052   3448    dh155122 	ipsecesp_stack_t	*espstack = ns->netstack_ipsecesp;
   1053      0      stevel 
   1054      0      stevel 	/* No peer?  No problem! */
   1055      0      stevel 	if (!assoc->ipsa_haspeer) {
   1056      0      stevel 		sadb_set_usetime(assoc);
   1057      0      stevel 		return;
   1058      0      stevel 	}
   1059      0      stevel 
   1060      0      stevel 	/*
   1061      0      stevel 	 * Otherwise, we want to grab both the original assoc and its peer.
   1062      0      stevel 	 * There might be a race for this, but if it's a real race, the times
   1063      0      stevel 	 * will be out-of-synch by at most a second, and since our time
   1064      0      stevel 	 * granularity is a second, this won't be a problem.
   1065      0      stevel 	 *
   1066      0      stevel 	 * If we need tight synchronization on the peer SA, then we need to
   1067      0      stevel 	 * reconsider.
   1068      0      stevel 	 */
   1069      0      stevel 
   1070      0      stevel 	/* Use address length to select IPv6/IPv4 */
   1071      0      stevel 	isv6 = (assoc->ipsa_addrfam == AF_INET6);
   1072   3448    dh155122 	sp = isv6 ? &espstack->esp_sadb.s_v6 : &espstack->esp_sadb.s_v4;
   1073      0      stevel 
   1074      0      stevel 	if (inbound) {
   1075      0      stevel 		inassoc = assoc;
   1076      0      stevel 		if (isv6) {
   1077    564    sommerfe 			outhash = OUTBOUND_HASH_V6(sp, *((in6_addr_t *)
   1078      0      stevel 			    &inassoc->ipsa_dstaddr));
   1079      0      stevel 		} else {
   1080    564    sommerfe 			outhash = OUTBOUND_HASH_V4(sp, *((ipaddr_t *)
   1081   4987      danmcd 			    &inassoc->ipsa_dstaddr));
   1082      0      stevel 		}
   1083      0      stevel 		bucket = &sp->sdb_of[outhash];
   1084      0      stevel 		mutex_enter(&bucket->isaf_lock);
   1085      0      stevel 		outassoc = ipsec_getassocbyspi(bucket, inassoc->ipsa_spi,
   1086      0      stevel 		    inassoc->ipsa_srcaddr, inassoc->ipsa_dstaddr,
   1087      0      stevel 		    inassoc->ipsa_addrfam);
   1088      0      stevel 		mutex_exit(&bucket->isaf_lock);
   1089      0      stevel 		if (outassoc == NULL) {
   1090      0      stevel 			/* Q: Do we wish to set haspeer == B_FALSE? */
   1091      0      stevel 			esp0dbg(("esp_set_usetime: "
   1092      0      stevel 			    "can't find peer for inbound.\n"));
   1093      0      stevel 			sadb_set_usetime(inassoc);
   1094      0      stevel 			return;
   1095      0      stevel 		}
   1096      0      stevel 	} else {
   1097      0      stevel 		outassoc = assoc;
   1098    564    sommerfe 		bucket = INBOUND_BUCKET(sp, outassoc->ipsa_spi);
   1099      0      stevel 		mutex_enter(&bucket->isaf_lock);
   1100      0      stevel 		inassoc = ipsec_getassocbyspi(bucket, outassoc->ipsa_spi,
   1101      0      stevel 		    outassoc->ipsa_srcaddr, outassoc->ipsa_dstaddr,
   1102      0      stevel 		    outassoc->ipsa_addrfam);
   1103      0      stevel 		mutex_exit(&bucket->isaf_lock);
   1104      0      stevel 		if (inassoc == NULL) {
   1105      0      stevel 			/* Q: Do we wish to set haspeer == B_FALSE? */
   1106      0      stevel 			esp0dbg(("esp_set_usetime: "
   1107      0      stevel 			    "can't find peer for outbound.\n"));
   1108      0      stevel 			sadb_set_usetime(outassoc);
   1109      0      stevel 			return;
   1110      0      stevel 		}
   1111      0      stevel 	}
   1112      0      stevel 
   1113      0      stevel 	/* Update usetime on both. */
   1114      0      stevel 	sadb_set_usetime(inassoc);
   1115      0      stevel 	sadb_set_usetime(outassoc);
   1116      0      stevel 
   1117      0      stevel 	/*
   1118      0      stevel 	 * REFRELE any peer SA.
   1119      0      stevel 	 *
   1120      0      stevel 	 * Because of the multi-line macro nature of IPSA_REFRELE, keep
   1121      0      stevel 	 * them in { }.
   1122      0      stevel 	 */
   1123      0      stevel 	if (inbound) {
   1124      0      stevel 		IPSA_REFRELE(outassoc);
   1125      0      stevel 	} else {
   1126      0      stevel 		IPSA_REFRELE(inassoc);
   1127      0      stevel 	}
   1128      0      stevel }
   1129      0      stevel 
   1130      0      stevel /*
   1131      0      stevel  * Handle ESP inbound data for IPv4 and IPv6.
   1132      0      stevel  * On success returns B_TRUE, on failure returns B_FALSE and frees the
   1133  11042        Erik  * mblk chain data_mp.
   1134  11042        Erik  */
   1135  11042        Erik mblk_t *
   1136  11042        Erik esp_inbound(mblk_t *data_mp, void *arg, ip_recv_attr_t *ira)
   1137  11042        Erik {
   1138      0      stevel 	esph_t *esph = (esph_t *)arg;
   1139  11042        Erik 	ipsa_t *ipsa = ira->ira_ipsec_esp_sa;
   1140  11042        Erik 	netstack_t	*ns = ira->ira_ill->ill_ipst->ips_netstack;
   1141   3448    dh155122 	ipsecesp_stack_t *espstack = ns->netstack_ipsecesp;
   1142   3448    dh155122 	ipsec_stack_t	*ipss = ns->netstack_ipsec;
   1143      0      stevel 
   1144      0      stevel 	/*
   1145      0      stevel 	 * We may wish to check replay in-range-only here as an optimization.
   1146      0      stevel 	 * Include the reality check of ipsa->ipsa_replay >
   1147      0      stevel 	 * ipsa->ipsa_replay_wsize for times when it's the first N packets,
   1148      0      stevel 	 * where N == ipsa->ipsa_replay_wsize.
   1149      0      stevel 	 *
   1150      0      stevel 	 * Another check that may come here later is the "collision" check.
   1151      0      stevel 	 * If legitimate packets flow quickly enough, this won't be a problem,
   1152      0      stevel 	 * but collisions may cause authentication algorithm crunching to
   1153      0      stevel 	 * take place when it doesn't need to.
   1154      0      stevel 	 */
   1155      0      stevel 	if (!sadb_replay_peek(ipsa, esph->esph_replay)) {
   1156   3448    dh155122 		ESP_BUMP_STAT(espstack, replay_early_failures);
   1157   3448    dh155122 		IP_ESP_BUMP_STAT(ipss, in_discards);
   1158  11042        Erik 		ip_drop_packet(data_mp, B_TRUE, ira->ira_ill,
   1159   3448    dh155122 		    DROPPER(ipss, ipds_esp_early_replay),
   1160   3448    dh155122 		    &espstack->esp_dropper);
   1161  11042        Erik 		BUMP_MIB(ira->ira_ill->ill_ip_mib, ipIfStatsInDiscards);
   1162  11042        Erik 		return (NULL);
   1163  11042        Erik 	}
   1164      0      stevel 
   1165      0      stevel 	/*
   1166      0      stevel 	 * Adjust the IP header's payload length to reflect the removal
   1167      0      stevel 	 * of the ICV.
   1168      0      stevel 	 */
   1169  11042        Erik 	if (!(ira->ira_flags & IRAF_IS_IPV4)) {
   1170      0      stevel 		ip6_t *ip6h = (ip6_t *)data_mp->b_rptr;
   1171      0      stevel 		ip6h->ip6_plen = htons(ntohs(ip6h->ip6_plen) -
   1172      0      stevel 		    ipsa->ipsa_mac_len);
   1173      0      stevel 	} else {
   1174      0      stevel 		ipha_t *ipha = (ipha_t *)data_mp->b_rptr;
   1175      0      stevel 		ipha->ipha_length = htons(ntohs(ipha->ipha_length) -
   1176      0      stevel 		    ipsa->ipsa_mac_len);
   1177      0      stevel 	}
   1178      0      stevel 
   1179      0      stevel 	/* submit the request to the crypto framework */
   1180  11042        Erik 	return (esp_submit_req_inbound(data_mp, ira, ipsa,
   1181      0      stevel 	    (uint8_t *)esph - data_mp->b_rptr));
   1182      0      stevel }
   1183      0      stevel 
   1184      0      stevel /*
   1185      0      stevel  * Perform the really difficult work of inserting the proposed situation.
   1186      0      stevel  * Called while holding the algorithm lock.
   1187      0      stevel  */
   1188      0      stevel static void
   1189  11042        Erik esp_insert_prop(sadb_prop_t *prop, ipsacq_t *acqrec, uint_t combs,
   1190  11042        Erik     netstack_t *ns)
   1191      0      stevel {
   1192      0      stevel 	sadb_comb_t *comb = (sadb_comb_t *)(prop + 1);
   1193      0      stevel 	ipsec_action_t *ap;
   1194      0      stevel 	ipsec_prot_t *prot;
   1195  11042        Erik 	ipsecesp_stack_t *espstack = ns->netstack_ipsecesp;
   1196  11042        Erik 	ipsec_stack_t	*ipss = ns->netstack_ipsec;
   1197  11042        Erik 
   1198   3448    dh155122 	ASSERT(MUTEX_HELD(&ipss->ipsec_alg_lock));
   1199      0      stevel 
   1200      0      stevel 	prop->sadb_prop_exttype = SADB_EXT_PROPOSAL;
   1201      0      stevel 	prop->sadb_prop_len = SADB_8TO64(sizeof (sadb_prop_t));
   1202      0      stevel 	*(uint32_t *)(&prop->sadb_prop_replay) = 0;	/* Quick zero-out! */
   1203      0      stevel 
   1204   3448    dh155122 	prop->sadb_prop_replay = espstack->ipsecesp_replay_size;
   1205      0      stevel 
   1206      0      stevel 	/*
   1207  11042        Erik 	 * Based upon algorithm properties, and what-not, prioritize a
   1208  11042        Erik 	 * proposal, based on the ordering of the ESP algorithms in the
   1209  11042        Erik 	 * alternatives in the policy rule or socket that was placed
   1210  11042        Erik 	 * in the acquire record.
   1211      0      stevel 	 *
   1212      0      stevel 	 * For each action in policy list
   1213      0      stevel 	 *   Add combination.  If I've hit limit, return.
   1214      0      stevel 	 */
   1215      0      stevel 
   1216      0      stevel 	for (ap = acqrec->ipsacq_act; ap != NULL;
   1217      0      stevel 	    ap = ap->ipa_next) {
   1218      0      stevel 		ipsec_alginfo_t *ealg = NULL;
   1219      0      stevel 		ipsec_alginfo_t *aalg = NULL;
   1220      0      stevel 
   1221      0      stevel 		if (ap->ipa_act.ipa_type != IPSEC_POLICY_APPLY)
   1222      0      stevel 			continue;
   1223      0      stevel 
   1224      0      stevel 		prot = &ap->ipa_act.ipa_apply;
   1225      0      stevel 
   1226      0      stevel 		if (!(prot->ipp_use_esp))
   1227      0      stevel 			continue;
   1228      0      stevel 
   1229      0      stevel 		if (prot->ipp_esp_auth_alg != 0) {
   1230   3448    dh155122 			aalg = ipss->ipsec_alglists[IPSEC_ALG_AUTH]
   1231      0      stevel 			    [prot->ipp_esp_auth_alg];
   1232      0      stevel 			if (aalg == NULL || !ALG_VALID(aalg))
   1233      0      stevel 				continue;
   1234      0      stevel 		}
   1235      0      stevel 
   1236      0      stevel 		ASSERT(prot->ipp_encr_alg > 0);
   1237   3448    dh155122 		ealg = ipss->ipsec_alglists[IPSEC_ALG_ENCR]
   1238   3448    dh155122 		    [prot->ipp_encr_alg];
   1239      0      stevel 		if (ealg == NULL || !ALG_VALID(ealg))
   1240      0      stevel 			continue;
   1241      0      stevel 
   1242      0      stevel 		comb->sadb_comb_flags = 0;
   1243      0      stevel 		comb->sadb_comb_reserved = 0;
   1244      0      stevel 		comb->sadb_comb_encrypt = ealg->alg_id;
   1245   2751      danmcd 		comb->sadb_comb_encrypt_minbits =
   1246   2751      danmcd 		    MAX(prot->ipp_espe_minbits, ealg->alg_ef_minbits);
   1247   2751      danmcd 		comb->sadb_comb_encrypt_maxbits =
   1248   2751      danmcd 		    MIN(prot->ipp_espe_maxbits, ealg->alg_ef_maxbits);
   1249  10824        Mark 
   1250      0      stevel 		if (aalg == NULL) {
   1251      0      stevel 			comb->sadb_comb_auth = 0;
   1252      0      stevel 			comb->sadb_comb_auth_minbits = 0;
   1253      0      stevel 			comb->sadb_comb_auth_maxbits = 0;
   1254      0      stevel 		} else {
   1255      0      stevel 			comb->sadb_comb_auth = aalg->alg_id;
   1256   2751      danmcd 			comb->sadb_comb_auth_minbits =
   1257   2751      danmcd 			    MAX(prot->ipp_espa_minbits, aalg->alg_ef_minbits);
   1258   2751      danmcd 			comb->sadb_comb_auth_maxbits =
   1259   2751      danmcd 			    MIN(prot->ipp_espa_maxbits, aalg->alg_ef_maxbits);
   1260      0      stevel 		}
   1261      0      stevel 
   1262      0      stevel 		/*
   1263      0      stevel 		 * The following may be based on algorithm
   1264      0      stevel 		 * properties, but in the meantime, we just pick
   1265      0      stevel 		 * some good, sensible numbers.  Key mgmt. can
   1266      0      stevel 		 * (and perhaps should) be the place to finalize
   1267      0      stevel 		 * such decisions.
   1268      0      stevel 		 */
   1269      0      stevel 
   1270      0      stevel 		/*
   1271      0      stevel 		 * No limits on allocations, since we really don't
   1272      0      stevel 		 * support that concept currently.
   1273      0      stevel 		 */
   1274      0      stevel 		comb->sadb_comb_soft_allocations = 0;
   1275      0      stevel 		comb->sadb_comb_hard_allocations = 0;
   1276      0      stevel 
   1277      0      stevel 		/*
   1278      0      stevel 		 * These may want to come from policy rule..
   1279      0      stevel 		 */
   1280   3448    dh155122 		comb->sadb_comb_soft_bytes =
   1281   3448    dh155122 		    espstack->ipsecesp_default_soft_bytes;
   1282   3448    dh155122 		comb->sadb_comb_hard_bytes =
   1283   3448    dh155122 		    espstack->ipsecesp_default_hard_bytes;
   1284   3448    dh155122 		comb->sadb_comb_soft_addtime =
   1285   3448    dh155122 		    espstack->ipsecesp_default_soft_addtime;
   1286   3448    dh155122 		comb->sadb_comb_hard_addtime =
   1287   3448    dh155122 		    espstack->ipsecesp_default_hard_addtime;
   1288   3448    dh155122 		comb->sadb_comb_soft_usetime =
   1289   3448    dh155122 		    espstack->ipsecesp_default_soft_usetime;
   1290   3448    dh155122 		comb->sadb_comb_hard_usetime =
   1291   3448    dh155122 		    espstack->ipsecesp_default_hard_usetime;
   1292      0      stevel 
   1293      0      stevel 		prop->sadb_prop_len += SADB_8TO64(sizeof (*comb));
   1294      0      stevel 		if (--combs == 0)
   1295      0      stevel 			break;	/* out of space.. */
   1296      0      stevel 		comb++;
   1297      0      stevel 	}
   1298      0      stevel }
   1299      0      stevel 
   1300      0      stevel /*
   1301      0      stevel  * Prepare and actually send the SADB_ACQUIRE message to PF_KEY.
   1302      0      stevel  */
   1303      0      stevel static void
   1304   3448    dh155122 esp_send_acquire(ipsacq_t *acqrec, mblk_t *extended, netstack_t *ns)
   1305      0      stevel {
   1306   3055      danmcd 	uint_t combs;
   1307      0      stevel 	sadb_msg_t *samsg;
   1308      0      stevel 	sadb_prop_t *prop;
   1309   3055      danmcd 	mblk_t *pfkeymp, *msgmp;
   1310   3448    dh155122 	ipsecesp_stack_t *espstack = ns->netstack_ipsecesp;
   1311   3448    dh155122 	ipsec_stack_t	*ipss = ns->netstack_ipsec;
   1312      0      stevel 
   1313   3448    dh155122 	ESP_BUMP_STAT(espstack, acquire_requests);
   1314      0      stevel 
   1315   7073     pwernau 	if (espstack->esp_pfkey_q == NULL) {
   1316   7073     pwernau 		mutex_exit(&acqrec->ipsacq_lock);
   1317   7073     pwernau 		return;
   1318   7073     pwernau 	}
   1319      0      stevel 
   1320      0      stevel 	/* Set up ACQUIRE. */
   1321   3448    dh155122 	pfkeymp = sadb_setup_acquire(acqrec, SADB_SATYPE_ESP,
   1322   3448    dh155122 	    ns->netstack_ipsec);
   1323   3055      danmcd 	if (pfkeymp == NULL) {
   1324      0      stevel 		esp0dbg(("sadb_setup_acquire failed.\n"));
   1325   7073     pwernau 		mutex_exit(&acqrec->ipsacq_lock);
   1326   3055      danmcd 		return;
   1327      0      stevel 	}
   1328   3448    dh155122 	ASSERT(MUTEX_HELD(&ipss->ipsec_alg_lock));
   1329   3448    dh155122 	combs = ipss->ipsec_nalgs[IPSEC_ALG_AUTH] *
   1330   3448    dh155122 	    ipss->ipsec_nalgs[IPSEC_ALG_ENCR];
   1331   3055      danmcd 	msgmp = pfkeymp->b_cont;
   1332   3055      danmcd 	samsg = (sadb_msg_t *)(msgmp->b_rptr);
   1333      0      stevel 
   1334      0      stevel 	/* Insert proposal here. */
   1335      0      stevel 
   1336      0      stevel 	prop = (sadb_prop_t *)(((uint64_t *)samsg) + samsg->sadb_msg_len);
   1337  11042        Erik 	esp_insert_prop(prop, acqrec, combs, ns);
   1338      0      stevel 	samsg->sadb_msg_len += prop->sadb_prop_len;
   1339      0      stevel 	msgmp->b_wptr += SADB_64TO8(samsg->sadb_msg_len);
   1340      0      stevel 
   1341   3448    dh155122 	mutex_exit(&ipss->ipsec_alg_lock);
   1342      0      stevel 
   1343      0      stevel 	/*
   1344      0      stevel 	 * Must mutex_exit() before sending PF_KEY message up, in
   1345      0      stevel 	 * order to avoid recursive mutex_enter() if there are no registered
   1346      0      stevel 	 * listeners.
   1347      0      stevel 	 *
   1348      0      stevel 	 * Once I've sent the message, I'm cool anyway.
   1349      0      stevel 	 */
   1350      0      stevel 	mutex_exit(&acqrec->ipsacq_lock);
   1351   3055      danmcd 	if (extended != NULL) {
   1352   3448    dh155122 		putnext(espstack->esp_pfkey_q, extended);
   1353      0      stevel 	}
   1354   3448    dh155122 	putnext(espstack->esp_pfkey_q, pfkeymp);
   1355      0      stevel }
   1356      0      stevel 
   1357  10934  sommerfeld /* XXX refactor me */
   1358      0      stevel /*
   1359      0      stevel  * Handle the SADB_GETSPI message.  Create a larval SA.
   1360      0      stevel  */
   1361      0      stevel static void
   1362   3448    dh155122 esp_getspi(mblk_t *mp, keysock_in_t *ksi, ipsecesp_stack_t *espstack)
   1363      0      stevel {
   1364      0      stevel 	ipsa_t *newbie, *target;
   1365      0      stevel 	isaf_t *outbound, *inbound;
   1366      0      stevel 	int rc, diagnostic;
   1367      0      stevel 	sadb_sa_t *assoc;
   1368      0      stevel 	keysock_out_t *kso;
   1369      0      stevel 	uint32_t newspi;
   1370      0      stevel 
   1371      0      stevel 	/*
   1372      0      stevel 	 * Randomly generate a proposed SPI value
   1373      0      stevel 	 */
   1374   7749  Thejaswini 	if (cl_inet_getspi != NULL) {
   1375   8392     Huafeng 		cl_inet_getspi(espstack->ipsecesp_netstack->netstack_stackid,
   1376   8392     Huafeng 		    IPPROTO_ESP, (uint8_t *)&newspi, sizeof (uint32_t), NULL);
   1377   7749  Thejaswini 	} else {
   1378   7749  Thejaswini 		(void) random_get_pseudo_bytes((uint8_t *)&newspi,
   1379   7749  Thejaswini 		    sizeof (uint32_t));
   1380   7749  Thejaswini 	}
   1381   3448    dh155122 	newbie = sadb_getspi(ksi, newspi, &diagnostic,
   1382   7749  Thejaswini 	    espstack->ipsecesp_netstack, IPPROTO_ESP);
   1383      0      stevel 
   1384      0      stevel 	if (newbie == NULL) {
   1385   3448    dh155122 		sadb_pfkey_error(espstack->esp_pfkey_q, mp, ENOMEM, diagnostic,
   1386      0      stevel 		    ksi->ks_in_serial);
   1387      0      stevel 		return;
   1388      0      stevel 	} else if (newbie == (ipsa_t *)-1) {
   1389   3448    dh155122 		sadb_pfkey_error(espstack->esp_pfkey_q, mp, EINVAL, diagnostic,
   1390      0      stevel 		    ksi->ks_in_serial);
   1391      0      stevel 		return;
   1392      0      stevel 	}
   1393      0      stevel 
   1394      0      stevel 	/*
   1395      0      stevel 	 * XXX - We may randomly collide.  We really should recover from this.
   1396      0      stevel 	 *	 Unfortunately, that could require spending way-too-much-time
   1397      0      stevel 	 *	 in here.  For now, let the user retry.
   1398      0      stevel 	 */
   1399      0      stevel 
   1400      0      stevel 	if (newbie->ipsa_addrfam == AF_INET6) {
   1401   3448    dh155122 		outbound = OUTBOUND_BUCKET_V6(&espstack->esp_sadb.s_v6,
   1402    564    sommerfe 		    *(uint32_t *)(newbie->ipsa_dstaddr));
   1403   3448    dh155122 		inbound = INBOUND_BUCKET(&espstack->esp_sadb.s_v6,
   1404   3448    dh155122 		    newbie->ipsa_spi);
   1405      0      stevel 	} else {
   1406      0      stevel 		ASSERT(newbie->ipsa_addrfam == AF_INET);
   1407   3448    dh155122 		outbound = OUTBOUND_BUCKET_V4(&espstack->esp_sadb.s_v4,
   1408    564    sommerfe 		    *(uint32_t *)(newbie->ipsa_dstaddr));
   1409   3448    dh155122 		inbound = INBOUND_BUCKET(&espstack->esp_sadb.s_v4,
   1410   3448    dh155122 		    newbie->ipsa_spi);
   1411      0      stevel 	}
   1412      0      stevel 
   1413      0      stevel 	mutex_enter(&outbound->isaf_lock);
   1414      0      stevel 	mutex_enter(&inbound->isaf_lock);
   1415      0      stevel 
   1416      0      stevel 	/*
   1417      0      stevel 	 * Check for collisions (i.e. did sadb_getspi() return with something
   1418      0      stevel 	 * that already exists?).
   1419      0      stevel 	 *
   1420      0      stevel 	 * Try outbound first.  Even though SADB_GETSPI is traditionally
   1421      0      stevel 	 * for inbound SAs, you never know what a user might do.
   1422      0      stevel 	 */
   1423      0      stevel 	target = ipsec_getassocbyspi(outbound, newbie->ipsa_spi,
   1424      0      stevel 	    newbie->ipsa_srcaddr, newbie->ipsa_dstaddr, newbie->ipsa_addrfam);
   1425      0      stevel 	if (target == NULL) {
   1426      0      stevel 		target = ipsec_getassocbyspi(inbound, newbie->ipsa_spi,
   1427      0      stevel 		    newbie->ipsa_srcaddr, newbie->ipsa_dstaddr,
   1428      0      stevel 		    newbie->ipsa_addrfam);
   1429      0      stevel 	}
   1430      0      stevel 
   1431      0      stevel 	/*
   1432      0      stevel 	 * I don't have collisions elsewhere!
   1433      0      stevel 	 * (Nor will I because I'm still holding inbound/outbound locks.)
   1434      0      stevel 	 */
   1435      0      stevel 
   1436      0      stevel 	if (target != NULL) {
   1437      0      stevel 		rc = EEXIST;
   1438      0      stevel 		IPSA_REFRELE(target);
   1439      0      stevel 	} else {
   1440      0      stevel 		/*
   1441      0      stevel 		 * sadb_insertassoc() also checks for collisions, so
   1442      0      stevel 		 * if there's a colliding entry, rc will be set
   1443      0      stevel 		 * to EEXIST.
   1444      0      stevel 		 */
   1445      0      stevel 		rc = sadb_insertassoc(newbie, inbound);
   1446   4987      danmcd 		newbie->ipsa_hardexpiretime = gethrestime_sec();
   1447   3448    dh155122 		newbie->ipsa_hardexpiretime +=
   1448   3448    dh155122 		    espstack->ipsecesp_larval_timeout;
   1449      0      stevel 	}
   1450      0      stevel 
   1451      0      stevel 	/*
   1452      0      stevel 	 * Can exit outbound mutex.  Hold inbound until we're done
   1453      0      stevel 	 * with newbie.
   1454      0      stevel 	 */
   1455      0      stevel 	mutex_exit(&outbound->isaf_lock);
   1456      0      stevel 
   1457      0      stevel 	if (rc != 0) {
   1458      0      stevel 		mutex_exit(&inbound->isaf_lock);
   1459      0      stevel 		IPSA_REFRELE(newbie);
   1460   3448    dh155122 		sadb_pfkey_error(espstack->esp_pfkey_q, mp, rc,
   1461   3448    dh155122 		    SADB_X_DIAGNOSTIC_NONE, ksi->ks_in_serial);
   1462      0      stevel 		return;
   1463      0      stevel 	}
   1464      0      stevel 
   1465      0      stevel 
   1466      0      stevel 	/* Can write here because I'm still holding the bucket lock. */
   1467      0      stevel 	newbie->ipsa_type = SADB_SATYPE_ESP;
   1468      0      stevel 
   1469      0      stevel 	/*
   1470   6668     markfen 	 * Construct successful return message. We have one thing going
   1471      0      stevel 	 * for us in PF_KEY v2.  That's the fact that
   1472      0      stevel 	 *	sizeof (sadb_spirange_t) == sizeof (sadb_sa_t)
   1473      0      stevel 	 */
   1474      0      stevel 	assoc = (sadb_sa_t *)ksi->ks_in_extv[SADB_EXT_SPIRANGE];
   1475      0      stevel 	assoc->sadb_sa_exttype = SADB_EXT_SA;
   1476      0      stevel 	assoc->sadb_sa_spi = newbie->ipsa_spi;
   1477      0      stevel 	*((uint64_t *)(&assoc->sadb_sa_replay)) = 0;
   1478      0      stevel 	mutex_exit(&inbound->isaf_lock);
   1479      0      stevel 
   1480      0      stevel 	/* Convert KEYSOCK_IN to KEYSOCK_OUT. */
   1481      0      stevel 	kso = (keysock_out_t *)ksi;
   1482      0      stevel 	kso->ks_out_len = sizeof (*kso);
   1483      0      stevel 	kso->ks_out_serial = ksi->ks_in_serial;
   1484      0      stevel 	kso->ks_out_type = KEYSOCK_OUT;
   1485      0      stevel 
   1486      0      stevel 	/*
   1487      0      stevel 	 * Can safely putnext() to esp_pfkey_q, because this is a turnaround
   1488      0      stevel 	 * from the esp_pfkey_q.
   1489      0      stevel 	 */
   1490   3448    dh155122 	putnext(espstack->esp_pfkey_q, mp);
   1491      0      stevel }
   1492      0      stevel 
   1493      0      stevel /*
   1494      0      stevel  * Insert the ESP header into a packet.  Duplicate an mblk, and insert a newly
   1495      0      stevel  * allocated mblk with the ESP header in between the two.
   1496      0      stevel  */
   1497      0      stevel static boolean_t
   1498   3448    dh155122 esp_insert_esp(mblk_t *mp, mblk_t *esp_mp, uint_t divpoint,
   1499   3448    dh155122     ipsecesp_stack_t *espstack)
   1500      0      stevel {
   1501      0      stevel 	mblk_t *split_mp = mp;
   1502      0      stevel 	uint_t wheretodiv = divpoint;
   1503      0      stevel 
   1504      0      stevel 	while ((split_mp->b_wptr - split_mp->b_rptr) < wheretodiv) {
   1505      0      stevel 		wheretodiv -= (split_mp->b_wptr - split_mp->b_rptr);
   1506      0      stevel 		split_mp = split_mp->b_cont;
   1507      0      stevel 		ASSERT(split_mp != NULL);
   1508      0      stevel 	}
   1509      0      stevel 
   1510      0      stevel 	if (split_mp->b_wptr - split_mp->b_rptr != wheretodiv) {
   1511      0      stevel 		mblk_t *scratch;
   1512      0      stevel 
   1513      0      stevel 		/* "scratch" is the 2nd half, split_mp is the first. */
   1514      0      stevel 		scratch = dupb(split_mp);
   1515      0      stevel 		if (scratch == NULL) {
   1516   3448    dh155122 			esp1dbg(espstack,
   1517   3448    dh155122 			    ("esp_insert_esp: can't allocate scratch.\n"));
   1518      0      stevel 			return (B_FALSE);
   1519      0      stevel 		}
   1520      0      stevel 		/* NOTE:  dupb() doesn't set b_cont appropriately. */
   1521      0      stevel 		scratch->b_cont = split_mp->b_cont;
   1522      0      stevel 		scratch->b_rptr += wheretodiv;
   1523      0      stevel 		split_mp->b_wptr = split_mp->b_rptr + wheretodiv;
   1524      0      stevel 		split_mp->b_cont = scratch;
   1525      0      stevel 	}
   1526      0      stevel 	/*
   1527      0      stevel 	 * At this point, split_mp is exactly "wheretodiv" bytes long, and
   1528      0      stevel 	 * holds the end of the pre-ESP part of the datagram.
   1529      0      stevel 	 */
   1530      0      stevel 	esp_mp->b_cont = split_mp->b_cont;
   1531      0      stevel 	split_mp->b_cont = esp_mp;
   1532      0      stevel 
   1533      0      stevel 	return (B_TRUE);
   1534      0      stevel }
   1535      0      stevel 
   1536      0      stevel /*
   1537   7066      danmcd  * Section 7 of RFC 3947 says:
   1538   7066      danmcd  *
   1539   7066      danmcd  * 7.  Recovering from the Expiring NAT Mappings
   1540   7066      danmcd  *
   1541   7066      danmcd  *    There are cases where NAT box decides to remove mappings that are still
   1542   7066      danmcd  *    alive (for example, when the keepalive interval is too long, or when the
   1543   7066      danmcd  *    NAT box is rebooted).  To recover from this, ends that are NOT behind
   1544   7066      danmcd  *    NAT SHOULD use the last valid UDP encapsulated IKE or IPsec packet from
   1545   7066      danmcd  *    the other end to determine which IP and port addresses should be used.
   1546   7066      danmcd  *    The host behind dynamic NAT MUST NOT do this, as otherwise it opens a
   1547   7066      danmcd  *    DoS attack possibility because the IP address or port of the other host
   1548   7066      danmcd  *    will not change (it is not behind NAT).
   1549   7066      danmcd  *
   1550   7066      danmcd  *    Keepalives cannot be used for these purposes, as they are not
   1551   7066      danmcd  *    authenticated, but any IKE authenticated IKE packet or ESP packet can be
   1552   7066      danmcd  *    used to detect whether the IP address or the port has changed.
   1553   7066      danmcd  *
   1554   7066      danmcd  * The following function will check an SA and its explicitly-set pair to see
   1555   7066      danmcd  * if the NAT-T remote port matches the received packet (which must have
   1556   7066      danmcd  * passed ESP authentication, see esp_in_done() for the caller context).  If
   1557   7066      danmcd  * there is a mismatch, the SAs are updated.  It is not important if we race
   1558   7066      danmcd  * with a transmitting thread, as if there is a transmitting thread, it will
   1559   7066      danmcd  * merely emit a packet that will most-likely be dropped.
   1560   7066      danmcd  *
   1561   7066      danmcd  * "ports" are ordered src,dst, and assoc is an inbound SA, where src should
   1562   7066      danmcd  * match ipsa_remote_nat_port and dst should match ipsa_local_nat_port.
   1563   7066      danmcd  */
   1564   7066      danmcd #ifdef _LITTLE_ENDIAN
   1565   7066      danmcd #define	FIRST_16(x) ((x) & 0xFFFF)
   1566   7066      danmcd #define	NEXT_16(x) (((x) >> 16) & 0xFFFF)
   1567   7066      danmcd #else
   1568   7066      danmcd #define	FIRST_16(x) (((x) >> 16) & 0xFFFF)
   1569   7066      danmcd #define	NEXT_16(x) ((x) & 0xFFFF)
   1570   7066      danmcd #endif
   1571   7066      danmcd static void
   1572   7066      danmcd esp_port_freshness(uint32_t ports, ipsa_t *assoc)
   1573   7066      danmcd {
   1574   7066      danmcd 	uint16_t remote = FIRST_16(ports);
   1575   7066      danmcd 	uint16_t local = NEXT_16(ports);
   1576   7066      danmcd 	ipsa_t *outbound_peer;
   1577   7066      danmcd 	isaf_t *bucket;
   1578   7066      danmcd 	ipsecesp_stack_t *espstack = assoc->ipsa_netstack->netstack_ipsecesp;
   1579   7066      danmcd 
   1580   7066      danmcd 	/* We found a conn_t, therefore local != 0. */
   1581   7066      danmcd 	ASSERT(local != 0);
   1582   7066      danmcd 	/* Assume an IPv4 SA. */
   1583   7066      danmcd 	ASSERT(assoc->ipsa_addrfam == AF_INET);
   1584   7066      danmcd 
   1585   7066      danmcd 	/*
   1586   7066      danmcd 	 * On-the-wire rport == 0 means something's very wrong.
   1587   7066      danmcd 	 * An unpaired SA is also useless to us.
   1588   7066      danmcd 	 * If we are behind the NAT, don't bother.
   1589   7066      danmcd 	 * A zero local NAT port defaults to 4500, so check that too.
   1590   7066      danmcd 	 * And, of course, if the ports already match, we don't need to
   1591   7066      danmcd 	 * bother.
   1592   7066      danmcd 	 */
   1593   7066      danmcd 	if (remote == 0 || assoc->ipsa_otherspi == 0 ||
   1594   7066      danmcd 	    (assoc->ipsa_flags & IPSA_F_BEHIND_NAT) ||
   1595   7066      danmcd 	    (assoc->ipsa_remote_nat_port == 0 &&
   1596   7066      danmcd 	    remote == htons(IPPORT_IKE_NATT)) ||
   1597   7066      danmcd 	    remote == assoc->ipsa_remote_nat_port)
   1598   7066      danmcd 		return;
   1599   7066      danmcd 
   1600   7066      danmcd 	/* Try and snag the peer.   NOTE:  Assume IPv4 for now. */
   1601   7066      danmcd 	bucket = OUTBOUND_BUCKET_V4(&(espstack->esp_sadb.s_v4),
   1602   7066      danmcd 	    assoc->ipsa_srcaddr[0]);
   1603   7066      danmcd 	mutex_enter(&bucket->isaf_lock);
   1604   7066      danmcd 	outbound_peer = ipsec_getassocbyspi(bucket, assoc->ipsa_otherspi,
   1605   7066      danmcd 	    assoc->ipsa_dstaddr, assoc->ipsa_srcaddr, AF_INET);
   1606   7066      danmcd 	mutex_exit(&bucket->isaf_lock);
   1607   7066      danmcd 
   1608   7066      danmcd 	/* We probably lost a race to a deleting or expiring thread. */
   1609   7066      danmcd 	if (outbound_peer == NULL)
   1610   7066      danmcd 		return;
   1611   7066      danmcd 
   1612   7066      danmcd 	/*
   1613   7066      danmcd 	 * Hold the mutexes for both SAs so we don't race another inbound
   1614   7066      danmcd 	 * thread.  A lock-entry order shouldn't matter, since all other
   1615   7066      danmcd 	 * per-ipsa locks are individually held-then-released.
   1616   7066      danmcd 	 *
   1617   7066      danmcd 	 * Luckily, this has nothing to do with the remote-NAT address,
   1618   7066      danmcd 	 * so we don't have to re-scribble the cached-checksum differential.
   1619   7066      danmcd 	 */
   1620   7066      danmcd 	mutex_enter(&outbound_peer->ipsa_lock);
   1621   7066      danmcd 	mutex_enter(&assoc->ipsa_lock);
   1622   7066      danmcd 	outbound_peer->ipsa_remote_nat_port = assoc->ipsa_remote_nat_port =
   1623   7066      danmcd 	    remote;
   1624   7066      danmcd 	mutex_exit(&assoc->ipsa_lock);
   1625   7066      danmcd 	mutex_exit(&outbound_peer->ipsa_lock);
   1626   7066      danmcd 	IPSA_REFRELE(outbound_peer);
   1627   7066      danmcd 	ESP_BUMP_STAT(espstack, sa_port_renumbers);
   1628   7066      danmcd }
   1629   7066      danmcd /*
   1630      0      stevel  * Finish processing of an inbound ESP packet after processing by the
   1631      0      stevel  * crypto framework.
   1632      0      stevel  * - Remove the ESP header.
   1633      0      stevel  * - Send packet back to IP.
   1634      0      stevel  * If authentication was performed on the packet, this function is called
   1635      0      stevel  * only if the authentication succeeded.
   1636      0      stevel  * On success returns B_TRUE, on failure returns B_FALSE and frees the
   1637  11042        Erik  * mblk chain data_mp.
   1638  11042        Erik  */
   1639  11042        Erik static mblk_t *
   1640  11042        Erik esp_in_done(mblk_t *data_mp, ip_recv_attr_t *ira, ipsec_crypto_t *ic)
   1641  11042        Erik {
   1642      0      stevel 	ipsa_t *assoc;
   1643      0      stevel 	uint_t espstart;
   1644      0      stevel 	uint32_t ivlen = 0;
   1645      0      stevel 	uint_t processed_len;
   1646      0      stevel 	esph_t *esph;
   1647      0      stevel 	kstat_named_t *counter;
   1648      0      stevel 	boolean_t is_natt;
   1649  11042        Erik 	netstack_t	*ns = ira->ira_ill->ill_ipst->ips_netstack;
   1650  11042        Erik 	ipsecesp_stack_t *espstack = ns->netstack_ipsecesp;
   1651  11042        Erik 	ipsec_stack_t	*ipss = ns->netstack_ipsec;
   1652  11042        Erik 
   1653  11042        Erik 	assoc = ira->ira_ipsec_esp_sa;
   1654      0      stevel 	ASSERT(assoc != NULL);
   1655      0      stevel 
   1656      0      stevel 	is_natt = ((assoc->ipsa_flags & IPSA_F_NATT) != 0);
   1657      0      stevel 
   1658      0      stevel 	/* get the pointer to the ESP header */
   1659      0      stevel 	if (assoc->ipsa_encr_alg == SADB_EALG_NULL) {
   1660      0      stevel 		/* authentication-only ESP */
   1661  11042        Erik 		espstart = ic->ic_crypto_data.cd_offset;
   1662  11042        Erik 		processed_len = ic->ic_crypto_data.cd_length;
   1663      0      stevel 	} else {
   1664      0      stevel 		/* encryption present */
   1665      0      stevel 		ivlen = assoc->ipsa_iv_len;
   1666      0      stevel 		if (assoc->ipsa_auth_alg == SADB_AALG_NONE) {
   1667      0      stevel 			/* encryption-only ESP */
   1668  11042        Erik 			espstart = ic->ic_crypto_data.cd_offset -
   1669   4987      danmcd 			    sizeof (esph_t) - assoc->ipsa_iv_len;
   1670  11042        Erik 			processed_len = ic->ic_crypto_data.cd_length +
   1671   4987      danmcd 			    ivlen;
   1672      0      stevel 		} else {
   1673      0      stevel 			/* encryption with authentication */
   1674  11042        Erik 			espstart = ic->ic_crypto_dual_data.dd_offset1;
   1675  11042        Erik 			processed_len = ic->ic_crypto_dual_data.dd_len2 +
   1676      0      stevel 			    ivlen;
   1677      0      stevel 		}
   1678      0      stevel 	}
   1679      0      stevel 
   1680      0      stevel 	esph = (esph_t *)(data_mp->b_rptr + espstart);
   1681      0      stevel 
   1682  10824        Mark 	if (assoc->ipsa_auth_alg != IPSA_AALG_NONE ||
   1683  10824        Mark 	    (assoc->ipsa_flags & IPSA_F_COMBINED)) {
   1684  10824        Mark 		/*
   1685  10824        Mark 		 * Authentication passed if we reach this point.
   1686  10824        Mark 		 * Packets with authentication will have the ICV
   1687  10824        Mark 		 * after the crypto data. Adjust b_wptr before
   1688  10824        Mark 		 * making padlen checks.
   1689  10824        Mark 		 */
   1690   3448    dh155122 		ESP_BUMP_STAT(espstack, good_auth);
   1691      0      stevel 		data_mp->b_wptr -= assoc->ipsa_mac_len;
   1692      0      stevel 
   1693      0      stevel 		/*
   1694      0      stevel 		 * Check replay window here!
   1695      0      stevel 		 * For right now, assume keysock will set the replay window
   1696      0      stevel 		 * size to zero for SAs that have an unspecified sender.
   1697      0      stevel 		 * This may change...
   1698      0      stevel 		 */
   1699      0      stevel 
   1700      0      stevel 		if (!sadb_replay_check(assoc, esph->esph_replay)) {
   1701      0      stevel 			/*
   1702      0      stevel 			 * Log the event. As of now we print out an event.
   1703      0      stevel 			 * Do not print the replay failure number, or else
   1704      0      stevel 			 * syslog cannot collate the error messages.  Printing
   1705      0      stevel 			 * the replay number that failed opens a denial-of-
   1706      0      stevel 			 * service attack.
   1707      0      stevel 			 */
   1708      0      stevel 			ipsec_assocfailure(info.mi_idnum, 0, 0,
   1709      0      stevel 			    SL_ERROR | SL_WARN,
   1710      0      stevel 			    "Replay failed for ESP spi 0x%x, dst %s.\n",
   1711      0      stevel 			    assoc->ipsa_spi, assoc->ipsa_dstaddr,
   1712   3448    dh155122 			    assoc->ipsa_addrfam, espstack->ipsecesp_netstack);
   1713   3448    dh155122 			ESP_BUMP_STAT(espstack, replay_failures);
   1714   3448    dh155122 			counter = DROPPER(ipss, ipds_esp_replay);
   1715      0      stevel 			goto drop_and_bail;
   1716      0      stevel 		}
   1717   7066      danmcd 
   1718  11042        Erik 		if (is_natt) {
   1719  11042        Erik 			ASSERT(ira->ira_flags & IRAF_ESP_UDP_PORTS);
   1720  11042        Erik 			ASSERT(ira->ira_esp_udp_ports != 0);
   1721  11042        Erik 			esp_port_freshness(ira->ira_esp_udp_ports, assoc);
   1722  11042        Erik 		}
   1723      0      stevel 	}
   1724   4987      danmcd 
   1725   4987      danmcd 	esp_set_usetime(assoc, B_TRUE);
   1726      0      stevel 
   1727      0      stevel 	if (!esp_age_bytes(assoc, processed_len, B_TRUE)) {
   1728      0      stevel 		/* The ipsa has hit hard expiration, LOG and AUDIT. */
   1729      0      stevel 		ipsec_assocfailure(info.mi_idnum, 0, 0,
   1730      0      stevel 		    SL_ERROR | SL_WARN,
   1731      0      stevel 		    "ESP association 0x%x, dst %s had bytes expire.\n",
   1732   3448    dh155122 		    assoc->ipsa_spi, assoc->ipsa_dstaddr, assoc->ipsa_addrfam,
   1733   3448    dh155122 		    espstack->ipsecesp_netstack);
   1734   3448    dh155122 		ESP_BUMP_STAT(espstack, bytes_expired);
   1735   3448    dh155122 		counter = DROPPER(ipss, ipds_esp_bytes_expire);
   1736      0      stevel 		goto drop_and_bail;
   1737      0      stevel 	}
   1738      0      stevel 
   1739      0      stevel 	/*
   1740      0      stevel 	 * Remove ESP header and padding from packet.  I hope the compiler
   1741      0      stevel 	 * spews "branch, predict taken" code for this.
   1742      0      stevel 	 */
   1743      0      stevel 
   1744  11042        Erik 	if (esp_strip_header(data_mp, (ira->ira_flags & IRAF_IS_IPV4),
   1745  11042        Erik 	    ivlen, &counter, espstack)) {
   1746  11042        Erik 
   1747  11042        Erik 		if (is_system_labeled() && assoc->ipsa_tsl != NULL) {
   1748  11042        Erik 			if (!ip_recv_attr_replace_label(ira, assoc->ipsa_tsl)) {
   1749  11042        Erik 				ip_drop_packet(data_mp, B_TRUE, ira->ira_ill,
   1750  11042        Erik 				    DROPPER(ipss, ipds_ah_nomem),
   1751  11042        Erik 				    &espstack->esp_dropper);
   1752  11042        Erik 				BUMP_MIB(ira->ira_ill->ill_ip_mib,
   1753  11042        Erik 				    ipIfStatsInDiscards);
   1754  11042        Erik 				return (NULL);
   1755  11042        Erik 			}
   1756  10934  sommerfeld 		}
   1757      0      stevel 		if (is_natt)
   1758      0      stevel 			return (esp_fix_natt_checksums(data_mp, assoc));
   1759  10934  sommerfeld 
   1760   7885      danmcd 		if (assoc->ipsa_state == IPSA_STATE_IDLE) {
   1761   7885      danmcd 			/*
   1762   7885      danmcd 			 * Cluster buffering case.  Tell caller that we're
   1763   7885      danmcd 			 * handling the packet.
   1764   7885      danmcd 			 */
   1765  11042        Erik 			sadb_buf_pkt(assoc, data_mp, ira);
   1766  11042        Erik 			return (NULL);
   1767  11042        Erik 		}
   1768  11042        Erik 
   1769  11042        Erik 		return (data_mp);
   1770      0      stevel 	}
   1771      0      stevel 
   1772   3448    dh155122 	esp1dbg(espstack, ("esp_in_done: esp_strip_header() failed\n"));
   1773      0      stevel drop_and_bail:
   1774   3448    dh155122 	IP_ESP_BUMP_STAT(ipss, in_discards);
   1775  11042        Erik 	ip_drop_packet(data_mp, B_TRUE, ira->ira_ill, counter,
   1776  11042        Erik 	    &espstack->esp_dropper);
   1777  11042        Erik 	BUMP_MIB(ira->ira_ill->ill_ip_mib, ipIfStatsInDiscards);
   1778  11042        Erik 	return (NULL);
   1779      0      stevel }
   1780      0      stevel 
   1781      0      stevel /*
   1782      0      stevel  * Called upon failing the inbound ICV check. The message passed as
   1783      0      stevel  * argument is freed.
   1784      0      stevel  */
   1785      0      stevel static void
   1786  11042        Erik esp_log_bad_auth(mblk_t *mp, ip_recv_attr_t *ira)
   1787  11042        Erik {
   1788  11042        Erik 	ipsa_t		*assoc = ira->ira_ipsec_esp_sa;
   1789  11042        Erik 	netstack_t	*ns = ira->ira_ill->ill_ipst->ips_netstack;
   1790   3448    dh155122 	ipsecesp_stack_t *espstack = ns->netstack_ipsecesp;
   1791   3448    dh155122 	ipsec_stack_t	*ipss = ns->netstack_ipsec;
   1792      0      stevel 
   1793      0      stevel 	/*
   1794      0      stevel 	 * Log the event. Don't print to the console, block
   1795      0      stevel 	 * potential denial-of-service attack.
   1796      0      stevel 	 */
   1797   3448    dh155122 	ESP_BUMP_STAT(espstack, bad_auth);
   1798      0      stevel 
   1799      0      stevel 	ipsec_assocfailure(info.mi_idnum, 0, 0, SL_ERROR | SL_WARN,
   1800      0      stevel 	    "ESP Authentication failed for spi 0x%x, dst %s.\n",
   1801   3448    dh155122 	    assoc->ipsa_spi, assoc->ipsa_dstaddr, assoc->ipsa_addrfam,
   1802   3448    dh155122 	    espstack->ipsecesp_netstack);
   1803      0      stevel 
   1804   3448    dh155122 	IP_ESP_BUMP_STAT(ipss, in_discards);
   1805  11042        Erik 	ip_drop_packet(mp, B_TRUE, ira->ira_ill,
   1806   3448    dh155122 	    DROPPER(ipss, ipds_esp_bad_auth),
   1807   3448    dh155122 	    &espstack->esp_dropper);
   1808      0      stevel }
   1809      0      stevel 
   1810      0      stevel 
   1811      0      stevel /*
   1812      0      stevel  * Invoked for outbound packets after ESP processing. If the packet
   1813      0      stevel  * also requires AH, performs the AH SA selection and AH processing.
   1814      0      stevel  * Returns B_TRUE if the AH processing was not needed or if it was
   1815      0      stevel  * performed successfully. Returns B_FALSE and consumes the passed mblk
   1816      0      stevel  * if AH processing was required but could not be performed.
   1817  11042        Erik  *
   1818  11042        Erik  * Returns data_mp unless data_mp was consumed/queued.
   1819  11042        Erik  */
   1820  11042        Erik static mblk_t *
   1821  11042        Erik esp_do_outbound_ah(mblk_t *data_mp, ip_xmit_attr_t *ixa)
   1822  11042        Erik {
   1823      0      stevel 	ipsec_action_t *ap;
   1824      0      stevel 
   1825  11042        Erik 	ap = ixa->ixa_ipsec_action;
   1826      0      stevel 	if (ap == NULL) {
   1827  11042        Erik 		ipsec_policy_t *pp = ixa->ixa_ipsec_policy;
   1828      0      stevel 		ap = pp->ipsp_act;
   1829      0      stevel 	}
   1830      0      stevel 
   1831      0      stevel 	if (!ap->ipa_want_ah)
   1832  11042        Erik 		return (data_mp);
   1833  11042        Erik 
   1834  11042        Erik 	/*
   1835  11042        Erik 	 * Normally the AH SA would have already been put in place
   1836  11042        Erik 	 * but it could have been flushed so we need to look for it.
   1837  11042        Erik 	 */
   1838  11042        Erik 	if (ixa->ixa_ipsec_ah_sa == NULL) {
   1839  11042        Erik 		if (!ipsec_outbound_sa(data_mp, ixa, IPPROTO_AH)) {
   1840  11042        Erik 			sadb_acquire(data_mp, ixa, B_TRUE, B_FALSE);
   1841  11042        Erik 			return (NULL);
   1842  11042        Erik 		}
   1843  11042        Erik 	}
   1844  11042        Erik 	ASSERT(ixa->ixa_ipsec_ah_sa != NULL);
   1845  11042        Erik 
   1846  11042        Erik 	data_mp = ixa->ixa_ipsec_ah_sa->ipsa_output_func(data_mp, ixa);
   1847  11042        Erik 	return (data_mp);
   1848      0      stevel }
   1849      0      stevel 
   1850      0      stevel 
   1851      0      stevel /*
   1852      0      stevel  * Kernel crypto framework callback invoked after completion of async
   1853  11042        Erik  * crypto requests for outbound packets.
   1854  11042        Erik  */
   1855  11042        Erik static void
   1856  11042        Erik esp_kcf_callback_outbound(void *arg, int status)
   1857  11042        Erik {
   1858  11042        Erik 	mblk_t		*mp = (mblk_t *)arg;
   1859  11042        Erik 	mblk_t		*async_mp;
   1860  11042        Erik 	netstack_t	*ns;
   1861  11042        Erik 	ipsec_stack_t	*ipss;
   1862  11042        Erik 	ipsecesp_stack_t *espstack;
   1863  11042        Erik 	mblk_t		*data_mp;
   1864  11042        Erik 	ip_xmit_attr_t	ixas;
   1865  11042        Erik 	ipsec_crypto_t	*ic;
   1866  11042        Erik 	ill_t		*ill;
   1867  11042        Erik 
   1868  11042        Erik 	/*
   1869  11042        Erik 	 * First remove the ipsec_crypto_t mblk
   1870  11042        Erik 	 * Note that we need to ipsec_free_crypto_data(mp) once done with ic.
   1871  11042        Erik 	 */
   1872  11042        Erik 	async_mp = ipsec_remove_crypto_data(mp, &ic);
   1873  11042        Erik 	ASSERT(async_mp != NULL);
   1874  11042        Erik 
   1875  11042        Erik 	/*
   1876  11042        Erik 	 * Extract the ip_xmit_attr_t from the first mblk.
   1877  11042        Erik 	 * Verifies that the netstack and ill is still around; could
   1878  11042        Erik 	 * have vanished while kEf was doing its work.
   1879  11042        Erik 	 * On succesful return we have a nce_t and the ill/ipst can't
   1880  11042        Erik 	 * disappear until we do the nce_refrele in ixa_cleanup.
   1881  11042        Erik 	 */
   1882  11042        Erik 	data_mp = async_mp->b_cont;
   1883  11042        Erik 	async_mp->b_cont = NULL;
   1884  11042        Erik 	if (!ip_xmit_attr_from_mblk(async_mp, &ixas)) {
   1885  11042        Erik 		/* Disappeared on us - no ill/ipst for MIB */
   1886  11042        Erik 		/* We have nowhere to do stats since ixa_ipst could be NULL */
   1887  11042        Erik 		if (ixas.ixa_nce != NULL) {
   1888  11042        Erik 			ill = ixas.ixa_nce->nce_ill;
   1889  11042        Erik 			BUMP_MIB(ill->ill_ip_mib, ipIfStatsOutDiscards);
   1890  11042        Erik 			ip_drop_output("ipIfStatsOutDiscards", data_mp, ill);
   1891  11042        Erik 		}
   1892  11042        Erik 		freemsg(data_mp);
   1893  11042        Erik 		goto done;
   1894  11042        Erik 	}
   1895  11042        Erik 	ns = ixas.ixa_ipst->ips_netstack;
   1896  11042        Erik 	espstack = ns->netstack_ipsecesp;
   1897  11042        Erik 	ipss = ns->netstack_ipsec;
   1898  11042        Erik 	ill = ixas.ixa_nce->nce_ill;
   1899  11042        Erik 
   1900  11042        Erik 	if (status == CRYPTO_SUCCESS) {
   1901  11042        Erik 		/*
   1902  11042        Erik 		 * If a ICV was computed, it was stored by the
   1903  11042        Erik 		 * crypto framework at the end of the packet.
   1904  11042        Erik 		 */
   1905  11042        Erik 		ipha_t *ipha = (ipha_t *)data_mp->b_rptr;
   1906  11042        Erik 
   1907  11042        Erik 		esp_set_usetime(ixas.ixa_ipsec_esp_sa, B_FALSE);
   1908  11042        Erik 		/* NAT-T packet. */
   1909  11042        Erik 		if (IPH_HDR_VERSION(ipha) == IP_VERSION &&
   1910  11042        Erik 		    ipha->ipha_protocol == IPPROTO_UDP)
   1911  11042        Erik 			esp_prepare_udp(ns, data_mp, ipha);
   1912  11042        Erik 
   1913  11042        Erik 		/* do AH processing if needed */
   1914  11042        Erik 		data_mp = esp_do_outbound_ah(data_mp, &ixas);
   1915  11042        Erik 		if (data_mp == NULL)
   1916  11042        Erik 			goto done;
   1917  11042        Erik 
   1918  11042        Erik 		(void) ip_output_post_ipsec(data_mp, &ixas);
   1919  11042        Erik 	} else {
   1920  11042        Erik 		/* Outbound shouldn't see invalid MAC */
   1921  11042        Erik 		ASSERT(status != CRYPTO_INVALID_MAC);
   1922  11042        Erik 
   1923  11042        Erik 		esp1dbg(espstack,
   1924  11042        Erik 		    ("esp_kcf_callback_outbound: crypto failed with 0x%x\n",
   1925  11042        Erik 		    status));
   1926  11042        Erik 		ESP_BUMP_STAT(espstack, crypto_failures);
   1927  11042        Erik 		ESP_BUMP_STAT(espstack, out_discards);
   1928  11042        Erik 		ip_drop_packet(data_mp, B_FALSE, ill,
   1929  11042        Erik 		    DROPPER(ipss, ipds_esp_crypto_failed),
   1930  11042        Erik 		    &espstack->esp_dropper);
   1931  11042        Erik 		BUMP_MIB(ill->ill_ip_mib, ipIfStatsOutDiscards);
   1932  11042        Erik 	}
   1933  11042        Erik done:
   1934  11042        Erik 	ixa_cleanup(&ixas);
   1935  11042        Erik 	(void) ipsec_free_crypto_data(mp);
   1936  11042        Erik }
   1937  11042        Erik 
   1938  11042        Erik /*
   1939  11042        Erik  * Kernel crypto framework callback invoked after completion of async
   1940  11042        Erik  * crypto requests for inbound packets.
   1941  11042        Erik  */
   1942  11042        Erik static void
   1943  11042        Erik esp_kcf_callback_inbound(void *arg, int status)
   1944  11042        Erik {
   1945  11042        Erik 	mblk_t		*mp = (mblk_t *)arg;
   1946  11042        Erik 	mblk_t		*async_mp;
   1947  11042        Erik 	netstack_t	*ns;
   1948   3448    dh155122 	ipsecesp_stack_t *espstack;
   1949   3448    dh155122 	ipsec_stack_t	*ipss;
   1950  11042        Erik 	mblk_t		*data_mp;
   1951  11042        Erik 	ip_recv_attr_t	iras;
   1952  11042        Erik 	ipsec_crypto_t	*ic;
   1953  11042        Erik 
   1954  11042        Erik 	/*
   1955  11042        Erik 	 * First remove the ipsec_crypto_t mblk
   1956  11042        Erik 	 * Note that we need to ipsec_free_crypto_data(mp) once done with ic.
   1957  11042        Erik 	 */
   1958  11042        Erik 	async_mp = ipsec_remove_crypto_data(mp, &ic);
   1959  11042        Erik 	ASSERT(async_mp != NULL);
   1960  11042        Erik 
   1961  11042        Erik 	/*
   1962  11042        Erik 	 * Extract the ip_recv_attr_t from the first mblk.
   1963  11042        Erik 	 * Verifies that the netstack and ill is still around; could
   1964  11042        Erik 	 * have vanished while kEf was doing its work.
   1965  11042        Erik 	 */
   1966  11042        Erik 	data_mp = async_mp->b_cont;
   1967  11042        Erik 	async_mp->b_cont = NULL;
   1968  11042        Erik 	if (!ip_recv_attr_from_mblk(async_mp, &iras)) {
   1969  11042        Erik 		/* The ill or ip_stack_t disappeared on us */
   1970  11042        Erik 		ip_drop_input("ip_recv_attr_from_mblk", data_mp, NULL);
   1971  11042        Erik 		freemsg(data_mp);
   1972  11042        Erik 		goto done;
   1973  11042        Erik 	}
   1974  11042        Erik 
   1975  11042        Erik 	ns = iras.ira_ill->ill_ipst->ips_netstack;
   1976   3448    dh155122 	espstack = ns->netstack_ipsecesp;
   1977   3448    dh155122 	ipss = ns->netstack_ipsec;
   1978   3448    dh155122 
   1979      0      stevel 	if (status == CRYPTO_SUCCESS) {
   1980  11042        Erik 		data_mp = esp_in_done(data_mp, &iras, ic);
   1981  11042        Erik 		if (data_mp == NULL)
   1982  11042        Erik 			goto done;
   1983  11042        Erik 
   1984  11042        Erik 		/* finish IPsec processing */
   1985  11042        Erik 		ip_input_post_ipsec(data_mp, &iras);
   1986      0      stevel 	} else if (status == CRYPTO_INVALID_MAC) {
   1987  11042        Erik 		esp_log_bad_auth(data_mp, &iras);
   1988      0      stevel 	} else {
   1989   3448    dh155122 		esp1dbg(espstack,
   1990   3448    dh155122 		    ("esp_kcf_callback: crypto failed with 0x%x\n",
   1991      0      stevel 		    status));
   1992   3448    dh155122 		ESP_BUMP_STAT(espstack, crypto_failures);
   1993  11042        Erik 		IP_ESP_BUMP_STAT(ipss, in_discards);
   1994  11042        Erik 		ip_drop_packet(data_mp, B_TRUE, iras.ira_ill,
   1995   3448    dh155122 		    DROPPER(ipss, ipds_esp_crypto_failed),
   1996   3448    dh155122 		    &espstack->esp_dropper);
   1997  11042        Erik 		BUMP_MIB(iras.ira_ill->ill_ip_mib, ipIfStatsInDiscards);
   1998  11042        Erik 	}
   1999  11042        Erik done:
   2000  11042        Erik 	ira_cleanup(&iras, B_TRUE);
   2001  11042        Erik 	(void) ipsec_free_crypto_data(mp);
   2002      0      stevel }
   2003      0      stevel 
   2004      0      stevel /*
   2005      0      stevel  * Invoked on crypto framework failure during inbound and outbound processing.
   2006      0      stevel  */
   2007      0      stevel static void
   2008  11042        Erik esp_crypto_failed(mblk_t *data_mp, boolean_t is_inbound, int kef_rc,
   2009  11042        Erik     ill_t *ill, ipsecesp_stack_t *espstack)
   2010      0      stevel {
   2011   3448    dh155122 	ipsec_stack_t	*ipss = espstack->ipsecesp_netstack->netstack_ipsec;
   2012   3448    dh155122 
   2013   3448    dh155122 	esp1dbg(espstack, ("crypto failed for %s ESP with 0x%x\n",
   2014      0      stevel 	    is_inbound ? "inbound" : "outbound", kef_rc));
   2015  11042        Erik 	ip_drop_packet(data_mp, is_inbound, ill,
   2016   3448    dh155122 	    DROPPER(ipss, ipds_esp_crypto_failed),
   2017   3448    dh155122 	    &espstack->esp_dropper);
   2018   3448    dh155122 	ESP_BUMP_STAT(espstack, crypto_failures);
   2019      0      stevel 	if (is_inbound)
   2020   3448    dh155122 		IP_ESP_BUMP_STAT(ipss, in_discards);
   2021      0      stevel 	else
   2022   3448    dh155122 		ESP_BUMP_STAT(espstack, out_discards);
   2023      0      stevel }
   2024      0      stevel 
   2025  11042        Erik /*
   2026  11042        Erik  * A statement-equivalent macro, _cr MUST point to a modifiable
   2027  11042        Erik  * crypto_call_req_t.
   2028  11042        Erik  */
   2029  11042        Erik #define	ESP_INIT_CALLREQ(_cr, _mp, _callback)				\
   2030  11042        Erik 	(_cr)->cr_flag = CRYPTO_SKIP_REQID|CRYPTO_ALWAYS_QUEUE;	\
   2031  11042        Erik 	(_cr)->cr_callback_arg = (_mp);				\
   2032  11042        Erik 	(_cr)->cr_callback_func = (_callback)
   2033      0      stevel 
   2034      0      stevel #define	ESP_INIT_CRYPTO_MAC(mac, icvlen, icvbuf) {			\
   2035      0      stevel 	(mac)->cd_format = CRYPTO_DATA_RAW;				\
   2036      0      stevel 	(mac)->cd_offset = 0;						\
   2037      0      stevel 	(mac)->cd_length = icvlen;					\
   2038      0      stevel 	(mac)->cd_raw.iov_base = (char *)icvbuf;			\
   2039      0      stevel 	(mac)->cd_raw.iov_len = icvlen;					\
   2040      0      stevel }
   2041      0      stevel 
   2042      0      stevel #define	ESP_INIT_CRYPTO_DATA(data, mp, off, len) {			\
   2043      0      stevel 	if (MBLKL(mp) >= (len) + (off)) {				\
   2044      0      stevel 		(data)->cd_format = CRYPTO_DATA_RAW;			\
   2045      0      stevel 		(data)->cd_raw.iov_base = (char *)(mp)->b_rptr;		\
   2046      0      stevel 		(data)->cd_raw.iov_len = MBLKL(mp);			\
   2047      0      stevel 		(data)->cd_offset = off;				\
   2048      0      stevel 	} else {							\
   2049      0      stevel 		(data)->cd_format = CRYPTO_DATA_MBLK;			\
   2050      0      stevel 		(data)->cd_mp = mp;			       		\
   2051      0      stevel 		(data)->cd_offset = off;				\
   2052      0      stevel 	}								\
   2053      0      stevel 	(data)->cd_length = len;					\
   2054      0      stevel }
   2055      0      stevel 
   2056      0      stevel #define	ESP_INIT_CRYPTO_DUAL_DATA(data, mp, off1, len1, off2, len2) {	\
   2057      0      stevel 	(data)->dd_format = CRYPTO_DATA_MBLK;				\
   2058      0      stevel 	(data)->dd_mp = mp;						\
   2059      0      stevel 	(data)->dd_len1 = len1;						\
   2060      0      stevel 	(data)->dd_offset1 = off1;					\
   2061      0      stevel 	(data)->dd_len2 = len2;						\
   2062      0      stevel 	(data)->dd_offset2 = off2;					\
   2063      0      stevel }
   2064      0      stevel 
   2065  11042        Erik /*
   2066  11042        Erik  * Returns data_mp if successfully completed the request. Returns
   2067  11042        Erik  * NULL if it failed (and increments InDiscards) or if it is pending.
   2068  11042        Erik  */
   2069  11042        Erik static mblk_t *
   2070  11042        Erik esp_submit_req_inbound(mblk_t *esp_mp, ip_recv_attr_t *ira,
   2071  11042        Erik     ipsa_t *assoc, uint_t esph_offset)
   2072  11042        Erik {
   2073      0      stevel 	uint_t auth_offset, msg_len, auth_len;
   2074  11042        Erik 	crypto_call_req_t call_req, *callrp;
   2075  11042        Erik 	mblk_t *mp;
   2076  10824        Mark 	esph_t *esph_ptr;
   2077  11042        Erik 	int kef_rc;
   2078      0      stevel 	uint_t icv_len = assoc->ipsa_mac_len;
   2079      0      stevel 	crypto_ctx_template_t auth_ctx_tmpl;
   2080  11042        Erik 	boolean_t do_auth, do_encr, force;
   2081      0      stevel 	uint_t encr_offset, encr_len;
   2082      0      stevel 	uint_t iv_len = assoc->ipsa_iv_len;
   2083      0      stevel 	crypto_ctx_template_t encr_ctx_tmpl;
   2084  11042        Erik 	ipsec_crypto_t	*ic, icstack;
   2085  10824        Mark 	uchar_t *iv_ptr;
   2086  11042        Erik 	netstack_t *ns = ira->ira_ill->ill_ipst->ips_netstack;
   2087  11042        Erik 	ipsec_stack_t *ipss = ns->netstack_ipsec;
   2088  11042        Erik 	ipsecesp_stack_t *espstack = ns->netstack_ipsecesp;
   2089      0      stevel 
   2090      0      stevel 	do_auth = assoc->ipsa_auth_alg != SADB_AALG_NONE;
   2091      0      stevel 	do_encr = assoc->ipsa_encr_alg != SADB_EALG_NULL;
   2092  11042        Erik 	force = (assoc->ipsa_flags & IPSA_F_ASYNC);
   2093  11042        Erik 
   2094  11042        Erik #ifdef IPSEC_LATENCY_TEST
   2095  11042        Erik 	kef_rc = CRYPTO_SUCCESS;
   2096  11042        Erik #else
   2097  11042        Erik 	kef_rc = CRYPTO_FAILED;
   2098  11042        Erik #endif
   2099      0      stevel 
   2100      0      stevel 	/*
   2101      0      stevel 	 * An inbound packet is of the form:
   2102  11042        Erik 	 * [IP,options,ESP,IV,data,ICV,pad]
   2103  11042        Erik 	 */
   2104  10824        Mark 	esph_ptr = (esph_t *)(esp_mp->b_rptr + esph_offset);
   2105  10824        Mark 	iv_ptr = (uchar_t *)(esph_ptr + 1);
   2106  10824        Mark 	/* Packet length starting at IP header ending after ESP ICV. */
   2107      0      stevel 	msg_len = MBLKL(esp_mp);
   2108      0      stevel 
   2109  10824        Mark 	encr_offset = esph_offset + sizeof (esph_t) + iv_len;
   2110  10824        Mark 	encr_len = msg_len - encr_offset;
   2111  10824        Mark 
   2112  10824        Mark 	/*
   2113  10824        Mark 	 * Counter mode algs need a nonce. This is setup in sadb_common_add().
   2114  10824        Mark 	 * If for some reason we are using a SA which does not have a nonce
   2115  10824        Mark 	 * then we must fail here.
   2116  10824        Mark 	 */
   2117  10824        Mark 	if ((assoc->ipsa_flags & IPSA_F_COUNTERMODE) &&
   2118  10824        Mark 	    (assoc->ipsa_nonce == NULL)) {
   2119  11042        Erik 		ip_drop_packet(esp_mp, B_TRUE, ira->ira_ill,
   2120  10824        Mark 		    DROPPER(ipss, ipds_esp_nomem), &espstack->esp_dropper);
   2121  11042        Erik 		return (NULL);
   2122  11042        Erik 	}
   2123  11042        Erik 
   2124  11042        Erik 	if (force) {
   2125  11042        Erik 		/* We are doing asynch; allocate mblks to hold state */
   2126  11042        Erik 		if ((mp = ip_recv_attr_to_mblk(ira)) == NULL ||
   2127  11042        Erik 		    (mp = ipsec_add_crypto_data(mp, &ic)) == NULL) {
   2128  11042        Erik 			BUMP_MIB(ira->ira_ill->ill_ip_mib, ipIfStatsInDiscards);
   2129  11042        Erik 			ip_drop_input("ipIfStatsInDiscards", esp_mp,
   2130  11042        Erik 			    ira->ira_ill);
   2131  11042        Erik 			return (NULL);
   2132  11042        Erik 		}
   2133  11042        Erik 		linkb(mp, esp_mp);
   2134  11042        Erik 		callrp = &call_req;
   2135  11042        Erik 		ESP_INIT_CALLREQ(callrp, mp, esp_kcf_callback_inbound);
   2136  11042        Erik 	} else {
   2137  11042        Erik 		/*
   2138  11042        Erik 		 * If we know we are going to do sync then ipsec_crypto_t
   2139  11042        Erik 		 * should be on the stack.
   2140  11042        Erik 		 */
   2141  11042        Erik 		ic = &icstack;
   2142  11042        Erik 		bzero(ic, sizeof (*ic));
   2143  11042        Erik 		callrp = NULL;
   2144  10824        Mark 	}
   2145      0      stevel 
   2146      0      stevel 	if (do_auth) {
   2147      0      stevel 		/* authentication context template */
   2148      0      stevel 		IPSEC_CTX_TMPL(assoc, ipsa_authtmpl, IPSEC_ALG_AUTH,
   2149      0      stevel 		    auth_ctx_tmpl);
   2150      0      stevel 
   2151      0      stevel 		/* ICV to be verified */
   2152  11042        Erik 		ESP_INIT_CRYPTO_MAC(&ic->ic_crypto_mac,
   2153      0      stevel 		    icv_len, esp_mp->b_wptr - icv_len);
   2154      0      stevel 
   2155      0      stevel 		/* authentication starts at the ESP header */
   2156      0      stevel 		auth_offset = esph_offset;
   2157      0      stevel 		auth_len = msg_len - auth_offset - icv_len;
   2158      0      stevel 		if (!do_encr) {
   2159      0      stevel 			/* authentication only */
   2160      0      stevel 			/* initialize input data argument */
   2161  11042        Erik 			ESP_INIT_CRYPTO_DATA(&ic->ic_crypto_data,
   2162      0      stevel 			    esp_mp, auth_offset, auth_len);
   2163      0      stevel 
   2164      0      stevel 			/* call the crypto framework */
   2165      0      stevel 			kef_rc = crypto_mac_verify(&assoc->ipsa_amech,
   2166  11042        Erik 			    &ic->ic_crypto_data,
   2167      0      stevel 			    &assoc->ipsa_kcfauthkey, auth_ctx_tmpl,
   2168  11042        Erik 			    &ic->ic_crypto_mac, callrp);
   2169      0      stevel 		}
   2170      0      stevel 	}
   2171      0      stevel 
   2172      0      stevel 	if (do_encr) {
   2173      0      stevel 		/* encryption template */
   2174      0      stevel 		IPSEC_CTX_TMPL(assoc, ipsa_encrtmpl, IPSEC_ALG_ENCR,
   2175      0      stevel 		    encr_ctx_tmpl);
   2176      0      stevel 
   2177  10824        Mark 		/* Call the nonce update function. Also passes in IV */
   2178  10824        Mark 		(assoc->ipsa_noncefunc)(assoc, (uchar_t *)esph_ptr, encr_len,
   2179  11042        Erik 		    iv_ptr, &ic->ic_cmm, &ic->ic_crypto_data);
   2180      0      stevel 
   2181      0      stevel 		if (!do_auth) {
   2182      0      stevel 			/* decryption only */
   2183      0      stevel 			/* initialize input data argument */
   2184  11042        Erik 			ESP_INIT_CRYPTO_DATA(&ic->ic_crypto_data,
   2185      0      stevel 			    esp_mp, encr_offset, encr_len);
   2186      0      stevel 
   2187      0      stevel 			/* call the crypto framework */
   2188  10824        Mark 			kef_rc = crypto_decrypt((crypto_mechanism_t *)
   2189  11042        Erik 			    &ic->ic_cmm, &ic->ic_crypto_data,
   2190      0      stevel 			    &assoc->ipsa_kcfencrkey, encr_ctx_tmpl,
   2191  11042        Erik 			    NULL, callrp);
   2192      0      stevel 		}
   2193      0      stevel 	}
   2194      0      stevel 
   2195      0      stevel 	if (do_auth && do_encr) {
   2196      0      stevel 		/* dual operation */
   2197      0      stevel 		/* initialize input data argument */
   2198  11042        Erik 		ESP_INIT_CRYPTO_DUAL_DATA(&ic->ic_crypto_dual_data,
   2199      0      stevel 		    esp_mp, auth_offset, auth_len,
   2200      0      stevel 		    encr_offset, encr_len - icv_len);
   2201      0      stevel 
   2202      0      stevel 		/* specify IV */
   2203  11042        Erik 		ic->ic_crypto_dual_data.dd_miscdata = (char *)iv_ptr;
   2204      0      stevel 
   2205      0      stevel 		/* call the framework */
   2206      0      stevel 		kef_rc = crypto_mac_verify_decrypt(&assoc->ipsa_amech,
   2207  11042        Erik 		    &assoc->ipsa_emech, &ic->ic_crypto_dual_data,
   2208      0      stevel 		    &assoc->ipsa_kcfauthkey, &assoc->ipsa_kcfencrkey,
   2209  11042        Erik 		    auth_ctx_tmpl, encr_ctx_tmpl, &ic->ic_crypto_mac,
   2210  11042        Erik 		    NULL, callrp);
   2211      0      stevel 	}
   2212      0      stevel 
   2213      0      stevel 	switch (kef_rc) {
   2214      0      stevel 	case CRYPTO_SUCCESS:
   2215   3448    dh155122 		ESP_BUMP_STAT(espstack, crypto_sync);
   2216  11042        Erik 		esp_mp = esp_in_done(esp_mp, ira, ic);
   2217  11042        Erik 		if (force) {
   2218  11042        Erik 			/* Free mp after we are done with ic */
   2219  11042        Erik 			mp = ipsec_free_crypto_data(mp);
   2220  11042        Erik 			(void) ip_recv_attr_free_mblk(mp);
   2221  11042        Erik 		}
   2222  11042        Erik 		return (esp_mp);
   2223      0      stevel 	case CRYPTO_QUEUED:
   2224  11042        Erik 		/* esp_kcf_callback_inbound() will be invoked on completion */
   2225   3448    dh155122 		ESP_BUMP_STAT(espstack, crypto_async);
   2226  11042        Erik 		return (NULL);
   2227      0      stevel 	case CRYPTO_INVALID_MAC:
   2228  11042        Erik 		if (force) {
   2229  11042        Erik 			mp = ipsec_free_crypto_data(mp);
   2230  11042        Erik 			esp_mp = ip_recv_attr_free_mblk(mp);
   2231  11042        Erik 		}
   2232   3448    dh155122 		ESP_BUMP_STAT(espstack, crypto_sync);
   2233  11042        Erik 		BUMP_MIB(ira->ira_ill->ill_ip_mib, ipIfStatsInDiscards);
   2234  11042        Erik 		esp_log_bad_auth(esp_mp, ira);
   2235  11042        Erik 		/* esp_mp was passed to ip_drop_packet */
   2236  11042        Erik 		return (NULL);
   2237  11042        Erik 	}
   2238  11042        Erik 
   2239  11042        Erik 	mp = ipsec_free_crypto_data(mp);
   2240  11042        Erik 	esp_mp = ip_recv_attr_free_mblk(mp);
   2241  11042        Erik 	BUMP_MIB(ira->ira_ill->ill_ip_mib, ipIfStatsInDiscards);
   2242  11042        Erik 	esp_crypto_failed(esp_mp, B_TRUE, kef_rc, ira->ira_ill, espstack);
   2243  11042        Erik 	/* esp_mp was passed to ip_drop_packet */
   2244  11042        Erik 	return (NULL);
   2245   4987      danmcd }
   2246   4987      danmcd 
   2247   4987      danmcd /*
   2248   4987      danmcd  * Compute the IP and UDP checksums -- common code for both keepalives and
   2249   4987      danmcd  * actual ESP-in-UDP packets.  Be flexible with multiple mblks because ESP
   2250   4987      danmcd  * uses mblk-insertion to insert the UDP header.
   2251   4987      danmcd  * TODO - If there is an easy way to prep a packet for HW checksums, make
   2252   4987      danmcd  * it happen here.
   2253  11042        Erik  * Note that this is used before both before calling ip_output_simple and
   2254  11042        Erik  * in the esp datapath. The former could use IXAF_SET_ULP_CKSUM but not the
   2255  11042        Erik  * latter.
   2256   4987      danmcd  */
   2257   4987      danmcd static void
   2258   4987      danmcd esp_prepare_udp(netstack_t *ns, mblk_t *mp, ipha_t *ipha)
   2259   4987      danmcd {
   2260   4987      danmcd 	int offset;
   2261   4987      danmcd 	uint32_t cksum;
   2262   4987      danmcd 	uint16_t *arr;
   2263   4987      danmcd 	mblk_t *udpmp = mp;
   2264   6352     wy83408 	uint_t hlen = IPH_HDR_LENGTH(ipha);
   2265   4987      danmcd 
   2266   4987      danmcd 	ASSERT(MBLKL(mp) >= sizeof (ipha_t));
   2267   4987      danmcd 
   2268   4987      danmcd 	ipha->ipha_hdr_checksum = 0;
   2269   4987      danmcd 	ipha->ipha_hdr_checksum = ip_csum_hdr(ipha);
   2270   4987      danmcd 
   2271   4987      danmcd 	if (ns->netstack_udp->us_do_checksum) {
   2272   4987      danmcd 		ASSERT(MBLKL(udpmp) >= sizeof (udpha_t));
   2273   4987      danmcd 		/* arr points to the IP header. */
   2274   4987      danmcd 		arr = (uint16_t *)ipha;
   2275   4987      danmcd 		IP_STAT(ns->netstack_ip, ip_out_sw_cksum);
   2276  11042        Erik 		IP_STAT_UPDATE(ns->netstack_ip, ip_out_sw_cksum_bytes,
   2277   6352     wy83408 		    ntohs(htons(ipha->ipha_length) - hlen));
   2278   4987      danmcd 		/* arr[6-9] are the IP addresses. */
   2279   4987      danmcd 		cksum = IP_UDP_CSUM_COMP + arr[6] + arr[7] + arr[8] + arr[9] +
   2280   6352     wy83408 		    ntohs(htons(ipha->ipha_length) - hlen);
   2281   6352     wy83408 		cksum = IP_CSUM(mp, hlen, cksum);
   2282   6352     wy83408 		offset = hlen + UDP_CHECKSUM_OFFSET;
   2283   4987      danmcd 		while (offset >= MBLKL(udpmp)) {
   2284   4987      danmcd 			offset -= MBLKL(udpmp);
   2285   4987      danmcd 			udpmp = udpmp->b_cont;
   2286   4987      danmcd 		}
   2287   4987      danmcd 		/* arr points to the UDP header's checksum field. */
   2288   4987      danmcd 		arr = (uint16_t *)(udpmp->b_rptr + offset);
   2289   4987      danmcd 		*arr = cksum;
   2290   4987      danmcd 	}
   2291   8704      danmcd }
   2292   8704      danmcd 
   2293   8704      danmcd /*
   2294   8704      danmcd  * taskq handler so we can send the NAT-T keepalive on a separate thread.
   2295   8704      danmcd  */
   2296   8704      danmcd static void
   2297   8704      danmcd actually_send_keepalive(void *arg)
   2298   8704      danmcd {
   2299  11042        Erik 	mblk_t *mp = (mblk_t *)arg;
   2300  11042        Erik 	ip_xmit_attr_t ixas;
   2301  11042        Erik 	netstack_t	*ns;
   2302  11042        Erik 	netstackid_t	stackid;
   2303  11042        Erik 
   2304  11042        Erik 	stackid = (netstackid_t)(uintptr_t)mp->b_prev;
   2305  11042        Erik 	mp->b_prev = NULL;
   2306  11042        Erik 	ns = netstack_find_by_stackid(stackid);
   2307  11042        Erik 	if (ns == NULL) {
   2308  11042        Erik 		/* Disappeared */
   2309  11042        Erik 		ip_drop_output("ipIfStatsOutDiscards", mp, NULL);
   2310  11042        Erik 		freemsg(mp);
   2311  11042        Erik 		return;
   2312  11042        Erik 	}
   2313  11042        Erik 
   2314  11042        Erik 	bzero(&ixas, sizeof (ixas));
   2315  11042        Erik 	ixas.ixa_zoneid = ALL_ZONES;
   2316  11042        Erik 	ixas.ixa_cred = kcred;
   2317  11042        Erik 	ixas.ixa_cpid = NOPID;
   2318  11042        Erik 	ixas.ixa_tsl = NULL;
   2319  11042        Erik 	ixas.ixa_ipst = ns->netstack_ip;
   2320  11042        Erik 	/* No ULP checksum; done by esp_prepare_udp */
   2321  11042        Erik 	ixas.ixa_flags = IXAF_IS_IPV4 | IXAF_NO_IPSEC;
   2322  11042        Erik 
   2323  11042        Erik 	(void) ip_output_simple(mp, &ixas);
   2324  11042        Erik 	ixa_cleanup(&ixas);
   2325   8704      danmcd 	netstack_rele(ns);
   2326   4987      danmcd }
   2327   4987      danmcd 
   2328   4987      danmcd /*
   2329  11042        Erik  * Send a one-byte UDP NAT-T keepalive.
   2330   4987      danmcd  */
   2331   4987      danmcd void
   2332   4987      danmcd ipsecesp_send_keepalive(ipsa_t *assoc)
   2333   4987      danmcd {
   2334  11042        Erik 	mblk_t		*mp;
   2335  11042        Erik 	ipha_t		*ipha;
   2336  11042        Erik 	udpha_t		*udpha;
   2337  11042        Erik 	netstack_t	*ns = assoc->ipsa_netstack;
   2338   4987      danmcd 
   2339   7373  sommerfeld 	ASSERT(MUTEX_NOT_HELD(&assoc->ipsa_lock));
   2340   4987      danmcd 
   2341   4987      danmcd 	mp = allocb(sizeof (ipha_t) + sizeof (udpha_t) + 1, BPRI_HI);
   2342   4987      danmcd 	if (mp == NULL)
   2343   4987      danmcd 		return;
   2344   4987      danmcd 	ipha = (ipha_t *)mp->b_rptr;
   2345   4987      danmcd 	ipha->ipha_version_and_hdr_length = IP_SIMPLE_HDR_VERSION;
   2346   4987      danmcd 	ipha->ipha_type_of_service = 0;
   2347   4987      danmcd 	ipha->ipha_length = htons(sizeof (ipha_t) + sizeof (udpha_t) + 1);
   2348   4987      danmcd 	/* Use the low-16 of the SPI so we have some clue where it came from. */
   2349   4987      danmcd 	ipha->ipha_ident = *(((uint16_t *)(&assoc->ipsa_spi)) + 1);
   2350   4987      danmcd 	ipha->ipha_fragment_offset_and_flags = 0;  /* Too small to fragment! */
   2351   4987      danmcd 	ipha->ipha_ttl = 0xFF;
   2352   4987      danmcd 	ipha->ipha_protocol = IPPROTO_UDP;
   2353   4987      danmcd 	ipha->ipha_hdr_checksum = 0;
   2354   4987      danmcd 	ipha->ipha_src = assoc->ipsa_srcaddr[0];
   2355   4987      danmcd 	ipha->ipha_dst = assoc->ipsa_dstaddr[0];
   2356   4987      danmcd 	udpha = (udpha_t *)(ipha + 1);
   2357   4987      danmcd 	udpha->uha_src_port = (assoc->ipsa_local_nat_port != 0) ?
   2358   4987      danmcd 	    assoc->ipsa_local_nat_port : htons(IPPORT_IKE_NATT);
   2359   4987      danmcd 	udpha->uha_dst_port = (assoc->ipsa_remote_nat_port != 0) ?
   2360   4987      danmcd 	    assoc->ipsa_remote_nat_port : htons(IPPORT_IKE_NATT);
   2361   4987      danmcd 	udpha->uha_length = htons(sizeof (udpha_t) + 1);
   2362   4987      danmcd 	udpha->uha_checksum = 0;
   2363   4987      danmcd 	mp->b_wptr = (uint8_t *)(udpha + 1);
   2364   4987      danmcd 	*(mp->b_wptr++) = 0xFF;
   2365   4987      danmcd 
   2366  11042        Erik 	esp_prepare_udp(ns, mp, ipha);
   2367  11042        Erik 
   2368   8704      danmcd 	/*
   2369   8704      danmcd 	 * We're holding an isaf_t bucket lock, so pawn off the actual
   2370   8704      danmcd 	 * packet transmission to another thread.  Just in case syncq
   2371   8704      danmcd 	 * processing causes a same-bucket packet to be processed.
   2372   8704      danmcd 	 */
   2373  11042        Erik 	mp->b_prev = (mblk_t *)(uintptr_t)ns->netstack_stackid;
   2374  11042        Erik 
   2375  11042        Erik 	if (taskq_dispatch(esp_taskq, actually_send_keepalive, mp,
   2376   8704      danmcd 	    TQ_NOSLEEP) == 0) {
   2377   8704      danmcd 		/* Assume no memory if taskq_dispatch() fails. */
   2378  11042        Erik 		mp->b_prev = NULL;
   2379  11042        Erik 		ip_drop_packet(mp, B_FALSE, NULL,
   2380  11042        Erik 		    DROPPER(ns->netstack_ipsec, ipds_esp_nomem),
   2381  11042        Erik 		    &ns->netstack_ipsecesp->esp_dropper);
   2382  11042        Erik 	}
   2383  11042        Erik }
   2384  11042        Erik 
   2385  11042        Erik /*
   2386  11042        Erik  * Returns mp if successfully completed the request. Returns
   2387  11042        Erik  * NULL if it failed (and increments InDiscards) or if it is pending.
   2388  11042        Erik  */
   2389  11042        Erik static mblk_t *
   2390  11042        Erik esp_submit_req_outbound(mblk_t *data_mp, ip_xmit_attr_t *ixa, ipsa_t *assoc,
   2391  11042        Erik     uchar_t *icv_buf, uint_t payload_len)
   2392  11042        Erik {
   2393      0      stevel 	uint_t auth_len;
   2394  11042        Erik 	crypto_call_req_t call_req, *callrp;
   2395  11042        Erik 	mblk_t *esp_mp;
   2396  10824        Mark 	esph_t *esph_ptr;
   2397  11042        Erik 	mblk_t *mp;
   2398      0      stevel 	int kef_rc = CRYPTO_FAILED;
   2399      0      stevel 	uint_t icv_len = assoc->ipsa_mac_len;
   2400      0      stevel 	crypto_ctx_template_t auth_ctx_tmpl;
   2401  11042        Erik 	boolean_t do_auth, do_encr, force;
   2402      0      stevel 	uint_t iv_len = assoc->ipsa_iv_len;
   2403      0      stevel 	crypto_ctx_template_t encr_ctx_tmpl;
   2404      0      stevel 	boolean_t is_natt = ((assoc->ipsa_flags & IPSA_F_NATT) != 0);
   2405      0      stevel 	size_t esph_offset = (is_natt ? UDPH_SIZE : 0);
   2406  11042        Erik 	netstack_t	*ns = ixa->ixa_ipst->ips_netstack;
   2407  11042        Erik 	ipsecesp_stack_t *espstack = ns->netstack_ipsecesp;
   2408  11042        Erik 	ipsec_crypto_t	*ic, icstack;
   2409  11042        Erik 	uchar_t		*iv_ptr;
   2410  11042        Erik 	crypto_data_t	*cd_ptr = NULL;
   2411  11042        Erik 	ill_t		*ill = ixa->ixa_nce->nce_ill;
   2412  11042        Erik 	ipsec_stack_t	*ipss = ns->netstack_ipsec;
   2413      0      stevel 
   2414   3448    dh155122 	esp3dbg(espstack, ("esp_submit_req_outbound:%s",
   2415   4987      danmcd 	    is_natt ? "natt" : "not natt"));
   2416      0      stevel 
   2417      0      stevel 	do_encr = assoc->ipsa_encr_alg != SADB_EALG_NULL;
   2418      0      stevel 	do_auth = assoc->ipsa_auth_alg != SADB_AALG_NONE;
   2419  11042        Erik 	force = (assoc->ipsa_flags & IPSA_F_ASYNC);
   2420  11042        Erik 
   2421  11042        Erik #ifdef IPSEC_LATENCY_TEST
   2422  11042        Erik 	kef_rc = CRYPTO_SUCCESS;
   2423  11042        Erik #else
   2424  11042        Erik 	kef_rc = CRYPTO_FAILED;
   2425  11042        Erik #endif
   2426      0      stevel 
   2427      0      stevel 	/*
   2428      0      stevel 	 * Outbound IPsec packets are of the form:
   2429  11042        Erik 	 * [IP,options] -> [ESP,IV] -> [data] -> [pad,ICV]
   2430      0      stevel 	 * unless it's NATT, then it's
   2431  11042        Erik 	 * [IP,options] -> [udp][ESP,IV] -> [data] -> [pad,ICV]
   2432      0      stevel 	 * Get a pointer to the mblk containing the ESP header.
   2433      0      stevel 	 */
   2434  11042        Erik 	ASSERT(data_mp->b_cont != NULL);
   2435  11042        Erik 	esp_mp = data_mp->b_cont;
   2436  10824        Mark 	esph_ptr = (esph_t *)(esp_mp->b_rptr + esph_offset);
   2437  10824        Mark 	iv_ptr = (uchar_t *)(esph_ptr + 1);
   2438  10824        Mark 
   2439  10824        Mark 	/*
   2440  10824        Mark 	 * Combined mode algs need a nonce. This is setup in sadb_common_add().
   2441  10824        Mark 	 * If for some reason we are using a SA which does not have a nonce
   2442  10824        Mark 	 * then we must fail here.
   2443  10824        Mark 	 */
   2444  10824        Mark 	if ((assoc->ipsa_flags & IPSA_F_COUNTERMODE) &&
   2445  10824        Mark 	    (assoc->ipsa_nonce == NULL)) {
   2446  11042        Erik 		ip_drop_packet(data_mp, B_FALSE, NULL,
   2447  10824        Mark 		    DROPPER(ipss, ipds_esp_nomem), &espstack->esp_dropper);
   2448  11042        Erik 		return (NULL);
   2449  11042        Erik 	}
   2450  11042        Erik 
   2451  11042        Erik 	if (force) {
   2452  11042        Erik 		/* We are doing asynch; allocate mblks to hold state */
   2453  11042        Erik 		if ((mp = ip_xmit_attr_to_mblk(ixa)) == NULL ||
   2454  11042        Erik 		    (mp = ipsec_add_crypto_data(mp, &ic)) == NULL) {
   2455  11042        Erik 			BUMP_MIB(ill->ill_ip_mib, ipIfStatsOutDiscards);
   2456  11042        Erik 			ip_drop_output("ipIfStatsOutDiscards", data_mp, ill);
   2457  11042        Erik 			freemsg(data_mp);
   2458  11042        Erik 			return (NULL);
   2459  11042        Erik 		}
   2460  11042        Erik 
   2461  11042        Erik 		linkb(mp, data_mp);
   2462  11042        Erik 		callrp = &call_req;
   2463  11042        Erik 		ESP_INIT_CALLREQ(callrp, mp, esp_kcf_callback_outbound);
   2464  11042        Erik 	} else {
   2465  11042        Erik 		/*
   2466  11042        Erik 		 * If we know we are going to do sync then ipsec_crypto_t
   2467  11042        Erik 		 * should be on the stack.
   2468  11042        Erik 		 */
   2469  11042        Erik 		ic = &icstack;
   2470  11042        Erik 		bzero(ic, sizeof (*ic));
   2471  11042        Erik 		callrp = NULL;
   2472  11042        Erik 	}
   2473  11042        Erik 
   2474      0      stevel 
   2475      0      stevel 	if (do_auth) {
   2476      0      stevel 		/* authentication context template */
   2477      0      stevel 		IPSEC_CTX_TMPL(assoc, ipsa_authtmpl, IPSEC_ALG_AUTH,
   2478      0      stevel 		    auth_ctx_tmpl);
   2479      0      stevel 
   2480      0      stevel 		/* where to store the computed mac */
   2481  11042        Erik 		ESP_INIT_CRYPTO_MAC(&ic->ic_crypto_mac,
   2482      0      stevel 		    icv_len, icv_buf);
   2483      0      stevel 
   2484      0      stevel 		/* authentication starts at the ESP header */
   2485    134      danmcd 		auth_len = payload_len + iv_len + sizeof (esph_t);
   2486      0      stevel 		if (!do_encr) {
   2487      0      stevel 			/* authentication only */
   2488      0      stevel 			/* initialize input data argument */
   2489  11042        Erik 			ESP_INIT_CRYPTO_DATA(&ic->ic_crypto_data,
   2490      0      stevel 			    esp_mp, esph_offset, auth_len);
   2491      0      stevel 
   2492      0      stevel 			/* call the crypto framework */
   2493      0      stevel 			kef_rc = crypto_mac(&assoc->ipsa_amech,
   2494  11042        Erik 			    &ic->ic_crypto_data,
   2495      0      stevel 			    &assoc->ipsa_kcfauthkey, auth_ctx_tmpl,
   2496  11042        Erik 			    &ic->ic_crypto_mac, callrp);
   2497      0      stevel 		}
   2498      0      stevel 	}
   2499      0      stevel 
   2500      0      stevel 	if (do_encr) {
   2501      0      stevel 		/* encryption context template */
   2502      0      stevel 		IPSEC_CTX_TMPL(assoc, ipsa_encrtmpl, IPSEC_ALG_ENCR,
   2503      0      stevel 		    encr_ctx_tmpl);
   2504  10824        Mark 		/* Call the nonce update function. */
   2505  10824        Mark 		(assoc->ipsa_noncefunc)(assoc, (uchar_t *)esph_ptr, payload_len,
   2506  11042        Erik 		    iv_ptr, &ic->ic_cmm, &ic->ic_crypto_data);
   2507      0      stevel 
   2508      0      stevel 		if (!do_auth) {
   2509      0      stevel 			/* encryption only, skip mblk that contains ESP hdr */
   2510      0      stevel 			/* initialize input data argument */
   2511  11042        Erik 			ESP_INIT_CRYPTO_DATA(&ic->ic_crypto_data,
   2512  11042        Erik 			    esp_mp->b_cont, 0, payload_len);
   2513  10824        Mark 
   2514  10824        Mark 			/*
   2515  10824        Mark 			 * For combined mode ciphers, the ciphertext is the same
   2516  10824        Mark 			 * size as the clear text, the ICV should follow the
   2517  10824        Mark 			 * ciphertext. To convince the kcf to allow in-line
   2518  10824        Mark 			 * encryption, with an ICV, use ipsec_out_crypto_mac
   2519  10824        Mark 			 * to point to the same buffer as the data. The calling
   2520  10824        Mark 			 * function need to ensure the buffer is large enough to
   2521  10824        Mark 			 * include the ICV.
   2522  10824        Mark 			 *
   2523  10824        Mark 			 * The IV is already written to the packet buffer, the
   2524  10824        Mark 			 * nonce setup function copied it to the params struct
   2525  10824        Mark 			 * for the cipher to use.
   2526  10824        Mark 			 */
   2527  10824        Mark 			if (assoc->ipsa_flags & IPSA_F_COMBINED) {
   2528  11042        Erik 				bcopy(&ic->ic_crypto_data,
   2529  11042        Erik 				    &ic->ic_crypto_mac,
   2530  10824        Mark 				    sizeof (crypto_data_t));
   2531  11042        Erik 				ic->ic_crypto_mac.cd_length =
   2532  10824        Mark 				    payload_len + icv_len;
   2533  11042        Erik 				cd_ptr = &ic->ic_crypto_mac;
   2534  10824        Mark 			}
   2535      0      stevel 
   2536      0      stevel 			/* call the crypto framework */
   2537  10824        Mark 			kef_rc = crypto_encrypt((crypto_mechanism_t *)
   2538  11042        Erik 			    &ic->ic_cmm, &ic->ic_crypto_data,
   2539      0      stevel 			    &assoc->ipsa_kcfencrkey, encr_ctx_tmpl,
   2540  11042        Erik 			    cd_ptr, callrp);
   2541  10824        Mark 
   2542      0      stevel 		}
   2543      0      stevel 	}
   2544      0      stevel 
   2545      0      stevel 	if (do_auth && do_encr) {
   2546      0      stevel 		/*
   2547      0      stevel 		 * Encryption and authentication:
   2548      0      stevel 		 * Pass the pointer to the mblk chain starting at the ESP
   2549      0      stevel 		 * header to the framework. Skip the ESP header mblk
   2550      0      stevel 		 * for encryption, which is reflected by an encryption
   2551      0      stevel 		 * offset equal to the length of that mblk. Start
   2552      0      stevel 		 * the authentication at the ESP header, i.e. use an
   2553      0      stevel 		 * authentication offset of zero.
   2554      0      stevel 		 */
   2555  11042        Erik 		ESP_INIT_CRYPTO_DUAL_DATA(&ic->ic_crypto_dual_data,
   2556      0      stevel 		    esp_mp, MBLKL(esp_mp), payload_len, esph_offset, auth_len);
   2557      0      stevel 
   2558      0      stevel 		/* specify IV */
   2559  11042        Erik 		ic->ic_crypto_dual_data.dd_miscdata = (char *)iv_ptr;
   2560      0      stevel 
   2561      0      stevel 		/* call the framework */
   2562      0      stevel 		kef_rc = crypto_encrypt_mac(&assoc->ipsa_emech,
   2563      0      stevel 		    &assoc->ipsa_amech, NULL,
   2564      0      stevel 		    &assoc->ipsa_kcfencrkey, &assoc->ipsa_kcfauthkey,
   2565      0      stevel 		    encr_ctx_tmpl, auth_ctx_tmpl,
   2566  11042        Erik 		    &ic->ic_crypto_dual_data,
   2567  11042        Erik 		    &ic->ic_crypto_mac, callrp);
   2568      0      stevel 	}
   2569      0      stevel 
   2570      0      stevel 	switch (kef_rc) {
   2571      0      stevel 	case CRYPTO_SUCCESS:
   2572   3448    dh155122 		ESP_BUMP_STAT(espstack, crypto_sync);
   2573   4987      danmcd 		esp_set_usetime(assoc, B_FALSE);
   2574  11042        Erik 		if (force) {
   2575  11042        Erik 			mp = ipsec_free_crypto_data(mp);
   2576  11042        Erik 			data_mp = ip_xmit_attr_free_mblk(mp);
   2577  11042        Erik 		}
   2578   4987      danmcd 		if (is_natt)
   2579  11042        Erik 			esp_prepare_udp(ns, data_mp, (ipha_t *)data_mp->b_rptr);
   2580  11042        Erik 		return (data_mp);
   2581      0      stevel 	case CRYPTO_QUEUED:
   2582  11042        Erik 		/* esp_kcf_callback_outbound() will be invoked on completion */
   2583   3448    dh155122 		ESP_BUMP_STAT(espstack, crypto_async);
   2584  11042        Erik 		return (NULL);
   2585  11042        Erik 	}
   2586  11042        Erik 
   2587  11042        Erik 	if (force) {
   2588  11042        Erik 		mp = ipsec_free_crypto_data(mp);
   2589  11042        Erik 		data_mp = ip_xmit_attr_free_mblk(mp);
   2590  11042        Erik 	}
   2591  11042        Erik 	BUMP_MIB(ill->ill_ip_mib, ipIfStatsOutDiscards);
   2592  11042        Erik 	esp_crypto_failed(data_mp, B_FALSE, kef_rc, NULL, espstack);
   2593  11042        Erik 	/* data_mp was passed to ip_drop_packet */
   2594  11042        Erik 	return (NULL);
   2595      0      stevel }
   2596      0      stevel 
   2597      0      stevel /*
   2598      0      stevel  * Handle outbound IPsec processing for IPv4 and IPv6
   2599  11042        Erik  *
   2600  11042        Erik  * Returns data_mp if successfully completed the request. Returns
   2601  11042        Erik  * NULL if it failed (and increments InDiscards) or if it is pending.
   2602  11042        Erik  */
   2603  11042        Erik static mblk_t *
   2604  11042        Erik esp_outbound(mblk_t *data_mp, ip_xmit_attr_t *ixa)
   2605  11042        Erik {
   2606  11042        Erik 	mblk_t *espmp, *tailmp;
   2607      0      stevel 	ipha_t *ipha;
   2608      0      stevel 	ip6_t *ip6h;
   2609  10824        Mark 	esph_t *esph_ptr, *iv_ptr;
   2610      0      stevel 	uint_t af;
   2611      0      stevel 	uint8_t *nhp;
   2612      0      stevel 	uintptr_t divpoint, datalen, adj, padlen, i, alloclen;
   2613      0      stevel 	uintptr_t esplen = sizeof (esph_t);
   2614      0      stevel 	uint8_t protocol;
   2615      0      stevel 	ipsa_t *assoc;
   2616  10824        Mark 	uint_t iv_len, block_size, mac_len = 0;
   2617      0      stevel 	uchar_t *icv_buf;
   2618      0      stevel 	udpha_t *udpha;
   2619      0      stevel 	boolean_t is_natt = B_FALSE;
   2620  11042        Erik 	netstack_t	*ns = ixa->ixa_ipst->ips_netstack;
   2621  11042        Erik 	ipsecesp_stack_t *espstack = ns->netstack_ipsecesp;
   2622  11042        Erik 	ipsec_stack_t	*ipss = ns->netstack_ipsec;
   2623  11042        Erik 	ill_t		*ill = ixa->ixa_nce->nce_ill;
   2624  11042        Erik 	boolean_t	need_refrele = B_FALSE;
   2625   3448    dh155122 
   2626   3448    dh155122 	ESP_BUMP_STAT(espstack, out_requests);
   2627      0      stevel 
   2628      0      stevel 	/*
   2629      0      stevel 	 * <sigh> We have to copy the message here, because TCP (for example)
   2630      0      stevel 	 * keeps a dupb() of the message lying around for retransmission.
   2631      0      stevel 	 * Since ESP changes the whole of the datagram, we have to create our
   2632      0      stevel 	 * own copy lest we clobber TCP's data.  Since we have to copy anyway,
   2633      0      stevel 	 * we might as well make use of msgpullup() and get the mblk into one
   2634      0      stevel 	 * contiguous piece!
   2635      0      stevel 	 */
   2636  11042        Erik 	tailmp = msgpullup(data_mp, -1);
   2637  11042        Erik 	if (tailmp == NULL) {
   2638      0      stevel 		esp0dbg(("esp_outbound: msgpullup() failed, "
   2639      0      stevel 		    "dropping packet.\n"));
   2640  11042        Erik 		ip_drop_packet(data_mp, B_FALSE, ill,
   2641   3448    dh155122 		    DROPPER(ipss, ipds_esp_nomem),
   2642   3448    dh155122 		    &espstack->esp_dropper);
   2643  11042        Erik 		BUMP_MIB(ill->ill_ip_mib, ipIfStatsOutDiscards);
   2644  11042        Erik 		return (NULL);
   2645  11042        Erik 	}
   2646  11042        Erik 	freemsg(data_mp);
   2647  11042        Erik 	data_mp = tailmp;
   2648  11042        Erik 
   2649  11042        Erik 	assoc = ixa->ixa_ipsec_esp_sa;
   2650  10934  sommerfeld 	ASSERT(assoc != NULL);
   2651  10934  sommerfeld 
   2652  10934  sommerfeld 	/*
   2653  10934  sommerfeld 	 * Get the outer IP header in shape to escape this system..
   2654  10934  sommerfeld 	 */
   2655  11042        Erik 	if (is_system_labeled() && (assoc->ipsa_otsl != NULL)) {
   2656  11042        Erik 		/*
   2657  11042        Erik 		 * Need to update packet with any CIPSO option and update
   2658  11042        Erik 		 * ixa_tsl to capture the new label.
   2659  11042        Erik 		 * We allocate a separate ixa for that purpose.
   2660  11042        Erik 		 */
   2661  11042        Erik 		ixa = ip_xmit_attr_duplicate(ixa);
   2662  11042        Erik 		if (ixa == NULL) {
   2663  11042        Erik 			ip_drop_packet(data_mp, B_FALSE, ill,
   2664  11042        Erik 			    DROPPER(ipss, ipds_esp_nomem),
   2665  11042        Erik 			    &espstack->esp_dropper);
   2666  11042        Erik 			return (NULL);
   2667  11042        Erik 		}
   2668  11042        Erik 		need_refrele = B_TRUE;
   2669  11042        Erik 
   2670  11042        Erik 		label_hold(assoc->ipsa_otsl);
   2671  11042        Erik 		ip_xmit_attr_replace_tsl(ixa, assoc->ipsa_otsl);
   2672  11042        Erik 
   2673  11042        Erik 		data_mp = sadb_whack_label(data_mp, assoc, ixa,
   2674  11042        Erik 		    DROPPER(ipss, ipds_esp_nomem), &espstack->esp_dropper);
   2675  11042        Erik 		if (data_mp == NULL) {
   2676  11042        Erik 			/* Packet dropped by sadb_whack_label */
   2677  11042        Erik 			ixa_refrele(ixa);
   2678  11042        Erik 			return (NULL);
   2679  11042        Erik 		}
   2680  11042        Erik 	}
   2681  10934  sommerfeld 
   2682      0      stevel 	/*
   2683      0      stevel 	 * Reality check....
   2684      0      stevel 	 */
   2685      0      stevel 	ipha = (ipha_t *)data_mp->b_rptr;  /* So we can call esp_acquire(). */
   2686      0      stevel 
   2687  11042        Erik 	if (ixa->ixa_flags & IXAF_IS_IPV4) {
   2688  11042        Erik 		ASSERT(IPH_HDR_VERSION(ipha) == IPV4_VERSION);
   2689  11042        Erik 
   2690      0      stevel 		af = AF_INET;
   2691      0      stevel 		divpoint = IPH_HDR_LENGTH(ipha);
   2692      0      stevel 		datalen = ntohs(ipha->ipha_length) - divpoint;
   2693      0      stevel 		nhp = (uint8_t *)&ipha->ipha_protocol;
   2694      0      stevel 	} else {
   2695  11042        Erik 		ip_pkt_t ipp;
   2696  11042        Erik 
   2697  11042        Erik 		ASSERT(IPH_HDR_VERSION(ipha) == IPV6_VERSION);
   2698      0      stevel 
   2699      0      stevel 		af = AF_INET6;
   2700      0      stevel 		ip6h = (ip6_t *)ipha;
   2701      0      stevel 		bzero(&ipp, sizeof (ipp));
   2702  11042        Erik 		divpoint = ip_find_hdr_v6(data_mp, ip6h, B_FALSE, &ipp, NULL);
   2703      0      stevel 		if (ipp.ipp_dstopts != NULL &&
   2704      0      stevel 		    ipp.ipp_dstopts->ip6d_nxt != IPPROTO_ROUTING) {
   2705      0      stevel 			/*
   2706      0      stevel 			 * Destination options are tricky.  If we get in here,
   2707      0      stevel 			 * then we have a terminal header following the
   2708      0      stevel 			 * destination options.  We need to adjust backwards
   2709      0      stevel 			 * so we insert ESP BEFORE the destination options
   2710      0      stevel 			 * bag.  (So that the dstopts get encrypted!)
   2711      0      stevel 			 *
   2712      0      stevel 			 * Since this is for outbound packets only, we know
   2713      0      stevel 			 * that non-terminal destination options only precede
   2714      0      stevel 			 * routing headers.
   2715      0      stevel 			 */
   2716      0      stevel 			divpoint -= ipp.ipp_dstoptslen;
   2717      0      stevel 		}
   2718      0      stevel 		datalen = ntohs(ip6h->ip6_plen) + sizeof (ip6_t) - divpoint;
   2719      0      stevel 
   2720      0      stevel 		if (ipp.ipp_rthdr != NULL) {
   2721      0      stevel 			nhp = &ipp.ipp_rthdr->ip6r_nxt;
   2722      0      stevel 		} else if (ipp.ipp_hopopts != NULL) {
   2723      0      stevel 			nhp = &ipp.ipp_hopopts->ip6h_nxt;
   2724      0      stevel 		} else {
   2725      0      stevel 			ASSERT(divpoint == sizeof (ip6_t));
   2726      0      stevel 			/* It's probably IP + ESP. */
   2727      0      stevel 			nhp = &ip6h->ip6_nxt;
   2728      0      stevel 		}
   2729      0      stevel 	}
   2730      0      stevel 
   2731  10824        Mark 	mac_len = assoc->ipsa_mac_len;
   2732      0      stevel 
   2733      0      stevel 	if (assoc->ipsa_flags & IPSA_F_NATT) {
   2734  10934  sommerfeld 		/* wedge in UDP header */
   2735      0      stevel 		is_natt = B_TRUE;
   2736      0      stevel 		esplen += UDPH_SIZE;
   2737      0      stevel 	}
   2738      0      stevel 
   2739      0      stevel 	/*
   2740      0      stevel 	 * Set up ESP header and encryption padding for ENCR PI request.
   2741      0      stevel 	 */
   2742      0      stevel 
   2743   3192      danmcd 	/* Determine the padding length.  Pad to 4-bytes for no-encryption. */
   2744   3192      danmcd 	if (assoc->ipsa_encr_alg != SADB_EALG_NULL) {
   2745   3192      danmcd 		iv_len = assoc->ipsa_iv_len;
   2746  10824        Mark 		block_size = assoc->ipsa_datalen;
   2747  10824        Mark 
   2748  10824        Mark 		/*
   2749  10824        Mark 		 * Pad the data to the length of the cipher block size.
   2750   3192      danmcd 		 * Include the two additional bytes (hence the - 2) for the
   2751   3192      danmcd 		 * padding length and the next header.  Take this into account
   2752   3192      danmcd 		 * when calculating the actual length of the padding.
   2753   3192      danmcd 		 */
   2754   3192      danmcd 		ASSERT(ISP2(iv_len));
   2755  10824        Mark 		padlen = ((unsigned)(block_size - datalen - 2)) &
   2756  10824        Mark 		    (block_size - 1);
   2757      0      stevel 	} else {
   2758   3192      danmcd 		iv_len = 0;
   2759   3192      danmcd 		padlen = ((unsigned)(sizeof (uint32_t) - datalen - 2)) &
   2760   3192      danmcd 		    (sizeof (uint32_t) - 1);
   2761      0      stevel 	}
   2762      0      stevel 
   2763      0      stevel 	/* Allocate ESP header and IV. */
   2764      0      stevel 	esplen += iv_len;
   2765      0      stevel 
   2766      0      stevel 	/*
   2767      0      stevel 	 * Update association byte-count lifetimes.  Don't forget to take
   2768      0      stevel 	 * into account the padding length and next-header (hence the + 2).
   2769    134      danmcd 	 *
   2770      0      stevel 	 * Use the amount of data fed into the "encryption algorithm".  This
   2771      0      stevel 	 * is the IV, the data length, the padding length, and the final two
   2772      0      stevel 	 * bytes (padlen, and next-header).
   2773      0      stevel 	 *
   2774      0      stevel 	 */
   2775      0      stevel 
   2776    134      danmcd 	if (!esp_age_bytes(assoc, datalen + padlen + iv_len + 2, B_FALSE)) {
   2777  11042        Erik 		ip_drop_packet(data_mp, B_FALSE, ill,
   2778   3448    dh155122 		    DROPPER(ipss, ipds_esp_bytes_expire),
   2779   3448    dh155122 		    &espstack->esp_dropper);
   2780  11042        Erik 		BUMP_MIB(ill->ill_ip_mib, ipIfStatsOutDiscards);
   2781  11042        Erik 		if (need_refrele)
   2782  11042        Erik 			ixa_refrele(ixa);
   2783  11042        Erik 		return (NULL);
   2784      0      stevel 	}
   2785      0      stevel 
   2786      0      stevel 	espmp = allocb(esplen, BPRI_HI);
   2787      0      stevel 	if (espmp == NULL) {
   2788   3448    dh155122 		ESP_BUMP_STAT(espstack, out_discards);
   2789   3448    dh155122 		esp1dbg(espstack, ("esp_outbound: can't allocate espmp.\n"));
   2790  11042        Erik 		ip_drop_packet(data_mp, B_FALSE, ill,
   2791   3448    dh155122 		    DROPPER(ipss, ipds_esp_nomem),
   2792   3448    dh155122 		    &espstack->esp_dropper);
   2793  11042        Erik 		BUMP_MIB(ill->ill_ip_mib, ipIfStatsOutDiscards);
   2794  11042        Erik 		if (need_refrele)
   2795  11042        Erik 			ixa_refrele(ixa);
   2796  11042        Erik 		return (NULL);
   2797      0      stevel 	}
   2798      0      stevel 	espmp->b_wptr += esplen;
   2799  10824        Mark 	esph_ptr = (esph_t *)espmp->b_rptr;
   2800      0      stevel 
   2801      0      stevel 	if (is_natt) {
   2802   3448    dh155122 		esp3dbg(espstack, ("esp_outbound: NATT"));
   2803      0      stevel 
   2804      0      stevel 		udpha = (udpha_t *)espmp->b_rptr;
   2805   4987      danmcd 		udpha->uha_src_port = (assoc->ipsa_local_nat_port != 0) ?
   2806   4987      danmcd 		    assoc->ipsa_local_nat_port : htons(IPPORT_IKE_NATT);
   2807   4987      danmcd 		udpha->uha_dst_port = (assoc->ipsa_remote_nat_port != 0) ?
   2808   4987      danmcd 		    assoc->ipsa_remote_nat_port : htons(IPPORT_IKE_NATT);
   2809   4987      danmcd 		/*
   2810   4987      danmcd 		 * Set the checksum to 0, so that the esp_prepare_udp() call
   2811      0      stevel 		 * can do the right thing.
   2812      0      stevel 		 */
   2813      0      stevel 		udpha->uha_checksum = 0;
   2814  10824        Mark 		esph_ptr = (esph_t *)(udpha + 1);
   2815  10824        Mark 	}
   2816  10824        Mark 
   2817  10824        Mark 	esph_ptr->esph_spi = assoc->ipsa_spi;
   2818  10824        Mark 
   2819  10824        Mark 	esph_ptr->esph_replay = htonl(atomic_add_32_nv(&assoc->ipsa_replay, 1));
   2820  10824        Mark 	if (esph_ptr->esph_replay == 0 && assoc->ipsa_replay_wsize != 0) {
   2821      0      stevel 		/*
   2822      0      stevel 		 * XXX We have replay counter wrapping.
   2823      0      stevel 		 * We probably want to nuke this SA (and its peer).
   2824      0      stevel 		 */
   2825      0      stevel 		ipsec_assocfailure(info.mi_idnum, 0, 0,
   2826      0      stevel 		    SL_ERROR | SL_CONSOLE | SL_WARN,
   2827      0      stevel 		    "Outbound ESP SA (0x%x, %s) has wrapped sequence.\n",
   2828  10824        Mark 		    esph_ptr->esph_spi, assoc->ipsa_dstaddr, af,
   2829   3448    dh155122 		    espstack->ipsecesp_netstack);
   2830      0      stevel 
   2831   3448    dh155122 		ESP_BUMP_STAT(espstack, out_discards);
   2832      0      stevel 		sadb_replay_delete(assoc);
   2833  11042        Erik 		ip_drop_packet(data_mp, B_FALSE, ill,
   2834   3448    dh155122 		    DROPPER(ipss, ipds_esp_replay),
   2835   3448    dh155122 		    &espstack->esp_dropper);
   2836  11042        Erik 		BUMP_MIB(ill->ill_ip_mib, ipIfStatsOutDiscards);
   2837  11042        Erik 		if (need_refrele)
   2838  11042        Erik 			ixa_refrele(ixa);
   2839  11042        Erik 		return (NULL);
   2840      0      stevel 	}
   2841      0      stevel 
   2842  10824        Mark 	iv_ptr = (esph_ptr + 1);
   2843  10824        Mark 	/*
   2844  10824        Mark 	 * iv_ptr points to the mblk which will contain the IV once we have
   2845  10824        Mark 	 * written it there. This mblk will be part of a mblk chain that
   2846  10824        Mark 	 * will make up the packet.
   2847  10824        Mark 	 *
   2848  10824        Mark 	 * For counter mode algorithms, the IV is a 64 bit quantity, it
   2849  10824        Mark 	 * must NEVER repeat in the lifetime of the SA, otherwise an
   2850  10824        Mark 	 * attacker who had recorded enough packets might be able to
   2851  10824        Mark 	 * determine some clear text.
   2852  10824        Mark 	 *
   2853  10824        Mark 	 * To ensure this does not happen, the IV is stored in the SA and
   2854  10824        Mark 	 * incremented for each packet, the IV is then copied into the
   2855  10824        Mark 	 * "packet" for transmission to the receiving system. The IV will
   2856  10824        Mark 	 * also be copied into the nonce, when the packet is encrypted.
   2857  10824        Mark 	 *
   2858  10824        Mark 	 * CBC mode algorithms use a random IV for each packet. We do not
   2859  10824        Mark 	 * require the highest quality random bits, but for best security
   2860  10824        Mark 	 * with CBC mode ciphers, the value must be unlikely to repeat and
   2861  10824        Mark 	 * must not be known in advance to an adversary capable of influencing
   2862  10824        Mark 	 * the clear text.
   2863  10824        Mark 	 */
   2864  10824        Mark 	if (!update_iv((uint8_t *)iv_ptr, espstack->esp_pfkey_q, assoc,
   2865  10824        Mark 	    espstack)) {
   2866  11042        Erik 		ip_drop_packet(data_mp, B_FALSE, ill,
   2867  10824        Mark 		    DROPPER(ipss, ipds_esp_iv_wrap), &espstack->esp_dropper);
   2868  11042        Erik 		if (need_refrele)
   2869  11042        Erik 			ixa_refrele(ixa);
   2870  11042        Erik 		return (NULL);
   2871  10824        Mark 	}
   2872      0      stevel 
   2873      0      stevel 	/* Fix the IP header. */
   2874      0      stevel 	alloclen = padlen + 2 + mac_len;
   2875      0      stevel 	adj = alloclen + (espmp->b_wptr - espmp->b_rptr);
   2876      0      stevel 
   2877      0      stevel 	protocol = *nhp;
   2878      0      stevel 
   2879  11042        Erik 	if (ixa->ixa_flags & IXAF_IS_IPV4) {
   2880      0      stevel 		ipha->ipha_length = htons(ntohs(ipha->ipha_length) + adj);
   2881      0      stevel 		if (is_natt) {
   2882      0      stevel 			*nhp = IPPROTO_UDP;
   2883      0      stevel 			udpha->uha_length = htons(ntohs(ipha->ipha_length) -
   2884      0      stevel 			    IPH_HDR_LENGTH(ipha));
   2885      0      stevel 		} else {
   2886      0      stevel 			*nhp = IPPROTO_ESP;
   2887      0      stevel 		}
   2888      0      stevel 		ipha->ipha_hdr_checksum = 0;
   2889      0      stevel 		ipha->ipha_hdr_checksum = (uint16_t)ip_csum_hdr(ipha);
   2890      0      stevel 	} else {
   2891      0      stevel 		ip6h->ip6_plen = htons(ntohs(ip6h->ip6_plen) + adj);
   2892      0      stevel 		*nhp = IPPROTO_ESP;
   2893      0      stevel 	}
   2894      0      stevel 
   2895      0      stevel 	/* I've got the two ESP mblks, now insert them. */
   2896      0      stevel 
   2897   3448    dh155122 	esp2dbg(espstack, ("data_mp before outbound ESP adjustment:\n"));
   2898   3448    dh155122 	esp2dbg(espstack, (dump_msg(data_mp)));
   2899      0      stevel 
   2900   3448    dh155122 	if (!esp_insert_esp(data_mp, espmp, divpoint, espstack)) {
   2901   3448    dh155122 		ESP_BUMP_STAT(espstack, out_discards);
   2902      0      stevel 		/* NOTE:  esp_insert_esp() only fails if there's no memory. */
   2903  11042        Erik 		ip_drop_packet(data_mp, B_FALSE, ill,
   2904   3448    dh155122 		    DROPPER(ipss, ipds_esp_nomem),
   2905   3448    dh155122 		    &espstack->esp_dropper);
   2906      0      stevel 		freeb(espmp);
   2907  11042        Erik 		BUMP_MIB(ill->ill_ip_mib, ipIfStatsOutDiscards);
   2908  11042        Erik 		if (need_refrele)
   2909  11042        Erik 			ixa_refrele(ixa);
   2910  11042        Erik 		return (NULL);
   2911      0      stevel 	}
   2912      0      stevel 
   2913      0      stevel 	/* Append padding (and leave room for ICV). */
   2914      0      stevel 	for (tailmp = data_mp; tailmp->b_cont != NULL; tailmp = tailmp->b_cont)
   2915      0      stevel 		;
   2916      0      stevel 	if (tailmp->b_wptr + alloclen > tailmp->b_datap->db_lim) {
   2917      0      stevel 		tailmp->b_cont = allocb(alloclen, BPRI_HI);
   2918      0      stevel 		if (tailmp->b_cont == NULL) {
   2919   3448    dh155122 			ESP_BUMP_STAT(espstack, out_discards);
   2920      0      stevel 			esp0dbg(("esp_outbound:  Can't allocate tailmp.\n"));
   2921  11042        Erik 			ip_drop_packet(data_mp, B_FALSE, ill,
   2922   3448    dh155122 			    DROPPER(ipss, ipds_esp_nomem),
   2923   3448    dh155122 			    &espstack->esp_dropper);
   2924  11042        Erik 			BUMP_MIB(ill->ill_ip_mib, ipIfStatsOutDiscards);
   2925  11042        Erik 			if (need_refrele)
   2926  11042        Erik 				ixa_refrele(ixa);
   2927  11042        Erik 			return (NULL);
   2928      0      stevel 		}
   2929      0      stevel 		tailmp = tailmp->b_cont;
   2930      0      stevel 	}
   2931      0      stevel 
   2932      0      stevel 	/*
   2933      0      stevel 	 * If there's padding, N bytes of padding must be of the form 0x1,