xref: /openbsd/sys/netinet/ip_ah.c (revision 404b540a)
1 /*	$OpenBSD: ip_ah.c,v 1.92 2008/09/15 21:46:01 chl Exp $ */
2 /*
3  * The authors of this code are John Ioannidis (ji@tla.org),
4  * Angelos D. Keromytis (kermit@csd.uch.gr) and
5  * Niels Provos (provos@physnet.uni-hamburg.de).
6  *
7  * The original version of this code was written by John Ioannidis
8  * for BSD/OS in Athens, Greece, in November 1995.
9  *
10  * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
11  * by Angelos D. Keromytis.
12  *
13  * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
14  * and Niels Provos.
15  *
16  * Additional features in 1999 by Angelos D. Keromytis and Niklas Hallqvist.
17  *
18  * Copyright (c) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
19  * Angelos D. Keromytis and Niels Provos.
20  * Copyright (c) 1999 Niklas Hallqvist.
21  * Copyright (c) 2001 Angelos D. Keromytis.
22  *
23  * Permission to use, copy, and modify this software with or without fee
24  * is hereby granted, provided that this entire notice is included in
25  * all copies of any software which is or includes a copy or
26  * modification of this software.
27  * You may use this code under the GNU public license if you so wish. Please
28  * contribute changes back to the authors under this freer than GPL license
29  * so that we may further the use of strong encryption without limitations to
30  * all.
31  *
32  * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
33  * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
34  * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
35  * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
36  * PURPOSE.
37  */
38 
39 #include "pfsync.h"
40 
41 #include <sys/param.h>
42 #include <sys/systm.h>
43 #include <sys/mbuf.h>
44 #include <sys/socket.h>
45 
46 #include <net/if.h>
47 #include <net/bpf.h>
48 
49 #ifdef INET
50 #include <netinet/in.h>
51 #include <netinet/in_systm.h>
52 #include <netinet/ip.h>
53 #include <netinet/ip_var.h>
54 #endif /* INET */
55 
56 #ifdef INET6
57 #ifndef INET
58 #include <netinet/in.h>
59 #endif /* INET */
60 #include <netinet/ip6.h>
61 #endif /* INET6 */
62 
63 #include <netinet/ip_ipsp.h>
64 #include <netinet/ip_ah.h>
65 #include <net/pfkeyv2.h>
66 #include <net/if_enc.h>
67 
68 #if NPFSYNC > 0
69 #include <net/pfvar.h>
70 #include <net/if_pfsync.h>
71 #endif /* NPFSYNC > 0 */
72 
73 #include <crypto/cryptodev.h>
74 #include <crypto/xform.h>
75 
76 #include "bpfilter.h"
77 
78 #ifdef ENCDEBUG
79 #define DPRINTF(x)	if (encdebug) printf x
80 #else
81 #define DPRINTF(x)
82 #endif
83 
84 struct ahstat ahstat;
85 
86 /*
87  * ah_attach() is called from the transformation initialization code.
88  */
89 int
90 ah_attach()
91 {
92 	return 0;
93 }
94 
95 /*
96  * ah_init() is called when an SPI is being set up.
97  */
98 int
99 ah_init(struct tdb *tdbp, struct xformsw *xsp, struct ipsecinit *ii)
100 {
101 	struct auth_hash *thash = NULL;
102 	struct cryptoini cria;
103 
104 	/* Authentication operation. */
105 	switch (ii->ii_authalg) {
106 	case SADB_AALG_MD5HMAC:
107 		thash = &auth_hash_hmac_md5_96;
108 		break;
109 
110 	case SADB_AALG_SHA1HMAC:
111 		thash = &auth_hash_hmac_sha1_96;
112 		break;
113 
114 	case SADB_X_AALG_RIPEMD160HMAC:
115 		thash = &auth_hash_hmac_ripemd_160_96;
116 		break;
117 
118 	case SADB_X_AALG_SHA2_256:
119 		thash = &auth_hash_hmac_sha2_256_96;
120 		break;
121 
122 	case SADB_X_AALG_SHA2_384:
123 		thash = &auth_hash_hmac_sha2_384_96;
124 		break;
125 
126 	case SADB_X_AALG_SHA2_512:
127 		thash = &auth_hash_hmac_sha2_512_96;
128 		break;
129 
130 	case SADB_X_AALG_MD5:
131 		thash = &auth_hash_key_md5;
132 		break;
133 
134 	case SADB_X_AALG_SHA1:
135 		thash = &auth_hash_key_sha1;
136 		break;
137 
138 	default:
139 		DPRINTF(("ah_init(): unsupported authentication algorithm %d specified\n", ii->ii_authalg));
140 		return EINVAL;
141 	}
142 
143 	if (ii->ii_authkeylen != thash->keysize && thash->keysize != 0) {
144 		DPRINTF(("ah_init(): keylength %d doesn't match algorithm "
145 		    "%s keysize (%d)\n", ii->ii_authkeylen, thash->name,
146 		    thash->keysize));
147 		return EINVAL;
148 	}
149 
150 	tdbp->tdb_xform = xsp;
151 	tdbp->tdb_authalgxform = thash;
152 	tdbp->tdb_bitmap = 0;
153 	tdbp->tdb_rpl = AH_HMAC_INITIAL_RPL;
154 
155 	DPRINTF(("ah_init(): initialized TDB with hash algorithm %s\n",
156 	    thash->name));
157 
158 	tdbp->tdb_amxkeylen = ii->ii_authkeylen;
159 	tdbp->tdb_amxkey = malloc(tdbp->tdb_amxkeylen, M_XDATA, M_WAITOK);
160 
161 	bcopy(ii->ii_authkey, tdbp->tdb_amxkey, tdbp->tdb_amxkeylen);
162 
163 	/* Initialize crypto session. */
164 	bzero(&cria, sizeof(cria));
165 	cria.cri_alg = tdbp->tdb_authalgxform->type;
166 	cria.cri_klen = ii->ii_authkeylen * 8;
167 	cria.cri_key = ii->ii_authkey;
168 
169 	return crypto_newsession(&tdbp->tdb_cryptoid, &cria, 0);
170 }
171 
172 /*
173  * Paranoia.
174  */
175 int
176 ah_zeroize(struct tdb *tdbp)
177 {
178 	int err;
179 
180 	if (tdbp->tdb_amxkey) {
181 		bzero(tdbp->tdb_amxkey, tdbp->tdb_amxkeylen);
182 		free(tdbp->tdb_amxkey, M_XDATA);
183 		tdbp->tdb_amxkey = NULL;
184 	}
185 
186 	err = crypto_freesession(tdbp->tdb_cryptoid);
187 	tdbp->tdb_cryptoid = 0;
188 	return err;
189 }
190 
191 /*
192  * Massage IPv4/IPv6 headers for AH processing.
193  */
194 int
195 ah_massage_headers(struct mbuf **m0, int proto, int skip, int alg, int out)
196 {
197 	struct mbuf *m = *m0;
198 	unsigned char *ptr;
199 	int off, count;
200 
201 #ifdef INET
202 	struct ip *ip;
203 #endif /* INET */
204 
205 #ifdef INET6
206 	struct ip6_ext *ip6e;
207 	struct ip6_hdr ip6;
208 	int ad, alloc, nxt;
209 #endif /* INET6 */
210 
211 	switch (proto) {
212 #ifdef INET
213 	case AF_INET:
214 		/*
215 		 * This is the least painful way of dealing with IPv4 header
216 		 * and option processing -- just make sure they're in
217 		 * contiguous memory.
218 		 */
219 		*m0 = m = m_pullup(m, skip);
220 		if (m == NULL) {
221 			DPRINTF(("ah_massage_headers(): m_pullup() failed\n"));
222 			ahstat.ahs_hdrops++;
223 			return ENOBUFS;
224 		}
225 
226 		/* Fix the IP header */
227 		ip = mtod(m, struct ip *);
228 		ip->ip_tos = 0;
229 		ip->ip_ttl = 0;
230 		ip->ip_sum = 0;
231 
232 		/*
233 		 * On input, fix ip_len which has been byte-swapped
234 		 * at ip_input().
235 		 */
236 		if (alg == CRYPTO_MD5_KPDK || alg == CRYPTO_SHA1_KPDK)
237 			ip->ip_off &= htons(IP_DF);
238 		else
239 			ip->ip_off = 0;
240 
241 		ptr = mtod(m, unsigned char *) + sizeof(struct ip);
242 
243 		/* IPv4 option processing */
244 		for (off = sizeof(struct ip); off < skip;) {
245 			if (ptr[off] == IPOPT_EOL || ptr[off] == IPOPT_NOP ||
246 			    off + 1 < skip)
247 				;
248 			else {
249 				DPRINTF(("ah_massage_headers(): illegal IPv4 "
250 				    "option length for option %d\n",
251 				    ptr[off]));
252 
253 				ahstat.ahs_hdrops++;
254 				m_freem(m);
255 				return EINVAL;
256 			}
257 
258 			switch (ptr[off]) {
259 			case IPOPT_EOL:
260 				off = skip;  /* End the loop. */
261 				break;
262 
263 			case IPOPT_NOP:
264 				off++;
265 				break;
266 
267 			case IPOPT_SECURITY:	/* 0x82 */
268 			case 0x85:	/* Extended security. */
269 			case 0x86:	/* Commercial security. */
270 			case 0x94:	/* Router alert */
271 			case 0x95:	/* RFC1770 */
272 				/* Sanity check for option length. */
273 				if (ptr[off + 1] < 2) {
274 					DPRINTF(("ah_massage_headers(): "
275 					    "illegal IPv4 option length for "
276 					    "option %d\n", ptr[off]));
277 
278 					ahstat.ahs_hdrops++;
279 					m_freem(m);
280 					return EINVAL;
281 				}
282 
283 				off += ptr[off + 1];
284 				break;
285 
286 			case IPOPT_LSRR:
287 			case IPOPT_SSRR:
288 				/* Sanity check for option length. */
289 				if (ptr[off + 1] < 2) {
290 					DPRINTF(("ah_massage_headers(): "
291 					    "illegal IPv4 option length for "
292 					    "option %d\n", ptr[off]));
293 
294 					ahstat.ahs_hdrops++;
295 					m_freem(m);
296 					return EINVAL;
297 				}
298 
299 				/*
300 				 * On output, if we have either of the
301 				 * source routing options, we should
302 				 * swap the destination address of the
303 				 * IP header with the last address
304 				 * specified in the option, as that is
305 				 * what the destination's IP header
306 				 * will look like.
307 				 */
308 				if (out)
309 					bcopy(ptr + off + ptr[off + 1] -
310 					    sizeof(struct in_addr),
311 					    &(ip->ip_dst), sizeof(struct in_addr));
312 
313 				/* FALLTHROUGH */
314 			default:
315 				/* Sanity check for option length. */
316 				if (ptr[off + 1] < 2) {
317 					DPRINTF(("ah_massage_headers(): "
318 					    "illegal IPv4 option length for "
319 					    "option %d\n", ptr[off]));
320 					ahstat.ahs_hdrops++;
321 					m_freem(m);
322 					return EINVAL;
323 				}
324 
325 				/* Zeroize all other options. */
326 				count = ptr[off + 1];
327 				bcopy(ipseczeroes, ptr, count);
328 				off += count;
329 				break;
330 			}
331 
332 			/* Sanity check. */
333 			if (off > skip)	{
334 				DPRINTF(("ah_massage_headers(): malformed "
335 				    "IPv4 options header\n"));
336 
337 				ahstat.ahs_hdrops++;
338 				m_freem(m);
339 				return EINVAL;
340 			}
341 		}
342 
343 		break;
344 #endif /* INET */
345 
346 #ifdef INET6
347 	case AF_INET6:  /* Ugly... */
348 		/* Copy and "cook" the IPv6 header. */
349 		m_copydata(m, 0, sizeof(ip6), (caddr_t) &ip6);
350 
351 		/* We don't do IPv6 Jumbograms. */
352 		if (ip6.ip6_plen == 0) {
353 			DPRINTF(("ah_massage_headers(): unsupported IPv6 "
354 			    "jumbogram"));
355 			ahstat.ahs_hdrops++;
356 			m_freem(m);
357 			return EMSGSIZE;
358 		}
359 
360 		ip6.ip6_flow = 0;
361 		ip6.ip6_hlim = 0;
362 		ip6.ip6_vfc &= ~IPV6_VERSION_MASK;
363 		ip6.ip6_vfc |= IPV6_VERSION;
364 
365 		/* Scoped address handling. */
366 		if (IN6_IS_SCOPE_EMBED(&ip6.ip6_src))
367 			ip6.ip6_src.s6_addr16[1] = 0;
368 		if (IN6_IS_SCOPE_EMBED(&ip6.ip6_dst))
369 			ip6.ip6_dst.s6_addr16[1] = 0;
370 
371 		/* Done with IPv6 header. */
372 		m_copyback(m, 0, sizeof(struct ip6_hdr), &ip6);
373 
374 		/* Let's deal with the remaining headers (if any). */
375 		if (skip - sizeof(struct ip6_hdr) > 0) {
376 			if (m->m_len <= skip) {
377 				ptr = malloc(skip - sizeof(struct ip6_hdr),
378 				    M_XDATA, M_NOWAIT);
379 				if (ptr == NULL) {
380 					DPRINTF(("ah_massage_headers(): failed to allocate memory for IPv6 headers\n"));
381 					ahstat.ahs_hdrops++;
382 					m_freem(m);
383 					return ENOBUFS;
384 				}
385 
386 				/*
387 				 * Copy all the protocol headers after
388 				 * the IPv6 header.
389 				 */
390 				m_copydata(m, sizeof(struct ip6_hdr),
391 				    skip - sizeof(struct ip6_hdr), ptr);
392 				alloc = 1;
393 			} else {
394 				/* No need to allocate memory. */
395 				ptr = mtod(m, unsigned char *) +
396 				    sizeof(struct ip6_hdr);
397 				alloc = 0;
398 			}
399 		} else
400 			break;
401 
402 		nxt = ip6.ip6_nxt & 0xff; /* Next header type. */
403 
404 		for (off = 0; off < skip - sizeof(struct ip6_hdr);) {
405 			switch (nxt) {
406 			case IPPROTO_HOPOPTS:
407 			case IPPROTO_DSTOPTS:
408 				ip6e = (struct ip6_ext *) (ptr + off);
409 
410 				/*
411 				 * Process the mutable/immutable
412 				 * options -- borrows heavily from the
413 				 * KAME code.
414 				 */
415 				for (count = off + sizeof(struct ip6_ext);
416 				     count < off + ((ip6e->ip6e_len + 1) << 3);) {
417 					if (ptr[count] == IP6OPT_PAD1) {
418 						count++;
419 						continue; /* Skip padding. */
420 					}
421 
422 					/* Sanity check. */
423 					if (count > off +
424 					    ((ip6e->ip6e_len + 1) << 3)) {
425 						ahstat.ahs_hdrops++;
426 						m_freem(m);
427 
428 						/* Free, if we allocated. */
429 						if (alloc)
430 							free(ptr, M_XDATA);
431 						return EINVAL;
432 					}
433 
434 					ad = ptr[count + 1];
435 
436 					/* If mutable option, zeroize. */
437 					if (ptr[count] & IP6OPT_MUTABLE)
438 						bcopy(ipseczeroes, ptr + count,
439 						    ptr[count + 1]);
440 
441 					count += ad;
442 
443 					/* Sanity check. */
444 					if (count >
445 					    skip - sizeof(struct ip6_hdr)) {
446 						ahstat.ahs_hdrops++;
447 						m_freem(m);
448 
449 						/* Free, if we allocated. */
450 						if (alloc)
451 							free(ptr, M_XDATA);
452 						return EINVAL;
453 					}
454 				}
455 
456 				/* Advance. */
457 				off += ((ip6e->ip6e_len + 1) << 3);
458 				nxt = ip6e->ip6e_nxt;
459 				break;
460 
461 			case IPPROTO_ROUTING:
462 				/*
463 				 * Always include routing headers in
464 				 * computation.
465 				 */
466 			    {
467 				struct ip6_rthdr *rh;
468 
469 				ip6e = (struct ip6_ext *) (ptr + off);
470 				rh = (struct ip6_rthdr *)(ptr + off);
471 				/*
472 				 * must adjust content to make it look like
473 				 * its final form (as seen at the final
474 				 * destination).
475 				 * we only know how to massage type 0 routing
476 				 * header.
477 				 */
478 				if (out && rh->ip6r_type == IPV6_RTHDR_TYPE_0) {
479 					struct ip6_rthdr0 *rh0;
480 					struct in6_addr *addr, finaldst;
481 					int i;
482 
483 					rh0 = (struct ip6_rthdr0 *)rh;
484 					addr = (struct in6_addr *)(rh0 + 1);
485 
486 					for (i = 0; i < rh0->ip6r0_segleft; i++)
487 						if (IN6_IS_SCOPE_EMBED(&addr[i]))
488 							addr[i].s6_addr16[1] = 0;
489 
490 					finaldst = addr[rh0->ip6r0_segleft - 1];
491 					ovbcopy(&addr[0], &addr[1],
492 					    sizeof(struct in6_addr) *
493 					    (rh0->ip6r0_segleft - 1));
494 
495 					m_copydata(m, 0, sizeof(ip6),
496 					    (caddr_t)&ip6);
497 					addr[0] = ip6.ip6_dst;
498 					ip6.ip6_dst = finaldst;
499 					m_copyback(m, 0, sizeof(ip6), &ip6);
500 
501 					rh0->ip6r0_segleft = 0;
502 				}
503 
504 				/* advance */
505 				off += ((ip6e->ip6e_len + 1) << 3);
506 				nxt = ip6e->ip6e_nxt;
507 				break;
508 			    }
509 
510 			default:
511 				DPRINTF(("ah_massage_headers(): unexpected "
512 				    "IPv6 header type %d\n", off));
513 				if (alloc)
514 					free(ptr, M_XDATA);
515 				ahstat.ahs_hdrops++;
516 				m_freem(m);
517 				return EINVAL;
518 			}
519 		}
520 
521 		/* Copyback and free, if we allocated. */
522 		if (alloc) {
523 			m_copyback(m, sizeof(struct ip6_hdr),
524 			    skip - sizeof(struct ip6_hdr), ptr);
525 			free(ptr, M_XDATA);
526 		}
527 
528 		break;
529 #endif /* INET6 */
530 	}
531 
532 	return 0;
533 }
534 
535 /*
536  * ah_input() gets called to verify that an input packet
537  * passes authentication.
538  */
539 int
540 ah_input(struct mbuf *m, struct tdb *tdb, int skip, int protoff)
541 {
542 	struct auth_hash *ahx = (struct auth_hash *) tdb->tdb_authalgxform;
543 	struct tdb_crypto *tc;
544 	struct m_tag *mtag;
545 	u_int32_t btsx;
546 	u_int8_t hl;
547 	int rplen;
548 
549 	struct cryptodesc *crda = NULL;
550 	struct cryptop *crp;
551 
552 	if (!(tdb->tdb_flags & TDBF_NOREPLAY))
553 		rplen = AH_FLENGTH + sizeof(u_int32_t);
554 	else
555 		rplen = AH_FLENGTH;
556 
557 	/* Save the AH header, we use it throughout. */
558 	m_copydata(m, skip + offsetof(struct ah, ah_hl), sizeof(u_int8_t),
559 	    (caddr_t) &hl);
560 
561 	/* Replay window checking, if applicable. */
562 	if ((tdb->tdb_wnd > 0) && (!(tdb->tdb_flags & TDBF_NOREPLAY))) {
563 		m_copydata(m, skip + offsetof(struct ah, ah_rpl),
564 		    sizeof(u_int32_t), (caddr_t) &btsx);
565 		btsx = ntohl(btsx);
566 
567 		switch (checkreplaywindow32(btsx, 0, &(tdb->tdb_rpl),
568 		    tdb->tdb_wnd, &(tdb->tdb_bitmap), 0)) {
569 		case 0: /* All's well. */
570 			break;
571 
572 		case 1:
573 			DPRINTF(("ah_input(): replay counter wrapped for "
574 			    "SA %s/%08x\n", ipsp_address(tdb->tdb_dst),
575 			    ntohl(tdb->tdb_spi)));
576 
577 			ahstat.ahs_wrap++;
578 			m_freem(m);
579 			return ENOBUFS;
580 
581 		case 2:
582 		case 3:
583 			DPRINTF(("ah_input(): duplicate packet received in "
584 			    "SA %s/%08x\n", ipsp_address(tdb->tdb_dst),
585 			    ntohl(tdb->tdb_spi)));
586 
587 			m_freem(m);
588 			return ENOBUFS;
589 
590 		default:
591 			DPRINTF(("ah_input(): bogus value from "
592 			    "checkreplaywindow32() in SA %s/%08x\n",
593 			    ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
594 
595 			ahstat.ahs_replay++;
596 			m_freem(m);
597 			return ENOBUFS;
598 		}
599 	}
600 
601 	/* Verify AH header length. */
602 	if (hl * sizeof(u_int32_t) != ahx->authsize + rplen - AH_FLENGTH) {
603 		DPRINTF(("ah_input(): bad authenticator length %d for packet "
604 		    "in SA %s/%08x\n", hl * sizeof(u_int32_t),
605 		    ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
606 
607 		ahstat.ahs_badauthl++;
608 		m_freem(m);
609 		return EACCES;
610 	}
611 
612 	/* Update the counters. */
613 	tdb->tdb_cur_bytes +=
614 	    (m->m_pkthdr.len - skip - hl * sizeof(u_int32_t));
615 	ahstat.ahs_ibytes += (m->m_pkthdr.len - skip - hl * sizeof(u_int32_t));
616 
617 	/* Hard expiration. */
618 	if (tdb->tdb_flags & TDBF_BYTES &&
619 	    tdb->tdb_cur_bytes >= tdb->tdb_exp_bytes) {
620 		pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_HARD);
621 		tdb_delete(tdb);
622 		m_freem(m);
623 		return ENXIO;
624 	}
625 
626 	/* Notify on expiration. */
627 	if (tdb->tdb_flags & TDBF_SOFT_BYTES &&
628 	    tdb->tdb_cur_bytes >= tdb->tdb_soft_bytes) {
629 		pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_SOFT);
630 		tdb->tdb_flags &= ~TDBF_SOFT_BYTES;  /* Turn off checking. */
631 	}
632 
633 	/* Get crypto descriptors. */
634 	crp = crypto_getreq(1);
635 	if (crp == NULL) {
636 		m_freem(m);
637 		DPRINTF(("ah_input(): failed to acquire crypto "
638 		    "descriptors\n"));
639 		ahstat.ahs_crypto++;
640 		return ENOBUFS;
641 	}
642 
643 	crda = crp->crp_desc;
644 
645 	crda->crd_skip = 0;
646 	crda->crd_len = m->m_pkthdr.len;
647 	crda->crd_inject = skip + rplen;
648 
649 	/* Authentication operation. */
650 	crda->crd_alg = ahx->type;
651 	crda->crd_key = tdb->tdb_amxkey;
652 	crda->crd_klen = tdb->tdb_amxkeylen * 8;
653 
654 #ifdef notyet
655 	/* Find out if we've already done crypto. */
656 	for (mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_CRYPTO_DONE, NULL);
657 	     mtag != NULL;
658 	     mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_CRYPTO_DONE, mtag)) {
659 		struct tdb_ident *tdbi;
660 
661 		tdbi = (struct tdb_ident *) (mtag + 1);
662 		if (tdbi->proto == tdb->tdb_sproto &&
663 		    tdbi->spi == tdb->tdb_spi &&
664 		    !bcmp(&tdbi->dst, &tdb->tdb_dst,
665 			sizeof(union sockaddr_union)))
666 			break;
667 	}
668 #else
669 	mtag = NULL;
670 #endif
671 
672 	/* Allocate IPsec-specific opaque crypto info. */
673 	if (mtag == NULL)
674 		tc = malloc(sizeof(*tc) + skip + rplen + ahx->authsize, M_XDATA,
675 		    M_NOWAIT | M_ZERO);
676 	else /* Hash verification has already been done successfully. */
677 		tc = malloc(sizeof(*tc), M_XDATA, M_NOWAIT | M_ZERO);
678 	if (tc == NULL) {
679 		m_freem(m);
680 		crypto_freereq(crp);
681 		DPRINTF(("ah_input(): failed to allocate tdb_crypto\n"));
682 		ahstat.ahs_crypto++;
683 		return ENOBUFS;
684 	}
685 
686 	/* Only save information if crypto processing is needed. */
687 	if (mtag == NULL) {
688 		/*
689 		 * Save the authenticator, the skipped portion of the packet,
690 		 * and the AH header.
691 		 */
692 		m_copydata(m, 0, skip + rplen + ahx->authsize,
693 		    (caddr_t) (tc + 1));
694 
695 		/* Zeroize the authenticator on the packet. */
696 		m_copyback(m, skip + rplen, ahx->authsize, ipseczeroes);
697 
698 		/* "Massage" the packet headers for crypto processing. */
699 		if ((btsx = ah_massage_headers(&m, tdb->tdb_dst.sa.sa_family,
700 		    skip, ahx->type, 0)) != 0) {
701 			/* mbuf will be free'd by callee. */
702 			free(tc, M_XDATA);
703 			crypto_freereq(crp);
704 			return btsx;
705 		}
706 	}
707 
708 	/* Crypto operation descriptor. */
709 	crp->crp_ilen = m->m_pkthdr.len; /* Total input length. */
710 	crp->crp_flags = CRYPTO_F_IMBUF;
711 	crp->crp_buf = (caddr_t) m;
712 	crp->crp_callback = (int (*) (struct cryptop *)) ah_input_cb;
713 	crp->crp_sid = tdb->tdb_cryptoid;
714 	crp->crp_opaque = (caddr_t) tc;
715 
716 	/* These are passed as-is to the callback. */
717 	tc->tc_skip = skip;
718 	tc->tc_protoff = protoff;
719 	tc->tc_spi = tdb->tdb_spi;
720 	tc->tc_proto = tdb->tdb_sproto;
721 	tc->tc_ptr = (caddr_t) mtag; /* Save the mtag we've identified. */
722 	bcopy(&tdb->tdb_dst, &tc->tc_dst, sizeof(union sockaddr_union));
723 
724 	if (mtag == NULL)
725 		return crypto_dispatch(crp);
726 	else
727 		return ah_input_cb(crp);
728 }
729 
730 /*
731  * AH input callback, called directly by the crypto driver.
732  */
733 int
734 ah_input_cb(void *op)
735 {
736 	int s, roff, rplen, error, skip, protoff;
737 	unsigned char calc[AH_ALEN_MAX];
738 	struct mbuf *m1, *m0, *m;
739 	struct auth_hash *ahx;
740 	struct tdb_crypto *tc;
741 	struct cryptop *crp;
742 	struct m_tag *mtag;
743 	struct tdb *tdb;
744 	u_int32_t btsx;
745 	u_int8_t prot;
746 	caddr_t ptr;
747 
748 	crp = (struct cryptop *) op;
749 
750 	tc = (struct tdb_crypto *) crp->crp_opaque;
751 	skip = tc->tc_skip;
752 	protoff = tc->tc_protoff;
753 	mtag = (struct m_tag *) tc->tc_ptr;
754 
755 	m = (struct mbuf *) crp->crp_buf;
756 	if (m == NULL) {
757 		/* Shouldn't happen... */
758 		free(tc, M_XDATA);
759 		crypto_freereq(crp);
760 		ahstat.ahs_crypto++;
761 		DPRINTF(("ah_input_cb(): bogus returned buffer from "
762 		    "crypto\n"));
763 		return (EINVAL);
764 	}
765 
766 	s = spltdb();
767 
768 	tdb = gettdb(tc->tc_spi, &tc->tc_dst, tc->tc_proto);
769 	if (tdb == NULL) {
770 		free(tc, M_XDATA);
771 		ahstat.ahs_notdb++;
772 		DPRINTF(("ah_input_cb(): TDB is expired while in crypto"));
773 		error = EPERM;
774 		goto baddone;
775 	}
776 
777 	ahx = (struct auth_hash *) tdb->tdb_authalgxform;
778 
779 	/* Check for crypto errors. */
780 	if (crp->crp_etype) {
781 		if (crp->crp_etype == EAGAIN) {
782 			/* Reset the session ID */
783 			if (tdb->tdb_cryptoid != 0)
784 				tdb->tdb_cryptoid = crp->crp_sid;
785 			splx(s);
786 			return crypto_dispatch(crp);
787 		}
788 		free(tc, M_XDATA);
789 		ahstat.ahs_noxform++;
790 		DPRINTF(("ah_input_cb(): crypto error %d\n", crp->crp_etype));
791 		error = crp->crp_etype;
792 		goto baddone;
793 	} else {
794 		crypto_freereq(crp); /* No longer needed. */
795 		crp = NULL;
796 	}
797 
798 	if (!(tdb->tdb_flags & TDBF_NOREPLAY))
799 		rplen = AH_FLENGTH + sizeof(u_int32_t);
800 	else
801 		rplen = AH_FLENGTH;
802 
803 	/* Copy authenticator off the packet. */
804 	m_copydata(m, skip + rplen, ahx->authsize, calc);
805 
806 	/*
807 	 * If we have an mtag, we don't need to verify the authenticator --
808 	 * it has been verified by an IPsec-aware NIC.
809 	 */
810 	if (mtag == NULL) {
811 		ptr = (caddr_t) (tc + 1);
812 
813 		/* Verify authenticator. */
814 		if (bcmp(ptr + skip + rplen, calc, ahx->authsize)) {
815 			free(tc, M_XDATA);
816 
817 			DPRINTF(("ah_input(): authentication failed for "
818 			    "packet in SA %s/%08x\n",
819 			    ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
820 
821 			ahstat.ahs_badauth++;
822 			error = EACCES;
823 			goto baddone;
824 		}
825 
826 		/* Fix the Next Protocol field. */
827 		((u_int8_t *) ptr)[protoff] = ((u_int8_t *) ptr)[skip];
828 
829 		/* Copyback the saved (uncooked) network headers. */
830 		m_copyback(m, 0, skip, ptr);
831 	} else {
832 		/* Fix the Next Protocol field. */
833 		m_copydata(m, skip, sizeof(u_int8_t), &prot);
834 		m_copyback(m, protoff, sizeof(u_int8_t), &prot);
835 	}
836 
837 	free(tc, M_XDATA);
838 
839 	/* Replay window checking, if applicable. */
840 	if ((tdb->tdb_wnd > 0) && (!(tdb->tdb_flags & TDBF_NOREPLAY))) {
841 		m_copydata(m, skip + offsetof(struct ah, ah_rpl),
842 		    sizeof(u_int32_t), (caddr_t) &btsx);
843 		btsx = ntohl(btsx);
844 
845 		switch (checkreplaywindow32(btsx, 0, &(tdb->tdb_rpl),
846 		    tdb->tdb_wnd, &(tdb->tdb_bitmap), 1)) {
847 		case 0: /* All's well. */
848 #if NPFSYNC > 0
849 			pfsync_update_tdb(tdb,0);
850 #endif
851 			break;
852 
853 		case 1:
854 			DPRINTF(("ah_input(): replay counter wrapped for "
855 			    "SA %s/%08x\n", ipsp_address(tdb->tdb_dst),
856 			    ntohl(tdb->tdb_spi)));
857 
858 			ahstat.ahs_wrap++;
859 			error = ENOBUFS;
860 			goto baddone;
861 
862 		case 2:
863 		case 3:
864 			DPRINTF(("ah_input_cb(): duplicate packet received in "
865 			    "SA %s/%08x\n", ipsp_address(tdb->tdb_dst),
866 			    ntohl(tdb->tdb_spi)));
867 
868 			error = ENOBUFS;
869 			goto baddone;
870 
871 		default:
872 			DPRINTF(("ah_input_cb(): bogus value from "
873 			    "checkreplaywindow32() in SA %s/%08x\n",
874 			    ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
875 
876 			ahstat.ahs_replay++;
877 			error = ENOBUFS;
878 			goto baddone;
879 		}
880 	}
881 
882 	/* Record the beginning of the AH header. */
883 	m1 = m_getptr(m, skip, &roff);
884 	if (m1 == NULL) {
885 		ahstat.ahs_hdrops++;
886 		splx(s);
887 		m_freem(m);
888 
889 		DPRINTF(("ah_input(): bad mbuf chain for packet in SA "
890 		    "%s/%08x\n", ipsp_address(tdb->tdb_dst),
891 		    ntohl(tdb->tdb_spi)));
892 
893 		return EINVAL;
894 	}
895 
896 	/* Remove the AH header from the mbuf. */
897 	if (roff == 0) {
898 		/*
899 		 * The AH header was conveniently at the beginning of
900 		 * the mbuf.
901 		 */
902 		m_adj(m1, rplen + ahx->authsize);
903 		if (!(m1->m_flags & M_PKTHDR))
904 			m->m_pkthdr.len -= rplen + ahx->authsize;
905 	} else
906 		if (roff + rplen + ahx->authsize >= m1->m_len) {
907 			/*
908 			 * Part or all of the AH header is at the end
909 			 * of this mbuf, so first let's remove the
910 			 * remainder of the AH header from the
911 			 * beginning of the remainder of the mbuf
912 			 * chain, if any.
913 			 */
914 			if (roff + rplen + ahx->authsize > m1->m_len) {
915 				/* Adjust the next mbuf by the remainder. */
916 				m_adj(m1->m_next, roff + rplen +
917 				    ahx->authsize - m1->m_len);
918 
919 				/*
920 				 * The second mbuf is guaranteed not
921 				 * to have a pkthdr...
922 				 */
923 				m->m_pkthdr.len -=
924 				    (roff + rplen + ahx->authsize - m1->m_len);
925 			}
926 
927 			/* Now, let's unlink the mbuf chain for a second... */
928 			m0 = m1->m_next;
929 			m1->m_next = NULL;
930 
931 			/*
932 			 * ...and trim the end of the first part of
933 			 * the chain...sick
934 			 */
935 			m_adj(m1, -(m1->m_len - roff));
936 			if (!(m1->m_flags & M_PKTHDR))
937 				m->m_pkthdr.len -= (m1->m_len - roff);
938 
939 			/* Finally, let's relink. */
940 			m1->m_next = m0;
941 		} else {
942 			/*
943 			 * The AH header lies in the "middle" of the
944 			 * mbuf...do an overlapping copy of the
945 			 * remainder of the mbuf over the ESP header.
946 			 */
947 			bcopy(mtod(m1, u_char *) + roff + rplen +
948 			    ahx->authsize, mtod(m1, u_char *) + roff,
949 			    m1->m_len - (roff + rplen + ahx->authsize));
950 			m1->m_len -= rplen + ahx->authsize;
951 			m->m_pkthdr.len -= rplen + ahx->authsize;
952 		}
953 
954 	error = ipsec_common_input_cb(m, tdb, skip, protoff, mtag);
955 	splx(s);
956 	return (error);
957 
958  baddone:
959 	splx(s);
960 
961 	if (m != NULL)
962 		m_freem(m);
963 
964 	if (crp != NULL)
965 		crypto_freereq(crp);
966 
967 	return (error);
968 }
969 
970 /*
971  * AH output routine, called by ipsp_process_packet().
972  */
973 int
974 ah_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int skip,
975     int protoff)
976 {
977 	struct auth_hash *ahx = (struct auth_hash *) tdb->tdb_authalgxform;
978 	struct cryptodesc *crda;
979 	struct tdb_crypto *tc;
980 	struct mbuf *mo, *mi;
981 	struct cryptop *crp;
982 	u_int16_t iplen;
983 	int len, rplen;
984 	u_int8_t prot;
985 	struct ah *ah;
986 #if NBPFILTER > 0
987 	struct ifnet *ifn = &(encif[0].sc_if);
988 
989 	ifn->if_opackets++;
990 	ifn->if_obytes += m->m_pkthdr.len;
991 
992 	if (ifn->if_bpf) {
993 		struct enchdr hdr;
994 
995 		bzero (&hdr, sizeof(hdr));
996 
997 		hdr.af = tdb->tdb_dst.sa.sa_family;
998 		hdr.spi = tdb->tdb_spi;
999 		hdr.flags |= M_AUTH | M_AUTH_AH;
1000 
1001 		bpf_mtap_hdr(ifn->if_bpf, (char *)&hdr, ENC_HDRLEN, m,
1002 		    BPF_DIRECTION_OUT);
1003 	}
1004 #endif
1005 
1006 	ahstat.ahs_output++;
1007 
1008 	/*
1009 	 * Check for replay counter wrap-around in automatic (not
1010 	 * manual) keying.
1011 	 */
1012 	if ((tdb->tdb_rpl == 0) && (tdb->tdb_wnd > 0) &&
1013 	    (!(tdb->tdb_flags & TDBF_NOREPLAY))) {
1014 		DPRINTF(("ah_output(): SA %s/%08x should have expired\n",
1015 		    ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
1016 		m_freem(m);
1017 		ahstat.ahs_wrap++;
1018 		return EINVAL;
1019 	}
1020 
1021 	if (!(tdb->tdb_flags & TDBF_NOREPLAY))
1022 		rplen = AH_FLENGTH + sizeof(u_int32_t);
1023 	else
1024 		rplen = AH_FLENGTH;
1025 
1026 	switch (tdb->tdb_dst.sa.sa_family) {
1027 #ifdef INET
1028 	case AF_INET:
1029 		/* Check for IP maximum packet size violations. */
1030 		if (rplen + ahx->authsize + m->m_pkthdr.len > IP_MAXPACKET) {
1031 			DPRINTF(("ah_output(): packet in SA %s/%08x got too "
1032 			    "big\n",
1033 			    ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
1034 			m_freem(m);
1035 			ahstat.ahs_toobig++;
1036 			return EMSGSIZE;
1037 		}
1038 		break;
1039 #endif /* INET */
1040 
1041 #ifdef INET6
1042 	case AF_INET6:
1043 		/* Check for IPv6 maximum packet size violations. */
1044 		if (rplen + ahx->authsize + m->m_pkthdr.len > IPV6_MAXPACKET) {
1045 			DPRINTF(("ah_output(): packet in SA %s/%08x "
1046 			    "got too big\n", ipsp_address(tdb->tdb_dst),
1047 			    ntohl(tdb->tdb_spi)));
1048 			m_freem(m);
1049 			ahstat.ahs_toobig++;
1050 			return EMSGSIZE;
1051 		}
1052 		break;
1053 #endif /* INET6 */
1054 
1055 	default:
1056 		DPRINTF(("ah_output(): unknown/unsupported protocol "
1057 		    "family %d, SA %s/%08x\n", tdb->tdb_dst.sa.sa_family,
1058 		    ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
1059 		m_freem(m);
1060 		ahstat.ahs_nopf++;
1061 		return EPFNOSUPPORT;
1062 	}
1063 
1064 	/* Update the counters. */
1065 	tdb->tdb_cur_bytes += m->m_pkthdr.len - skip;
1066 	ahstat.ahs_obytes += m->m_pkthdr.len - skip;
1067 
1068 	/* Hard expiration. */
1069 	if (tdb->tdb_flags & TDBF_BYTES &&
1070 	    tdb->tdb_cur_bytes >= tdb->tdb_exp_bytes) {
1071 		pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_HARD);
1072 		tdb_delete(tdb);
1073 		m_freem(m);
1074 		return EINVAL;
1075 	}
1076 
1077 	/* Notify on expiration. */
1078 	if (tdb->tdb_flags & TDBF_SOFT_BYTES &&
1079 	    tdb->tdb_cur_bytes >= tdb->tdb_soft_bytes) {
1080 		pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_SOFT);
1081 		tdb->tdb_flags &= ~TDBF_SOFT_BYTES; /* Turn off checking */
1082 	}
1083 
1084 	/*
1085 	 * Loop through mbuf chain; if we find a readonly mbuf,
1086 	 * replace the rest of the chain.
1087 	 */
1088 	mo = NULL;
1089 	mi = m;
1090 	while (mi != NULL && !M_READONLY(mi)) {
1091 		mo = mi;
1092 		mi = mi->m_next;
1093 	}
1094 
1095 	if (mi != NULL) {
1096 		/* Replace the rest of the mbuf chain. */
1097 		struct mbuf *n = m_copym2(mi, 0, M_COPYALL, M_DONTWAIT);
1098 
1099 		if (n == NULL) {
1100 			ahstat.ahs_hdrops++;
1101 			m_freem(m);
1102 			return ENOBUFS;
1103 		}
1104 
1105 		if (mo != NULL)
1106 			mo->m_next = n;
1107 		else
1108 			m = n;
1109 
1110 		m_freem(mi);
1111 	}
1112 
1113 	/* Inject AH header. */
1114 	mi = m_inject(m, skip, rplen + ahx->authsize, M_DONTWAIT);
1115 	if (mi == NULL) {
1116 		DPRINTF(("ah_output(): failed to inject AH header for SA "
1117 		    "%s/%08x\n", ipsp_address(tdb->tdb_dst),
1118 		    ntohl(tdb->tdb_spi)));
1119 
1120 		m_freem(m);
1121 		ahstat.ahs_hdrops++;
1122 		return ENOBUFS;
1123 	}
1124 
1125 	/*
1126 	 * The AH header is guaranteed by m_inject() to be in
1127 	 * contiguous memory, at the beginning of the returned mbuf.
1128 	 */
1129 	ah = mtod(mi, struct ah *);
1130 
1131 	/* Initialize the AH header. */
1132 	m_copydata(m, protoff, sizeof(u_int8_t), (caddr_t) &ah->ah_nh);
1133 	ah->ah_hl = (rplen + ahx->authsize - AH_FLENGTH) / sizeof(u_int32_t);
1134 	ah->ah_rv = 0;
1135 	ah->ah_spi = tdb->tdb_spi;
1136 
1137 	/* Zeroize authenticator. */
1138 	m_copyback(m, skip + rplen, ahx->authsize, ipseczeroes);
1139 
1140 	if (!(tdb->tdb_flags & TDBF_NOREPLAY)) {
1141 		ah->ah_rpl = htonl(tdb->tdb_rpl++);
1142 #if NPFSYNC > 0
1143 		pfsync_update_tdb(tdb,1);
1144 #endif
1145 	}
1146 
1147 	/* Get crypto descriptors. */
1148 	crp = crypto_getreq(1);
1149 	if (crp == NULL) {
1150 		m_freem(m);
1151 		DPRINTF(("ah_output(): failed to acquire crypto "
1152 		    "descriptors\n"));
1153 		ahstat.ahs_crypto++;
1154 		return ENOBUFS;
1155 	}
1156 
1157 	crda = crp->crp_desc;
1158 
1159 	crda->crd_skip = 0;
1160 	crda->crd_inject = skip + rplen;
1161 	crda->crd_len = m->m_pkthdr.len;
1162 
1163 	/* Authentication operation. */
1164 	crda->crd_alg = ahx->type;
1165 	crda->crd_key = tdb->tdb_amxkey;
1166 	crda->crd_klen = tdb->tdb_amxkeylen * 8;
1167 
1168 	/* Allocate IPsec-specific opaque crypto info. */
1169 	if ((tdb->tdb_flags & TDBF_SKIPCRYPTO) == 0)
1170 		tc = malloc(sizeof(*tc) + skip, M_XDATA, M_NOWAIT | M_ZERO);
1171 	else
1172 		tc = malloc(sizeof(*tc), M_XDATA, M_NOWAIT | M_ZERO);
1173 	if (tc == NULL) {
1174 		m_freem(m);
1175 		crypto_freereq(crp);
1176 		DPRINTF(("ah_output(): failed to allocate tdb_crypto\n"));
1177 		ahstat.ahs_crypto++;
1178 		return ENOBUFS;
1179 	}
1180 
1181 	/* Save the skipped portion of the packet. */
1182 	if ((tdb->tdb_flags & TDBF_SKIPCRYPTO) == 0) {
1183 		m_copydata(m, 0, skip, (caddr_t) (tc + 1));
1184 
1185 		/*
1186 		 * Fix IP header length on the header used for
1187 		 * authentication. We don't need to fix the original
1188 		 * header length as it will be fixed by our caller.
1189 		 */
1190 		switch (tdb->tdb_dst.sa.sa_family) {
1191 #ifdef INET
1192 		case AF_INET:
1193 			bcopy(((caddr_t)(tc + 1)) +
1194 			    offsetof(struct ip, ip_len),
1195 			    (caddr_t) &iplen, sizeof(u_int16_t));
1196 			iplen = htons(ntohs(iplen) + rplen + ahx->authsize);
1197 			m_copyback(m, offsetof(struct ip, ip_len),
1198 			    sizeof(u_int16_t), &iplen);
1199 			break;
1200 #endif /* INET */
1201 
1202 #ifdef INET6
1203 		case AF_INET6:
1204 			bcopy(((caddr_t)(tc + 1)) +
1205 			    offsetof(struct ip6_hdr, ip6_plen),
1206 			    (caddr_t) &iplen, sizeof(u_int16_t));
1207 			iplen = htons(ntohs(iplen) + rplen + ahx->authsize);
1208 			m_copyback(m, offsetof(struct ip6_hdr, ip6_plen),
1209 			    sizeof(u_int16_t), &iplen);
1210 			break;
1211 #endif /* INET6 */
1212 		}
1213 
1214 		/* Fix the Next Header field in saved header. */
1215 		((u_int8_t *) (tc + 1))[protoff] = IPPROTO_AH;
1216 
1217 		/* Update the Next Protocol field in the IP header. */
1218 		prot = IPPROTO_AH;
1219 		m_copyback(m, protoff, sizeof(u_int8_t), &prot);
1220 
1221 		/* "Massage" the packet headers for crypto processing. */
1222 		if ((len = ah_massage_headers(&m, tdb->tdb_dst.sa.sa_family,
1223 		    skip, ahx->type, 1)) != 0) {
1224 			/* mbuf will be free'd by callee. */
1225 			free(tc, M_XDATA);
1226 			crypto_freereq(crp);
1227 			return len;
1228 		}
1229 	} else {
1230 		/* Update the Next Protocol field in the IP header. */
1231 		prot = IPPROTO_AH;
1232 		m_copyback(m, protoff, sizeof(u_int8_t), &prot);
1233 	}
1234 
1235 	/* Crypto operation descriptor. */
1236 	crp->crp_ilen = m->m_pkthdr.len; /* Total input length. */
1237 	crp->crp_flags = CRYPTO_F_IMBUF;
1238 	crp->crp_buf = (caddr_t) m;
1239 	crp->crp_callback = (int (*) (struct cryptop *)) ah_output_cb;
1240 	crp->crp_sid = tdb->tdb_cryptoid;
1241 	crp->crp_opaque = (caddr_t) tc;
1242 
1243 	/* These are passed as-is to the callback. */
1244 	tc->tc_skip = skip;
1245 	tc->tc_protoff = protoff;
1246 	tc->tc_spi = tdb->tdb_spi;
1247 	tc->tc_proto = tdb->tdb_sproto;
1248 	bcopy(&tdb->tdb_dst, &tc->tc_dst, sizeof(union sockaddr_union));
1249 
1250 	if ((tdb->tdb_flags & TDBF_SKIPCRYPTO) == 0)
1251 		return crypto_dispatch(crp);
1252 	else
1253 		return ah_output_cb(crp);
1254 }
1255 
1256 /*
1257  * AH output callback, called directly from the crypto handler.
1258  */
1259 int
1260 ah_output_cb(void *op)
1261 {
1262 	int skip, error;
1263 	struct tdb_crypto *tc;
1264 	struct cryptop *crp;
1265 	struct tdb *tdb;
1266 	struct mbuf *m;
1267 	caddr_t ptr;
1268 	int err, s;
1269 
1270 	crp = (struct cryptop *) op;
1271 	tc = (struct tdb_crypto *) crp->crp_opaque;
1272 	skip = tc->tc_skip;
1273 	ptr = (caddr_t) (tc + 1);
1274 
1275 	m = (struct mbuf *) crp->crp_buf;
1276 	if (m == NULL) {
1277 		/* Shouldn't happen... */
1278 		free(tc, M_XDATA);
1279 		crypto_freereq(crp);
1280 		ahstat.ahs_crypto++;
1281 		DPRINTF(("ah_output_cb(): bogus returned buffer from "
1282 		    "crypto\n"));
1283 		return (EINVAL);
1284 	}
1285 
1286 	s = spltdb();
1287 
1288 	tdb = gettdb(tc->tc_spi, &tc->tc_dst, tc->tc_proto);
1289 	if (tdb == NULL) {
1290 		free(tc, M_XDATA);
1291 		ahstat.ahs_notdb++;
1292 		DPRINTF(("ah_output_cb(): TDB is expired while in crypto\n"));
1293 		error = EPERM;
1294 		goto baddone;
1295 	}
1296 
1297 	/* Check for crypto errors. */
1298 	if (crp->crp_etype) {
1299 		if (crp->crp_etype == EAGAIN) {
1300 			/* Reset the session ID */
1301 			if (tdb->tdb_cryptoid != 0)
1302 				tdb->tdb_cryptoid = crp->crp_sid;
1303 			splx(s);
1304 			return crypto_dispatch(crp);
1305 		}
1306 		free(tc, M_XDATA);
1307 		ahstat.ahs_noxform++;
1308 		DPRINTF(("ah_output_cb(): crypto error %d\n", crp->crp_etype));
1309 		error = crp->crp_etype;
1310 		goto baddone;
1311 	}
1312 
1313 	/*
1314 	 * Copy original headers (with the new protocol number) back
1315 	 * in place.
1316 	 */
1317 	if ((tdb->tdb_flags & TDBF_SKIPCRYPTO) == 0)
1318 		m_copyback(m, 0, skip, ptr);
1319 
1320 	free(tc, M_XDATA);
1321 
1322 	/* No longer needed. */
1323 	crypto_freereq(crp);
1324 
1325 	err =  ipsp_process_done(m, tdb);
1326 	splx(s);
1327 	return err;
1328 
1329  baddone:
1330 	splx(s);
1331 
1332 	if (m != NULL)
1333 		m_freem(m);
1334 
1335 	crypto_freereq(crp);
1336 
1337 	return error;
1338 }
1339