xref: /openbsd-src/sys/netinet/ip_esp.c (revision 4c1e55dc91edd6e69ccc60ce855900fbc12cf34f)
1 /*	$OpenBSD: ip_esp.c,v 1.117 2012/06/29 14:48:04 mikeb 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.
17  *
18  * Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
19  * Angelos D. Keromytis and Niels Provos.
20  * Copyright (c) 2001 Angelos D. Keromytis.
21  *
22  * Permission to use, copy, and modify this software with or without fee
23  * is hereby granted, provided that this entire notice is included in
24  * all copies of any software which is or includes a copy or
25  * modification of this software.
26  * You may use this code under the GNU public license if you so wish. Please
27  * contribute changes back to the authors under this freer than GPL license
28  * so that we may further the use of strong encryption without limitations to
29  * all.
30  *
31  * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
32  * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
33  * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
34  * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
35  * PURPOSE.
36  */
37 
38 #include "pfsync.h"
39 
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/mbuf.h>
43 #include <sys/socket.h>
44 
45 #include <net/if.h>
46 #include <net/bpf.h>
47 
48 #include <dev/rndvar.h>
49 
50 #ifdef INET
51 #include <netinet/in.h>
52 #include <netinet/in_systm.h>
53 #include <netinet/ip.h>
54 #include <netinet/ip_var.h>
55 #endif /* INET */
56 
57 #ifdef INET6
58 #ifndef INET
59 #include <netinet/in.h>
60 #endif
61 #include <netinet/ip6.h>
62 #endif /* INET6 */
63 
64 #include <netinet/ip_ipsp.h>
65 #include <netinet/ip_esp.h>
66 #include <net/pfkeyv2.h>
67 #include <net/if_enc.h>
68 
69 #if NPFSYNC > 0
70 #include <net/pfvar.h>
71 #include <net/if_pfsync.h>
72 #endif /* NPFSYNC > 0 */
73 
74 #include <crypto/cryptodev.h>
75 #include <crypto/xform.h>
76 
77 #include "bpfilter.h"
78 
79 #ifdef ENCDEBUG
80 #define DPRINTF(x)	if (encdebug) printf x
81 #else
82 #define DPRINTF(x)
83 #endif
84 
85 struct espstat espstat;
86 
87 /*
88  * esp_attach() is called from the transformation initialization code.
89  */
90 int
91 esp_attach()
92 {
93 	return 0;
94 }
95 
96 /*
97  * esp_init() is called when an SPI is being set up.
98  */
99 int
100 esp_init(struct tdb *tdbp, struct xformsw *xsp, struct ipsecinit *ii)
101 {
102 	struct enc_xform *txform = NULL;
103 	struct auth_hash *thash = NULL;
104 	struct cryptoini cria, crie, crin;
105 
106 	if (!ii->ii_encalg && !ii->ii_authalg) {
107 		DPRINTF(("esp_init(): neither authentication nor encryption "
108 		    "algorithm given"));
109 		return EINVAL;
110 	}
111 
112 	if (ii->ii_encalg) {
113 		switch (ii->ii_encalg) {
114 		case SADB_EALG_NULL:
115 			txform = &enc_xform_null;
116 			break;
117 
118 		case SADB_EALG_DESCBC:
119 			txform = &enc_xform_des;
120 			break;
121 
122 		case SADB_EALG_3DESCBC:
123 			txform = &enc_xform_3des;
124 			break;
125 
126 		case SADB_X_EALG_AES:
127 			txform = &enc_xform_rijndael128;
128 			break;
129 
130 		case SADB_X_EALG_AESCTR:
131 			txform = &enc_xform_aes_ctr;
132 			break;
133 
134 		case SADB_X_EALG_AESGCM16:
135 			txform = &enc_xform_aes_gcm;
136 			break;
137 
138 		case SADB_X_EALG_AESGMAC:
139 			txform = &enc_xform_aes_gmac;
140 			break;
141 
142 		case SADB_X_EALG_BLF:
143 			txform = &enc_xform_blf;
144 			break;
145 
146 		case SADB_X_EALG_CAST:
147 			txform = &enc_xform_cast5;
148 			break;
149 
150 		default:
151 			DPRINTF(("esp_init(): unsupported encryption algorithm %d specified\n", ii->ii_encalg));
152 			return EINVAL;
153 		}
154 
155 		if (ii->ii_enckeylen < txform->minkey) {
156 			DPRINTF(("esp_init(): keylength %d too small (min length is %d) for algorithm %s\n", ii->ii_enckeylen, txform->minkey, txform->name));
157 			return EINVAL;
158 		}
159 
160 		if (ii->ii_enckeylen > txform->maxkey) {
161 			DPRINTF(("esp_init(): keylength %d too large (max length is %d) for algorithm %s\n", ii->ii_enckeylen, txform->maxkey, txform->name));
162 			return EINVAL;
163 		}
164 
165 		if (ii->ii_encalg == SADB_X_EALG_AESGCM16 ||
166 		    ii->ii_encalg == SADB_X_EALG_AESGMAC) {
167 			switch (ii->ii_enckeylen) {
168 			case 20:
169 				ii->ii_authalg = SADB_X_AALG_AES128GMAC;
170 				break;
171 			case 28:
172 				ii->ii_authalg = SADB_X_AALG_AES192GMAC;
173 				break;
174 			case 36:
175 				ii->ii_authalg = SADB_X_AALG_AES256GMAC;
176 				break;
177 			}
178 			ii->ii_authkeylen = ii->ii_enckeylen;
179 			ii->ii_authkey = ii->ii_enckey;
180 		}
181 
182 		tdbp->tdb_encalgxform = txform;
183 
184 		DPRINTF(("esp_init(): initialized TDB with enc algorithm %s\n",
185 		    txform->name));
186 
187 		tdbp->tdb_ivlen = txform->ivsize;
188 		if (tdbp->tdb_flags & TDBF_HALFIV)
189 			tdbp->tdb_ivlen /= 2;
190 	}
191 
192 	if (ii->ii_authalg) {
193 		switch (ii->ii_authalg) {
194 		case SADB_AALG_MD5HMAC:
195 			thash = &auth_hash_hmac_md5_96;
196 			break;
197 
198 		case SADB_AALG_SHA1HMAC:
199 			thash = &auth_hash_hmac_sha1_96;
200 			break;
201 
202 		case SADB_X_AALG_RIPEMD160HMAC:
203 			thash = &auth_hash_hmac_ripemd_160_96;
204 			break;
205 
206 		case SADB_X_AALG_SHA2_256:
207 			thash = &auth_hash_hmac_sha2_256_128;
208 			break;
209 
210 		case SADB_X_AALG_SHA2_384:
211 			thash = &auth_hash_hmac_sha2_384_192;
212 			break;
213 
214 		case SADB_X_AALG_SHA2_512:
215 			thash = &auth_hash_hmac_sha2_512_256;
216 			break;
217 
218 		case SADB_X_AALG_AES128GMAC:
219 			thash = &auth_hash_gmac_aes_128;
220 			break;
221 
222 		case SADB_X_AALG_AES192GMAC:
223 			thash = &auth_hash_gmac_aes_192;
224 			break;
225 
226 		case SADB_X_AALG_AES256GMAC:
227 			thash = &auth_hash_gmac_aes_256;
228 			break;
229 
230 		default:
231 			DPRINTF(("esp_init(): unsupported authentication algorithm %d specified\n", ii->ii_authalg));
232 			return EINVAL;
233 		}
234 
235 		if (ii->ii_authkeylen != thash->keysize) {
236 			DPRINTF(("esp_init(): keylength %d doesn't match algorithm %s keysize (%d)\n", ii->ii_authkeylen, thash->name, thash->keysize));
237 			return EINVAL;
238 		}
239 
240 		tdbp->tdb_authalgxform = thash;
241 
242 		DPRINTF(("esp_init(): initialized TDB with hash algorithm %s\n",
243 		    thash->name));
244 	}
245 
246 	tdbp->tdb_xform = xsp;
247 	tdbp->tdb_bitmap = 0;
248 	tdbp->tdb_rpl = AH_HMAC_INITIAL_RPL;
249 
250 	/* Initialize crypto session */
251 	if (tdbp->tdb_encalgxform) {
252 		/* Save the raw keys */
253 		tdbp->tdb_emxkeylen = ii->ii_enckeylen;
254 		tdbp->tdb_emxkey = malloc(tdbp->tdb_emxkeylen, M_XDATA,
255 		    M_WAITOK);
256 		bcopy(ii->ii_enckey, tdbp->tdb_emxkey, tdbp->tdb_emxkeylen);
257 
258 		bzero(&crie, sizeof(crie));
259 
260 		crie.cri_alg = tdbp->tdb_encalgxform->type;
261 
262 		if (tdbp->tdb_authalgxform)
263 			crie.cri_next = &cria;
264 		else
265 			crie.cri_next = NULL;
266 
267 		crie.cri_klen = ii->ii_enckeylen * 8;
268 		crie.cri_key = ii->ii_enckey;
269 		/* XXX Rounds ? */
270 	}
271 
272 	if (tdbp->tdb_authalgxform) {
273 		/* Save the raw keys */
274 		tdbp->tdb_amxkeylen = ii->ii_authkeylen;
275 		tdbp->tdb_amxkey = malloc(tdbp->tdb_amxkeylen, M_XDATA,
276 		    M_WAITOK);
277 		bcopy(ii->ii_authkey, tdbp->tdb_amxkey, tdbp->tdb_amxkeylen);
278 
279 		bzero(&cria, sizeof(cria));
280 
281 		cria.cri_alg = tdbp->tdb_authalgxform->type;
282 
283 		if ((tdbp->tdb_wnd > 0) && !(tdbp->tdb_flags & TDBF_NOREPLAY) &&
284 		    (tdbp->tdb_flags & TDBF_ESN)) {
285 			bzero(&crin, sizeof(crin));
286 			crin.cri_alg = CRYPTO_ESN;
287 			cria.cri_next = &crin;
288 		}
289 
290 		cria.cri_klen = ii->ii_authkeylen * 8;
291 		cria.cri_key = ii->ii_authkey;
292 	}
293 
294 	return crypto_newsession(&tdbp->tdb_cryptoid,
295 	    (tdbp->tdb_encalgxform ? &crie : &cria), 0);
296 }
297 
298 /*
299  * Paranoia.
300  */
301 int
302 esp_zeroize(struct tdb *tdbp)
303 {
304 	int err;
305 
306 	if (tdbp->tdb_amxkey) {
307 		explicit_bzero(tdbp->tdb_amxkey, tdbp->tdb_amxkeylen);
308 		free(tdbp->tdb_amxkey, M_XDATA);
309 		tdbp->tdb_amxkey = NULL;
310 	}
311 
312 	if (tdbp->tdb_emxkey) {
313 		explicit_bzero(tdbp->tdb_emxkey, tdbp->tdb_emxkeylen);
314 		free(tdbp->tdb_emxkey, M_XDATA);
315 		tdbp->tdb_emxkey = NULL;
316 	}
317 
318 	err = crypto_freesession(tdbp->tdb_cryptoid);
319 	tdbp->tdb_cryptoid = 0;
320 	return err;
321 }
322 
323 #define MAXBUFSIZ (AH_ALEN_MAX > ESP_MAX_IVS ? AH_ALEN_MAX : ESP_MAX_IVS)
324 
325 /*
326  * ESP input processing, called (eventually) through the protocol switch.
327  */
328 int
329 esp_input(struct mbuf *m, struct tdb *tdb, int skip, int protoff)
330 {
331 	struct auth_hash *esph = (struct auth_hash *) tdb->tdb_authalgxform;
332 	struct enc_xform *espx = (struct enc_xform *) tdb->tdb_encalgxform;
333 	struct cryptodesc *crde = NULL, *crda = NULL;
334 	struct cryptop *crp;
335 	struct tdb_crypto *tc;
336 	int plen, alen, hlen;
337 	struct m_tag *mtag;
338 	u_int32_t btsx, esn;
339 
340 	/* Determine the ESP header length */
341 	if (tdb->tdb_flags & TDBF_NOREPLAY)
342 		hlen = sizeof(u_int32_t) + tdb->tdb_ivlen; /* "old" ESP */
343 	else
344 		hlen = 2 * sizeof(u_int32_t) + tdb->tdb_ivlen; /* "new" ESP */
345 
346 	alen = esph ? esph->authsize : 0;
347 	plen = m->m_pkthdr.len - (skip + hlen + alen);
348 	if (plen <= 0) {
349 		DPRINTF(("esp_input: invalid payload length\n"));
350 		espstat.esps_badilen++;
351 		m_freem(m);
352 		return EINVAL;
353 	}
354 
355 	if (espx) {
356 		/*
357 		 * Verify payload length is multiple of encryption algorithm
358 		 * block size.
359 		 */
360 		if (plen & (espx->blocksize - 1)) {
361 			DPRINTF(("esp_input(): payload of %d octets not a multiple of %d octets, SA %s/%08x\n", plen, espx->blocksize, ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
362 			espstat.esps_badilen++;
363 			m_freem(m);
364 			return EINVAL;
365 		}
366 	}
367 
368 	/* Replay window checking, if appropriate -- no value commitment. */
369 	if ((tdb->tdb_wnd > 0) && (!(tdb->tdb_flags & TDBF_NOREPLAY))) {
370 		m_copydata(m, skip + sizeof(u_int32_t), sizeof(u_int32_t),
371 		    (unsigned char *) &btsx);
372 		btsx = ntohl(btsx);
373 
374 		switch (checkreplaywindow(btsx, &tdb->tdb_rpl, tdb->tdb_wnd,
375 		    &tdb->tdb_bitmap, &esn, tdb->tdb_flags & TDBF_ESN, 0)) {
376 		case 0: /* All's well */
377 			break;
378 
379 		case 1:
380 			m_freem(m);
381 			DPRINTF(("esp_input(): replay counter wrapped for SA %s/%08x\n", ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
382 			espstat.esps_wrap++;
383 			return EACCES;
384 
385 		case 2:
386 		case 3:
387 			DPRINTF(("esp_input(): duplicate packet received in SA %s/%08x\n", ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
388 			m_freem(m);
389 			espstat.esps_replay++;
390 			return EACCES;
391 
392 		default:
393 			m_freem(m);
394 			DPRINTF(("esp_input(): bogus value from checkreplaywindow() in SA %s/%08x\n", ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
395 			return EACCES;
396 		}
397 	}
398 
399 	/* Update the counters */
400 	tdb->tdb_cur_bytes += m->m_pkthdr.len - skip - hlen - alen;
401 	espstat.esps_ibytes += m->m_pkthdr.len - skip - hlen - alen;
402 
403 	/* Hard expiration */
404 	if ((tdb->tdb_flags & TDBF_BYTES) &&
405 	    (tdb->tdb_cur_bytes >= tdb->tdb_exp_bytes))	{
406 		pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_HARD);
407 		tdb_delete(tdb);
408 		m_freem(m);
409 		return ENXIO;
410 	}
411 
412 	/* Notify on soft expiration */
413 	if ((tdb->tdb_flags & TDBF_SOFT_BYTES) &&
414 	    (tdb->tdb_cur_bytes >= tdb->tdb_soft_bytes)) {
415 		pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_SOFT);
416 		tdb->tdb_flags &= ~TDBF_SOFT_BYTES;       /* Turn off checking */
417 	}
418 
419 #ifdef notyet
420 	/* Find out if we've already done crypto */
421 	for (mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_CRYPTO_DONE, NULL);
422 	     mtag != NULL;
423 	     mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_CRYPTO_DONE, mtag)) {
424 		struct tdb_ident *tdbi;
425 
426 		tdbi = (struct tdb_ident *) (mtag + 1);
427 		if (tdbi->proto == tdb->tdb_sproto && tdbi->spi == tdb->tdb_spi &&
428 		    tdbi->rdomain == tdb->tdb_rdomain && !bcmp(&tdbi->dst,
429 		    &tdb->tdb_dst, sizeof(union sockaddr_union)))
430 			break;
431 	}
432 #else
433 	mtag = NULL;
434 #endif
435 
436 	/* Get crypto descriptors */
437 	crp = crypto_getreq(esph && espx ? 2 : 1);
438 	if (crp == NULL) {
439 		m_freem(m);
440 		DPRINTF(("esp_input(): failed to acquire crypto descriptors\n"));
441 		espstat.esps_crypto++;
442 		return ENOBUFS;
443 	}
444 
445 	/* Get IPsec-specific opaque pointer */
446 	if (esph == NULL || mtag != NULL)
447 		tc = malloc(sizeof(*tc), M_XDATA, M_NOWAIT | M_ZERO);
448 	else
449 		tc = malloc(sizeof(*tc) + alen, M_XDATA, M_NOWAIT | M_ZERO);
450 	if (tc == NULL)	{
451 		m_freem(m);
452 		crypto_freereq(crp);
453 		DPRINTF(("esp_input(): failed to allocate tdb_crypto\n"));
454 		espstat.esps_crypto++;
455 		return ENOBUFS;
456 	}
457 
458 	tc->tc_ptr = (caddr_t) mtag;
459 
460 	if (esph) {
461 		crda = crp->crp_desc;
462 		crde = crda->crd_next;
463 
464 		/* Authentication descriptor */
465 		crda->crd_skip = skip;
466 		crda->crd_inject = m->m_pkthdr.len - alen;
467 
468 		crda->crd_alg = esph->type;
469 		crda->crd_key = tdb->tdb_amxkey;
470 		crda->crd_klen = tdb->tdb_amxkeylen * 8;
471 
472 		if ((tdb->tdb_wnd > 0) && !(tdb->tdb_flags & TDBF_NOREPLAY) &&
473 		    (tdb->tdb_flags & TDBF_ESN)) {
474 			esn = htonl(esn);
475 			bcopy(&esn, crda->crd_esn, 4);
476 			crda->crd_flags |= CRD_F_ESN;
477 		}
478 
479 		if (espx && espx->type == CRYPTO_AES_GCM_16)
480 			crda->crd_len = hlen - tdb->tdb_ivlen;
481 		else
482 			crda->crd_len = m->m_pkthdr.len - (skip + alen);
483 
484 		/* Copy the authenticator */
485 		if (mtag == NULL)
486 			m_copydata(m, m->m_pkthdr.len - alen, alen, (caddr_t) (tc + 1));
487 	} else
488 		crde = crp->crp_desc;
489 
490 	/* Crypto operation descriptor */
491 	crp->crp_ilen = m->m_pkthdr.len; /* Total input length */
492 	crp->crp_flags = CRYPTO_F_IMBUF;
493 	crp->crp_buf = (caddr_t) m;
494 	crp->crp_callback = (int (*) (struct cryptop *)) esp_input_cb;
495 	crp->crp_sid = tdb->tdb_cryptoid;
496 	crp->crp_opaque = (caddr_t) tc;
497 
498 	/* These are passed as-is to the callback */
499 	tc->tc_skip = skip;
500 	tc->tc_protoff = protoff;
501 	tc->tc_spi = tdb->tdb_spi;
502 	tc->tc_proto = tdb->tdb_sproto;
503 	tc->tc_rdomain = tdb->tdb_rdomain;
504 	bcopy(&tdb->tdb_dst, &tc->tc_dst, sizeof(union sockaddr_union));
505 
506 	/* Decryption descriptor */
507 	if (espx) {
508 		crde->crd_skip = skip + hlen;
509 		crde->crd_inject = skip + hlen - tdb->tdb_ivlen;
510 
511 		if (tdb->tdb_flags & TDBF_HALFIV) {
512 			/* Copy half-IV from packet */
513 			m_copydata(m, crde->crd_inject, tdb->tdb_ivlen, crde->crd_iv);
514 
515 			/* Cook IV */
516 			for (btsx = 0; btsx < tdb->tdb_ivlen; btsx++)
517 				crde->crd_iv[tdb->tdb_ivlen + btsx] = ~crde->crd_iv[btsx];
518 
519 			crde->crd_flags |= CRD_F_IV_EXPLICIT;
520 		}
521 
522 		crde->crd_alg = espx->type;
523 		crde->crd_key = tdb->tdb_emxkey;
524 		crde->crd_klen = tdb->tdb_emxkeylen * 8;
525 		/* XXX Rounds ? */
526 
527 		if (crde->crd_alg == CRYPTO_AES_GMAC)
528 			crde->crd_len = 0;
529 		else
530 			crde->crd_len = m->m_pkthdr.len - (skip + hlen + alen);
531 	}
532 
533 	if (mtag == NULL)
534 		return crypto_dispatch(crp);
535 	else
536 		return esp_input_cb(crp);
537 }
538 
539 /*
540  * ESP input callback, called directly by the crypto driver.
541  */
542 int
543 esp_input_cb(void *op)
544 {
545 	u_int8_t lastthree[3], aalg[AH_HMAC_MAX_HASHLEN];
546 	int s, hlen, roff, skip, protoff, error;
547 	struct mbuf *m1, *mo, *m;
548 	struct auth_hash *esph;
549 	struct tdb_crypto *tc;
550 	struct cryptop *crp;
551 	struct m_tag *mtag;
552 	struct tdb *tdb;
553 	u_int32_t btsx, esn;
554 	caddr_t ptr;
555 
556 	crp = (struct cryptop *) op;
557 
558 	tc = (struct tdb_crypto *) crp->crp_opaque;
559 	skip = tc->tc_skip;
560 	protoff = tc->tc_protoff;
561 	mtag = (struct m_tag *) tc->tc_ptr;
562 
563 	m = (struct mbuf *) crp->crp_buf;
564 	if (m == NULL) {
565 		/* Shouldn't happen... */
566 		free(tc, M_XDATA);
567 		crypto_freereq(crp);
568 		espstat.esps_crypto++;
569 		DPRINTF(("esp_input_cb(): bogus returned buffer from crypto\n"));
570 		return (EINVAL);
571 	}
572 
573 	s = spltdb();
574 
575 	tdb = gettdb(tc->tc_rdomain, tc->tc_spi, &tc->tc_dst, tc->tc_proto);
576 	if (tdb == NULL) {
577 		free(tc, M_XDATA);
578 		espstat.esps_notdb++;
579 		DPRINTF(("esp_input_cb(): TDB is expired while in crypto"));
580 		error = EPERM;
581 		goto baddone;
582 	}
583 
584 	esph = (struct auth_hash *) tdb->tdb_authalgxform;
585 
586 	/* Check for crypto errors */
587 	if (crp->crp_etype) {
588 		if (crp->crp_etype == EAGAIN) {
589 			/* Reset the session ID */
590 			if (tdb->tdb_cryptoid != 0)
591 				tdb->tdb_cryptoid = crp->crp_sid;
592 			splx(s);
593 			return crypto_dispatch(crp);
594 		}
595 		free(tc, M_XDATA);
596 		espstat.esps_noxform++;
597 		DPRINTF(("esp_input_cb(): crypto error %d\n", crp->crp_etype));
598 		error = crp->crp_etype;
599 		goto baddone;
600 	}
601 
602 	/* If authentication was performed, check now. */
603 	if (esph != NULL) {
604 		/*
605 		 * If we have a tag, it means an IPsec-aware NIC did the verification
606 		 * for us.
607 		 */
608 		if (mtag == NULL) {
609 			/* Copy the authenticator from the packet */
610 			m_copydata(m, m->m_pkthdr.len - esph->authsize,
611 			    esph->authsize, aalg);
612 
613 			ptr = (caddr_t) (tc + 1);
614 
615 			/* Verify authenticator */
616 			if (timingsafe_bcmp(ptr, aalg, esph->authsize)) {
617 				free(tc, M_XDATA);
618 				DPRINTF(("esp_input_cb(): authentication failed for packet in SA %s/%08x\n", ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
619 				espstat.esps_badauth++;
620 				error = EACCES;
621 				goto baddone;
622 			}
623 		}
624 
625 		/* Remove trailing authenticator */
626 		m_adj(m, -(esph->authsize));
627 	}
628 	free(tc, M_XDATA);
629 
630 	/* Replay window checking, if appropriate */
631 	if ((tdb->tdb_wnd > 0) && (!(tdb->tdb_flags & TDBF_NOREPLAY))) {
632 		m_copydata(m, skip + sizeof(u_int32_t), sizeof(u_int32_t),
633 		    (unsigned char *) &btsx);
634 		btsx = ntohl(btsx);
635 
636 		switch (checkreplaywindow(btsx, &tdb->tdb_rpl, tdb->tdb_wnd,
637 		    &tdb->tdb_bitmap, &esn, tdb->tdb_flags & TDBF_ESN, 1)) {
638 		case 0: /* All's well */
639 #if NPFSYNC > 0
640 			pfsync_update_tdb(tdb,0);
641 #endif
642 			break;
643 
644 		case 1:
645 			DPRINTF(("esp_input_cb(): replay counter wrapped for SA %s/%08x\n", ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
646 			espstat.esps_wrap++;
647 			error = EACCES;
648 			goto baddone;
649 
650 		case 2:
651 		case 3:
652 			DPRINTF(("esp_input_cb(): duplicate packet received in SA %s/%08x\n", ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
653 			espstat.esps_replay++;
654 			error = EACCES;
655 			goto baddone;
656 
657 		default:
658 			DPRINTF(("esp_input_cb(): bogus value from checkreplaywindow() in SA %s/%08x\n", ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
659 			error = EACCES;
660 			goto baddone;
661 		}
662 	}
663 
664 	/* Release the crypto descriptors */
665 	crypto_freereq(crp);
666 
667 	/* Determine the ESP header length */
668 	if (tdb->tdb_flags & TDBF_NOREPLAY)
669 		hlen = sizeof(u_int32_t) + tdb->tdb_ivlen; /* "old" ESP */
670 	else
671 		hlen = 2 * sizeof(u_int32_t) + tdb->tdb_ivlen; /* "new" ESP */
672 
673 	/* Find beginning of ESP header */
674 	m1 = m_getptr(m, skip, &roff);
675 	if (m1 == NULL)	{
676 		espstat.esps_hdrops++;
677 		splx(s);
678 		DPRINTF(("esp_input_cb(): bad mbuf chain, SA %s/%08x\n",
679 		    ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
680 		m_freem(m);
681 		return EINVAL;
682 	}
683 
684 	/* Remove the ESP header and IV from the mbuf. */
685 	if (roff == 0) {
686 		/* The ESP header was conveniently at the beginning of the mbuf */
687 		m_adj(m1, hlen);
688 		if (!(m1->m_flags & M_PKTHDR))
689 			m->m_pkthdr.len -= hlen;
690 	} else if (roff + hlen >= m1->m_len) {
691 		/*
692 		 * Part or all of the ESP header is at the end of this mbuf, so
693 		 * first let's remove the remainder of the ESP header from the
694 		 * beginning of the remainder of the mbuf chain, if any.
695 		 */
696 		if (roff + hlen > m1->m_len) {
697 			/* Adjust the next mbuf by the remainder */
698 			m_adj(m1->m_next, roff + hlen - m1->m_len);
699 
700 			/* The second mbuf is guaranteed not to have a pkthdr... */
701 			m->m_pkthdr.len -= (roff + hlen - m1->m_len);
702 		}
703 
704 		/* Now, let's unlink the mbuf chain for a second...*/
705 		mo = m1->m_next;
706 		m1->m_next = NULL;
707 
708 		/* ...and trim the end of the first part of the chain...sick */
709 		m_adj(m1, -(m1->m_len - roff));
710 		if (!(m1->m_flags & M_PKTHDR))
711 			m->m_pkthdr.len -= (m1->m_len - roff);
712 
713 		/* Finally, let's relink */
714 		m1->m_next = mo;
715 	} else {
716 		/*
717 		 * The ESP header lies in the "middle" of the mbuf...do an
718 		 * overlapping copy of the remainder of the mbuf over the ESP
719 		 * header.
720 		 */
721 		bcopy(mtod(m1, u_char *) + roff + hlen,
722 		    mtod(m1, u_char *) + roff, m1->m_len - (roff + hlen));
723 		m1->m_len -= hlen;
724 		m->m_pkthdr.len -= hlen;
725 	}
726 
727 	/* Save the last three bytes of decrypted data */
728 	m_copydata(m, m->m_pkthdr.len - 3, 3, lastthree);
729 
730 	/* Verify pad length */
731 	if (lastthree[1] + 2 > m->m_pkthdr.len - skip) {
732 		espstat.esps_badilen++;
733 		splx(s);
734 		DPRINTF(("esp_input_cb(): invalid padding length %d for packet in SA %s/%08x\n", lastthree[1], ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
735 		m_freem(m);
736 		return EINVAL;
737 	}
738 
739 	/* Verify correct decryption by checking the last padding bytes */
740 	if (!(tdb->tdb_flags & TDBF_RANDOMPADDING)) {
741 		if ((lastthree[1] != lastthree[0]) && (lastthree[1] != 0)) {
742 			espstat.esps_badenc++;
743 			splx(s);
744 			DPRINTF(("esp_input(): decryption failed for packet in SA %s/%08x\n", ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
745 			m_freem(m);
746 			return EINVAL;
747 		}
748 	}
749 
750 	/* Trim the mbuf chain to remove the trailing authenticator and padding */
751 	m_adj(m, -(lastthree[1] + 2));
752 
753 	/* Restore the Next Protocol field */
754 	m_copyback(m, protoff, sizeof(u_int8_t), lastthree + 2, M_NOWAIT);
755 
756 	/* Back to generic IPsec input processing */
757 	error = ipsec_common_input_cb(m, tdb, skip, protoff, mtag);
758 	splx(s);
759 	return (error);
760 
761  baddone:
762 	splx(s);
763 
764 	if (m != NULL)
765 		m_freem(m);
766 
767 	crypto_freereq(crp);
768 
769 	return (error);
770 }
771 
772 /*
773  * ESP output routine, called by ipsp_process_packet().
774  */
775 int
776 esp_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int skip,
777     int protoff)
778 {
779 	struct enc_xform *espx = (struct enc_xform *) tdb->tdb_encalgxform;
780 	struct auth_hash *esph = (struct auth_hash *) tdb->tdb_authalgxform;
781 	int ilen, hlen, rlen, padding, blks, alen;
782 	struct mbuf *mi, *mo = (struct mbuf *) NULL;
783 	struct tdb_crypto *tc;
784 	unsigned char *pad;
785 	u_int8_t prot;
786 
787 	struct cryptodesc *crde = NULL, *crda = NULL;
788 	struct cryptop *crp;
789 #if NBPFILTER > 0
790 	struct ifnet *encif;
791 
792 	if ((encif = enc_getif(tdb->tdb_rdomain, tdb->tdb_tap)) != NULL) {
793 		encif->if_opackets++;
794 		encif->if_obytes += m->m_pkthdr.len;
795 
796 		if (encif->if_bpf) {
797 			struct enchdr hdr;
798 
799 			bzero (&hdr, sizeof(hdr));
800 
801 			hdr.af = tdb->tdb_dst.sa.sa_family;
802 			hdr.spi = tdb->tdb_spi;
803 			if (espx)
804 				hdr.flags |= M_CONF;
805 			if (esph)
806 				hdr.flags |= M_AUTH;
807 
808 			bpf_mtap_hdr(encif->if_bpf, (char *)&hdr,
809 			    ENC_HDRLEN, m, BPF_DIRECTION_OUT);
810 		}
811 	}
812 #endif
813 
814 	if (tdb->tdb_flags & TDBF_NOREPLAY)
815 		hlen = sizeof(u_int32_t) + tdb->tdb_ivlen;
816 	else
817 		hlen = 2 * sizeof(u_int32_t) + tdb->tdb_ivlen;
818 
819 	rlen = m->m_pkthdr.len - skip; /* Raw payload length. */
820 	if (espx)
821 		blks = MAX(espx->blocksize, 4);
822 	else
823 		blks = 4; /* If no encryption, we have to be 4-byte aligned. */
824 
825 	padding = ((blks - ((rlen + 2) % blks)) % blks) + 2;
826 
827 	alen = esph ? esph->authsize : 0;
828 	espstat.esps_output++;
829 
830 	switch (tdb->tdb_dst.sa.sa_family) {
831 #ifdef INET
832 	case AF_INET:
833 		/* Check for IP maximum packet size violations. */
834 		if (skip + hlen + rlen + padding + alen > IP_MAXPACKET)	{
835 			DPRINTF(("esp_output(): packet in SA %s/%08x got "
836 			    "too big\n", ipsp_address(tdb->tdb_dst),
837 			    ntohl(tdb->tdb_spi)));
838 			m_freem(m);
839 			espstat.esps_toobig++;
840 			return EMSGSIZE;
841 		}
842 		break;
843 #endif /* INET */
844 
845 #ifdef INET6
846 	case AF_INET6:
847 		/* Check for IPv6 maximum packet size violations. */
848 		if (skip + hlen + rlen + padding + alen > IPV6_MAXPACKET) {
849 			DPRINTF(("esp_output(): packet in SA %s/%08x got too "
850 			    "big\n", ipsp_address(tdb->tdb_dst),
851 			    ntohl(tdb->tdb_spi)));
852 			m_freem(m);
853 			espstat.esps_toobig++;
854 			return EMSGSIZE;
855 		}
856 		break;
857 #endif /* INET6 */
858 
859 	default:
860 		DPRINTF(("esp_output(): unknown/unsupported protocol "
861 		    "family %d, SA %s/%08x\n", tdb->tdb_dst.sa.sa_family
862 		    , ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
863 		m_freem(m);
864 		espstat.esps_nopf++;
865 		return EPFNOSUPPORT;
866 	}
867 
868 	/* Update the counters. */
869 	tdb->tdb_cur_bytes += m->m_pkthdr.len - skip;
870 	espstat.esps_obytes += m->m_pkthdr.len - skip;
871 
872 	/* Hard byte expiration. */
873 	if (tdb->tdb_flags & TDBF_BYTES &&
874 	    tdb->tdb_cur_bytes >= tdb->tdb_exp_bytes) {
875 		pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_HARD);
876 		tdb_delete(tdb);
877 		m_freem(m);
878 		return EINVAL;
879 	}
880 
881 	/* Soft byte expiration. */
882 	if (tdb->tdb_flags & TDBF_SOFT_BYTES &&
883 	    tdb->tdb_cur_bytes >= tdb->tdb_soft_bytes) {
884 		pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_SOFT);
885 		tdb->tdb_flags &= ~TDBF_SOFT_BYTES;    /* Turn off checking. */
886 	}
887 
888 	/*
889 	 * Loop through mbuf chain; if we find a readonly mbuf,
890 	 * replace the rest of the chain.
891 	 */
892 	mo = NULL;
893 	mi = m;
894 	while (mi != NULL && !M_READONLY(mi)) {
895 		mo = mi;
896 		mi = mi->m_next;
897 	}
898 
899 	if (mi != NULL)	{
900 		/* Replace the rest of the mbuf chain. */
901 		struct mbuf *n = m_copym2(mi, 0, M_COPYALL, M_DONTWAIT);
902 
903 		if (n == NULL) {
904 			DPRINTF(("esp_output(): bad mbuf chain, SA %s/%08x\n",
905 			    ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
906 			espstat.esps_hdrops++;
907 			m_freem(m);
908 			return ENOBUFS;
909 		}
910 
911 		if (mo != NULL)
912 			mo->m_next = n;
913 		else
914 			m = n;
915 
916 		m_freem(mi);
917 	}
918 
919 	/* Inject ESP header. */
920 	mo = m_inject(m, skip, hlen, M_DONTWAIT);
921 	if (mo == NULL) {
922 		DPRINTF(("esp_output(): failed to inject ESP header for "
923 		    "SA %s/%08x\n", ipsp_address(tdb->tdb_dst),
924 		    ntohl(tdb->tdb_spi)));
925 		m_freem(m);
926 		espstat.esps_hdrops++;
927 		return ENOBUFS;
928 	}
929 
930 	/* Initialize ESP header. */
931 	bcopy((caddr_t) &tdb->tdb_spi, mtod(mo, caddr_t), sizeof(u_int32_t));
932 	if (!(tdb->tdb_flags & TDBF_NOREPLAY)) {
933 		u_int32_t replay;
934 		tdb->tdb_rpl++;
935 		replay = htonl((u_int32_t)tdb->tdb_rpl);
936 		bcopy((caddr_t) &replay, mtod(mo, caddr_t) + sizeof(u_int32_t),
937 		    sizeof(u_int32_t));
938 #if NPFSYNC > 0
939 		pfsync_update_tdb(tdb,1);
940 #endif
941 	}
942 
943 	/*
944 	 * Add padding -- better to do it ourselves than use the crypto engine,
945 	 * although if/when we support compression, we'd have to do that.
946 	 */
947 	mo = m_inject(m, m->m_pkthdr.len, padding + alen, M_DONTWAIT);
948 	if (mo == NULL) {
949 		DPRINTF(("esp_output(): m_inject failed for SA %s/%08x\n",
950 		    ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
951 		m_freem(m);
952 		return ENOBUFS;
953 	}
954 	pad = mtod(mo, u_char *);
955 
956 	/* Self-describing or random padding ? */
957 	if (!(tdb->tdb_flags & TDBF_RANDOMPADDING))
958 		for (ilen = 0; ilen < padding - 2; ilen++)
959 			pad[ilen] = ilen + 1;
960 	else
961 		arc4random_buf((void *) pad, padding - 2);
962 
963 	/* Fix padding length and Next Protocol in padding itself. */
964 	pad[padding - 2] = padding - 2;
965 	m_copydata(m, protoff, sizeof(u_int8_t), pad + padding - 1);
966 
967 	/* Fix Next Protocol in IPv4/IPv6 header. */
968 	prot = IPPROTO_ESP;
969 	m_copyback(m, protoff, sizeof(u_int8_t), &prot, M_NOWAIT);
970 
971 	/* Get crypto descriptors. */
972 	crp = crypto_getreq(esph && espx ? 2 : 1);
973 	if (crp == NULL) {
974 		m_freem(m);
975 		DPRINTF(("esp_output(): failed to acquire crypto "
976 		    "descriptors\n"));
977 		espstat.esps_crypto++;
978 		return ENOBUFS;
979 	}
980 
981 	if (espx) {
982 		crde = crp->crp_desc;
983 		crda = crde->crd_next;
984 
985 		/* Encryption descriptor. */
986 		crde->crd_skip = skip + hlen;
987 		crde->crd_flags = CRD_F_ENCRYPT;
988 		crde->crd_inject = skip + hlen - tdb->tdb_ivlen;
989 
990 		if (tdb->tdb_flags & TDBF_HALFIV) {
991 			/* Copy half-iv in the packet. */
992 			m_copyback(m, crde->crd_inject, tdb->tdb_ivlen,
993 			    tdb->tdb_iv, M_NOWAIT);
994 
995 			/* Cook half-iv. */
996 			bcopy(tdb->tdb_iv, crde->crd_iv, tdb->tdb_ivlen);
997 			for (ilen = 0; ilen < tdb->tdb_ivlen; ilen++)
998 				crde->crd_iv[tdb->tdb_ivlen + ilen] =
999 				    ~crde->crd_iv[ilen];
1000 
1001 			crde->crd_flags |=
1002 			    CRD_F_IV_PRESENT | CRD_F_IV_EXPLICIT;
1003 		}
1004 
1005 		/* Encryption operation. */
1006 		crde->crd_alg = espx->type;
1007 		crde->crd_key = tdb->tdb_emxkey;
1008 		crde->crd_klen = tdb->tdb_emxkeylen * 8;
1009 		/* XXX Rounds ? */
1010 
1011 		if (crde->crd_alg == CRYPTO_AES_GMAC)
1012 			crde->crd_len = 0;
1013 		else
1014 			crde->crd_len = m->m_pkthdr.len - (skip + hlen + alen);
1015 	} else
1016 		crda = crp->crp_desc;
1017 
1018 	/* IPsec-specific opaque crypto info. */
1019 	tc = malloc(sizeof(*tc), M_XDATA, M_NOWAIT | M_ZERO);
1020 	if (tc == NULL) {
1021 		m_freem(m);
1022 		crypto_freereq(crp);
1023 		DPRINTF(("esp_output(): failed to allocate tdb_crypto\n"));
1024 		espstat.esps_crypto++;
1025 		return ENOBUFS;
1026 	}
1027 
1028 	tc->tc_spi = tdb->tdb_spi;
1029 	tc->tc_proto = tdb->tdb_sproto;
1030 	tc->tc_rdomain = tdb->tdb_rdomain;
1031 	bcopy(&tdb->tdb_dst, &tc->tc_dst, sizeof(union sockaddr_union));
1032 
1033 	/* Crypto operation descriptor. */
1034 	crp->crp_ilen = m->m_pkthdr.len; /* Total input length. */
1035 	crp->crp_flags = CRYPTO_F_IMBUF;
1036 	crp->crp_buf = (caddr_t) m;
1037 	crp->crp_callback = (int (*) (struct cryptop *)) esp_output_cb;
1038 	crp->crp_opaque = (caddr_t) tc;
1039 	crp->crp_sid = tdb->tdb_cryptoid;
1040 
1041 	if (esph) {
1042 		/* Authentication descriptor. */
1043 		crda->crd_skip = skip;
1044 		crda->crd_inject = m->m_pkthdr.len - alen;
1045 
1046 		/* Authentication operation. */
1047 		crda->crd_alg = esph->type;
1048 		crda->crd_key = tdb->tdb_amxkey;
1049 		crda->crd_klen = tdb->tdb_amxkeylen * 8;
1050 
1051 		if ((tdb->tdb_wnd > 0) && !(tdb->tdb_flags & TDBF_NOREPLAY) &&
1052 		    (tdb->tdb_flags & TDBF_ESN)) {
1053 			u_int32_t esn;
1054 
1055 			esn = htonl((u_int32_t)(tdb->tdb_rpl >> 32));
1056 			bcopy(&esn, crda->crd_esn, 4);
1057 			crda->crd_flags |= CRD_F_ESN;
1058 		}
1059 
1060 		if (espx && espx->type == CRYPTO_AES_GCM_16)
1061 			crda->crd_len = hlen - tdb->tdb_ivlen;
1062 		else
1063 			crda->crd_len = m->m_pkthdr.len - (skip + alen);
1064 	}
1065 
1066 	if ((tdb->tdb_flags & TDBF_SKIPCRYPTO) == 0)
1067 		return crypto_dispatch(crp);
1068 	else
1069 		return esp_output_cb(crp);
1070 }
1071 
1072 /*
1073  * ESP output callback, called directly by the crypto driver.
1074  */
1075 int
1076 esp_output_cb(void *op)
1077 {
1078 	struct cryptop *crp = (struct cryptop *) op;
1079 	struct tdb_crypto *tc;
1080 	struct tdb *tdb;
1081 	struct mbuf *m;
1082 	int error, s;
1083 
1084 	tc = (struct tdb_crypto *) crp->crp_opaque;
1085 
1086 	m = (struct mbuf *) crp->crp_buf;
1087 	if (m == NULL) {
1088 		/* Shouldn't happen... */
1089 		free(tc, M_XDATA);
1090 		crypto_freereq(crp);
1091 		espstat.esps_crypto++;
1092 		DPRINTF(("esp_output_cb(): bogus returned buffer from "
1093 		    "crypto\n"));
1094 		return (EINVAL);
1095 	}
1096 
1097 
1098 	s = spltdb();
1099 
1100 	tdb = gettdb(tc->tc_rdomain, tc->tc_spi, &tc->tc_dst, tc->tc_proto);
1101 	if (tdb == NULL) {
1102 		free(tc, M_XDATA);
1103 		espstat.esps_notdb++;
1104 		DPRINTF(("esp_output_cb(): TDB is expired while in crypto\n"));
1105 		error = EPERM;
1106 		goto baddone;
1107 	}
1108 
1109 	/* Check for crypto errors. */
1110 	if (crp->crp_etype) {
1111 		if (crp->crp_etype == EAGAIN) {
1112 			/* Reset the session ID */
1113 			if (tdb->tdb_cryptoid != 0)
1114 				tdb->tdb_cryptoid = crp->crp_sid;
1115 			splx(s);
1116 			return crypto_dispatch(crp);
1117 		}
1118 		free(tc, M_XDATA);
1119 		espstat.esps_noxform++;
1120 		DPRINTF(("esp_output_cb(): crypto error %d\n",
1121 		    crp->crp_etype));
1122 		error = crp->crp_etype;
1123 		goto baddone;
1124 	}
1125 	free(tc, M_XDATA);
1126 
1127 	/* Release crypto descriptors. */
1128 	crypto_freereq(crp);
1129 
1130 	/*
1131 	 * If we're doing half-iv, keep a copy of the last few bytes of the
1132 	 * encrypted part, for use as the next IV. Note that HALF-IV is only
1133 	 * supposed to be used without authentication (the old ESP specs).
1134 	 */
1135 	if (tdb->tdb_flags & TDBF_HALFIV)
1136 		m_copydata(m, m->m_pkthdr.len - tdb->tdb_ivlen, tdb->tdb_ivlen,
1137 		    tdb->tdb_iv);
1138 
1139 	/* Call the IPsec input callback. */
1140 	error = ipsp_process_done(m, tdb);
1141 	splx(s);
1142 	return error;
1143 
1144  baddone:
1145 	splx(s);
1146 
1147 	if (m != NULL)
1148 		m_freem(m);
1149 
1150 	crypto_freereq(crp);
1151 
1152 	return error;
1153 }
1154 
1155 static __inline int
1156 checkreplay(u_int64_t *bitmap, u_int32_t diff)
1157 {
1158 	if (*bitmap & (1ULL << diff))
1159 		return (1);
1160 	return (0);
1161 }
1162 
1163 static __inline void
1164 setreplay(u_int64_t *bitmap, u_int32_t diff, u_int32_t window, int wupdate)
1165 {
1166 	if (wupdate) {
1167 		if (diff < window)
1168 			*bitmap = ((*bitmap) << diff) | 1;
1169 		else
1170 			*bitmap = 1;
1171 	} else
1172 		*bitmap |= 1ULL << diff;
1173 }
1174 
1175 /*
1176  * To prevent ESN desynchronization replay distance specifies maximum
1177  * valid difference between the received SN and the last authenticated
1178  * one.  It's arbitrary chosen to be 1000 packets, meaning that only
1179  * up to 999 packets can be lost.
1180  */
1181 #define REPLAY_DISTANCE (1000)
1182 
1183 /*
1184  * return 0 on success
1185  * return 1 for counter == 0
1186  * return 2 for very old packet
1187  * return 3 for packet within current window but already received
1188  */
1189 int
1190 checkreplaywindow(u_int32_t seq, u_int64_t *last, u_int32_t window,
1191     u_int64_t *bitmap, u_int32_t *seqhigh, int esn, int commit)
1192 {
1193 	u_int32_t	tl, th, wl;
1194 	u_int32_t	seqh, diff;
1195 
1196 	tl = (u_int32_t)*last;
1197 	th = (u_int32_t)(*last >> 32);
1198 
1199 	/* Zero SN is not allowed */
1200 	if (seq == 0 && tl == 0 && th == 0)
1201 		return (1);
1202 
1203 	/* Current replay window starts here */
1204 	wl = tl - window + 1;
1205 
1206 	/*
1207 	 * We keep the high part intact when:
1208 	 * 1) the SN is within [wl, 0xffffffff] and the whole window is
1209 	 *    within one subspace;
1210 	 * 2) the SN is within [0, wl) and window spans two subspaces.
1211 	 */
1212 	if ((tl >= window - 1 && seq >= wl) ||
1213 	    (tl <  window - 1 && seq <  wl)) {
1214 		seqh = *seqhigh = th;
1215 		if (seq > tl) {
1216 			if (seq - tl >= REPLAY_DISTANCE)
1217 				return (2);
1218 			if (commit) {
1219 				setreplay(bitmap, seq - tl, window, 1);
1220 				*last = ((u_int64_t)seqh << 32) | seq;
1221 			}
1222 		} else {
1223 			if (checkreplay(bitmap, tl - seq))
1224 				return (3);
1225 			if (commit)
1226 				setreplay(bitmap, tl - seq, window, 0);
1227 		}
1228 		return (0);
1229 	}
1230 
1231 	/* Can't wrap if not doing ESN */
1232 	if (!esn)
1233 		return (1);
1234 
1235 	/*
1236 	 * SN is within [wl, 0xffffffff] and wl is within
1237 	 * [0xffffffff-window, 0xffffffff].  This means we got a SN
1238 	 * which is within our replay window, but in the previous
1239 	 * subspace.
1240 	 */
1241 	if (tl < window - 1 && seq >= wl) {
1242 		seqh = *seqhigh = th - 1;
1243 		diff = (u_int32_t)((((u_int64_t)th << 32) | tl) -
1244 		    (((u_int64_t)seqh << 32) | seq));
1245 		if (checkreplay(bitmap, diff))
1246 			return (3);
1247 		if (commit)
1248 			setreplay(bitmap, diff, window, 0);
1249 		return (0);
1250 	}
1251 
1252 	/*
1253 	 * SN has wrapped and the last authenticated SN is in the old
1254 	 * subspace.
1255 	 */
1256 
1257 	if (seq - tl >= REPLAY_DISTANCE)
1258 		return (2);
1259 
1260 	seqh = *seqhigh = th + 1;
1261 	if (seqh == 0)		/* Don't let high bit to wrap */
1262 		return (1);
1263 	if (commit) {
1264 		diff = (u_int32_t)((((u_int64_t)seqh << 32) | seq) -
1265 		    (((u_int64_t)th << 32) | tl));
1266 		setreplay(bitmap, diff, window, 1);
1267 		*last = ((u_int64_t)seqh << 32) | seq;
1268 	}
1269 
1270 	return (0);
1271 }
1272