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