1/*	$FreeBSD$	*/
2/*	$OpenBSD: ip_ah.c,v 1.63 2001/06/26 06:18:58 angelos Exp $ */
3/*-
4 * The authors of this code are John Ioannidis (ji@tla.org),
5 * Angelos D. Keromytis (kermit@csd.uch.gr) and
6 * Niels Provos (provos@physnet.uni-hamburg.de).
7 *
8 * The original version of this code was written by John Ioannidis
9 * for BSD/OS in Athens, Greece, in November 1995.
10 *
11 * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
12 * by Angelos D. Keromytis.
13 *
14 * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
15 * and Niels Provos.
16 *
17 * Additional features in 1999 by Angelos D. Keromytis and Niklas Hallqvist.
18 *
19 * Copyright (c) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
20 * Angelos D. Keromytis and Niels Provos.
21 * Copyright (c) 1999 Niklas Hallqvist.
22 * Copyright (c) 2001 Angelos D. Keromytis.
23 *
24 * Permission to use, copy, and modify this software with or without fee
25 * is hereby granted, provided that this entire notice is included in
26 * all copies of any software which is or includes a copy or
27 * modification of this software.
28 * You may use this code under the GNU public license if you so wish. Please
29 * contribute changes back to the authors under this freer than GPL license
30 * so that we may further the use of strong encryption without limitations to
31 * all.
32 *
33 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
34 * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
35 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
36 * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
37 * PURPOSE.
38 */
39#include "opt_inet.h"
40#include "opt_inet6.h"
41#include "opt_ipsec.h"
42
43#include <sys/param.h>
44#include <sys/systm.h>
45#include <sys/mbuf.h>
46#include <sys/socket.h>
47#include <sys/syslog.h>
48#include <sys/kernel.h>
49#include <sys/lock.h>
50#include <sys/mutex.h>
51#include <sys/sysctl.h>
52
53#include <net/if.h>
54#include <net/vnet.h>
55
56#include <netinet/in.h>
57#include <netinet/in_systm.h>
58#include <netinet/ip.h>
59#include <netinet/ip_ecn.h>
60#include <netinet/ip6.h>
61
62#include <netipsec/ipsec.h>
63#include <netipsec/ah.h>
64#include <netipsec/ah_var.h>
65#include <netipsec/xform.h>
66
67#ifdef INET6
68#include <netinet6/ip6_var.h>
69#include <netipsec/ipsec6.h>
70#include <netinet6/ip6_ecn.h>
71#endif
72
73#include <netipsec/key.h>
74#include <netipsec/key_debug.h>
75
76#include <opencrypto/cryptodev.h>
77
78/*
79 * Return header size in bytes.  The old protocol did not support
80 * the replay counter; the new protocol always includes the counter.
81 */
82#define HDRSIZE(sav) \
83	(((sav)->flags & SADB_X_EXT_OLD) ? \
84		sizeof (struct ah) : sizeof (struct ah) + sizeof (u_int32_t))
85/*
86 * Return authenticator size in bytes, based on a field in the
87 * algorithm descriptor.
88 */
89#define	AUTHSIZE(sav)	((sav->flags & SADB_X_EXT_OLD) ? 16 :	\
90			 xform_ah_authsize((sav)->tdb_authalgxform))
91
92VNET_DEFINE(int, ah_enable) = 1;	/* control flow of packets with AH */
93VNET_DEFINE(int, ah_cleartos) = 1;	/* clear ip_tos when doing AH calc */
94VNET_PCPUSTAT_DEFINE(struct ahstat, ahstat);
95VNET_PCPUSTAT_SYSINIT(ahstat);
96
97#ifdef VIMAGE
98VNET_PCPUSTAT_SYSUNINIT(ahstat);
99#endif /* VIMAGE */
100
101#ifdef INET
102SYSCTL_DECL(_net_inet_ah);
103SYSCTL_INT(_net_inet_ah, OID_AUTO, ah_enable,
104	CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ah_enable), 0, "");
105SYSCTL_INT(_net_inet_ah, OID_AUTO, ah_cleartos,
106	CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ah_cleartos), 0, "");
107SYSCTL_VNET_PCPUSTAT(_net_inet_ah, IPSECCTL_STATS, stats, struct ahstat,
108    ahstat, "AH statistics (struct ahstat, netipsec/ah_var.h)");
109#endif
110
111static unsigned char ipseczeroes[256];	/* larger than an ip6 extension hdr */
112
113static int ah_input_cb(struct cryptop*);
114static int ah_output_cb(struct cryptop*);
115
116int
117xform_ah_authsize(const struct auth_hash *esph)
118{
119	int alen;
120
121	if (esph == NULL)
122		return 0;
123
124	switch (esph->type) {
125	case CRYPTO_SHA2_256_HMAC:
126	case CRYPTO_SHA2_384_HMAC:
127	case CRYPTO_SHA2_512_HMAC:
128		alen = esph->hashsize / 2;	/* RFC4868 2.3 */
129		break;
130
131	case CRYPTO_AES_NIST_GMAC:
132		alen = esph->hashsize;
133		break;
134
135	default:
136		alen = AH_HMAC_HASHLEN;
137		break;
138	}
139
140	return alen;
141}
142
143size_t
144ah_hdrsiz(struct secasvar *sav)
145{
146	size_t size;
147
148	if (sav != NULL) {
149		int authsize, rplen, align;
150
151		IPSEC_ASSERT(sav->tdb_authalgxform != NULL, ("null xform"));
152		/*XXX not right for null algorithm--does it matter??*/
153
154		/* RFC4302: use the correct alignment. */
155		align = sizeof(uint32_t);
156#ifdef INET6
157		if (sav->sah->saidx.dst.sa.sa_family == AF_INET6) {
158			align = sizeof(uint64_t);
159		}
160#endif
161		rplen = HDRSIZE(sav);
162		authsize = AUTHSIZE(sav);
163		size = roundup(rplen + authsize, align);
164	} else {
165		/* default guess */
166		size = sizeof (struct ah) + sizeof (u_int32_t) + 16;
167	}
168	return size;
169}
170
171/*
172 * NB: public for use by esp_init.
173 */
174int
175ah_init0(struct secasvar *sav, struct xformsw *xsp,
176    struct crypto_session_params *csp)
177{
178	const struct auth_hash *thash;
179	int keylen;
180
181	thash = auth_algorithm_lookup(sav->alg_auth);
182	if (thash == NULL) {
183		DPRINTF(("%s: unsupported authentication algorithm %u\n",
184			__func__, sav->alg_auth));
185		return EINVAL;
186	}
187
188	/*
189	 * Verify the replay state block allocation is consistent with
190	 * the protocol type.  We check here so we can make assumptions
191	 * later during protocol processing.
192	 */
193	/* NB: replay state is setup elsewhere (sigh) */
194	if (((sav->flags&SADB_X_EXT_OLD) == 0) ^ (sav->replay != NULL)) {
195		DPRINTF(("%s: replay state block inconsistency, "
196			"%s algorithm %s replay state\n", __func__,
197			(sav->flags & SADB_X_EXT_OLD) ? "old" : "new",
198			sav->replay == NULL ? "without" : "with"));
199		return EINVAL;
200	}
201	if (sav->key_auth == NULL) {
202		DPRINTF(("%s: no authentication key for %s algorithm\n",
203			__func__, thash->name));
204		return EINVAL;
205	}
206	keylen = _KEYLEN(sav->key_auth);
207	if (keylen > thash->keysize && thash->keysize != 0) {
208		DPRINTF(("%s: invalid keylength %d, algorithm %s requires "
209			"keysize less than %d\n", __func__,
210			 keylen, thash->name, thash->keysize));
211		return EINVAL;
212	}
213
214	sav->tdb_xform = xsp;
215	sav->tdb_authalgxform = thash;
216
217	/* Initialize crypto session. */
218	csp->csp_auth_alg = sav->tdb_authalgxform->type;
219	if (csp->csp_auth_alg != CRYPTO_NULL_HMAC) {
220		csp->csp_auth_klen = _KEYBITS(sav->key_auth) / 8;
221		csp->csp_auth_key = sav->key_auth->key_data;
222	};
223	csp->csp_auth_mlen = AUTHSIZE(sav);
224
225	return 0;
226}
227
228/*
229 * ah_init() is called when an SPI is being set up.
230 */
231static int
232ah_init(struct secasvar *sav, struct xformsw *xsp)
233{
234	struct crypto_session_params csp;
235	int error;
236
237	memset(&csp, 0, sizeof(csp));
238	csp.csp_mode = CSP_MODE_DIGEST;
239
240	if (sav->flags & SADB_X_SAFLAGS_ESN)
241		csp.csp_flags |= CSP_F_ESN;
242
243	error = ah_init0(sav, xsp, &csp);
244	return error ? error :
245		 crypto_newsession(&sav->tdb_cryptoid, &csp, V_crypto_support);
246}
247
248static void
249ah_cleanup(struct secasvar *sav)
250{
251
252	crypto_freesession(sav->tdb_cryptoid);
253	sav->tdb_cryptoid = NULL;
254	sav->tdb_authalgxform = NULL;
255}
256
257/*
258 * Massage IPv4/IPv6 headers for AH processing.
259 */
260static int
261ah_massage_headers(struct mbuf **m0, int proto, int skip, int alg, int out)
262{
263	struct mbuf *m = *m0;
264	unsigned char *ptr;
265	int off, count;
266
267#ifdef INET
268	struct ip *ip;
269#endif /* INET */
270
271#ifdef INET6
272	struct ip6_ext *ip6e;
273	struct ip6_hdr ip6;
274	int ad, alloc, nxt, noff;
275#endif /* INET6 */
276
277	switch (proto) {
278#ifdef INET
279	case AF_INET:
280		/*
281		 * This is the least painful way of dealing with IPv4 header
282		 * and option processing -- just make sure they're in
283		 * contiguous memory.
284		 */
285		*m0 = m = m_pullup(m, skip);
286		if (m == NULL) {
287			DPRINTF(("%s: m_pullup failed\n", __func__));
288			return ENOBUFS;
289		}
290
291		/* Fix the IP header */
292		ip = mtod(m, struct ip *);
293		if (V_ah_cleartos)
294			ip->ip_tos = 0;
295		ip->ip_ttl = 0;
296		ip->ip_sum = 0;
297		ip->ip_off = htons(0);
298
299		ptr = mtod(m, unsigned char *);
300
301		/* IPv4 option processing */
302		for (off = sizeof(struct ip); off < skip;) {
303			if (ptr[off] == IPOPT_EOL || ptr[off] == IPOPT_NOP ||
304			    off + 1 < skip)
305				;
306			else {
307				DPRINTF(("%s: illegal IPv4 option length for "
308					"option %d\n", __func__, ptr[off]));
309
310				m_freem(m);
311				return EINVAL;
312			}
313
314			switch (ptr[off]) {
315			case IPOPT_EOL:
316				off = skip;  /* End the loop. */
317				break;
318
319			case IPOPT_NOP:
320				off++;
321				break;
322
323			case IPOPT_SECURITY:	/* 0x82 */
324			case 0x85:	/* Extended security. */
325			case 0x86:	/* Commercial security. */
326			case 0x94:	/* Router alert */
327			case 0x95:	/* RFC1770 */
328				/* Sanity check for option length. */
329				if (ptr[off + 1] < 2) {
330					DPRINTF(("%s: illegal IPv4 option "
331						"length for option %d\n",
332						__func__, ptr[off]));
333
334					m_freem(m);
335					return EINVAL;
336				}
337
338				off += ptr[off + 1];
339				break;
340
341			case IPOPT_LSRR:
342			case IPOPT_SSRR:
343				/* Sanity check for option length. */
344				if (ptr[off + 1] < 2) {
345					DPRINTF(("%s: illegal IPv4 option "
346						"length for option %d\n",
347						__func__, ptr[off]));
348
349					m_freem(m);
350					return EINVAL;
351				}
352
353				/*
354				 * On output, if we have either of the
355				 * source routing options, we should
356				 * swap the destination address of the
357				 * IP header with the last address
358				 * specified in the option, as that is
359				 * what the destination's IP header
360				 * will look like.
361				 */
362				if (out)
363					bcopy(ptr + off + ptr[off + 1] -
364					    sizeof(struct in_addr),
365					    &(ip->ip_dst), sizeof(struct in_addr));
366
367				/* Fall through */
368			default:
369				/* Sanity check for option length. */
370				if (ptr[off + 1] < 2) {
371					DPRINTF(("%s: illegal IPv4 option "
372						"length for option %d\n",
373						__func__, ptr[off]));
374					m_freem(m);
375					return EINVAL;
376				}
377
378				/* Zeroize all other options. */
379				count = ptr[off + 1];
380				bcopy(ipseczeroes, ptr + off, count);
381				off += count;
382				break;
383			}
384
385			/* Sanity check. */
386			if (off > skip)	{
387				DPRINTF(("%s: malformed IPv4 options header\n",
388					__func__));
389
390				m_freem(m);
391				return EINVAL;
392			}
393		}
394
395		break;
396#endif /* INET */
397
398#ifdef INET6
399	case AF_INET6:  /* Ugly... */
400		/* Copy and "cook" the IPv6 header. */
401		m_copydata(m, 0, sizeof(ip6), (caddr_t) &ip6);
402
403		/* We don't do IPv6 Jumbograms. */
404		if (ip6.ip6_plen == 0) {
405			DPRINTF(("%s: unsupported IPv6 jumbogram\n", __func__));
406			m_freem(m);
407			return EMSGSIZE;
408		}
409
410		ip6.ip6_flow = 0;
411		ip6.ip6_hlim = 0;
412		ip6.ip6_vfc &= ~IPV6_VERSION_MASK;
413		ip6.ip6_vfc |= IPV6_VERSION;
414
415		/* Scoped address handling. */
416		if (IN6_IS_SCOPE_LINKLOCAL(&ip6.ip6_src))
417			ip6.ip6_src.s6_addr16[1] = 0;
418		if (IN6_IS_SCOPE_LINKLOCAL(&ip6.ip6_dst))
419			ip6.ip6_dst.s6_addr16[1] = 0;
420
421		/* Done with IPv6 header. */
422		m_copyback(m, 0, sizeof(struct ip6_hdr), (caddr_t) &ip6);
423
424		/* Let's deal with the remaining headers (if any). */
425		if (skip - sizeof(struct ip6_hdr) > 0) {
426			if (m->m_len <= skip) {
427				ptr = (unsigned char *) malloc(
428				    skip - sizeof(struct ip6_hdr),
429				    M_XDATA, M_NOWAIT);
430				if (ptr == NULL) {
431					DPRINTF(("%s: failed to allocate memory"
432						"for IPv6 headers\n",__func__));
433					m_freem(m);
434					return ENOBUFS;
435				}
436
437				/*
438				 * Copy all the protocol headers after
439				 * the IPv6 header.
440				 */
441				m_copydata(m, sizeof(struct ip6_hdr),
442				    skip - sizeof(struct ip6_hdr), ptr);
443				alloc = 1;
444			} else {
445				/* No need to allocate memory. */
446				ptr = mtod(m, unsigned char *) +
447				    sizeof(struct ip6_hdr);
448				alloc = 0;
449			}
450		} else
451			break;
452
453		nxt = ip6.ip6_nxt & 0xff; /* Next header type. */
454
455		for (off = 0; off < skip - sizeof(struct ip6_hdr);)
456			switch (nxt) {
457			case IPPROTO_HOPOPTS:
458			case IPPROTO_DSTOPTS:
459				ip6e = (struct ip6_ext *)(ptr + off);
460				noff = off + ((ip6e->ip6e_len + 1) << 3);
461
462				/* Sanity check. */
463				if (noff > skip - sizeof(struct ip6_hdr))
464					goto error6;
465
466				/*
467				 * Zero out mutable options.
468				 */
469				for (count = off + sizeof(struct ip6_ext);
470				     count < noff;) {
471					if (ptr[count] == IP6OPT_PAD1) {
472						count++;
473						continue; /* Skip padding. */
474					}
475
476					ad = ptr[count + 1] + 2;
477					if (count + ad > noff)
478						goto error6;
479
480					if (ptr[count] & IP6OPT_MUTABLE)
481						memset(ptr + count, 0, ad);
482					count += ad;
483				}
484
485				if (count != noff)
486					goto error6;
487
488				/* Advance. */
489				off += ((ip6e->ip6e_len + 1) << 3);
490				nxt = ip6e->ip6e_nxt;
491				break;
492
493			case IPPROTO_ROUTING:
494				/*
495				 * Always include routing headers in
496				 * computation.
497				 */
498				ip6e = (struct ip6_ext *) (ptr + off);
499				off += ((ip6e->ip6e_len + 1) << 3);
500				nxt = ip6e->ip6e_nxt;
501				break;
502
503			default:
504				DPRINTF(("%s: unexpected IPv6 header type %d",
505					__func__, off));
506error6:
507				if (alloc)
508					free(ptr, M_XDATA);
509				m_freem(m);
510				return EINVAL;
511			}
512
513		/* Copyback and free, if we allocated. */
514		if (alloc) {
515			m_copyback(m, sizeof(struct ip6_hdr),
516			    skip - sizeof(struct ip6_hdr), ptr);
517			free(ptr, M_XDATA);
518		}
519
520		break;
521#endif /* INET6 */
522	}
523
524	return 0;
525}
526
527/*
528 * ah_input() gets called to verify that an input packet
529 * passes authentication.
530 */
531static int
532ah_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff)
533{
534	IPSEC_DEBUG_DECLARE(char buf[128]);
535	const struct auth_hash *ahx;
536	struct cryptop *crp;
537	struct xform_data *xd;
538	struct newah *ah;
539	crypto_session_t cryptoid;
540	int hl, rplen, authsize, ahsize, error;
541	uint32_t seqh;
542
543	IPSEC_ASSERT(sav != NULL, ("null SA"));
544	IPSEC_ASSERT(sav->key_auth != NULL, ("null authentication key"));
545	IPSEC_ASSERT(sav->tdb_authalgxform != NULL,
546		("null authentication xform"));
547
548	/* Figure out header size. */
549	rplen = HDRSIZE(sav);
550
551	if (m->m_len < skip + rplen) {
552		m = m_pullup(m, skip + rplen);
553		if (m == NULL) {
554			DPRINTF(("ah_input: cannot pullup header\n"));
555			AHSTAT_INC(ahs_hdrops);		/*XXX*/
556			error = ENOBUFS;
557			goto bad;
558		}
559	}
560	ah = (struct newah *)(mtod(m, caddr_t) + skip);
561
562	/* Check replay window, if applicable. */
563	SECASVAR_LOCK(sav);
564	if (sav->replay != NULL && sav->replay->wsize != 0 &&
565	    ipsec_chkreplay(ntohl(ah->ah_seq), &seqh, sav) == 0) {
566		SECASVAR_UNLOCK(sav);
567		AHSTAT_INC(ahs_replay);
568		DPRINTF(("%s: packet replay failure: %s\n", __func__,
569		    ipsec_sa2str(sav, buf, sizeof(buf))));
570		error = EACCES;
571		goto bad;
572	}
573	cryptoid = sav->tdb_cryptoid;
574	SECASVAR_UNLOCK(sav);
575
576	/* Verify AH header length. */
577	hl = sizeof(struct ah) + (ah->ah_len * sizeof (u_int32_t));
578	ahx = sav->tdb_authalgxform;
579	authsize = AUTHSIZE(sav);
580	ahsize = ah_hdrsiz(sav);
581	if (hl != ahsize) {
582		DPRINTF(("%s: bad authenticator length %u (expecting %lu)"
583		    " for packet in SA %s/%08lx\n", __func__, hl,
584		    (u_long)ahsize,
585		    ipsec_address(&sav->sah->saidx.dst, buf, sizeof(buf)),
586		    (u_long) ntohl(sav->spi)));
587		AHSTAT_INC(ahs_badauthl);
588		error = EACCES;
589		goto bad;
590	}
591	if (skip + ahsize > m->m_pkthdr.len) {
592		DPRINTF(("%s: bad mbuf length %u (expecting %lu)"
593		    " for packet in SA %s/%08lx\n", __func__,
594		    m->m_pkthdr.len, (u_long)(skip + ahsize),
595		    ipsec_address(&sav->sah->saidx.dst, buf, sizeof(buf)),
596		    (u_long) ntohl(sav->spi)));
597		AHSTAT_INC(ahs_badauthl);
598		error = EACCES;
599		goto bad;
600	}
601	AHSTAT_ADD(ahs_ibytes, m->m_pkthdr.len - skip - hl);
602
603	/* Get crypto descriptors. */
604	crp = crypto_getreq(cryptoid, M_NOWAIT);
605	if (crp == NULL) {
606		DPRINTF(("%s: failed to acquire crypto descriptor\n",
607		    __func__));
608		AHSTAT_INC(ahs_crypto);
609		error = ENOBUFS;
610		goto bad;
611	}
612
613	crp->crp_payload_start = 0;
614	crp->crp_payload_length = m->m_pkthdr.len;
615	crp->crp_digest_start = skip + rplen;
616
617	/* Allocate IPsec-specific opaque crypto info. */
618	xd = malloc(sizeof(*xd) + skip + rplen + authsize, M_XDATA,
619	    M_NOWAIT | M_ZERO);
620	if (xd == NULL) {
621		DPRINTF(("%s: failed to allocate xform_data\n", __func__));
622		AHSTAT_INC(ahs_crypto);
623		crypto_freereq(crp);
624		error = ENOBUFS;
625		goto bad;
626	}
627
628	/*
629	 * Save the authenticator, the skipped portion of the packet,
630	 * and the AH header.
631	 */
632	m_copydata(m, 0, skip + rplen + authsize, (caddr_t)(xd + 1));
633
634	/* Zeroize the authenticator on the packet. */
635	m_copyback(m, skip + rplen, authsize, ipseczeroes);
636
637	/* Save ah_nxt, since ah pointer can become invalid after "massage" */
638	hl = ah->ah_nxt;
639
640	/* "Massage" the packet headers for crypto processing. */
641	error = ah_massage_headers(&m, sav->sah->saidx.dst.sa.sa_family,
642	    skip, ahx->type, 0);
643	if (error != 0) {
644		/* NB: mbuf is free'd by ah_massage_headers */
645		AHSTAT_INC(ahs_hdrops);
646		free(xd, M_XDATA);
647		crypto_freereq(crp);
648		key_freesav(&sav);
649		return (error);
650	}
651
652	/* Crypto operation descriptor. */
653	crp->crp_op = CRYPTO_OP_COMPUTE_DIGEST;
654	crp->crp_flags = CRYPTO_F_CBIFSYNC;
655	if (V_async_crypto)
656		crp->crp_flags |= CRYPTO_F_ASYNC | CRYPTO_F_ASYNC_KEEPORDER;
657	crypto_use_mbuf(crp, m);
658	crp->crp_callback = ah_input_cb;
659	crp->crp_opaque = xd;
660
661	if (sav->flags & SADB_X_SAFLAGS_ESN &&
662	    sav->replay != NULL && sav->replay->wsize != 0) {
663		seqh = htonl(seqh);
664		memcpy(crp->crp_esn, &seqh, sizeof(seqh));
665	}
666
667	/* These are passed as-is to the callback. */
668	xd->sav = sav;
669	xd->nxt = hl;
670	xd->protoff = protoff;
671	xd->skip = skip;
672	xd->cryptoid = cryptoid;
673	xd->vnet = curvnet;
674	return (crypto_dispatch(crp));
675bad:
676	m_freem(m);
677	key_freesav(&sav);
678	return (error);
679}
680
681/*
682 * AH input callback from the crypto driver.
683 */
684static int
685ah_input_cb(struct cryptop *crp)
686{
687	IPSEC_DEBUG_DECLARE(char buf[IPSEC_ADDRSTRLEN]);
688	unsigned char calc[AH_ALEN_MAX];
689	struct mbuf *m;
690	struct xform_data *xd;
691	struct secasvar *sav;
692	struct secasindex *saidx;
693	caddr_t ptr;
694	crypto_session_t cryptoid;
695	int authsize, rplen, ahsize, error, skip, protoff;
696	uint8_t nxt;
697
698	m = crp->crp_buf.cb_mbuf;
699	xd = crp->crp_opaque;
700	CURVNET_SET(xd->vnet);
701	sav = xd->sav;
702	skip = xd->skip;
703	nxt = xd->nxt;
704	protoff = xd->protoff;
705	cryptoid = xd->cryptoid;
706	saidx = &sav->sah->saidx;
707	IPSEC_ASSERT(saidx->dst.sa.sa_family == AF_INET ||
708		saidx->dst.sa.sa_family == AF_INET6,
709		("unexpected protocol family %u", saidx->dst.sa.sa_family));
710
711	/* Check for crypto errors. */
712	if (crp->crp_etype) {
713		if (crp->crp_etype == EAGAIN) {
714			/* Reset the session ID */
715			if (ipsec_updateid(sav, &crp->crp_session, &cryptoid) != 0)
716				crypto_freesession(cryptoid);
717			xd->cryptoid = crp->crp_session;
718			CURVNET_RESTORE();
719			return (crypto_dispatch(crp));
720		}
721		AHSTAT_INC(ahs_noxform);
722		DPRINTF(("%s: crypto error %d\n", __func__, crp->crp_etype));
723		error = crp->crp_etype;
724		goto bad;
725	} else {
726		AHSTAT_INC(ahs_hist[sav->alg_auth]);
727		crypto_freereq(crp);		/* No longer needed. */
728		crp = NULL;
729	}
730
731	/* Shouldn't happen... */
732	if (m == NULL) {
733		AHSTAT_INC(ahs_crypto);
734		DPRINTF(("%s: bogus returned buffer from crypto\n", __func__));
735		error = EINVAL;
736		goto bad;
737	}
738
739	/* Figure out header size. */
740	rplen = HDRSIZE(sav);
741	authsize = AUTHSIZE(sav);
742	ahsize = ah_hdrsiz(sav);
743
744	/* Copy authenticator off the packet. */
745	m_copydata(m, skip + rplen, authsize, calc);
746
747	/* Verify authenticator. */
748	ptr = (caddr_t) (xd + 1);
749	if (timingsafe_bcmp(ptr + skip + rplen, calc, authsize)) {
750		DPRINTF(("%s: authentication hash mismatch for packet "
751		    "in SA %s/%08lx\n", __func__,
752		    ipsec_address(&saidx->dst, buf, sizeof(buf)),
753		    (u_long) ntohl(sav->spi)));
754		AHSTAT_INC(ahs_badauth);
755		error = EACCES;
756		goto bad;
757	}
758	/* Fix the Next Protocol field. */
759	((uint8_t *) ptr)[protoff] = nxt;
760
761	/* Copyback the saved (uncooked) network headers. */
762	m_copyback(m, 0, skip, ptr);
763	free(xd, M_XDATA), xd = NULL;			/* No longer needed */
764
765	/*
766	 * Header is now authenticated.
767	 */
768	m->m_flags |= M_AUTHIPHDR|M_AUTHIPDGM;
769
770	/*
771	 * Update replay sequence number, if appropriate.
772	 */
773	if (sav->replay) {
774		u_int32_t seq;
775
776		m_copydata(m, skip + offsetof(struct newah, ah_seq),
777			   sizeof (seq), (caddr_t) &seq);
778		SECASVAR_LOCK(sav);
779		if (ipsec_updatereplay(ntohl(seq), sav)) {
780			SECASVAR_UNLOCK(sav);
781			AHSTAT_INC(ahs_replay);
782			error = EACCES;
783			goto bad;
784		}
785		SECASVAR_UNLOCK(sav);
786	}
787
788	/*
789	 * Remove the AH header and authenticator from the mbuf.
790	 */
791	error = m_striphdr(m, skip, ahsize);
792	if (error) {
793		DPRINTF(("%s: mangled mbuf chain for SA %s/%08lx\n", __func__,
794		    ipsec_address(&saidx->dst, buf, sizeof(buf)),
795		    (u_long) ntohl(sav->spi)));
796		AHSTAT_INC(ahs_hdrops);
797		goto bad;
798	}
799
800	switch (saidx->dst.sa.sa_family) {
801#ifdef INET6
802	case AF_INET6:
803		error = ipsec6_common_input_cb(m, sav, skip, protoff);
804		break;
805#endif
806#ifdef INET
807	case AF_INET:
808		error = ipsec4_common_input_cb(m, sav, skip, protoff);
809		break;
810#endif
811	default:
812		panic("%s: Unexpected address family: %d saidx=%p", __func__,
813		    saidx->dst.sa.sa_family, saidx);
814	}
815	CURVNET_RESTORE();
816	return error;
817bad:
818	CURVNET_RESTORE();
819	if (sav)
820		key_freesav(&sav);
821	if (m != NULL)
822		m_freem(m);
823	if (xd != NULL)
824		free(xd, M_XDATA);
825	if (crp != NULL)
826		crypto_freereq(crp);
827	return error;
828}
829
830/*
831 * AH output routine, called by ipsec[46]_perform_request().
832 */
833static int
834ah_output(struct mbuf *m, struct secpolicy *sp, struct secasvar *sav,
835    u_int idx, int skip, int protoff)
836{
837	IPSEC_DEBUG_DECLARE(char buf[IPSEC_ADDRSTRLEN]);
838	const struct auth_hash *ahx;
839	struct xform_data *xd;
840	struct mbuf *mi;
841	struct cryptop *crp;
842	struct newah *ah;
843	crypto_session_t cryptoid;
844	uint16_t iplen;
845	int error, rplen, authsize, ahsize, maxpacketsize, roff;
846	uint8_t prot;
847	uint32_t seqh;
848
849	IPSEC_ASSERT(sav != NULL, ("null SA"));
850	ahx = sav->tdb_authalgxform;
851	IPSEC_ASSERT(ahx != NULL, ("null authentication xform"));
852
853	AHSTAT_INC(ahs_output);
854
855	/* Figure out header size. */
856	rplen = HDRSIZE(sav);
857	authsize = AUTHSIZE(sav);
858	ahsize = ah_hdrsiz(sav);
859
860	/* Check for maximum packet size violations. */
861	switch (sav->sah->saidx.dst.sa.sa_family) {
862#ifdef INET
863	case AF_INET:
864		maxpacketsize = IP_MAXPACKET;
865		break;
866#endif /* INET */
867#ifdef INET6
868	case AF_INET6:
869		maxpacketsize = IPV6_MAXPACKET;
870		break;
871#endif /* INET6 */
872	default:
873		DPRINTF(("%s: unknown/unsupported protocol family %u, "
874		    "SA %s/%08lx\n", __func__,
875		    sav->sah->saidx.dst.sa.sa_family,
876		    ipsec_address(&sav->sah->saidx.dst, buf, sizeof(buf)),
877		    (u_long) ntohl(sav->spi)));
878		AHSTAT_INC(ahs_nopf);
879		error = EPFNOSUPPORT;
880		goto bad;
881	}
882	if (ahsize + m->m_pkthdr.len > maxpacketsize) {
883		DPRINTF(("%s: packet in SA %s/%08lx got too big "
884		    "(len %u, max len %u)\n", __func__,
885		    ipsec_address(&sav->sah->saidx.dst, buf, sizeof(buf)),
886		    (u_long) ntohl(sav->spi),
887		    ahsize + m->m_pkthdr.len, maxpacketsize));
888		AHSTAT_INC(ahs_toobig);
889		error = EMSGSIZE;
890		goto bad;
891	}
892
893	/* Update the counters. */
894	AHSTAT_ADD(ahs_obytes, m->m_pkthdr.len - skip);
895
896	m = m_unshare(m, M_NOWAIT);
897	if (m == NULL) {
898		DPRINTF(("%s: cannot clone mbuf chain, SA %s/%08lx\n", __func__,
899		    ipsec_address(&sav->sah->saidx.dst, buf, sizeof(buf)),
900		    (u_long) ntohl(sav->spi)));
901		AHSTAT_INC(ahs_hdrops);
902		error = ENOBUFS;
903		goto bad;
904	}
905
906	/* Inject AH header. */
907	mi = m_makespace(m, skip, ahsize, &roff);
908	if (mi == NULL) {
909		DPRINTF(("%s: failed to inject %u byte AH header for SA "
910		    "%s/%08lx\n", __func__, ahsize,
911		    ipsec_address(&sav->sah->saidx.dst, buf, sizeof(buf)),
912		    (u_long) ntohl(sav->spi)));
913		AHSTAT_INC(ahs_hdrops);		/*XXX differs from openbsd */
914		error = ENOBUFS;
915		goto bad;
916	}
917
918	/*
919	 * The AH header is guaranteed by m_makespace() to be in
920	 * contiguous memory, at roff bytes offset into the returned mbuf.
921	 */
922	ah = (struct newah *)(mtod(mi, caddr_t) + roff);
923
924	/* Initialize the AH header. */
925	m_copydata(m, protoff, sizeof(u_int8_t), (caddr_t) &ah->ah_nxt);
926	ah->ah_len = (ahsize - sizeof(struct ah)) / sizeof(u_int32_t);
927	ah->ah_reserve = 0;
928	ah->ah_spi = sav->spi;
929
930	/* Zeroize authenticator. */
931	m_copyback(m, skip + rplen, authsize, ipseczeroes);
932
933	/* Zeroize padding */
934	m_copyback(m, skip + rplen + authsize, ahsize - (rplen + authsize),
935	    ipseczeroes);
936
937	/* Insert packet replay counter, as requested.  */
938	SECASVAR_LOCK(sav);
939	if (sav->replay) {
940		if ((sav->replay->count == ~0 ||
941		    (!(sav->flags & SADB_X_SAFLAGS_ESN) &&
942		    ((uint32_t)sav->replay->count) == ~0)) &&
943		    (sav->flags & SADB_X_EXT_CYCSEQ) == 0) {
944			SECASVAR_UNLOCK(sav);
945			DPRINTF(("%s: replay counter wrapped for SA %s/%08lx\n",
946			    __func__, ipsec_address(&sav->sah->saidx.dst, buf,
947			    sizeof(buf)), (u_long) ntohl(sav->spi)));
948			AHSTAT_INC(ahs_wrap);
949			error = EACCES;
950			goto bad;
951		}
952#ifdef REGRESSION
953		/* Emulate replay attack when ipsec_replay is TRUE. */
954		if (!V_ipsec_replay)
955#endif
956			sav->replay->count++;
957		ah->ah_seq = htonl((uint32_t)sav->replay->count);
958	}
959	cryptoid = sav->tdb_cryptoid;
960	SECASVAR_UNLOCK(sav);
961
962	/* Get crypto descriptors. */
963	crp = crypto_getreq(cryptoid, M_NOWAIT);
964	if (crp == NULL) {
965		DPRINTF(("%s: failed to acquire crypto descriptors\n",
966			__func__));
967		AHSTAT_INC(ahs_crypto);
968		error = ENOBUFS;
969		goto bad;
970	}
971
972	crp->crp_payload_start = 0;
973	crp->crp_payload_length = m->m_pkthdr.len;
974	crp->crp_digest_start = skip + rplen;
975
976	/* Allocate IPsec-specific opaque crypto info. */
977	xd =  malloc(sizeof(struct xform_data) + skip, M_XDATA,
978	    M_NOWAIT | M_ZERO);
979	if (xd == NULL) {
980		crypto_freereq(crp);
981		DPRINTF(("%s: failed to allocate xform_data\n", __func__));
982		AHSTAT_INC(ahs_crypto);
983		error = ENOBUFS;
984		goto bad;
985	}
986
987	/* Save the skipped portion of the packet. */
988	m_copydata(m, 0, skip, (caddr_t) (xd + 1));
989
990	/*
991	 * Fix IP header length on the header used for
992	 * authentication. We don't need to fix the original
993	 * header length as it will be fixed by our caller.
994	 */
995	switch (sav->sah->saidx.dst.sa.sa_family) {
996#ifdef INET
997	case AF_INET:
998		bcopy(((caddr_t)(xd + 1)) +
999		    offsetof(struct ip, ip_len),
1000		    (caddr_t) &iplen, sizeof(u_int16_t));
1001		iplen = htons(ntohs(iplen) + ahsize);
1002		m_copyback(m, offsetof(struct ip, ip_len),
1003		    sizeof(u_int16_t), (caddr_t) &iplen);
1004		break;
1005#endif /* INET */
1006
1007#ifdef INET6
1008	case AF_INET6:
1009		bcopy(((caddr_t)(xd + 1)) +
1010		    offsetof(struct ip6_hdr, ip6_plen),
1011		    (caddr_t) &iplen, sizeof(uint16_t));
1012		iplen = htons(ntohs(iplen) + ahsize);
1013		m_copyback(m, offsetof(struct ip6_hdr, ip6_plen),
1014		    sizeof(uint16_t), (caddr_t) &iplen);
1015		break;
1016#endif /* INET6 */
1017	}
1018
1019	/* Fix the Next Header field in saved header. */
1020	((uint8_t *) (xd + 1))[protoff] = IPPROTO_AH;
1021
1022	/* Update the Next Protocol field in the IP header. */
1023	prot = IPPROTO_AH;
1024	m_copyback(m, protoff, sizeof(uint8_t), (caddr_t) &prot);
1025
1026	/* "Massage" the packet headers for crypto processing. */
1027	error = ah_massage_headers(&m, sav->sah->saidx.dst.sa.sa_family,
1028			skip, ahx->type, 1);
1029	if (error != 0) {
1030		m = NULL;	/* mbuf was free'd by ah_massage_headers. */
1031		free(xd, M_XDATA);
1032		crypto_freereq(crp);
1033		goto bad;
1034	}
1035
1036	/* Crypto operation descriptor. */
1037	crp->crp_op = CRYPTO_OP_COMPUTE_DIGEST;
1038	crp->crp_flags = CRYPTO_F_CBIFSYNC;
1039	if (V_async_crypto)
1040		crp->crp_flags |= CRYPTO_F_ASYNC | CRYPTO_F_ASYNC_KEEPORDER;
1041	crypto_use_mbuf(crp, m);
1042	crp->crp_callback = ah_output_cb;
1043	crp->crp_opaque = xd;
1044
1045	if (sav->flags & SADB_X_SAFLAGS_ESN && sav->replay != NULL) {
1046		seqh = htonl((uint32_t)(sav->replay->count >> IPSEC_SEQH_SHIFT));
1047		memcpy(crp->crp_esn, &seqh, sizeof(seqh));
1048	}
1049
1050	/* These are passed as-is to the callback. */
1051	xd->sp = sp;
1052	xd->sav = sav;
1053	xd->skip = skip;
1054	xd->idx = idx;
1055	xd->cryptoid = cryptoid;
1056	xd->vnet = curvnet;
1057
1058	return crypto_dispatch(crp);
1059bad:
1060	if (m)
1061		m_freem(m);
1062	key_freesav(&sav);
1063	key_freesp(&sp);
1064	return (error);
1065}
1066
1067/*
1068 * AH output callback from the crypto driver.
1069 */
1070static int
1071ah_output_cb(struct cryptop *crp)
1072{
1073	struct xform_data *xd;
1074	struct secpolicy *sp;
1075	struct secasvar *sav;
1076	struct mbuf *m;
1077	crypto_session_t cryptoid;
1078	caddr_t ptr;
1079	u_int idx;
1080	int skip, error;
1081
1082	m = crp->crp_buf.cb_mbuf;
1083	xd = (struct xform_data *) crp->crp_opaque;
1084	CURVNET_SET(xd->vnet);
1085	sp = xd->sp;
1086	sav = xd->sav;
1087	skip = xd->skip;
1088	idx = xd->idx;
1089	cryptoid = xd->cryptoid;
1090	ptr = (caddr_t) (xd + 1);
1091
1092	/* Check for crypto errors. */
1093	if (crp->crp_etype) {
1094		if (crp->crp_etype == EAGAIN) {
1095			/* Reset the session ID */
1096			if (ipsec_updateid(sav, &crp->crp_session, &cryptoid) != 0)
1097				crypto_freesession(cryptoid);
1098			xd->cryptoid = crp->crp_session;
1099			CURVNET_RESTORE();
1100			return (crypto_dispatch(crp));
1101		}
1102		AHSTAT_INC(ahs_noxform);
1103		DPRINTF(("%s: crypto error %d\n", __func__, crp->crp_etype));
1104		error = crp->crp_etype;
1105		m_freem(m);
1106		goto bad;
1107	}
1108
1109	/* Shouldn't happen... */
1110	if (m == NULL) {
1111		AHSTAT_INC(ahs_crypto);
1112		DPRINTF(("%s: bogus returned buffer from crypto\n", __func__));
1113		error = EINVAL;
1114		goto bad;
1115	}
1116	/*
1117	 * Copy original headers (with the new protocol number) back
1118	 * in place.
1119	 */
1120	m_copyback(m, 0, skip, ptr);
1121
1122	free(xd, M_XDATA);
1123	crypto_freereq(crp);
1124	AHSTAT_INC(ahs_hist[sav->alg_auth]);
1125#ifdef REGRESSION
1126	/* Emulate man-in-the-middle attack when ipsec_integrity is TRUE. */
1127	if (V_ipsec_integrity) {
1128		int alen;
1129
1130		/*
1131		 * Corrupt HMAC if we want to test integrity verification of
1132		 * the other side.
1133		 */
1134		alen = AUTHSIZE(sav);
1135		m_copyback(m, m->m_pkthdr.len - alen, alen, ipseczeroes);
1136	}
1137#endif
1138
1139	/* NB: m is reclaimed by ipsec_process_done. */
1140	error = ipsec_process_done(m, sp, sav, idx);
1141	CURVNET_RESTORE();
1142	return (error);
1143bad:
1144	CURVNET_RESTORE();
1145	free(xd, M_XDATA);
1146	crypto_freereq(crp);
1147	key_freesav(&sav);
1148	key_freesp(&sp);
1149	return (error);
1150}
1151
1152static struct xformsw ah_xformsw = {
1153	.xf_type =	XF_AH,
1154	.xf_name =	"IPsec AH",
1155	.xf_init =	ah_init,
1156	.xf_cleanup =	ah_cleanup,
1157	.xf_input =	ah_input,
1158	.xf_output =	ah_output,
1159};
1160
1161SYSINIT(ah_xform_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_MIDDLE,
1162    xform_attach, &ah_xformsw);
1163SYSUNINIT(ah_xform_uninit, SI_SUB_PROTO_DOMAIN, SI_ORDER_MIDDLE,
1164    xform_detach, &ah_xformsw);
1165