xref: /openbsd/sys/netinet/ip_ah.c (revision fb8de0f1)
1 /*	$OpenBSD: ip_ah.c,v 1.174 2022/05/03 09:18:11 claudio 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/if_var.h>
48 #include <net/bpf.h>
49 
50 #include <netinet/in.h>
51 #include <netinet/ip.h>
52 #include <netinet/ip_var.h>
53 
54 #ifdef INET6
55 #include <netinet/ip6.h>
56 #endif /* INET6 */
57 
58 #include <netinet/ip_ipsp.h>
59 #include <netinet/ip_ah.h>
60 #include <net/pfkeyv2.h>
61 #include <net/if_enc.h>
62 
63 #if NPFSYNC > 0
64 #include <net/pfvar.h>
65 #include <net/if_pfsync.h>
66 #endif /* NPFSYNC > 0 */
67 
68 #include <crypto/cryptodev.h>
69 #include <crypto/xform.h>
70 
71 #include "bpfilter.h"
72 
73 #ifdef ENCDEBUG
74 #define DPRINTF(fmt, args...)						\
75 	do {								\
76 		if (encdebug)						\
77 			printf("%s: " fmt "\n", __func__, ## args);	\
78 	} while (0)
79 #else
80 #define DPRINTF(fmt, args...)						\
81 	do { } while (0)
82 #endif
83 
84 int	ah_massage_headers(struct mbuf **, int, int, int, int);
85 
86 const unsigned char ipseczeroes[IPSEC_ZEROES_SIZE]; /* zeroes! */
87 
88 
89 /*
90  * ah_attach() is called from the transformation initialization code.
91  */
92 int
ah_attach(void)93 ah_attach(void)
94 {
95 	return 0;
96 }
97 
98 /*
99  * ah_init() is called when an SPI is being set up.
100  */
101 int
ah_init(struct tdb * tdbp,const struct xformsw * xsp,struct ipsecinit * ii)102 ah_init(struct tdb *tdbp, const struct xformsw *xsp, struct ipsecinit *ii)
103 {
104 	const struct auth_hash *thash = NULL;
105 	struct cryptoini cria, crin;
106 	int error;
107 
108 	/* Authentication operation. */
109 	switch (ii->ii_authalg) {
110 	case SADB_AALG_MD5HMAC:
111 		thash = &auth_hash_hmac_md5_96;
112 		break;
113 
114 	case SADB_AALG_SHA1HMAC:
115 		thash = &auth_hash_hmac_sha1_96;
116 		break;
117 
118 	case SADB_X_AALG_RIPEMD160HMAC:
119 		thash = &auth_hash_hmac_ripemd_160_96;
120 		break;
121 
122 	case SADB_X_AALG_SHA2_256:
123 		thash = &auth_hash_hmac_sha2_256_128;
124 		break;
125 
126 	case SADB_X_AALG_SHA2_384:
127 		thash = &auth_hash_hmac_sha2_384_192;
128 		break;
129 
130 	case SADB_X_AALG_SHA2_512:
131 		thash = &auth_hash_hmac_sha2_512_256;
132 		break;
133 
134 	default:
135 		DPRINTF("unsupported authentication algorithm %d specified",
136 		    ii->ii_authalg);
137 		return EINVAL;
138 	}
139 
140 	if (ii->ii_authkeylen != thash->keysize && thash->keysize != 0) {
141 		DPRINTF("keylength %d doesn't match algorithm %s keysize (%d)",
142 		    ii->ii_authkeylen, thash->name, thash->keysize);
143 		return EINVAL;
144 	}
145 
146 	tdbp->tdb_xform = xsp;
147 	tdbp->tdb_authalgxform = thash;
148 	tdbp->tdb_rpl = AH_HMAC_INITIAL_RPL;
149 
150 	DPRINTF("initialized TDB with hash algorithm %s", thash->name);
151 
152 	tdbp->tdb_amxkeylen = ii->ii_authkeylen;
153 	tdbp->tdb_amxkey = malloc(tdbp->tdb_amxkeylen, M_XDATA, M_WAITOK);
154 
155 	memcpy(tdbp->tdb_amxkey, ii->ii_authkey, tdbp->tdb_amxkeylen);
156 
157 	/* Initialize crypto session. */
158 	memset(&cria, 0, sizeof(cria));
159 	cria.cri_alg = tdbp->tdb_authalgxform->type;
160 	cria.cri_klen = ii->ii_authkeylen * 8;
161 	cria.cri_key = ii->ii_authkey;
162 
163 	if ((tdbp->tdb_wnd > 0) && (tdbp->tdb_flags & TDBF_ESN)) {
164 		memset(&crin, 0, sizeof(crin));
165 		crin.cri_alg = CRYPTO_ESN;
166 		cria.cri_next = &crin;
167 	}
168 
169 	KERNEL_LOCK();
170 	error = crypto_newsession(&tdbp->tdb_cryptoid, &cria, 0);
171 	KERNEL_UNLOCK();
172 	return error;
173 }
174 
175 /*
176  * Paranoia.
177  */
178 int
ah_zeroize(struct tdb * tdbp)179 ah_zeroize(struct tdb *tdbp)
180 {
181 	int error;
182 
183 	if (tdbp->tdb_amxkey) {
184 		explicit_bzero(tdbp->tdb_amxkey, tdbp->tdb_amxkeylen);
185 		free(tdbp->tdb_amxkey, M_XDATA, tdbp->tdb_amxkeylen);
186 		tdbp->tdb_amxkey = NULL;
187 	}
188 
189 	KERNEL_LOCK();
190 	error = crypto_freesession(tdbp->tdb_cryptoid);
191 	KERNEL_UNLOCK();
192 	tdbp->tdb_cryptoid = 0;
193 	return error;
194 }
195 
196 /*
197  * Massage IPv4/IPv6 headers for AH processing.
198  */
199 int
ah_massage_headers(struct mbuf ** mp,int af,int skip,int alg,int out)200 ah_massage_headers(struct mbuf **mp, int af, int skip, int alg, int out)
201 {
202 	struct mbuf *m = *mp;
203 	unsigned char *ptr;
204 	int off, count, error;
205 	struct ip *ip;
206 #ifdef INET6
207 	struct ip6_ext *ip6e;
208 	struct ip6_hdr ip6;
209 	int ad, alloc, nxt, noff;
210 #endif /* INET6 */
211 
212 	switch (af) {
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 		m = *mp = m_pullup(m, skip);
220 		if (m == NULL) {
221 			DPRINTF("m_pullup() failed");
222 			ahstat_inc(ahs_hdrops);
223 			error = ENOBUFS;
224 			goto drop;
225 		}
226 
227 		/* Fix the IP header */
228 		ip = mtod(m, struct ip *);
229 		ip->ip_tos = 0;
230 		ip->ip_ttl = 0;
231 		ip->ip_sum = 0;
232 		ip->ip_off = 0;
233 
234 		ptr = mtod(m, unsigned char *);
235 
236 		/* IPv4 option processing */
237 		for (off = sizeof(struct ip); off < skip;) {
238 			if (ptr[off] != IPOPT_EOL && ptr[off] != IPOPT_NOP &&
239 			    off + 1 >= skip) {
240 				DPRINTF("illegal IPv4 option length "
241 				    "for option %d",
242 				    ptr[off]);
243 				ahstat_inc(ahs_hdrops);
244 				error = EINVAL;
245 				goto drop;
246 			}
247 
248 			switch (ptr[off]) {
249 			case IPOPT_EOL:
250 				off = skip;  /* End the loop. */
251 				break;
252 
253 			case IPOPT_NOP:
254 				off++;
255 				break;
256 
257 			case IPOPT_SECURITY:	/* 0x82 */
258 			case 0x85:	/* Extended security. */
259 			case 0x86:	/* Commercial security. */
260 			case 0x94:	/* Router alert */
261 			case 0x95:	/* RFC1770 */
262 				/* Sanity check for option length. */
263 				if (ptr[off + 1] < 2) {
264 					DPRINTF("illegal IPv4 option length "
265 					    "for option %d",
266 					    ptr[off]);
267 					ahstat_inc(ahs_hdrops);
268 					error = EINVAL;
269 					goto drop;
270 				}
271 
272 				off += ptr[off + 1];
273 				break;
274 
275 			case IPOPT_LSRR:
276 			case IPOPT_SSRR:
277 				/* Sanity check for option length. */
278 				if (ptr[off + 1] < 2) {
279 					DPRINTF("illegal IPv4 option length "
280 					    "for option %d",
281 					    ptr[off]);
282 					ahstat_inc(ahs_hdrops);
283 					error = EINVAL;
284 					goto drop;
285 				}
286 
287 				/*
288 				 * On output, if we have either of the
289 				 * source routing options, we should
290 				 * swap the destination address of the
291 				 * IP header with the last address
292 				 * specified in the option, as that is
293 				 * what the destination's IP header
294 				 * will look like.
295 				 */
296 				if (out &&
297 				    ptr[off + 1] >= 2 + sizeof(struct in_addr))
298 					memcpy(&ip->ip_dst,
299 					    ptr + off + ptr[off + 1] -
300 					    sizeof(struct in_addr),
301 					    sizeof(struct in_addr));
302 
303 				/* FALLTHROUGH */
304 			default:
305 				/* Sanity check for option length. */
306 				if (ptr[off + 1] < 2) {
307 					DPRINTF("illegal IPv4 option length "
308 					    "for option %d",
309 					    ptr[off]);
310 					ahstat_inc(ahs_hdrops);
311 					error = EINVAL;
312 					goto drop;
313 				}
314 
315 				/* Zeroize all other options. */
316 				count = ptr[off + 1];
317 				memset(ptr + off, 0, count);
318 				off += count;
319 				break;
320 			}
321 
322 			/* Sanity check. */
323 			if (off > skip)	{
324 				DPRINTF("malformed IPv4 options header");
325 				ahstat_inc(ahs_hdrops);
326 				error = EINVAL;
327 				goto drop;
328 			}
329 		}
330 
331 		break;
332 
333 #ifdef INET6
334 	case AF_INET6:  /* Ugly... */
335 		/* Copy and "cook" the IPv6 header. */
336 		m_copydata(m, 0, sizeof(ip6), &ip6);
337 
338 		/* We don't do IPv6 Jumbograms. */
339 		if (ip6.ip6_plen == 0) {
340 			DPRINTF("unsupported IPv6 jumbogram");
341 			ahstat_inc(ahs_hdrops);
342 			error = EMSGSIZE;
343 			goto drop;
344 		}
345 
346 		ip6.ip6_flow = 0;
347 		ip6.ip6_hlim = 0;
348 		ip6.ip6_vfc &= ~IPV6_VERSION_MASK;
349 		ip6.ip6_vfc |= IPV6_VERSION;
350 
351 		/* Scoped address handling. */
352 		if (IN6_IS_SCOPE_EMBED(&ip6.ip6_src))
353 			ip6.ip6_src.s6_addr16[1] = 0;
354 		if (IN6_IS_SCOPE_EMBED(&ip6.ip6_dst))
355 			ip6.ip6_dst.s6_addr16[1] = 0;
356 
357 		/* Done with IPv6 header. */
358 		error = m_copyback(m, 0, sizeof(struct ip6_hdr), &ip6,
359 		    M_NOWAIT);
360 		if (error) {
361 			DPRINTF("m_copyback no memory");
362 			ahstat_inc(ahs_hdrops);
363 			goto drop;
364 		}
365 
366 		/* Let's deal with the remaining headers (if any). */
367 		if (skip - sizeof(struct ip6_hdr) > 0) {
368 			if (m->m_len <= skip) {
369 				ptr = malloc(skip - sizeof(struct ip6_hdr),
370 				    M_XDATA, M_NOWAIT);
371 				if (ptr == NULL) {
372 					DPRINTF("failed to allocate "
373 					    "memory for IPv6 headers");
374 					ahstat_inc(ahs_hdrops);
375 					error = ENOBUFS;
376 					goto drop;
377 				}
378 
379 				/*
380 				 * Copy all the protocol headers after
381 				 * the IPv6 header.
382 				 */
383 				m_copydata(m, sizeof(struct ip6_hdr),
384 				    skip - sizeof(struct ip6_hdr), ptr);
385 				alloc = 1;
386 			} else {
387 				/* No need to allocate memory. */
388 				ptr = mtod(m, unsigned char *) +
389 				    sizeof(struct ip6_hdr);
390 				alloc = 0;
391 			}
392 		} else
393 			break;
394 
395 		nxt = ip6.ip6_nxt;  /* Next header type. */
396 
397 		for (off = 0; off < skip - sizeof(struct ip6_hdr);) {
398 			if (off + sizeof(struct ip6_ext) >
399 			    skip - sizeof(struct ip6_hdr))
400 				goto error6;
401 			ip6e = (struct ip6_ext *)(ptr + off);
402 
403 			switch (nxt) {
404 			case IPPROTO_HOPOPTS:
405 			case IPPROTO_DSTOPTS:
406 				noff = off + ((ip6e->ip6e_len + 1) << 3);
407 
408 				/* Sanity check. */
409 				if (noff > skip - sizeof(struct ip6_hdr))
410 					goto error6;
411 
412 				/*
413 				 * Zero out mutable options.
414 				 */
415 				for (count = off + sizeof(struct ip6_ext);
416 				     count < noff;) {
417 					if (ptr[count] == IP6OPT_PAD1) {
418 						count++;
419 						continue; /* Skip padding. */
420 					}
421 
422 					if (count + 2 > noff)
423 						goto error6;
424 					ad = ptr[count + 1] + 2;
425 					if (count + ad > noff)
426 						goto error6;
427 
428 					/* If mutable option, zeroize. */
429 					if (ptr[count] & IP6OPT_MUTABLE)
430 						memset(ptr + count, 0, ad);
431 
432 					count += ad;
433 				}
434 
435 				if (count != noff)
436 					goto error6;
437 				break;
438 
439 			case IPPROTO_ROUTING:
440 				/*
441 				 * Always include routing headers in
442 				 * computation.
443 				 */
444 			    {
445 				struct ip6_rthdr *rh;
446 
447 				rh = (struct ip6_rthdr *)(ptr + off);
448 				/*
449 				 * must adjust content to make it look like
450 				 * its final form (as seen at the final
451 				 * destination).
452 				 * we only know how to massage type 0 routing
453 				 * header.
454 				 */
455 				if (out && rh->ip6r_type == IPV6_RTHDR_TYPE_0) {
456 					struct ip6_rthdr0 *rh0;
457 					struct in6_addr *addr, finaldst;
458 					int i;
459 
460 					rh0 = (struct ip6_rthdr0 *)rh;
461 					addr = (struct in6_addr *)(rh0 + 1);
462 
463 					for (i = 0; i < rh0->ip6r0_segleft; i++)
464 						if (IN6_IS_SCOPE_EMBED(&addr[i]))
465 							addr[i].s6_addr16[1] = 0;
466 
467 					finaldst = addr[rh0->ip6r0_segleft - 1];
468 					memmove(&addr[1], &addr[0],
469 					    sizeof(struct in6_addr) *
470 					    (rh0->ip6r0_segleft - 1));
471 
472 					m_copydata(m, 0, sizeof(ip6), &ip6);
473 					addr[0] = ip6.ip6_dst;
474 					ip6.ip6_dst = finaldst;
475 					error = m_copyback(m, 0, sizeof(ip6),
476 					    &ip6, M_NOWAIT);
477 					if (error) {
478 						if (alloc)
479 							free(ptr, M_XDATA, 0);
480 						ahstat_inc(ahs_hdrops);
481 						goto drop;
482 					}
483 					rh0->ip6r0_segleft = 0;
484 				}
485 				break;
486 			    }
487 
488 			default:
489 				DPRINTF("unexpected IPv6 header type %d", off);
490 error6:
491 				if (alloc)
492 					free(ptr, M_XDATA, 0);
493 				ahstat_inc(ahs_hdrops);
494 				error = EINVAL;
495 				goto drop;
496 			}
497 
498 			/* Advance. */
499 			off += ((ip6e->ip6e_len + 1) << 3);
500 			nxt = ip6e->ip6e_nxt;
501 		}
502 
503 		/* Copyback and free, if we allocated. */
504 		if (alloc) {
505 			error = m_copyback(m, sizeof(struct ip6_hdr),
506 			    skip - sizeof(struct ip6_hdr), ptr, M_NOWAIT);
507 			free(ptr, M_XDATA, 0);
508 			if (error) {
509 				ahstat_inc(ahs_hdrops);
510 				goto drop;
511 			}
512 		}
513 
514 		break;
515 #endif /* INET6 */
516 	}
517 
518 	return 0;
519 
520  drop:
521 	m_freemp(mp);
522 	return error;
523 }
524 
525 /*
526  * ah_input() gets called to verify that an input packet
527  * passes authentication.
528  */
529 int
ah_input(struct mbuf ** mp,struct tdb * tdb,int skip,int protoff)530 ah_input(struct mbuf **mp, struct tdb *tdb, int skip, int protoff)
531 {
532 	const struct auth_hash *ahx = tdb->tdb_authalgxform;
533 	struct mbuf *m = *mp, *m1, *m0;
534 	struct cryptodesc *crda = NULL;
535 	struct cryptop *crp = NULL;
536 	int roff;
537 	uint32_t btsx, esn;
538 	uint8_t *ptr = NULL;
539 	uint8_t hl;
540 	int error, rplen;
541 	uint64_t ibytes;
542 #ifdef ENCDEBUG
543 	char buf[INET6_ADDRSTRLEN];
544 #endif
545 	uint8_t calc[AH_ALEN_MAX];
546 
547 	rplen = AH_FLENGTH + sizeof(u_int32_t);
548 
549 	/* Save the AH header, we use it throughout. */
550 	m_copydata(m, skip + offsetof(struct ah, ah_hl), sizeof(u_int8_t), &hl);
551 
552 	/* Replay window checking, if applicable. */
553 	if (tdb->tdb_wnd > 0) {
554 		m_copydata(m, skip + offsetof(struct ah, ah_rpl),
555 		    sizeof(u_int32_t), &btsx);
556 		btsx = ntohl(btsx);
557 
558 		switch (checkreplaywindow(tdb, tdb->tdb_rpl, btsx, &esn, 0)) {
559 		case 0: /* All's well. */
560 			break;
561 		case 1:
562 			DPRINTF("replay counter wrapped for SA %s/%08x",
563 			    ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)),
564 			    ntohl(tdb->tdb_spi));
565 			ahstat_inc(ahs_wrap);
566 			goto drop;
567 		case 2:
568 			DPRINTF("old packet received in SA %s/%08x",
569 			    ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)),
570 			    ntohl(tdb->tdb_spi));
571 			ahstat_inc(ahs_replay);
572 			goto drop;
573 		case 3:
574 			DPRINTF("duplicate packet received in SA %s/%08x",
575 			    ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)),
576 			    ntohl(tdb->tdb_spi));
577 			ahstat_inc(ahs_replay);
578 			goto drop;
579 		default:
580 			DPRINTF("bogus value from checkreplaywindow() "
581 			    "in SA %s/%08x",
582 			    ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)),
583 			    ntohl(tdb->tdb_spi));
584 			ahstat_inc(ahs_replay);
585 			goto drop;
586 		}
587 	}
588 
589 	/* Verify AH header length. */
590 	if (hl * sizeof(u_int32_t) != ahx->authsize + rplen - AH_FLENGTH) {
591 		DPRINTF("bad authenticator length %ld for packet in SA %s/%08x",
592 		    hl * sizeof(u_int32_t),
593 		    ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)),
594 		    ntohl(tdb->tdb_spi));
595 		ahstat_inc(ahs_badauthl);
596 		goto drop;
597 	}
598 	if (skip + ahx->authsize + rplen > m->m_pkthdr.len) {
599 		DPRINTF("bad mbuf length %d (expecting %d) for packet "
600 		    "in SA %s/%08x",
601 		    m->m_pkthdr.len, skip + ahx->authsize + rplen,
602 		    ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)),
603 		    ntohl(tdb->tdb_spi));
604 		ahstat_inc(ahs_badauthl);
605 		goto drop;
606 	}
607 
608 	/* Update the counters. */
609 	ibytes = (m->m_pkthdr.len - skip - hl * sizeof(u_int32_t));
610 	tdb->tdb_cur_bytes += ibytes;
611 	tdbstat_add(tdb, tdb_ibytes, ibytes);
612 	ahstat_add(ahs_ibytes, ibytes);
613 
614 	/* Hard expiration. */
615 	if ((tdb->tdb_flags & TDBF_BYTES) &&
616 	    (tdb->tdb_cur_bytes >= tdb->tdb_exp_bytes)) {
617 		ipsecstat_inc(ipsec_exctdb);
618 		pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_HARD);
619 		tdb_delete(tdb);
620 		goto drop;
621 	}
622 
623 	/* Notify on expiration. */
624 	mtx_enter(&tdb->tdb_mtx);
625 	if ((tdb->tdb_flags & TDBF_SOFT_BYTES) &&
626 	    (tdb->tdb_cur_bytes >= tdb->tdb_soft_bytes)) {
627 		tdb->tdb_flags &= ~TDBF_SOFT_BYTES;  /* Turn off checking */
628 		mtx_leave(&tdb->tdb_mtx);
629 		/* may sleep in solock() for the pfkey socket */
630 		pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_SOFT);
631 	} else
632 		mtx_leave(&tdb->tdb_mtx);
633 
634 	/* Get crypto descriptors. */
635 	crp = crypto_getreq(1);
636 	if (crp == NULL) {
637 		DPRINTF("failed to acquire crypto descriptors");
638 		ahstat_inc(ahs_crypto);
639 		goto drop;
640 	}
641 
642 	crda = &crp->crp_desc[0];
643 
644 	crda->crd_skip = 0;
645 	crda->crd_len = m->m_pkthdr.len;
646 	crda->crd_inject = skip + rplen;
647 
648 	/* Authentication operation. */
649 	crda->crd_alg = ahx->type;
650 	crda->crd_key = tdb->tdb_amxkey;
651 	crda->crd_klen = tdb->tdb_amxkeylen * 8;
652 
653 	if ((tdb->tdb_wnd > 0) && (tdb->tdb_flags & TDBF_ESN)) {
654 		esn = htonl(esn);
655 		memcpy(crda->crd_esn, &esn, 4);
656 		crda->crd_flags |= CRD_F_ESN;
657 	}
658 
659 	/* Allocate IPsec-specific opaque crypto info. */
660 	ptr = malloc(skip + rplen + ahx->authsize, M_XDATA, M_NOWAIT | M_ZERO);
661 	if (ptr == NULL) {
662 		DPRINTF("failed to allocate buffer");
663 		ahstat_inc(ahs_crypto);
664 		goto drop;
665 	}
666 
667 	/*
668 	 * Save the authenticator, the skipped portion of the packet,
669 	 * and the AH header.
670 	 */
671 	m_copydata(m, 0, skip + rplen + ahx->authsize, ptr);
672 
673 	/* Zeroize the authenticator on the packet. */
674 	m_copyback(m, skip + rplen, ahx->authsize, ipseczeroes, M_NOWAIT);
675 
676 	/* "Massage" the packet headers for crypto processing. */
677 	error = ah_massage_headers(mp, tdb->tdb_dst.sa.sa_family, skip,
678 	    ahx->type, 0);
679 	/* callee may change or free mbuf */
680 	m = *mp;
681 	if (error)
682 		goto drop;
683 
684 	/* Crypto operation descriptor. */
685 	crp->crp_ilen = m->m_pkthdr.len; /* Total input length. */
686 	crp->crp_flags = CRYPTO_F_IMBUF;
687 	crp->crp_buf = (caddr_t)m;
688 	crp->crp_sid = tdb->tdb_cryptoid;
689 
690 	while ((error = crypto_invoke(crp)) == EAGAIN) {
691 		/* Reset the session ID */
692 		if (tdb->tdb_cryptoid != 0)
693 			tdb->tdb_cryptoid = crp->crp_sid;
694 	}
695 	if (error) {
696 		DPRINTF("crypto error %d", error);
697 		ipsecstat_inc(ipsec_noxform);
698 		goto drop;
699 	}
700 
701 	/* Release the crypto descriptors */
702 	crypto_freereq(crp);
703 	crp = NULL;
704 
705 	/* Copy authenticator off the packet. */
706 	m_copydata(m, skip + rplen, ahx->authsize, calc);
707 
708 	/* Verify authenticator. */
709 	if (timingsafe_bcmp(ptr + skip + rplen, calc, ahx->authsize)) {
710 		DPRINTF("authentication failed for packet in SA %s/%08x",
711 		    ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)),
712 		    ntohl(tdb->tdb_spi));
713 		ahstat_inc(ahs_badauth);
714 		goto drop;
715 	}
716 
717 	/* Fix the Next Protocol field. */
718 	ptr[protoff] = ptr[skip];
719 
720 	/* Copyback the saved (uncooked) network headers. */
721 	m_copyback(m, 0, skip, ptr, M_NOWAIT);
722 
723 	free(ptr, M_XDATA, 0);
724 	ptr = NULL;
725 
726 	/* Replay window checking, if applicable. */
727 	if (tdb->tdb_wnd > 0) {
728 		m_copydata(m, skip + offsetof(struct ah, ah_rpl),
729 		    sizeof(u_int32_t), &btsx);
730 		btsx = ntohl(btsx);
731 
732 		switch (checkreplaywindow(tdb, tdb->tdb_rpl, btsx, &esn, 1)) {
733 		case 0: /* All's well. */
734 #if NPFSYNC > 0
735 			pfsync_update_tdb(tdb,0);
736 #endif
737 			break;
738 		case 1:
739 			DPRINTF("replay counter wrapped for SA %s/%08x",
740 			    ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)),
741 			    ntohl(tdb->tdb_spi));
742 			ahstat_inc(ahs_wrap);
743 			goto drop;
744 		case 2:
745 			DPRINTF("old packet received in SA %s/%08x",
746 			    ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)),
747 			    ntohl(tdb->tdb_spi));
748 			ahstat_inc(ahs_replay);
749 			goto drop;
750 		case 3:
751 			DPRINTF("duplicate packet received in SA %s/%08x",
752 			    ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)),
753 			    ntohl(tdb->tdb_spi));
754 			ahstat_inc(ahs_replay);
755 			goto drop;
756 		default:
757 			DPRINTF("bogus value from checkreplaywindow() "
758 			    "in SA %s/%08x",
759 			    ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)),
760 			    ntohl(tdb->tdb_spi));
761 			ahstat_inc(ahs_replay);
762 			goto drop;
763 		}
764 	}
765 
766 	/* Record the beginning of the AH header. */
767 	m1 = m_getptr(m, skip, &roff);
768 	if (m1 == NULL) {
769 		DPRINTF("bad mbuf chain for packet in SA %s/%08x",
770 		    ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)),
771 		    ntohl(tdb->tdb_spi));
772 		ahstat_inc(ahs_hdrops);
773 		goto drop;
774 	}
775 
776 	/* Remove the AH header from the mbuf. */
777 	if (roff == 0) {
778 		/*
779 		 * The AH header was conveniently at the beginning of
780 		 * the mbuf.
781 		 */
782 		m_adj(m1, rplen + ahx->authsize);
783 		/*
784 		 * If m1 is the first mbuf, it has set M_PKTHDR and m_adj()
785 		 * has already adjusted the packet header length for us.
786 		 */
787 		if (m1 != m)
788 			m->m_pkthdr.len -= rplen + ahx->authsize;
789 	} else
790 		if (roff + rplen + ahx->authsize >= m1->m_len) {
791 			int adjlen;
792 
793 			/*
794 			 * Part or all of the AH header is at the end
795 			 * of this mbuf, so first let's remove the
796 			 * remainder of the AH header from the
797 			 * beginning of the remainder of the mbuf
798 			 * chain, if any.
799 			 */
800 			if (roff + rplen + ahx->authsize > m1->m_len) {
801 				adjlen = roff + rplen + ahx->authsize -
802 				    m1->m_len;
803 				/* Adjust the next mbuf by the remainder. */
804 				m_adj(m1->m_next, adjlen);
805 
806 				/*
807 				 * The second mbuf is guaranteed not
808 				 * to have a pkthdr...
809 				 */
810 				m->m_pkthdr.len -= adjlen;
811 			}
812 
813 			/* Now, let's unlink the mbuf chain for a second... */
814 			m0 = m1->m_next;
815 			m1->m_next = NULL;
816 
817 			/*
818 			 * ...and trim the end of the first part of
819 			 * the chain...sick
820 			 */
821 			adjlen = m1->m_len - roff;
822 			m_adj(m1, -adjlen);
823 			/*
824 			 * If m1 is the first mbuf, it has set M_PKTHDR and
825 			 * m_adj() has already adjusted the packet header len.
826 			 */
827 			if (m1 != m)
828 				m->m_pkthdr.len -= adjlen;
829 
830 			/* Finally, let's relink. */
831 			m1->m_next = m0;
832 		} else {
833 			/*
834 			 * The AH header lies in the "middle" of the
835 			 * mbuf...do an overlapping copy of the
836 			 * remainder of the mbuf over the ESP header.
837 			 */
838 			bcopy(mtod(m1, u_char *) + roff + rplen +
839 			    ahx->authsize, mtod(m1, u_char *) + roff,
840 			    m1->m_len - (roff + rplen + ahx->authsize));
841 			m1->m_len -= rplen + ahx->authsize;
842 			m->m_pkthdr.len -= rplen + ahx->authsize;
843 		}
844 
845 	return ipsec_common_input_cb(mp, tdb, skip, protoff);
846 
847  drop:
848 	free(ptr, M_XDATA, 0);
849 	m_freemp(mp);
850 	crypto_freereq(crp);
851 	return IPPROTO_DONE;
852 }
853 
854 /*
855  * AH output routine, called by ipsp_process_packet().
856  */
857 int
ah_output(struct mbuf * m,struct tdb * tdb,int skip,int protoff)858 ah_output(struct mbuf *m, struct tdb *tdb, int skip, int protoff)
859 {
860 	const struct auth_hash *ahx = tdb->tdb_authalgxform;
861 	struct cryptodesc *crda;
862 	struct mbuf *mi;
863 	struct cryptop *crp = NULL;
864 	uint64_t replay64;
865 	uint16_t iplen;
866 	int error, rplen, roff;
867 	uint8_t *ptr = NULL;
868 	uint8_t prot;
869 	struct ah *ah;
870 #if NBPFILTER > 0
871 	struct ifnet *encif;
872 #ifdef ENCDEBUG
873 	char buf[INET6_ADDRSTRLEN];
874 #endif
875 
876 	if ((encif = enc_getif(tdb->tdb_rdomain, tdb->tdb_tap)) != NULL) {
877 		encif->if_opackets++;
878 		encif->if_obytes += m->m_pkthdr.len;
879 
880 		if (encif->if_bpf) {
881 			struct enchdr hdr;
882 
883 			memset(&hdr, 0, sizeof(hdr));
884 
885 			hdr.af = tdb->tdb_dst.sa.sa_family;
886 			hdr.spi = tdb->tdb_spi;
887 			hdr.flags |= M_AUTH;
888 
889 			bpf_mtap_hdr(encif->if_bpf, (char *)&hdr,
890 			    ENC_HDRLEN, m, BPF_DIRECTION_OUT);
891 		}
892 	}
893 #endif
894 
895 	ahstat_inc(ahs_output);
896 
897 	/*
898 	 * Check for replay counter wrap-around in automatic (not
899 	 * manual) keying.
900 	 */
901 	if ((tdb->tdb_rpl == 0) && (tdb->tdb_wnd > 0)) {
902 		DPRINTF("SA %s/%08x should have expired",
903 		    ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)),
904 		    ntohl(tdb->tdb_spi));
905 		ahstat_inc(ahs_wrap);
906 		error = EINVAL;
907 		goto drop;
908 	}
909 
910 	rplen = AH_FLENGTH + sizeof(u_int32_t);
911 
912 	switch (tdb->tdb_dst.sa.sa_family) {
913 	case AF_INET:
914 		/* Check for IP maximum packet size violations. */
915 		if (rplen + ahx->authsize + m->m_pkthdr.len > IP_MAXPACKET) {
916 			DPRINTF("packet in SA %s/%08x got too big",
917 			    ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)),
918 			    ntohl(tdb->tdb_spi));
919 			ahstat_inc(ahs_toobig);
920 			error = EMSGSIZE;
921 			goto drop;
922 		}
923 		break;
924 
925 #ifdef INET6
926 	case AF_INET6:
927 		/* Check for IPv6 maximum packet size violations. */
928 		if (rplen + ahx->authsize + m->m_pkthdr.len > IPV6_MAXPACKET) {
929 			DPRINTF("packet in SA %s/%08x got too big",
930 			    ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)),
931 			    ntohl(tdb->tdb_spi));
932 			ahstat_inc(ahs_toobig);
933 			error = EMSGSIZE;
934 			goto drop;
935 		}
936 		break;
937 #endif /* INET6 */
938 
939 	default:
940 		DPRINTF("unknown/unsupported protocol family %d, SA %s/%08x",
941 		    tdb->tdb_dst.sa.sa_family,
942 		    ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)),
943 		    ntohl(tdb->tdb_spi));
944 		ahstat_inc(ahs_nopf);
945 		error = EPFNOSUPPORT;
946 		goto drop;
947 	}
948 
949 	/* Update the counters. */
950 	tdb->tdb_cur_bytes += m->m_pkthdr.len - skip;
951 	ahstat_add(ahs_obytes, m->m_pkthdr.len - skip);
952 
953 	/* Hard expiration. */
954 	if ((tdb->tdb_flags & TDBF_BYTES) &&
955 	    (tdb->tdb_cur_bytes >= tdb->tdb_exp_bytes)) {
956 		ipsecstat_inc(ipsec_exctdb);
957 		pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_HARD);
958 		tdb_delete(tdb);
959 		error = EINVAL;
960 		goto drop;
961 	}
962 
963 	/* Notify on expiration. */
964 	mtx_enter(&tdb->tdb_mtx);
965 	if ((tdb->tdb_flags & TDBF_SOFT_BYTES) &&
966 	    (tdb->tdb_cur_bytes >= tdb->tdb_soft_bytes)) {
967 		tdb->tdb_flags &= ~TDBF_SOFT_BYTES;  /* Turn off checking */
968 		mtx_leave(&tdb->tdb_mtx);
969 		/* may sleep in solock() for the pfkey socket */
970 		pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_SOFT);
971 	} else
972 		mtx_leave(&tdb->tdb_mtx);
973 
974 	/*
975 	 * Loop through mbuf chain; if we find a readonly mbuf,
976 	 * copy the packet.
977 	 */
978 	mi = m;
979 	while (mi != NULL && !M_READONLY(mi))
980 		mi = mi->m_next;
981 
982 	if (mi != NULL) {
983 		struct mbuf *n = m_dup_pkt(m, 0, M_DONTWAIT);
984 
985 		if (n == NULL) {
986 			ahstat_inc(ahs_hdrops);
987 			error = ENOBUFS;
988 			goto drop;
989 		}
990 
991 		m_freem(m);
992 		m = n;
993 	}
994 
995 	/* Inject AH header. */
996 	mi = m_makespace(m, skip, rplen + ahx->authsize, &roff);
997 	if (mi == NULL) {
998 		DPRINTF("failed to inject AH header for SA %s/%08x",
999 		    ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)),
1000 		    ntohl(tdb->tdb_spi));
1001 		ahstat_inc(ahs_hdrops);
1002 		error = ENOBUFS;
1003 		goto drop;
1004 	}
1005 
1006 	/*
1007 	 * The AH header is guaranteed by m_makespace() to be in
1008 	 * contiguous memory, at 'roff' of the returned mbuf.
1009 	 */
1010 	ah = (struct ah *)(mtod(mi, caddr_t) + roff);
1011 
1012 	/* Initialize the AH header. */
1013 	m_copydata(m, protoff, sizeof(u_int8_t), &ah->ah_nh);
1014 	ah->ah_hl = (rplen + ahx->authsize - AH_FLENGTH) / sizeof(u_int32_t);
1015 	ah->ah_rv = 0;
1016 	ah->ah_spi = tdb->tdb_spi;
1017 
1018 	/* Zeroize authenticator. */
1019 	m_copyback(m, skip + rplen, ahx->authsize, ipseczeroes, M_NOWAIT);
1020 
1021 	replay64 = tdb->tdb_rpl++;
1022 	ah->ah_rpl = htonl((u_int32_t)replay64);
1023 #if NPFSYNC > 0
1024 	pfsync_update_tdb(tdb,1);
1025 #endif
1026 
1027 	/* Get crypto descriptors. */
1028 	crp = crypto_getreq(1);
1029 	if (crp == NULL) {
1030 		DPRINTF("failed to acquire crypto descriptors");
1031 		ahstat_inc(ahs_crypto);
1032 		error = ENOBUFS;
1033 		goto drop;
1034 	}
1035 
1036 	crda = &crp->crp_desc[0];
1037 
1038 	crda->crd_skip = 0;
1039 	crda->crd_inject = skip + rplen;
1040 	crda->crd_len = m->m_pkthdr.len;
1041 
1042 	/* Authentication operation. */
1043 	crda->crd_alg = ahx->type;
1044 	crda->crd_key = tdb->tdb_amxkey;
1045 	crda->crd_klen = tdb->tdb_amxkeylen * 8;
1046 
1047 	if ((tdb->tdb_wnd > 0) && (tdb->tdb_flags & TDBF_ESN)) {
1048 		u_int32_t esn;
1049 
1050 		esn = htonl((u_int32_t)(replay64 >> 32));
1051 		memcpy(crda->crd_esn, &esn, 4);
1052 		crda->crd_flags |= CRD_F_ESN;
1053 	}
1054 
1055 	ptr = malloc(skip, M_XDATA, M_NOWAIT | M_ZERO);
1056 	if (ptr == NULL) {
1057 		DPRINTF("failed to allocate buffer");
1058 		ahstat_inc(ahs_crypto);
1059 		error = ENOBUFS;
1060 		goto drop;
1061 	}
1062 
1063 	/* Save the skipped portion of the packet. */
1064 	m_copydata(m, 0, skip, ptr);
1065 
1066 	/*
1067 	 * Fix IP header length on the header used for
1068 	 * authentication. We don't need to fix the original
1069 	 * header length as it will be fixed by our caller.
1070 	 */
1071 	switch (tdb->tdb_dst.sa.sa_family) {
1072 	case AF_INET:
1073 		memcpy((caddr_t) &iplen, ((caddr_t)ptr) +
1074 		    offsetof(struct ip, ip_len), sizeof(u_int16_t));
1075 		iplen = htons(ntohs(iplen) + rplen + ahx->authsize);
1076 		m_copyback(m, offsetof(struct ip, ip_len),
1077 		    sizeof(u_int16_t), &iplen, M_NOWAIT);
1078 		break;
1079 
1080 #ifdef INET6
1081 	case AF_INET6:
1082 		memcpy((caddr_t) &iplen, ((caddr_t)ptr) +
1083 		    offsetof(struct ip6_hdr, ip6_plen), sizeof(u_int16_t));
1084 		iplen = htons(ntohs(iplen) + rplen + ahx->authsize);
1085 		m_copyback(m, offsetof(struct ip6_hdr, ip6_plen),
1086 		    sizeof(u_int16_t), &iplen, M_NOWAIT);
1087 		break;
1088 #endif /* INET6 */
1089 	}
1090 
1091 	/* Fix the Next Header field in saved header. */
1092 	ptr[protoff] = IPPROTO_AH;
1093 
1094 	/* Update the Next Protocol field in the IP header. */
1095 	prot = IPPROTO_AH;
1096 	m_copyback(m, protoff, sizeof(u_int8_t), &prot, M_NOWAIT);
1097 
1098 	/* "Massage" the packet headers for crypto processing. */
1099 	error = ah_massage_headers(&m, tdb->tdb_dst.sa.sa_family, skip,
1100 	    ahx->type, 1);
1101 	if (error) {
1102 		/* mbuf was freed by callee. */
1103 		m = NULL;
1104 		goto drop;
1105 	}
1106 
1107 	/* Crypto operation descriptor. */
1108 	crp->crp_ilen = m->m_pkthdr.len; /* Total input length. */
1109 	crp->crp_flags = CRYPTO_F_IMBUF;
1110 	crp->crp_buf = (caddr_t)m;
1111 	crp->crp_sid = tdb->tdb_cryptoid;
1112 
1113 	while ((error = crypto_invoke(crp)) == EAGAIN) {
1114 		/* Reset the session ID */
1115 		if (tdb->tdb_cryptoid != 0)
1116 			tdb->tdb_cryptoid = crp->crp_sid;
1117 	}
1118 	if (error) {
1119 		DPRINTF("crypto error %d", error);
1120 		ipsecstat_inc(ipsec_noxform);
1121 		goto drop;
1122 	}
1123 
1124 	/* Release the crypto descriptors */
1125 	crypto_freereq(crp);
1126 	crp = NULL;
1127 
1128 	/*
1129 	 * Copy original headers (with the new protocol number) back
1130 	 * in place.
1131 	 */
1132 	m_copyback(m, 0, skip, ptr, M_NOWAIT);
1133 	free(ptr, M_XDATA, 0);
1134 	ptr = NULL;
1135 
1136 	/* Call the IPsec input callback. */
1137 	error = ipsp_process_done(m, tdb);
1138 	if (error)
1139 		ahstat_inc(ahs_outfail);
1140 	return error;
1141 
1142  drop:
1143 	free(ptr, M_XDATA, 0);
1144 	m_freem(m);
1145 	crypto_freereq(crp);
1146 	return error;
1147 }
1148