ipsec_input.c revision 171497
1157184Sache/*	$FreeBSD: head/sys/netipsec/ipsec_input.c 171497 2007-07-19 09:57:54Z bz $	*/
2157184Sache/*	$OpenBSD: ipsec_input.c,v 1.63 2003/02/20 18:35:43 deraadt Exp $	*/
3157184Sache/*-
4157184Sache * The authors of this code are John Ioannidis (ji@tla.org),
5157184Sache * Angelos D. Keromytis (kermit@csd.uch.gr) and
6157184Sache * Niels Provos (provos@physnet.uni-hamburg.de).
7157184Sache *
8157184Sache * This code was written by John Ioannidis for BSD/OS in Athens, Greece,
9157184Sache * in November 1995.
10157184Sache *
11157184Sache * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
12157184Sache * by Angelos D. Keromytis.
13157184Sache *
14157184Sache * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
15157184Sache * and Niels Provos.
16157184Sache *
17157184Sache * Additional features in 1999 by Angelos D. Keromytis.
18157184Sache *
19157184Sache * Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
20157184Sache * Angelos D. Keromytis and Niels Provos.
21157184Sache * Copyright (c) 2001, Angelos D. Keromytis.
22157184Sache *
23157184Sache * Permission to use, copy, and modify this software with or without fee
24157184Sache * is hereby granted, provided that this entire notice is included in
25157184Sache * all copies of any software which is or includes a copy or
26157184Sache * modification of this software.
27157184Sache * You may use this code under the GNU public license if you so wish. Please
28157184Sache * contribute changes back to the authors under this freer than GPL license
29157184Sache * so that we may further the use of strong encryption without limitations to
30157184Sache * all.
31157184Sache *
32157184Sache * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
33157184Sache * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
34157184Sache * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
35157184Sache * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
36157184Sache * PURPOSE.
37157184Sache */
38157184Sache
39157184Sache/*
40157184Sache * IPsec input processing.
41157184Sache */
42157184Sache
43157184Sache#include "opt_inet.h"
44157184Sache#include "opt_inet6.h"
45157184Sache#include "opt_ipsec.h"
46157184Sache#include "opt_enc.h"
47157184Sache
48157184Sache#include <sys/param.h>
49157184Sache#include <sys/systm.h>
50157184Sache#include <sys/malloc.h>
51157184Sache#include <sys/mbuf.h>
52157184Sache#include <sys/domain.h>
53157184Sache#include <sys/protosw.h>
54157184Sache#include <sys/socket.h>
55157184Sache#include <sys/errno.h>
56157184Sache#include <sys/syslog.h>
57157184Sache
58157184Sache#include <net/if.h>
59157184Sache#include <net/pfil.h>
60157184Sache#include <net/route.h>
61157184Sache#include <net/netisr.h>
62157184Sache
63157184Sache#include <netinet/in.h>
64157184Sache#include <netinet/in_systm.h>
65157184Sache#include <netinet/ip.h>
66157184Sache#include <netinet/ip_var.h>
67157184Sache#include <netinet/in_var.h>
68157184Sache
69157184Sache#include <netinet/ip6.h>
70157184Sache#ifdef INET6
71157184Sache#include <netinet6/ip6_var.h>
72157184Sache#endif
73157184Sache#include <netinet/in_pcb.h>
74157184Sache#ifdef INET6
75157184Sache#include <netinet/icmp6.h>
76157184Sache#endif
77157184Sache
78157184Sache#include <netipsec/ipsec.h>
79157184Sache#ifdef INET6
80157184Sache#include <netipsec/ipsec6.h>
81157184Sache#endif
82157184Sache#include <netipsec/ah_var.h>
83157184Sache#include <netipsec/esp.h>
84157184Sache#include <netipsec/esp_var.h>
85157184Sache#include <netipsec/ipcomp_var.h>
86157184Sache
87157184Sache#include <netipsec/key.h>
88157184Sache#include <netipsec/keydb.h>
89157184Sache
90157184Sache#include <netipsec/xform.h>
91157184Sache#include <netinet6/ip6protosw.h>
92157184Sache
93157184Sache#include <machine/in_cksum.h>
94157184Sache#include <machine/stdarg.h>
95157184Sache
96157184Sache#define IPSEC_ISTAT(p,x,y,z) ((p) == IPPROTO_ESP ? (x)++ : \
97157184Sache			    (p) == IPPROTO_AH ? (y)++ : (z)++)
98157184Sache
99157184Sachestatic void ipsec4_common_ctlinput(int, struct sockaddr *, void *, int);
100157184Sache
101157184Sache/*
102157184Sache * ipsec_common_input gets called when an IPsec-protected packet
103157184Sache * is received by IPv4 or IPv6.  It's job is to find the right SA
104157184Sache * and call the appropriate transform.  The transform callback
105157184Sache * takes care of further processing (like ingress filtering).
106157184Sache */
107157184Sachestatic int
108157184Sacheipsec_common_input(struct mbuf *m, int skip, int protoff, int af, int sproto)
109157184Sache{
110157184Sache	union sockaddr_union dst_address;
111157184Sache	struct secasvar *sav;
112157184Sache	u_int32_t spi;
113157184Sache	int error;
114157184Sache
115157184Sache	IPSEC_ISTAT(sproto, espstat.esps_input, ahstat.ahs_input,
116157184Sache		ipcompstat.ipcomps_input);
117157184Sache
118157184Sache	IPSEC_ASSERT(m != NULL, ("null packet"));
119157184Sache
120157184Sache	IPSEC_ASSERT(sproto == IPPROTO_ESP || sproto == IPPROTO_AH ||
121157184Sache		sproto == IPPROTO_IPCOMP,
122157184Sache		("unexpected security protocol %u", sproto));
123157184Sache
124157184Sache	if ((sproto == IPPROTO_ESP && !esp_enable) ||
125157184Sache	    (sproto == IPPROTO_AH && !ah_enable) ||
126157184Sache	    (sproto == IPPROTO_IPCOMP && !ipcomp_enable)) {
127157184Sache		m_freem(m);
128157184Sache		IPSEC_ISTAT(sproto, espstat.esps_pdrops, ahstat.ahs_pdrops,
129157184Sache		    ipcompstat.ipcomps_pdrops);
130157184Sache		return EOPNOTSUPP;
131157184Sache	}
132157184Sache
133157184Sache	if (m->m_pkthdr.len - skip < 2 * sizeof (u_int32_t)) {
134157184Sache		m_freem(m);
135157184Sache		IPSEC_ISTAT(sproto, espstat.esps_hdrops, ahstat.ahs_hdrops,
136157184Sache		    ipcompstat.ipcomps_hdrops);
137157184Sache		DPRINTF(("%s: packet too small\n", __func__));
138157184Sache		return EINVAL;
139157184Sache	}
140157184Sache
141157184Sache	/* Retrieve the SPI from the relevant IPsec header */
142157184Sache	if (sproto == IPPROTO_ESP)
143157184Sache		m_copydata(m, skip, sizeof(u_int32_t), (caddr_t) &spi);
144157184Sache	else if (sproto == IPPROTO_AH)
145157184Sache		m_copydata(m, skip + sizeof(u_int32_t), sizeof(u_int32_t),
146157184Sache		    (caddr_t) &spi);
147157184Sache	else if (sproto == IPPROTO_IPCOMP) {
148157184Sache		u_int16_t cpi;
149157184Sache		m_copydata(m, skip + sizeof(u_int16_t), sizeof(u_int16_t),
150157184Sache		    (caddr_t) &cpi);
151157184Sache		spi = ntohl(htons(cpi));
152157184Sache	}
153157184Sache
154157184Sache	/*
155157184Sache	 * Find the SA and (indirectly) call the appropriate
156157184Sache	 * kernel crypto routine. The resulting mbuf chain is a valid
157157184Sache	 * IP packet ready to go through input processing.
158157184Sache	 */
159157184Sache	bzero(&dst_address, sizeof (dst_address));
160157184Sache	dst_address.sa.sa_family = af;
161157184Sache	switch (af) {
162157184Sache#ifdef INET
163157184Sache	case AF_INET:
164157184Sache		dst_address.sin.sin_len = sizeof(struct sockaddr_in);
165157184Sache		m_copydata(m, offsetof(struct ip, ip_dst),
166157184Sache		    sizeof(struct in_addr),
167157184Sache		    (caddr_t) &dst_address.sin.sin_addr);
168157184Sache		break;
169157184Sache#endif /* INET */
170157184Sache#ifdef INET6
171157184Sache	case AF_INET6:
172157184Sache		dst_address.sin6.sin6_len = sizeof(struct sockaddr_in6);
173157184Sache		m_copydata(m, offsetof(struct ip6_hdr, ip6_dst),
174157184Sache		    sizeof(struct in6_addr),
175157184Sache		    (caddr_t) &dst_address.sin6.sin6_addr);
176157184Sache		break;
177157184Sache#endif /* INET6 */
178157184Sache	default:
179157184Sache		DPRINTF(("%s: unsupported protocol family %u\n", __func__, af));
180157184Sache		m_freem(m);
181157184Sache		IPSEC_ISTAT(sproto, espstat.esps_nopf, ahstat.ahs_nopf,
182157184Sache		    ipcompstat.ipcomps_nopf);
183157184Sache		return EPFNOSUPPORT;
184157184Sache	}
185157184Sache
186157184Sache	/* NB: only pass dst since key_allocsa follows RFC2401 */
187157184Sache	sav = KEY_ALLOCSA(&dst_address, sproto, spi);
188157184Sache	if (sav == NULL) {
189157184Sache		DPRINTF(("%s: no key association found for SA %s/%08lx/%u\n",
190157184Sache			  __func__, ipsec_address(&dst_address),
191157184Sache			  (u_long) ntohl(spi), sproto));
192157184Sache		IPSEC_ISTAT(sproto, espstat.esps_notdb, ahstat.ahs_notdb,
193157184Sache		    ipcompstat.ipcomps_notdb);
194157184Sache		m_freem(m);
195157184Sache		return ENOENT;
196157184Sache	}
197157184Sache
198157184Sache	if (sav->tdb_xform == NULL) {
199157184Sache		DPRINTF(("%s: attempted to use uninitialized SA %s/%08lx/%u\n",
200157184Sache			 __func__, ipsec_address(&dst_address),
201157184Sache			 (u_long) ntohl(spi), sproto));
202157184Sache		IPSEC_ISTAT(sproto, espstat.esps_noxform, ahstat.ahs_noxform,
203157184Sache		    ipcompstat.ipcomps_noxform);
204157184Sache		KEY_FREESAV(&sav);
205157184Sache		m_freem(m);
206157184Sache		return ENXIO;
207157184Sache	}
208157184Sache
209157184Sache	/*
210157184Sache	 * Call appropriate transform and return -- callback takes care of
211157184Sache	 * everything else.
212157184Sache	 */
213157184Sache	error = (*sav->tdb_xform->xf_input)(m, sav, skip, protoff);
214157184Sache	KEY_FREESAV(&sav);
215157184Sache	return error;
216157184Sache}
217157184Sache
218157184Sache#ifdef INET
219157184Sache/*
220157184Sache * Common input handler for IPv4 AH, ESP, and IPCOMP.
221157184Sache */
222157184Sacheint
223157184Sacheipsec4_common_input(struct mbuf *m, ...)
224157184Sache{
225157184Sache	va_list ap;
226157184Sache	int off, nxt;
227157184Sache
228157184Sache	va_start(ap, m);
229157184Sache	off = va_arg(ap, int);
230157184Sache	nxt = va_arg(ap, int);
231157184Sache	va_end(ap);
232157184Sache
233157184Sache	return ipsec_common_input(m, off, offsetof(struct ip, ip_p),
234157184Sache				  AF_INET, nxt);
235157184Sache}
236157184Sache
237157184Sachevoid
238157184Sacheah4_input(struct mbuf *m, int off)
239157184Sache{
240157184Sache	ipsec4_common_input(m, off, IPPROTO_AH);
241157184Sache}
242157184Sachevoid
243157184Sacheah4_ctlinput(int cmd, struct sockaddr *sa, void *v)
244157184Sache{
245157184Sache	if (sa->sa_family == AF_INET &&
246157184Sache	    sa->sa_len == sizeof(struct sockaddr_in))
247157184Sache		ipsec4_common_ctlinput(cmd, sa, v, IPPROTO_AH);
248157184Sache}
249157184Sache
250157184Sachevoid
251157184Sacheesp4_input(struct mbuf *m, int off)
252157184Sache{
253157184Sache	ipsec4_common_input(m, off, IPPROTO_ESP);
254157184Sache}
255157184Sachevoid
256157184Sacheesp4_ctlinput(int cmd, struct sockaddr *sa, void *v)
257157184Sache{
258157184Sache	if (sa->sa_family == AF_INET &&
259157184Sache	    sa->sa_len == sizeof(struct sockaddr_in))
260157184Sache		ipsec4_common_ctlinput(cmd, sa, v, IPPROTO_ESP);
261157184Sache}
262157184Sache
263157184Sachevoid
264157184Sacheipcomp4_input(struct mbuf *m, int off)
265157184Sache{
266157184Sache	ipsec4_common_input(m, off, IPPROTO_IPCOMP);
267157184Sache}
268157184Sache
269157184Sache/*
270157184Sache * IPsec input callback for INET protocols.
271157184Sache * This routine is called as the transform callback.
272157184Sache * Takes care of filtering and other sanity checks on
273157184Sache * the processed packet.
274157184Sache */
275157184Sacheint
276157184Sacheipsec4_common_input_cb(struct mbuf *m, struct secasvar *sav,
277157184Sache			int skip, int protoff, struct m_tag *mt)
278157184Sache{
279157184Sache	int prot, af, sproto;
280157184Sache	struct ip *ip;
281157184Sache	struct m_tag *mtag;
282157184Sache	struct tdb_ident *tdbi;
283157184Sache	struct secasindex *saidx;
284157184Sache	int error;
285157184Sache#ifdef INET6
286157184Sache#ifdef notyet
287157184Sache	char ip6buf[INET6_ADDRSTRLEN];
288157184Sache#endif
289157184Sache#endif
290157184Sache
291157184Sache	IPSEC_SPLASSERT_SOFTNET(__func__);
292157184Sache
293157184Sache	IPSEC_ASSERT(m != NULL, ("null mbuf"));
294157184Sache	IPSEC_ASSERT(sav != NULL, ("null SA"));
295157184Sache	IPSEC_ASSERT(sav->sah != NULL, ("null SAH"));
296157184Sache	saidx = &sav->sah->saidx;
297157184Sache	af = saidx->dst.sa.sa_family;
298157184Sache	IPSEC_ASSERT(af == AF_INET, ("unexpected af %u", af));
299157184Sache	sproto = saidx->proto;
300157184Sache	IPSEC_ASSERT(sproto == IPPROTO_ESP || sproto == IPPROTO_AH ||
301157184Sache		sproto == IPPROTO_IPCOMP,
302157184Sache		("unexpected security protocol %u", sproto));
303157184Sache
304157184Sache	/* Sanity check */
305157184Sache	if (m == NULL) {
306157184Sache		DPRINTF(("%s: null mbuf", __func__));
307157184Sache		IPSEC_ISTAT(sproto, espstat.esps_badkcr, ahstat.ahs_badkcr,
308157184Sache		    ipcompstat.ipcomps_badkcr);
309157184Sache		KEY_FREESAV(&sav);
310157184Sache		return EINVAL;
311157184Sache	}
312157184Sache
313157184Sache	if (skip != 0) {
314157184Sache		/* Fix IPv4 header */
315157184Sache		if (m->m_len < skip && (m = m_pullup(m, skip)) == NULL) {
316157184Sache			DPRINTF(("%s: processing failed for SA %s/%08lx\n",
317157184Sache			    __func__, ipsec_address(&sav->sah->saidx.dst),
318157184Sache			    (u_long) ntohl(sav->spi)));
319157184Sache			IPSEC_ISTAT(sproto, espstat.esps_hdrops, ahstat.ahs_hdrops,
320157184Sache			    ipcompstat.ipcomps_hdrops);
321157184Sache			error = ENOBUFS;
322157184Sache			goto bad;
323157184Sache		}
324157184Sache
325157184Sache		ip = mtod(m, struct ip *);
326157184Sache		ip->ip_len = htons(m->m_pkthdr.len);
327157184Sache		ip->ip_off = htons(ip->ip_off);
328157184Sache		ip->ip_sum = 0;
329157184Sache		ip->ip_sum = in_cksum(m, ip->ip_hl << 2);
330157184Sache	} else {
331157184Sache		ip = mtod(m, struct ip *);
332157184Sache	}
333157184Sache	prot = ip->ip_p;
334157184Sache
335157184Sache#ifdef notyet
336157184Sache	/* IP-in-IP encapsulation */
337157184Sache	if (prot == IPPROTO_IPIP) {
338157184Sache		struct ip ipn;
339157184Sache
340157184Sache		if (m->m_pkthdr.len - skip < sizeof(struct ip)) {
341157184Sache			IPSEC_ISTAT(sproto, espstat.esps_hdrops,
342157184Sache			    ahstat.ahs_hdrops,
343157184Sache			    ipcompstat.ipcomps_hdrops);
344157184Sache			error = EINVAL;
345157184Sache			goto bad;
346157184Sache		}
347157184Sache		/* ipn will now contain the inner IPv4 header */
348157184Sache		m_copydata(m, ip->ip_hl << 2, sizeof(struct ip),
349157184Sache		    (caddr_t) &ipn);
350157184Sache
351157184Sache		/* XXX PROXY address isn't recorded in SAH */
352157184Sache		/*
353157184Sache		 * Check that the inner source address is the same as
354157184Sache		 * the proxy address, if available.
355157184Sache		 */
356157184Sache		if ((saidx->proxy.sa.sa_family == AF_INET &&
357157184Sache		    saidx->proxy.sin.sin_addr.s_addr !=
358157184Sache		    INADDR_ANY &&
359157184Sache		    ipn.ip_src.s_addr !=
360157184Sache		    saidx->proxy.sin.sin_addr.s_addr) ||
361157184Sache		    (saidx->proxy.sa.sa_family != AF_INET &&
362157184Sache			saidx->proxy.sa.sa_family != 0)) {
363157184Sache
364157184Sache			DPRINTF(("%s: inner source address %s doesn't "
365157184Sache			    "correspond to expected proxy source %s, "
366157184Sache			    "SA %s/%08lx\n", __func__,
367157184Sache			    inet_ntoa4(ipn.ip_src),
368157184Sache			    ipsp_address(saidx->proxy),
369157184Sache			    ipsp_address(saidx->dst),
370157184Sache			    (u_long) ntohl(sav->spi)));
371157184Sache
372157184Sache			IPSEC_ISTAT(sproto, espstat.esps_pdrops,
373157184Sache			    ahstat.ahs_pdrops,
374157184Sache			    ipcompstat.ipcomps_pdrops);
375157184Sache			error = EACCES;
376157184Sache			goto bad;
377157184Sache		}
378157184Sache	}
379157184Sache#ifdef INET6
380157184Sache	/* IPv6-in-IP encapsulation. */
381157184Sache	if (prot == IPPROTO_IPV6) {
382157184Sache		struct ip6_hdr ip6n;
383157184Sache
384157184Sache		if (m->m_pkthdr.len - skip < sizeof(struct ip6_hdr)) {
385157184Sache			IPSEC_ISTAT(sproto, espstat.esps_hdrops,
386157184Sache			    ahstat.ahs_hdrops,
387157184Sache			    ipcompstat.ipcomps_hdrops);
388			error = EINVAL;
389			goto bad;
390		}
391		/* ip6n will now contain the inner IPv6 header. */
392		m_copydata(m, ip->ip_hl << 2, sizeof(struct ip6_hdr),
393		    (caddr_t) &ip6n);
394
395		/*
396		 * Check that the inner source address is the same as
397		 * the proxy address, if available.
398		 */
399		if ((saidx->proxy.sa.sa_family == AF_INET6 &&
400		    !IN6_IS_ADDR_UNSPECIFIED(&saidx->proxy.sin6.sin6_addr) &&
401		    !IN6_ARE_ADDR_EQUAL(&ip6n.ip6_src,
402			&saidx->proxy.sin6.sin6_addr)) ||
403		    (saidx->proxy.sa.sa_family != AF_INET6 &&
404			saidx->proxy.sa.sa_family != 0)) {
405
406			DPRINTF(("%s: inner source address %s doesn't "
407			    "correspond to expected proxy source %s, "
408			    "SA %s/%08lx\n", __func__,
409			    ip6_sprintf(ip6buf, &ip6n.ip6_src),
410			    ipsec_address(&saidx->proxy),
411			    ipsec_address(&saidx->dst),
412			    (u_long) ntohl(sav->spi)));
413
414			IPSEC_ISTAT(sproto, espstat.esps_pdrops,
415			    ahstat.ahs_pdrops,
416			    ipcompstat.ipcomps_pdrops);
417			error = EACCES;
418			goto bad;
419		}
420	}
421#endif /* INET6 */
422#endif /*XXX*/
423
424	/*
425	 * Record what we've done to the packet (under what SA it was
426	 * processed). If we've been passed an mtag, it means the packet
427	 * was already processed by an ethernet/crypto combo card and
428	 * thus has a tag attached with all the right information, but
429	 * with a PACKET_TAG_IPSEC_IN_CRYPTO_DONE as opposed to
430	 * PACKET_TAG_IPSEC_IN_DONE type; in that case, just change the type.
431	 */
432	if (mt == NULL && sproto != IPPROTO_IPCOMP) {
433		mtag = m_tag_get(PACKET_TAG_IPSEC_IN_DONE,
434		    sizeof(struct tdb_ident), M_NOWAIT);
435		if (mtag == NULL) {
436			DPRINTF(("%s: failed to get tag\n", __func__));
437			IPSEC_ISTAT(sproto, espstat.esps_hdrops,
438			    ahstat.ahs_hdrops, ipcompstat.ipcomps_hdrops);
439			error = ENOMEM;
440			goto bad;
441		}
442
443		tdbi = (struct tdb_ident *)(mtag + 1);
444		bcopy(&saidx->dst, &tdbi->dst, saidx->dst.sa.sa_len);
445		tdbi->proto = sproto;
446		tdbi->spi = sav->spi;
447
448		m_tag_prepend(m, mtag);
449	} else if (mt != NULL) {
450		mt->m_tag_id = PACKET_TAG_IPSEC_IN_DONE;
451		/* XXX do we need to mark m_flags??? */
452	}
453
454	key_sa_recordxfer(sav, m);		/* record data transfer */
455
456#ifdef DEV_ENC
457	/*
458	 * Pass the mbuf to enc0 for bpf and pfil. We will filter the IPIP
459	 * packet later after it has been decapsulated.
460	 */
461	ipsec_bpf(m, sav, AF_INET);
462
463	if (prot != IPPROTO_IPIP)
464		if ((error = ipsec_filter(&m, PFIL_IN)) != 0)
465			return (error);
466#endif
467
468	/*
469	 * Re-dispatch via software interrupt.
470	 */
471	if ((error = netisr_queue(NETISR_IP, m))) {
472		IPSEC_ISTAT(sproto, espstat.esps_qfull, ahstat.ahs_qfull,
473			    ipcompstat.ipcomps_qfull);
474
475		DPRINTF(("%s: queue full; proto %u packet dropped\n",
476			__func__, sproto));
477		return error;
478	}
479	return 0;
480bad:
481	m_freem(m);
482	return error;
483}
484
485void
486ipsec4_common_ctlinput(int cmd, struct sockaddr *sa, void *v, int proto)
487{
488	/* XXX nothing just yet */
489}
490#endif /* INET */
491
492#ifdef INET6
493/* IPv6 AH wrapper. */
494int
495ipsec6_common_input(struct mbuf **mp, int *offp, int proto)
496{
497	int l = 0;
498	int protoff;
499	struct ip6_ext ip6e;
500
501	if (*offp < sizeof(struct ip6_hdr)) {
502		DPRINTF(("%s: bad offset %u\n", __func__, *offp));
503		return IPPROTO_DONE;
504	} else if (*offp == sizeof(struct ip6_hdr)) {
505		protoff = offsetof(struct ip6_hdr, ip6_nxt);
506	} else {
507		/* Chase down the header chain... */
508		protoff = sizeof(struct ip6_hdr);
509
510		do {
511			protoff += l;
512			m_copydata(*mp, protoff, sizeof(ip6e),
513			    (caddr_t) &ip6e);
514
515			if (ip6e.ip6e_nxt == IPPROTO_AH)
516				l = (ip6e.ip6e_len + 2) << 2;
517			else
518				l = (ip6e.ip6e_len + 1) << 3;
519			IPSEC_ASSERT(l > 0, ("l went zero or negative"));
520		} while (protoff + l < *offp);
521
522		/* Malformed packet check */
523		if (protoff + l != *offp) {
524			DPRINTF(("%s: bad packet header chain, protoff %u, "
525				"l %u, off %u\n", __func__, protoff, l, *offp));
526			IPSEC_ISTAT(proto, espstat.esps_hdrops,
527				    ahstat.ahs_hdrops,
528				    ipcompstat.ipcomps_hdrops);
529			m_freem(*mp);
530			*mp = NULL;
531			return IPPROTO_DONE;
532		}
533		protoff += offsetof(struct ip6_ext, ip6e_nxt);
534	}
535	(void) ipsec_common_input(*mp, *offp, protoff, AF_INET6, proto);
536	return IPPROTO_DONE;
537}
538
539/*
540 * IPsec input callback, called by the transform callback. Takes care of
541 * filtering and other sanity checks on the processed packet.
542 */
543int
544ipsec6_common_input_cb(struct mbuf *m, struct secasvar *sav, int skip, int protoff,
545    struct m_tag *mt)
546{
547	int prot, af, sproto;
548	struct ip6_hdr *ip6;
549	struct m_tag *mtag;
550	struct tdb_ident *tdbi;
551	struct secasindex *saidx;
552	int nxt;
553	u_int8_t nxt8;
554	int error, nest;
555#ifdef notyet
556	char ip6buf[INET6_ADDRSTRLEN];
557#endif
558
559	IPSEC_ASSERT(m != NULL, ("null mbuf"));
560	IPSEC_ASSERT(sav != NULL, ("null SA"));
561	IPSEC_ASSERT(sav->sah != NULL, ("null SAH"));
562	saidx = &sav->sah->saidx;
563	af = saidx->dst.sa.sa_family;
564	IPSEC_ASSERT(af == AF_INET6, ("unexpected af %u", af));
565	sproto = saidx->proto;
566	IPSEC_ASSERT(sproto == IPPROTO_ESP || sproto == IPPROTO_AH ||
567		sproto == IPPROTO_IPCOMP,
568		("unexpected security protocol %u", sproto));
569
570	/* Sanity check */
571	if (m == NULL) {
572		DPRINTF(("%s: null mbuf", __func__));
573		IPSEC_ISTAT(sproto, espstat.esps_badkcr, ahstat.ahs_badkcr,
574		    ipcompstat.ipcomps_badkcr);
575		error = EINVAL;
576		goto bad;
577	}
578
579	/* Fix IPv6 header */
580	if (m->m_len < sizeof(struct ip6_hdr) &&
581	    (m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) {
582
583		DPRINTF(("%s: processing failed for SA %s/%08lx\n",
584		    __func__, ipsec_address(&sav->sah->saidx.dst),
585		    (u_long) ntohl(sav->spi)));
586
587		IPSEC_ISTAT(sproto, espstat.esps_hdrops, ahstat.ahs_hdrops,
588		    ipcompstat.ipcomps_hdrops);
589		error = EACCES;
590		goto bad;
591	}
592
593	ip6 = mtod(m, struct ip6_hdr *);
594	ip6->ip6_plen = htons(m->m_pkthdr.len - sizeof(struct ip6_hdr));
595
596	/* Save protocol */
597	m_copydata(m, protoff, 1, (unsigned char *) &prot);
598
599#ifdef notyet
600#ifdef INET
601	/* IP-in-IP encapsulation */
602	if (prot == IPPROTO_IPIP) {
603		struct ip ipn;
604
605		if (m->m_pkthdr.len - skip < sizeof(struct ip)) {
606			IPSEC_ISTAT(sproto, espstat.esps_hdrops,
607			    ahstat.ahs_hdrops,
608			    ipcompstat.ipcomps_hdrops);
609			error = EINVAL;
610			goto bad;
611		}
612		/* ipn will now contain the inner IPv4 header */
613		m_copydata(m, skip, sizeof(struct ip), (caddr_t) &ipn);
614
615		/*
616		 * Check that the inner source address is the same as
617		 * the proxy address, if available.
618		 */
619		if ((saidx->proxy.sa.sa_family == AF_INET &&
620		    saidx->proxy.sin.sin_addr.s_addr != INADDR_ANY &&
621		    ipn.ip_src.s_addr != saidx->proxy.sin.sin_addr.s_addr) ||
622		    (saidx->proxy.sa.sa_family != AF_INET &&
623			saidx->proxy.sa.sa_family != 0)) {
624
625			DPRINTF(("%s: inner source address %s doesn't "
626			    "correspond to expected proxy source %s, "
627			    "SA %s/%08lx\n", __func__,
628			    inet_ntoa4(ipn.ip_src),
629			    ipsec_address(&saidx->proxy),
630			    ipsec_address(&saidx->dst),
631			    (u_long) ntohl(sav->spi)));
632
633			IPSEC_ISTATsproto, (espstat.esps_pdrops,
634			    ahstat.ahs_pdrops, ipcompstat.ipcomps_pdrops);
635			error = EACCES;
636			goto bad;
637		}
638	}
639#endif /* INET */
640
641	/* IPv6-in-IP encapsulation */
642	if (prot == IPPROTO_IPV6) {
643		struct ip6_hdr ip6n;
644
645		if (m->m_pkthdr.len - skip < sizeof(struct ip6_hdr)) {
646			IPSEC_ISTAT(sproto, espstat.esps_hdrops,
647			    ahstat.ahs_hdrops,
648			    ipcompstat.ipcomps_hdrops);
649			error = EINVAL;
650			goto bad;
651		}
652		/* ip6n will now contain the inner IPv6 header. */
653		m_copydata(m, skip, sizeof(struct ip6_hdr),
654		    (caddr_t) &ip6n);
655
656		/*
657		 * Check that the inner source address is the same as
658		 * the proxy address, if available.
659		 */
660		if ((saidx->proxy.sa.sa_family == AF_INET6 &&
661		    !IN6_IS_ADDR_UNSPECIFIED(&saidx->proxy.sin6.sin6_addr) &&
662		    !IN6_ARE_ADDR_EQUAL(&ip6n.ip6_src,
663			&saidx->proxy.sin6.sin6_addr)) ||
664		    (saidx->proxy.sa.sa_family != AF_INET6 &&
665			saidx->proxy.sa.sa_family != 0)) {
666
667			DPRINTF(("%s: inner source address %s doesn't "
668			    "correspond to expected proxy source %s, "
669			    "SA %s/%08lx\n", __func__,
670			    ip6_sprintf(ip6buf, &ip6n.ip6_src),
671			    ipsec_address(&saidx->proxy),
672			    ipsec_address(&saidx->dst),
673			    (u_long) ntohl(sav->spi)));
674
675			IPSEC_ISTAT(sproto, espstat.esps_pdrops,
676			    ahstat.ahs_pdrops, ipcompstat.ipcomps_pdrops);
677			error = EACCES;
678			goto bad;
679		}
680	}
681#endif /*XXX*/
682
683	/*
684	 * Record what we've done to the packet (under what SA it was
685	 * processed). If we've been passed an mtag, it means the packet
686	 * was already processed by an ethernet/crypto combo card and
687	 * thus has a tag attached with all the right information, but
688	 * with a PACKET_TAG_IPSEC_IN_CRYPTO_DONE as opposed to
689	 * PACKET_TAG_IPSEC_IN_DONE type; in that case, just change the type.
690	 */
691	if (mt == NULL && sproto != IPPROTO_IPCOMP) {
692		mtag = m_tag_get(PACKET_TAG_IPSEC_IN_DONE,
693		    sizeof(struct tdb_ident), M_NOWAIT);
694		if (mtag == NULL) {
695			DPRINTF(("%s: failed to get tag\n", __func__));
696			IPSEC_ISTAT(sproto, espstat.esps_hdrops,
697			    ahstat.ahs_hdrops, ipcompstat.ipcomps_hdrops);
698			error = ENOMEM;
699			goto bad;
700		}
701
702		tdbi = (struct tdb_ident *)(mtag + 1);
703		bcopy(&saidx->dst, &tdbi->dst, sizeof(union sockaddr_union));
704		tdbi->proto = sproto;
705		tdbi->spi = sav->spi;
706
707		m_tag_prepend(m, mtag);
708	} else {
709		if (mt != NULL)
710			mt->m_tag_id = PACKET_TAG_IPSEC_IN_DONE;
711		/* XXX do we need to mark m_flags??? */
712	}
713
714	key_sa_recordxfer(sav, m);
715
716	/* Retrieve new protocol */
717	m_copydata(m, protoff, sizeof(u_int8_t), (caddr_t) &nxt8);
718
719	/*
720	 * See the end of ip6_input for this logic.
721	 * IPPROTO_IPV[46] case will be processed just like other ones
722	 */
723	nest = 0;
724	nxt = nxt8;
725	while (nxt != IPPROTO_DONE) {
726		if (ip6_hdrnestlimit && (++nest > ip6_hdrnestlimit)) {
727			ip6stat.ip6s_toomanyhdr++;
728			error = EINVAL;
729			goto bad;
730		}
731
732		/*
733		 * Protection against faulty packet - there should be
734		 * more sanity checks in header chain processing.
735		 */
736		if (m->m_pkthdr.len < skip) {
737			ip6stat.ip6s_tooshort++;
738			in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_truncated);
739			error = EINVAL;
740			goto bad;
741		}
742		/*
743		 * Enforce IPsec policy checking if we are seeing last header.
744		 * note that we do not visit this with protocols with pcb layer
745		 * code - like udp/tcp/raw ip.
746		 */
747		if ((inet6sw[ip6_protox[nxt]].pr_flags & PR_LASTHDR) != 0 &&
748		    ipsec6_in_reject(m, NULL)) {
749			error = EINVAL;
750			goto bad;
751		}
752		nxt = (*inet6sw[ip6_protox[nxt]].pr_input)(&m, &skip, nxt);
753	}
754	return 0;
755bad:
756	if (m)
757		m_freem(m);
758	return error;
759}
760
761void
762esp6_ctlinput(int cmd, struct sockaddr *sa, void *d)
763{
764	if (sa->sa_family != AF_INET6 ||
765	    sa->sa_len != sizeof(struct sockaddr_in6))
766		return;
767	if ((unsigned)cmd >= PRC_NCMDS)
768		return;
769
770	/* if the parameter is from icmp6, decode it. */
771	if (d !=  NULL) {
772		struct ip6ctlparam *ip6cp = (struct ip6ctlparam *)d;
773		struct mbuf *m = ip6cp->ip6c_m;
774		int off = ip6cp->ip6c_off;
775
776		struct ip6ctlparam ip6cp1;
777
778		/*
779		 * Notify the error to all possible sockets via pfctlinput2.
780		 * Since the upper layer information (such as protocol type,
781		 * source and destination ports) is embedded in the encrypted
782		 * data and might have been cut, we can't directly call
783		 * an upper layer ctlinput function. However, the pcbnotify
784		 * function will consider source and destination addresses
785		 * as well as the flow info value, and may be able to find
786		 * some PCB that should be notified.
787		 * Although pfctlinput2 will call esp6_ctlinput(), there is
788		 * no possibility of an infinite loop of function calls,
789		 * because we don't pass the inner IPv6 header.
790		 */
791		bzero(&ip6cp1, sizeof(ip6cp1));
792		ip6cp1.ip6c_src = ip6cp->ip6c_src;
793		pfctlinput2(cmd, sa, (void *)&ip6cp1);
794
795		/*
796		 * Then go to special cases that need ESP header information.
797		 * XXX: We assume that when ip6 is non NULL,
798		 * M and OFF are valid.
799		 */
800
801		if (cmd == PRC_MSGSIZE) {
802			struct secasvar *sav;
803			u_int32_t spi;
804			int valid;
805
806			/* check header length before using m_copydata */
807			if (m->m_pkthdr.len < off + sizeof (struct esp))
808				return;
809			m_copydata(m, off + offsetof(struct esp, esp_spi),
810				sizeof(u_int32_t), (caddr_t) &spi);
811			/*
812			 * Check to see if we have a valid SA corresponding to
813			 * the address in the ICMP message payload.
814			 */
815			sav = KEY_ALLOCSA((union sockaddr_union *)sa,
816					IPPROTO_ESP, spi);
817			valid = (sav != NULL);
818			if (sav)
819				KEY_FREESAV(&sav);
820
821			/* XXX Further validation? */
822
823			/*
824			 * Depending on whether the SA is "valid" and
825			 * routing table size (mtudisc_{hi,lo}wat), we will:
826			 * - recalcurate the new MTU and create the
827			 *   corresponding routing entry, or
828			 * - ignore the MTU change notification.
829			 */
830			icmp6_mtudisc_update(ip6cp, valid);
831		}
832	} else {
833		/* we normally notify any pcb here */
834	}
835}
836#endif /* INET6 */
837