Home | History | Annotate | Download | only in inet
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 /*
     22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     23  * Use is subject to license terms.
     24  */
     25 
     26 #ifndef	_INET_IPSEC_INFO_H
     27 #define	_INET_IPSEC_INFO_H
     28 
     29 #ifdef	__cplusplus
     30 extern "C" {
     31 #endif
     32 
     33 #include <sys/crypto/common.h>
     34 
     35 /*
     36  * IPsec informational messages.  These are M_CTL STREAMS messages, which
     37  * convey IPsec information between various IP and related modules.  The
     38  * messages come in a few flavors:
     39  *
     40  *	* IPSEC_{IN,OUT}  -  These show what IPsec action have been taken (for
     41  *	  inbound datagrams), or need to be taken (for outbound datagrams).
     42  *	  They flow between AH/ESP and IP.
     43  *
     44  *	* Keysock consumer interface  -  These messages are wrappers for
     45  *	  PF_KEY messages.  They flow between AH/ESP and keysock.
     46  *
     47  * Some of these messages include pointers such as a netstack_t pointer.
     48  * We do not explicitly reference count those with netstack_hold/rele,
     49  * since we depend on IP's ability to discard all of the IPSEC_{IN,OUT}
     50  * messages in order to handle the ipsa pointers.
     51  * We have special logic when doing asynch callouts to kEF for which we
     52  * verify netstack_t pointer using the netstackid_t.
     53  */
     54 
     55 /*
     56  * The IPsec M_CTL value MUST be something that will not be even close
     57  * to an IPv4 or IPv6 header.  This means the first byte must not be
     58  * 0x40 - 0x4f or 0x60-0x6f.  For big-endian machines, this is fixable with
     59  * the IPSEC_M_CTL prefix.  For little-endian machines, the actual M_CTL
     60  * _type_ must not be in the aforementioned ranges.
     61  *
     62  * The reason for this avoidance is because M_CTL's with a real IPv4/IPv6
     63  * datagram get sent from to TCP or UDP when an ICMP datagram affects a
     64  * TCP/UDP session.
     65  */
     66 #define	IPSEC_M_CTL	0x73706900
     67 
     68 /*
     69  * M_CTL types for IPsec messages.  Remember, the values 0x40 - 0x4f and 0x60
     70  * - 0x6f are not to be used because of potential little-endian confusion.
     71  *
     72  * Offsets 1-25 (decimal) are in use, spread through this file.
     73  * Check for duplicates through the whole file before adding.
     74  */
     75 
     76 /*
     77  * IPSEC_{IN,OUT} policy expressors.
     78  */
     79 #define	IPSEC_IN	(IPSEC_M_CTL + 1)
     80 #define	IPSEC_OUT	(IPSEC_M_CTL + 2)
     81 #define	MAXSALTSIZE 8
     82 
     83 /*
     84  * For combined mode ciphers, store the crypto_mechanism_t in the
     85  * per-packet ipsec_in_t/ipsec_out_t structures. This is because the PARAMS
     86  * and nonce values change for each packet. For non-combined mode
     87  * ciphers, these values are constant for the life of the SA.
     88  */
     89 typedef struct ipsa_cm_mech_s {
     90 	crypto_mechanism_t combined_mech;
     91 	union {
     92 		CK_AES_CCM_PARAMS paramu_ccm;
     93 		CK_AES_GCM_PARAMS paramu_gcm;
     94 	} paramu;
     95 	uint8_t nonce[MAXSALTSIZE + sizeof (uint64_t)];
     96 #define	param_ulMACSize paramu.paramu_ccm.ulMACSize
     97 #define	param_ulNonceSize paramu.paramu_ccm.ipsa_ulNonceSize
     98 #define	param_ulAuthDataSize paramu.paramu_ccm.ipsa_ulAuthDataSize
     99 #define	param_ulDataSize paramu.paramu_ccm.ipsa_ulDataSize
    100 #define	param_nonce paramu.paramu_ccm.nonce
    101 #define	param_authData paramu.paramu_ccm.authData
    102 #define	param_pIv paramu.paramu_gcm.ipsa_pIv
    103 #define	param_ulIvLen paramu.paramu_gcm.ulIvLen
    104 #define	param_ulIvBits paramu.paramu_gcm.ulIvBits
    105 #define	param_pAAD paramu.paramu_gcm.pAAD
    106 #define	param_ulAADLen paramu.paramu_gcm.ulAADLen
    107 #define	param_ulTagBits paramu.paramu_gcm.ulTagBits
    108 } ipsa_cm_mech_t;
    109 
    110 /*
    111  * This is used for communication between IP and IPSEC (AH/ESP)
    112  * for Inbound datagrams. IPSEC_IN is allocated by IP before IPSEC
    113  * processing begins. On return spi fields are initialized so that
    114  * IP can locate the security associations later on for doing policy
    115  * checks. For loopback case, IPSEC processing is not done. But the
    116  * attributes of the security are reflected in <foo>_done fields below.
    117  * The code in policy check infers that it is a loopback case and
    118  * would not try to get the associations.
    119  *
    120  * The comment below (and for other netstack_t references) refers
    121  * to the fact that we only do netstack_hold in particular cases,
    122  * such as the references from open streams (ill_t and conn_t's
    123  * pointers). Internally within IP we rely on IP's ability to cleanup e.g.
    124  * ire_t's when an ill goes away.
    125  */
    126 typedef struct ipsec_in_s {
    127 	uint32_t ipsec_in_type;
    128 	uint32_t ipsec_in_len;
    129 	frtn_t ipsec_in_frtn;		/* for esballoc() callback */
    130 	struct ipsa_s 	*ipsec_in_ah_sa;	/* SA for AH */
    131 	struct ipsa_s 	*ipsec_in_esp_sa;	/* SA for ESP */
    132 
    133 	struct ipsec_policy_head_s *ipsec_in_policy;
    134 	struct ipsec_action_s *ipsec_in_action; /* how we made it in.. */
    135 	unsigned int
    136 		ipsec_in_secure : 1,	/* Is the message attached secure ? */
    137 		ipsec_in_v4 : 1,	/* Is this an ipv4 packet ? */
    138 		ipsec_in_loopback : 1,	/* Is this a loopback request ? */
    139 		ipsec_in_dont_check : 1, /* Used by TCP to avoid policy check */
    140 
    141 		ipsec_in_decaps : 1,	/* Was this packet decapsulated from */
    142 					/* a matching inner packet? */
    143 		ipsec_in_accelerated : 1, /* hardware accelerated packet */
    144 
    145 		ipsec_in_icmp_loopback : 1, /* Looped-back ICMP packet, */
    146 					    /* all should trust this. */
    147 		ipsec_in_pad_bits : 25;
    148 
    149 	int    ipsec_in_ill_index;	/* interface on which ipha_dst was */
    150 					/* configured when pkt was recv'd  */
    151 	int    ipsec_in_rill_index;	/* interface on which pkt was recv'd */
    152 	uint32_t ipsec_in_esp_udp_ports;	/* For an ESP-in-UDP packet. */
    153 	mblk_t *ipsec_in_da;		/* data attr. for accelerated pkts */
    154 
    155 	/*
    156 	 * For call to the kernel crypto framework. State needed during
    157 	 * the execution of a crypto request. Storing these here
    158 	 * allow us to avoid a separate allocation before calling the
    159 	 * crypto framework.
    160 	 */
    161 	size_t ipsec_in_skip_len;		/* len to skip for AH auth */
    162 	crypto_data_t ipsec_in_crypto_data;	/* single op crypto data */
    163 	crypto_dual_data_t ipsec_in_crypto_dual_data; /* for dual ops */
    164 	crypto_data_t ipsec_in_crypto_mac;	/* to store the MAC */
    165 
    166 	zoneid_t ipsec_in_zoneid;	/* target zone for the datagram */
    167 	netstack_t *ipsec_in_ns;	/* Does not have a netstack_hold */
    168 	ipsa_cm_mech_t ipsec_in_cmm;	/* PARAMS for Combined mode mechs */
    169 	netstackid_t ipsec_in_stackid;	/* Used while waing for kEF callback */
    170 } ipsec_in_t;
    171 
    172 #define	IPSECOUT_MAX_ADDRLEN 4	/* Max addr len. (in 32-bit words) */
    173 /*
    174  * This is used for communication between IP and IPSEC (AH/ESP)
    175  * for Outbound datagrams. IPSEC_OUT is allocated by IP before IPSEC
    176  * processing begins. On return SA fields are initialized so that
    177  * IP can locate the security associations later on for doing policy
    178  * checks.  The policy and the actions associated with this packet are
    179  * stored in the ipsec_out_policy and ipsec_out_act fields respectively.
    180  * IPSEC_OUT is also used to carry non-ipsec information when conn is
    181  * absent or the conn information is lost across the calls to ARP.
    182  * example: message from ARP or from ICMP error routines.
    183  */
    184 typedef struct ipsec_out_s {
    185 	uint32_t ipsec_out_type;
    186 	uint32_t ipsec_out_len;
    187 	frtn_t ipsec_out_frtn;		/* for esballoc() callback */
    188 	struct ipsec_policy_head_s *ipsec_out_polhead;
    189 	ipsec_latch_t		*ipsec_out_latch;
    190 	struct ipsec_policy_s 	*ipsec_out_policy; /* why are we here? */
    191 	struct ipsec_action_s	*ipsec_out_act;	/* what do we want? */
    192 	struct ipsa_s	*ipsec_out_ah_sa; /* AH SA used for the packet */
    193 	struct ipsa_s	*ipsec_out_esp_sa; /* ESP SA used for the packet */
    194 	/*
    195 	 * NOTE: "Source" and "Dest" are w.r.t. outbound datagrams.  Ports can
    196 	 *	 be zero, and the protocol number is needed to make the ports
    197 	 *	 significant.
    198 	 */
    199 	uint16_t ipsec_out_src_port;	/* Source port number of d-gram. */
    200 	uint16_t ipsec_out_dst_port;	/* Destination port number of d-gram. */
    201 	uint8_t  ipsec_out_icmp_type;	/* ICMP type of d-gram */
    202 	uint8_t  ipsec_out_icmp_code;	/* ICMP code of d-gram */
    203 
    204 	sa_family_t ipsec_out_inaf;	/* Inner address family */
    205 	uint32_t ipsec_out_insrc[IPSECOUT_MAX_ADDRLEN];	/* Inner src address */
    206 	uint32_t ipsec_out_indst[IPSECOUT_MAX_ADDRLEN];	/* Inner dest address */
    207 	uint8_t  ipsec_out_insrcpfx;	/* Inner source prefix */
    208 	uint8_t  ipsec_out_indstpfx;	/* Inner destination prefix */
    209 
    210 	uint_t ipsec_out_ill_index;	/* ill index used for multicast etc. */
    211 	uint8_t ipsec_out_proto;	/* IP protocol number for d-gram. */
    212 	unsigned int
    213 		ipsec_out_tunnel : 1,	/* Tunnel mode? */
    214 		ipsec_out_use_global_policy : 1, /* Inherit global policy ? */
    215 		ipsec_out_secure : 1,	/* Is this secure ? */
    216 		ipsec_out_proc_begin : 1, /* IPSEC processing begun */
    217 		/*
    218 		 * Following five values reflects the values stored
    219 		 * in conn.
    220 		 */
    221 		ipsec_out_multicast_loop : 1,
    222 		ipsec_out_dontroute : 1,
    223 		ipsec_out_reserved : 1,
    224 		ipsec_out_v4 : 1,
    225 
    226 		ipsec_out_unspec_src : 1,	/* IPv6 ip6i_t info */
    227 		ipsec_out_reachable : 1, 	/* NDP reachability info */
    228 		ipsec_out_failed: 1,
    229 		ipsec_out_se_done: 1,
    230 
    231 		ipsec_out_esp_done: 1,
    232 		ipsec_out_ah_done: 1,
    233 		ipsec_out_need_policy: 1,
    234 
    235 		/*
    236 		 * To indicate that packet must be accelerated, i.e.
    237 		 * ICV or encryption performed, by Provider.
    238 		 */
    239 		ipsec_out_accelerated : 1,
    240 		/*
    241 		 * Used by IP to tell IPsec that the outbound ill for this
    242 		 * packet supports acceleration of the AH or ESP prototocol.
    243 		 * If set, ipsec_out_capab_ill_index contains the
    244 		 * index of the ill.
    245 		 */
    246 		ipsec_out_is_capab_ill : 1,
    247 		/*
    248 		 * Indicates ICMP message destined for self.  These
    249 		 * messages are to be trusted by all receivers.
    250 		 */
    251 		ipsec_out_icmp_loopback: 1,
    252 		ipsec_out_ip_nexthop : 1,	/* IP_NEXTHOP option is set */
    253 		ipsec_out_pad_bits : 13;
    254 	cred_t	*ipsec_out_cred;
    255 	uint32_t ipsec_out_capab_ill_index;
    256 
    257 	/*
    258 	 * For call to the kernel crypto framework. State needed during
    259 	 * the execution of a crypto request. Storing these here
    260 	 * allow us to avoid a separate allocation before calling the
    261 	 * crypto framework.
    262 	 */
    263 	size_t ipsec_out_skip_len;		/* len to skip for AH auth */
    264 	crypto_data_t ipsec_out_crypto_data;	/* single op crypto data */
    265 	crypto_dual_data_t ipsec_out_crypto_dual_data; /* for dual ops */
    266 	crypto_data_t ipsec_out_crypto_mac;	/* to store the MAC */
    267 
    268 	zoneid_t ipsec_out_zoneid;	/* source zone for the datagram */
    269 	in6_addr_t ipsec_out_nexthop_v6;	/* nexthop IP address */
    270 #define	ipsec_out_nexthop_addr V4_PART_OF_V6(ipsec_out_nexthop_v6)
    271 	netstack_t *ipsec_out_ns;	/* Does not have a netstack_hold */
    272 	netstackid_t ipsec_out_stackid;	/* Used while waing for kEF callback */
    273 	ipsa_cm_mech_t ipsec_out_cmm;	/* PARAMS for Combined mode mechs */
    274 } ipsec_out_t;
    275 
    276 /*
    277  * This is used to mark the ipsec_out_t *req* fields
    278  * when the operation is done without affecting the
    279  * requests.
    280  */
    281 #define	IPSEC_REQ_DONE		0x80000000
    282 /*
    283  * Operation could not be performed by the AH/ESP
    284  * module.
    285  */
    286 #define	IPSEC_REQ_FAILED	0x40000000
    287 
    288 /*
    289  * Keysock consumer interface.
    290  *
    291  * The driver/module keysock (which is a driver to PF_KEY sockets, but is
    292  * a module to 'consumers' like AH and ESP) uses keysock consumer interface
    293  * messages to pass on PF_KEY messages to consumers who process and act upon
    294  * them.
    295  */
    296 #define	KEYSOCK_IN		(IPSEC_M_CTL + 3)
    297 #define	KEYSOCK_OUT		(IPSEC_M_CTL + 4)
    298 #define	KEYSOCK_OUT_ERR		(IPSEC_M_CTL + 5)
    299 #define	KEYSOCK_HELLO		(IPSEC_M_CTL + 6)
    300 #define	KEYSOCK_HELLO_ACK	(IPSEC_M_CTL + 7)
    301 
    302 /*
    303  * KEYSOCK_HELLO is sent by keysock to a consumer when it is pushed on top
    304  * of one (i.e. opened as a module).
    305  *
    306  * NOTE: Keysock_hello is simply an ipsec_info_t
    307  */
    308 
    309 /*
    310  * KEYSOCK_HELLO_ACK is sent by a consumer to acknowledge a KEYSOCK_HELLO.
    311  * It contains the PF_KEYv2 sa_type, so keysock can redirect PF_KEY messages
    312  * to the right consumer.
    313  */
    314 typedef struct keysock_hello_ack_s {
    315 	uint32_t ks_hello_type;
    316 	uint32_t ks_hello_len;
    317 	uint8_t ks_hello_satype;	/* PF_KEYv2 sa_type of ks client */
    318 } keysock_hello_ack_t;
    319 
    320 #define	KS_IN_ADDR_UNKNOWN 0
    321 #define	KS_IN_ADDR_NOTTHERE 1
    322 #define	KS_IN_ADDR_UNSPEC 2
    323 #define	KS_IN_ADDR_ME 3
    324 #define	KS_IN_ADDR_NOTME 4
    325 #define	KS_IN_ADDR_MBCAST 5
    326 #define	KS_IN_ADDR_DONTCARE 6
    327 
    328 /*
    329  * KEYSOCK_IN is a PF_KEY message from a PF_KEY socket destined for a consumer.
    330  */
    331 typedef struct keysock_in_s {
    332 	uint32_t ks_in_type;
    333 	uint32_t ks_in_len;
    334 	/*
    335 	 * NOTE:	These pointers MUST be into the M_DATA that follows
    336 	 *		this M_CTL message.  If they aren't, weirdness
    337 	 *		results.
    338 	 */
    339 	struct sadb_ext *ks_in_extv[SADB_EXT_MAX + 1];
    340 	int ks_in_srctype;	/* Source address type. */
    341 	int ks_in_dsttype;	/* Dest address type. */
    342 	minor_t ks_in_serial;	/* Serial # of sending socket. */
    343 } keysock_in_t;
    344 
    345 /*
    346  * KEYSOCK_OUT is a PF_KEY message from a consumer destined for a PF_KEY
    347  * socket.
    348  */
    349 typedef struct keysock_out_s {
    350 	uint32_t ks_out_type;
    351 	uint32_t ks_out_len;
    352 	minor_t ks_out_serial;	/* Serial # of sending socket. */
    353 } keysock_out_t;
    354 
    355 /*
    356  * KEYSOCK_OUT_ERR is sent to a consumer from keysock if for some reason
    357  * keysock could not find a PF_KEY socket to deliver a consumer-originated
    358  * message (e.g. SADB_ACQUIRE).
    359  */
    360 typedef struct keysock_out_err_s {
    361 	uint32_t ks_err_type;
    362 	uint32_t ks_err_len;
    363 	minor_t ks_err_serial;
    364 	int ks_err_errno;
    365 	/*
    366 	 * Other, richer error information may end up going here eventually.
    367 	 */
    368 } keysock_out_err_t;
    369 
    370 /*
    371  * M_CTL message type for sending inbound pkt information between IP & ULP.
    372  * These are _not_ related to IPsec in any way, but are here so that there is
    373  * one place where all these values are defined which makes it easier to track.
    374  * The choice of this value has the same rationale as explained above.
    375  */
    376 #define	IN_PKTINFO		(IPSEC_M_CTL + 24)
    377 
    378 
    379 /*
    380  * IPSEC_CTL messages are used by IPsec to send control type requests
    381  * to IP. Such a control message is currently used by IPsec to request
    382  * that IP send the contents of an IPsec SA or the entire SADB to
    383  * every IPsec hardware acceleration capable provider.
    384  */
    385 
    386 #define	IPSEC_CTL		(IPSEC_M_CTL + 25)
    387 
    388 typedef struct ipsec_ctl_s {
    389 	uint32_t ipsec_ctl_type;
    390 	uint32_t ipsec_ctl_len;
    391 	uint_t ipsec_ctl_sa_type;
    392 	void *ipsec_ctl_sa;
    393 } ipsec_ctl_t;
    394 
    395 
    396 /*
    397  * All IPsec informational messages are placed into the ipsec_info_t
    398  * union, so that allocation can be done once, and IPsec informational
    399  * messages can be recycled.
    400  */
    401 typedef union ipsec_info_u {
    402 	struct {
    403 		uint32_t ipsec_allu_type;
    404 		uint32_t ipsec_allu_len;	/* In bytes */
    405 	} ipsec_allu;
    406 	ipsec_in_t ipsec_in;
    407 	ipsec_out_t ipsec_out;
    408 	keysock_hello_ack_t keysock_hello_ack;
    409 	keysock_in_t keysock_in;
    410 	keysock_out_t keysock_out;
    411 	keysock_out_err_t keysock_out_err;
    412 	ipsec_ctl_t ipsec_ctl;
    413 } ipsec_info_t;
    414 #define	ipsec_info_type ipsec_allu.ipsec_allu_type
    415 #define	ipsec_info_len ipsec_allu.ipsec_allu_len
    416 
    417 #ifdef	__cplusplus
    418 }
    419 #endif
    420 
    421 #endif	/* _INET_IPSEC_INFO_H */
    422