ip6_ipsec.c revision 180090
121308Sache/*-
221308Sache * Copyright (c) 1982, 1986, 1988, 1993
321308Sache *      The Regents of the University of California.  All rights reserved.
421308Sache *
521308Sache * Redistribution and use in source and binary forms, with or without
621308Sache * modification, are permitted provided that the following conditions
721308Sache * are met:
821308Sache * 1. Redistributions of source code must retain the above copyright
921308Sache *    notice, this list of conditions and the following disclaimer.
1021308Sache * 2. Redistributions in binary form must reproduce the above copyright
1121308Sache *    notice, this list of conditions and the following disclaimer in the
1221308Sache *    documentation and/or other materials provided with the distribution.
1321308Sache * 4. Neither the name of the University nor the names of its contributors
1421308Sache *    may be used to endorse or promote products derived from this software
1521308Sache *    without specific prior written permission.
1621308Sache *
1721308Sache * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
1821308Sache * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1921308Sache * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2021308Sache * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2121308Sache * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2221308Sache * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2321308Sache * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2421308Sache * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2521308Sache * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2621308Sache * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2721308Sache * SUCH DAMAGE.
2821308Sache */
2921308Sache
3021308Sache#include <sys/cdefs.h>
3121308Sache__FBSDID("$FreeBSD: head/sys/netinet6/ip6_ipsec.c 180090 2008-06-29 07:34:21Z bz $");
3221308Sache
3321308Sache#include "opt_ipsec.h"
3421308Sache
3521308Sache#include <sys/param.h>
3621308Sache#include <sys/systm.h>
3721308Sache#include <sys/kernel.h>
3821308Sache#include <sys/mac.h>
3921308Sache#include <sys/malloc.h>
4021308Sache#include <sys/mbuf.h>
4121308Sache#include <sys/protosw.h>
4221308Sache#include <sys/socket.h>
4321308Sache#include <sys/socketvar.h>
4421308Sache#include <sys/sysctl.h>
4521308Sache
4621308Sache#include <net/if.h>
4721308Sache#include <net/route.h>
4821308Sache
4921308Sache#include <netinet/in.h>
50#include <netinet/in_systm.h>
51#include <netinet/in_var.h>
52#include <netinet/ip.h>
53#include <netinet/ip6.h>
54#include <netinet/in_pcb.h>
55#include <netinet/ip_var.h>
56#include <netinet/ip_options.h>
57
58#include <machine/in_cksum.h>
59
60#ifdef IPSEC
61#include <netipsec/ipsec.h>
62#include <netipsec/ipsec6.h>
63#include <netipsec/xform.h>
64#include <netipsec/key.h>
65#ifdef IPSEC_DEBUG
66#include <netipsec/key_debug.h>
67#else
68#define	KEYDEBUG(lev,arg)
69#endif
70#endif /*IPSEC*/
71
72#include <netinet6/ip6_ipsec.h>
73#include <netinet6/ip6_var.h>
74
75extern	struct protosw inet6sw[];
76
77/*
78 * Check if we have to jump over firewall processing for this packet.
79 * Called from ip_input().
80 * 1 = jump over firewall, 0 = packet goes through firewall.
81 */
82int
83ip6_ipsec_filtertunnel(struct mbuf *m)
84{
85#if defined(IPSEC) && !defined(IPSEC_FILTERTUNNEL)
86	/*
87	 * Bypass packet filtering for packets from a tunnel.
88	 */
89	if (m_tag_find(m, PACKET_TAG_IPSEC_IN_DONE, NULL) != NULL)
90		return 1;
91#endif
92	return 0;
93}
94
95/*
96 * Check if this packet has an active SA and needs to be dropped instead
97 * of forwarded.
98 * Called from ip_input().
99 * 1 = drop packet, 0 = forward packet.
100 */
101int
102ip6_ipsec_fwd(struct mbuf *m)
103{
104#ifdef IPSEC
105	struct m_tag *mtag;
106	struct tdb_ident *tdbi;
107	struct secpolicy *sp;
108	int s, error;
109	mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_DONE, NULL);
110	s = splnet();
111	if (mtag != NULL) {
112		tdbi = (struct tdb_ident *)(mtag + 1);
113		sp = ipsec_getpolicy(tdbi, IPSEC_DIR_INBOUND);
114	} else {
115		sp = ipsec_getpolicybyaddr(m, IPSEC_DIR_INBOUND,
116					   IP_FORWARDING, &error);
117	}
118	if (sp == NULL) {	/* NB: can happen if error */
119		splx(s);
120		/*XXX error stat???*/
121		DPRINTF(("ip_input: no SP for forwarding\n"));	/*XXX*/
122		return 1;
123	}
124
125	/*
126	 * Check security policy against packet attributes.
127	 */
128	error = ipsec_in_reject(sp, m);
129	KEY_FREESP(&sp);
130	splx(s);
131	if (error) {
132		ip6stat.ip6s_cantforward++;
133		return 1;
134	}
135#endif /* IPSEC */
136	return 0;
137}
138
139/*
140 * Check if protocol type doesn't have a further header and do IPSEC
141 * decryption or reject right now.  Protocols with further headers get
142 * their IPSEC treatment within the protocol specific processing.
143 * Called from ip_input().
144 * 1 = drop packet, 0 = continue processing packet.
145 */
146int
147ip6_ipsec_input(struct mbuf *m, int nxt)
148{
149#ifdef IPSEC
150	struct m_tag *mtag;
151	struct tdb_ident *tdbi;
152	struct secpolicy *sp;
153	int s, error;
154	/*
155	 * enforce IPsec policy checking if we are seeing last header.
156	 * note that we do not visit this with protocols with pcb layer
157	 * code - like udp/tcp/raw ip.
158	 */
159	if ((inet6sw[ip6_protox[nxt]].pr_flags & PR_LASTHDR) != 0 &&
160	    ipsec6_in_reject(m, NULL)) {
161
162		/*
163		 * Check if the packet has already had IPsec processing
164		 * done.  If so, then just pass it along.  This tag gets
165		 * set during AH, ESP, etc. input handling, before the
166		 * packet is returned to the ip input queue for delivery.
167		 */
168		mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_DONE, NULL);
169		s = splnet();
170		if (mtag != NULL) {
171			tdbi = (struct tdb_ident *)(mtag + 1);
172			sp = ipsec_getpolicy(tdbi, IPSEC_DIR_INBOUND);
173		} else {
174			sp = ipsec_getpolicybyaddr(m, IPSEC_DIR_INBOUND,
175						   IP_FORWARDING, &error);
176		}
177		if (sp != NULL) {
178			/*
179			 * Check security policy against packet attributes.
180			 */
181			error = ipsec_in_reject(sp, m);
182			KEY_FREESP(&sp);
183		} else {
184			/* XXX error stat??? */
185			error = EINVAL;
186			DPRINTF(("ip_input: no SP, packet discarded\n"));/*XXX*/
187			return 1;
188		}
189		splx(s);
190		if (error)
191			return 1;
192	}
193#endif /* IPSEC */
194	return 0;
195}
196
197/*
198 * Called from ip6_output().
199 * 1 = drop packet, 0 = continue processing packet,
200 * -1 = packet was reinjected and stop processing packet
201 */
202
203int
204ip6_ipsec_output(struct mbuf **m, struct inpcb *inp, int *flags, int *error,
205    struct ifnet **ifp, struct secpolicy **sp)
206{
207#ifdef IPSEC
208	struct tdb_ident *tdbi;
209	struct m_tag *mtag;
210	/* XXX int s; */
211	if (sp == NULL)
212		return 1;
213	mtag = m_tag_find(*m, PACKET_TAG_IPSEC_PENDING_TDB, NULL);
214	if (mtag != NULL) {
215		tdbi = (struct tdb_ident *)(mtag + 1);
216		*sp = ipsec_getpolicy(tdbi, IPSEC_DIR_OUTBOUND);
217		if (*sp == NULL)
218			*error = -EINVAL;	/* force silent drop */
219		m_tag_delete(*m, mtag);
220	} else {
221		*sp = ipsec4_checkpolicy(*m, IPSEC_DIR_OUTBOUND, *flags,
222					error, inp);
223	}
224
225	/*
226	 * There are four return cases:
227	 *    sp != NULL		    apply IPsec policy
228	 *    sp == NULL, error == 0	    no IPsec handling needed
229	 *    sp == NULL, error == -EINVAL  discard packet w/o error
230	 *    sp == NULL, error != 0	    discard packet, report error
231	 */
232	if (*sp != NULL) {
233		/* Loop detection, check if ipsec processing already done */
234		KASSERT((*sp)->req != NULL, ("ip_output: no ipsec request"));
235		for (mtag = m_tag_first(*m); mtag != NULL;
236		     mtag = m_tag_next(*m, mtag)) {
237			if (mtag->m_tag_cookie != MTAG_ABI_COMPAT)
238				continue;
239			if (mtag->m_tag_id != PACKET_TAG_IPSEC_OUT_DONE &&
240			    mtag->m_tag_id != PACKET_TAG_IPSEC_OUT_CRYPTO_NEEDED)
241				continue;
242			/*
243			 * Check if policy has an SA associated with it.
244			 * This can happen when an SP has yet to acquire
245			 * an SA; e.g. on first reference.  If it occurs,
246			 * then we let ipsec4_process_packet do its thing.
247			 */
248			if ((*sp)->req->sav == NULL)
249				break;
250			tdbi = (struct tdb_ident *)(mtag + 1);
251			if (tdbi->spi == (*sp)->req->sav->spi &&
252			    tdbi->proto == (*sp)->req->sav->sah->saidx.proto &&
253			    bcmp(&tdbi->dst, &(*sp)->req->sav->sah->saidx.dst,
254				 sizeof (union sockaddr_union)) == 0) {
255				/*
256				 * No IPsec processing is needed, free
257				 * reference to SP.
258				 *
259				 * NB: null pointer to avoid free at
260				 *     done: below.
261				 */
262				KEY_FREESP(sp), *sp = NULL;
263				/* XXX splx(s); */
264				goto done;
265			}
266		}
267
268		/*
269		 * Do delayed checksums now because we send before
270		 * this is done in the normal processing path.
271		 */
272		if ((*m)->m_pkthdr.csum_flags & CSUM_DELAY_DATA) {
273			in_delayed_cksum(*m);
274			(*m)->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA;
275		}
276
277		/*
278		 * Preserve KAME behaviour: ENOENT can be returned
279		 * when an SA acquire is in progress.  Don't propagate
280		 * this to user-level; it confuses applications.
281		 *
282		 * XXX this will go away when the SADB is redone.
283		 */
284		if (*error == ENOENT)
285			*error = 0;
286		goto do_ipsec;
287	} else {	/* sp == NULL */
288		if (*error != 0) {
289			/*
290			 * Hack: -EINVAL is used to signal that a packet
291			 * should be silently discarded.  This is typically
292			 * because we asked key management for an SA and
293			 * it was delayed (e.g. kicked up to IKE).
294			 */
295			if (*error == -EINVAL)
296				*error = 0;
297			goto bad;
298		} else {
299			/* No IPsec processing for this packet. */
300		}
301	}
302done:
303	return 0;
304do_ipsec:
305	return -1;
306bad:
307	return 1;
308#endif /* IPSEC */
309	return 0;
310}
311
312#if 0
313/*
314 * Compute the MTU for a forwarded packet that gets IPSEC encapsulated.
315 * Called from ip_forward().
316 * Returns MTU suggestion for ICMP needfrag reply.
317 */
318int
319ip6_ipsec_mtu(struct mbuf *m)
320{
321	int mtu = 0;
322	/*
323	 * If the packet is routed over IPsec tunnel, tell the
324	 * originator the tunnel MTU.
325	 *	tunnel MTU = if MTU - sizeof(IP) - ESP/AH hdrsiz
326	 * XXX quickhack!!!
327	 */
328#ifdef IPSEC
329	struct secpolicy *sp = NULL;
330	int ipsecerror;
331	int ipsechdr;
332	struct route *ro;
333	sp = ipsec_getpolicybyaddr(m,
334				   IPSEC_DIR_OUTBOUND,
335				   IP_FORWARDING,
336				   &ipsecerror);
337	if (sp != NULL) {
338		/* count IPsec header size */
339		ipsechdr = ipsec4_hdrsiz(m,
340					 IPSEC_DIR_OUTBOUND,
341					 NULL);
342
343		/*
344		 * find the correct route for outer IPv4
345		 * header, compute tunnel MTU.
346		 */
347		if (sp->req != NULL &&
348		    sp->req->sav != NULL &&
349		    sp->req->sav->sah != NULL) {
350			ro = &sp->req->sav->sah->sa_route;
351			if (ro->ro_rt && ro->ro_rt->rt_ifp) {
352				mtu =
353				    ro->ro_rt->rt_rmx.rmx_mtu ?
354				    ro->ro_rt->rt_rmx.rmx_mtu :
355				    ro->ro_rt->rt_ifp->if_mtu;
356				mtu -= ipsechdr;
357			}
358		}
359		KEY_FREESP(&sp);
360	}
361#endif /* IPSEC */
362	/* XXX else case missing. */
363	return mtu;
364}
365#endif
366