xref: /xnu-10063.121.3/bsd/netinet6/esp_input.c (revision 2c2f96dc2b9a4408a43d3150ae9c105355ca3daa)
1 /*
2  * Copyright (c) 2008-2016, 2022-2023 Apple Inc. All rights reserved.
3  *
4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5  *
6  * This file contains Original Code and/or Modifications of Original Code
7  * as defined in and that are subject to the Apple Public Source License
8  * Version 2.0 (the 'License'). You may not use this file except in
9  * compliance with the License. The rights granted to you under the License
10  * may not be used to create, or enable the creation or redistribution of,
11  * unlawful or unlicensed copies of an Apple operating system, or to
12  * circumvent, violate, or enable the circumvention or violation of, any
13  * terms of an Apple operating system software license agreement.
14  *
15  * Please obtain a copy of the License at
16  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17  *
18  * The Original Code and all software distributed under the License are
19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23  * Please see the License for the specific language governing rights and
24  * limitations under the License.
25  *
26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27  */
28 
29 /*	$FreeBSD: src/sys/netinet6/esp_input.c,v 1.1.2.3 2001/07/03 11:01:50 ume Exp $	*/
30 /*	$KAME: esp_input.c,v 1.55 2001/03/23 08:08:47 itojun Exp $	*/
31 
32 /*
33  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
34  * All rights reserved.
35  *
36  * Redistribution and use in source and binary forms, with or without
37  * modification, are permitted provided that the following conditions
38  * are met:
39  * 1. Redistributions of source code must retain the above copyright
40  *    notice, this list of conditions and the following disclaimer.
41  * 2. Redistributions in binary form must reproduce the above copyright
42  *    notice, this list of conditions and the following disclaimer in the
43  *    documentation and/or other materials provided with the distribution.
44  * 3. Neither the name of the project nor the names of its contributors
45  *    may be used to endorse or promote products derived from this software
46  *    without specific prior written permission.
47  *
48  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
49  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
52  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58  * SUCH DAMAGE.
59  */
60 
61 #define _IP_VHL
62 
63 /*
64  * RFC1827/2406 Encapsulated Security Payload.
65  */
66 
67 #include <sys/param.h>
68 #include <sys/systm.h>
69 #include <sys/malloc.h>
70 #include <sys/mbuf.h>
71 #include <sys/mcache.h>
72 #include <sys/domain.h>
73 #include <sys/protosw.h>
74 #include <sys/socket.h>
75 #include <sys/errno.h>
76 #include <sys/time.h>
77 #include <sys/kernel.h>
78 #include <sys/syslog.h>
79 
80 #include <net/if.h>
81 #include <net/if_ipsec.h>
82 #include <net/multi_layer_pkt_log.h>
83 #include <net/route.h>
84 #include <net/if_ports_used.h>
85 #include <kern/cpu_number.h>
86 #include <kern/locks.h>
87 
88 #include <netinet/in.h>
89 #include <netinet/in_systm.h>
90 #include <netinet/ip.h>
91 #include <netinet/ip_var.h>
92 #include <netinet/in_var.h>
93 #include <netinet/ip_ecn.h>
94 #include <netinet/in_pcb.h>
95 #include <netinet/udp.h>
96 #include <netinet/tcp.h>
97 #include <netinet/in_tclass.h>
98 #include <netinet6/ip6_ecn.h>
99 
100 #include <netinet/ip6.h>
101 #include <netinet6/in6_pcb.h>
102 #include <netinet6/ip6_var.h>
103 #include <netinet/icmp6.h>
104 #include <netinet6/ip6protosw.h>
105 
106 #include <netinet6/ipsec.h>
107 #include <netinet6/ipsec6.h>
108 #include <netinet6/ah.h>
109 #include <netinet6/ah6.h>
110 #include <netinet6/esp.h>
111 #include <netinet6/esp6.h>
112 #include <netkey/key.h>
113 #include <netkey/keydb.h>
114 #include <netkey/key_debug.h>
115 
116 #include <net/kpi_protocol.h>
117 #include <netinet/kpi_ipfilter_var.h>
118 
119 #include <net/net_osdep.h>
120 #include <mach/sdt.h>
121 #include <corecrypto/cc.h>
122 
123 #if SKYWALK
124 #include <skywalk/os_skywalk_private.h>
125 #endif // SKYWALK
126 
127 #include <sys/kdebug.h>
128 #define DBG_LAYER_BEG           NETDBG_CODE(DBG_NETIPSEC, 1)
129 #define DBG_LAYER_END           NETDBG_CODE(DBG_NETIPSEC, 3)
130 #define DBG_FNC_ESPIN           NETDBG_CODE(DBG_NETIPSEC, (6 << 8))
131 #define DBG_FNC_DECRYPT         NETDBG_CODE(DBG_NETIPSEC, (7 << 8))
132 #define IPLEN_FLIPPED
133 
134 #define ESPMAXLEN \
135 	(sizeof(struct esp) < sizeof(struct newesp) \
136 	        ? sizeof(struct newesp) : sizeof(struct esp))
137 
138 static struct ip *
esp4_input_strip_udp_encap(struct mbuf * m,int iphlen)139 esp4_input_strip_udp_encap(struct mbuf *m, int iphlen)
140 {
141 	// strip the udp header that's encapsulating ESP
142 	struct ip *ip;
143 	u_int8_t stripsiz = (u_int8_t)sizeof(struct udphdr);
144 
145 	ip = mtod(m, __typeof__(ip));
146 	ovbcopy((caddr_t)ip, (caddr_t)(((u_char *)ip) + stripsiz), iphlen);
147 	m->m_data += stripsiz;
148 	m->m_len -= stripsiz;
149 	m->m_pkthdr.len -= stripsiz;
150 	ip = mtod(m, __typeof__(ip));
151 	ip->ip_len = ip->ip_len - stripsiz;
152 	ip->ip_p = IPPROTO_ESP;
153 	return ip;
154 }
155 
156 static struct ip6_hdr *
esp6_input_strip_udp_encap(struct mbuf * m,int ip6hlen)157 esp6_input_strip_udp_encap(struct mbuf *m, int ip6hlen)
158 {
159 	// strip the udp header that's encapsulating ESP
160 	struct ip6_hdr *ip6;
161 	u_int8_t stripsiz = (u_int8_t)sizeof(struct udphdr);
162 
163 	ip6 = mtod(m, __typeof__(ip6));
164 	ovbcopy((caddr_t)ip6, (caddr_t)(((u_char *)ip6) + stripsiz), ip6hlen);
165 	m->m_data += stripsiz;
166 	m->m_len -= stripsiz;
167 	m->m_pkthdr.len -= stripsiz;
168 	ip6 = mtod(m, __typeof__(ip6));
169 	ip6->ip6_plen = htons(ntohs(ip6->ip6_plen) - stripsiz);
170 	ip6->ip6_nxt = IPPROTO_ESP;
171 	return ip6;
172 }
173 
174 static void
esp_input_log(struct mbuf * m,struct secasvar * sav,u_int32_t spi,u_int32_t seq)175 esp_input_log(struct mbuf *m, struct secasvar *sav, u_int32_t spi, u_int32_t seq)
176 {
177 	if (net_mpklog_enabled &&
178 	    (sav->sah->ipsec_if->if_xflags & IFXF_MPK_LOG) == IFXF_MPK_LOG) {
179 		struct tcphdr th = {};
180 		u_int32_t proto_len = 0;
181 		u_int8_t iphlen = 0;
182 		u_int8_t proto = 0;
183 
184 		struct ip *inner_ip = mtod(m, struct ip *);
185 		if (IP_VHL_V(inner_ip->ip_vhl) == 4) {
186 			iphlen = (u_int8_t)(IP_VHL_HL(inner_ip->ip_vhl) << 2);
187 			proto = inner_ip->ip_p;
188 		} else if (IP_VHL_V(inner_ip->ip_vhl) == 6) {
189 			struct ip6_hdr *inner_ip6 = mtod(m, struct ip6_hdr *);
190 			iphlen = sizeof(struct ip6_hdr);
191 			proto = inner_ip6->ip6_nxt;
192 		}
193 
194 		if (proto == IPPROTO_TCP) {
195 			if ((int)(iphlen + sizeof(th)) <= m->m_pkthdr.len) {
196 				m_copydata(m, iphlen, sizeof(th), (u_int8_t *)&th);
197 			}
198 
199 			proto_len = m->m_pkthdr.len - iphlen - (th.th_off << 2);
200 			MPKL_ESP_INPUT_TCP(esp_mpkl_log_object,
201 			    ntohl(spi), seq,
202 			    ntohs(th.th_sport), ntohs(th.th_dport),
203 			    ntohl(th.th_seq), proto_len);
204 		}
205 	}
206 }
207 
208 void
esp4_input(struct mbuf * m,int off)209 esp4_input(struct mbuf *m, int off)
210 {
211 	(void)esp4_input_extended(m, off, NULL);
212 }
213 
214 struct mbuf *
esp4_input_extended(struct mbuf * m,int off,ifnet_t interface)215 esp4_input_extended(struct mbuf *m, int off, ifnet_t interface)
216 {
217 	struct ip *ip;
218 	struct ip6_hdr *ip6;
219 	struct esp *esp;
220 	struct esptail esptail;
221 	u_int32_t spi;
222 	u_int32_t seq;
223 	u_int32_t replay_index = 0;
224 	struct secasvar *sav = NULL;
225 	size_t taillen;
226 	u_int16_t nxt;
227 	const struct esp_algorithm *algo;
228 	int ivlen;
229 	size_t esplen;
230 	u_int8_t hlen;
231 	sa_family_t     ifamily;
232 	struct mbuf *out_m = NULL;
233 
234 	KERNEL_DEBUG(DBG_FNC_ESPIN | DBG_FUNC_START, 0, 0, 0, 0, 0);
235 	/* sanity check for alignment. */
236 	if (off % 4 != 0 || m->m_pkthdr.len % 4 != 0) {
237 		ipseclog((LOG_ERR, "IPv4 ESP input: packet alignment problem "
238 		    "(off=%d, pktlen=%d)\n", off, m->m_pkthdr.len));
239 		IPSEC_STAT_INCREMENT(ipsecstat.in_inval);
240 		goto bad;
241 	}
242 
243 	if (m->m_len < off + ESPMAXLEN) {
244 		m = m_pullup(m, off + ESPMAXLEN);
245 		if (!m) {
246 			ipseclog((LOG_DEBUG,
247 			    "IPv4 ESP input: can't pullup in esp4_input\n"));
248 			IPSEC_STAT_INCREMENT(ipsecstat.in_inval);
249 			goto bad;
250 		}
251 	}
252 
253 	m->m_pkthdr.csum_flags &= ~CSUM_RX_FLAGS;
254 
255 	/* Expect 32-bit aligned data pointer on strict-align platforms */
256 	MBUF_STRICT_DATA_ALIGNMENT_CHECK_32(m);
257 
258 	ip = mtod(m, struct ip *);
259 	// expect udp-encap and esp packets only
260 	if (ip->ip_p != IPPROTO_ESP &&
261 	    !(ip->ip_p == IPPROTO_UDP && off >= sizeof(struct udphdr))) {
262 		ipseclog((LOG_DEBUG,
263 		    "IPv4 ESP input: invalid protocol type\n"));
264 		IPSEC_STAT_INCREMENT(ipsecstat.in_inval);
265 		goto bad;
266 	}
267 	esp = (struct esp *)(void *)(((u_int8_t *)ip) + off);
268 #ifdef _IP_VHL
269 	hlen = (u_int8_t)(IP_VHL_HL(ip->ip_vhl) << 2);
270 #else
271 	hlen = ip->ip_hl << 2;
272 #endif
273 
274 	/* find the sassoc. */
275 	spi = esp->esp_spi;
276 
277 	if ((sav = key_allocsa_extended(AF_INET,
278 	    (caddr_t)&ip->ip_src, (caddr_t)&ip->ip_dst, IFSCOPE_NONE,
279 	    IPPROTO_ESP, spi, interface)) == 0) {
280 		ipseclog((LOG_WARNING,
281 		    "IPv4 ESP input: no key association found for spi %u (0x%08x)\n",
282 		    (u_int32_t)ntohl(spi), (u_int32_t)ntohl(spi)));
283 		IPSEC_STAT_INCREMENT(ipsecstat.in_nosa);
284 		goto bad;
285 	}
286 	KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
287 	    printf("DP esp4_input called to allocate SA:0x%llx\n",
288 	    (uint64_t)VM_KERNEL_ADDRPERM(sav)));
289 	if (sav->state != SADB_SASTATE_MATURE
290 	    && sav->state != SADB_SASTATE_DYING) {
291 		ipseclog((LOG_DEBUG,
292 		    "IPv4 ESP input: non-mature/dying SA found for spi %u (0x%08x)\n",
293 		    (u_int32_t)ntohl(spi), (u_int32_t)ntohl(spi)));
294 		IPSEC_STAT_INCREMENT(ipsecstat.in_badspi);
295 		goto bad;
296 	}
297 	algo = esp_algorithm_lookup(sav->alg_enc);
298 	if (!algo) {
299 		ipseclog((LOG_DEBUG, "IPv4 ESP input: "
300 		    "unsupported encryption algorithm for spi %u (0x%08x)\n",
301 		    (u_int32_t)ntohl(spi), (u_int32_t)ntohl(spi)));
302 		IPSEC_STAT_INCREMENT(ipsecstat.in_badspi);
303 		goto bad;
304 	}
305 
306 	/* check if we have proper ivlen information */
307 	ivlen = sav->ivlen;
308 	if (ivlen < 0) {
309 		ipseclog((LOG_ERR, "inproper ivlen in IPv4 ESP input: %s %s\n",
310 		    ipsec4_logpacketstr(ip, spi), ipsec_logsastr(sav)));
311 		IPSEC_STAT_INCREMENT(ipsecstat.in_inval);
312 		goto bad;
313 	}
314 
315 	seq = ntohl(((struct newesp *)esp)->esp_seq);
316 
317 	if ((sav->flags2 & SADB_X_EXT_SA2_SEQ_PER_TRAFFIC_CLASS) ==
318 	    SADB_X_EXT_SA2_SEQ_PER_TRAFFIC_CLASS) {
319 		replay_index = seq >> PER_TC_REPLAY_WINDOW_SN_SHIFT;
320 	}
321 
322 	if (!((sav->flags & SADB_X_EXT_OLD) == 0 && sav->replay[replay_index] != NULL &&
323 	    ((sav->alg_auth && sav->key_auth) || algo->finalizedecrypt))) {
324 		goto noreplaycheck;
325 	}
326 
327 	if ((sav->alg_auth == SADB_X_AALG_NULL || sav->alg_auth == SADB_AALG_NONE) &&
328 	    !algo->finalizedecrypt) {
329 		goto noreplaycheck;
330 	}
331 
332 	/*
333 	 * check for sequence number.
334 	 */
335 	_CASSERT(MBUF_TC_MAX <= UINT8_MAX);
336 	if (ipsec_chkreplay(seq, sav, (u_int8_t)replay_index)) {
337 		; /*okey*/
338 	} else {
339 		IPSEC_STAT_INCREMENT(ipsecstat.in_espreplay);
340 		ipseclog((LOG_WARNING,
341 		    "replay packet in IPv4 ESP input: seq(%u) idx(%u) %s %s\n",
342 		    seq, (u_int8_t)replay_index, ipsec4_logpacketstr(ip, spi), ipsec_logsastr(sav)));
343 		goto bad;
344 	}
345 
346 	/* Save ICV from packet for verification later */
347 	size_t siz = 0;
348 	unsigned char saved_icv[AH_MAXSUMSIZE] __attribute__((aligned(4)));
349 	if (algo->finalizedecrypt) {
350 		siz = algo->icvlen;
351 		VERIFY(siz <= USHRT_MAX);
352 		if (m->m_pkthdr.len < off + ESPMAXLEN + siz) {
353 			ipseclog((LOG_DEBUG,
354 			    "invalid ESP packet length %u, missing ICV\n",
355 			    m->m_pkthdr.len));
356 			IPSEC_STAT_INCREMENT(ipsecstat.in_inval);
357 			goto bad;
358 		}
359 		m_copydata(m, m->m_pkthdr.len - (u_short)siz, (u_short)siz, (caddr_t) saved_icv);
360 	} else {
361 		/* check ICV immediately */
362 		u_char sum0[AH_MAXSUMSIZE] __attribute__((aligned(4)));
363 		u_char sum[AH_MAXSUMSIZE] __attribute__((aligned(4)));
364 		const struct ah_algorithm *sumalgo;
365 
366 		sumalgo = ah_algorithm_lookup(sav->alg_auth);
367 		if (!sumalgo) {
368 			goto noreplaycheck;
369 		}
370 		siz = (((*sumalgo->sumsiz)(sav) + 3) & ~(4 - 1));
371 		if (m->m_pkthdr.len < off + ESPMAXLEN + siz) {
372 			ipseclog((LOG_DEBUG,
373 			    "invalid ESP packet length %u, missing ICV\n",
374 			    m->m_pkthdr.len));
375 			IPSEC_STAT_INCREMENT(ipsecstat.in_inval);
376 			goto bad;
377 		}
378 		if (AH_MAXSUMSIZE < siz) {
379 			ipseclog((LOG_DEBUG,
380 			    "internal error: AH_MAXSUMSIZE must be larger than %u\n",
381 			    (u_int32_t)siz));
382 			IPSEC_STAT_INCREMENT(ipsecstat.in_inval);
383 			goto bad;
384 		}
385 
386 		m_copydata(m, m->m_pkthdr.len - (int)siz, (int)siz, (caddr_t) &sum0[0]);
387 
388 		if (esp_auth(m, off, m->m_pkthdr.len - off - siz, sav, sum)) {
389 			ipseclog((LOG_WARNING, "auth fail in IPv4 ESP input: %s %s\n",
390 			    ipsec4_logpacketstr(ip, spi), ipsec_logsastr(sav)));
391 			IPSEC_STAT_INCREMENT(ipsecstat.in_espauthfail);
392 			goto bad;
393 		}
394 
395 		if (cc_cmp_safe(siz, sum0, sum)) {
396 			ipseclog((LOG_WARNING, "cc_cmp fail in IPv4 ESP input: %s %s\n",
397 			    ipsec4_logpacketstr(ip, spi), ipsec_logsastr(sav)));
398 			IPSEC_STAT_INCREMENT(ipsecstat.in_espauthfail);
399 			goto bad;
400 		}
401 
402 		m->m_flags |= M_AUTHIPDGM;
403 		IPSEC_STAT_INCREMENT(ipsecstat.in_espauthsucc);
404 
405 		/*
406 		 * update replay window.
407 		 */
408 		if ((sav->flags & SADB_X_EXT_OLD) == 0 && sav->replay[replay_index] != NULL) {
409 			if (ipsec_updatereplay(seq, sav, (u_int8_t)replay_index)) {
410 				IPSEC_STAT_INCREMENT(ipsecstat.in_espreplay);
411 				goto bad;
412 			}
413 		}
414 	}
415 
416 
417 	/* strip off the authentication data */
418 	m_adj(m, (int)-siz);
419 	ip = mtod(m, struct ip *);
420 #ifdef IPLEN_FLIPPED
421 	ip->ip_len = ip->ip_len - (u_short)siz;
422 #else
423 	ip->ip_len = htons(ntohs(ip->ip_len) - siz);
424 #endif
425 
426 noreplaycheck:
427 
428 	/* process main esp header. */
429 	if (sav->flags & SADB_X_EXT_OLD) {
430 		/* RFC 1827 */
431 		esplen = sizeof(struct esp);
432 	} else {
433 		/* RFC 2406 */
434 		if (sav->flags & SADB_X_EXT_DERIV) {
435 			esplen = sizeof(struct esp);
436 		} else {
437 			esplen = sizeof(struct newesp);
438 		}
439 	}
440 
441 	if (m->m_pkthdr.len < off + esplen + ivlen + sizeof(esptail)) {
442 		ipseclog((LOG_WARNING,
443 		    "IPv4 ESP input: packet too short\n"));
444 		IPSEC_STAT_INCREMENT(ipsecstat.in_inval);
445 		goto bad;
446 	}
447 
448 	if (m->m_len < off + esplen + ivlen) {
449 		m = m_pullup(m, (int)(off + esplen + ivlen));
450 		if (!m) {
451 			ipseclog((LOG_DEBUG,
452 			    "IPv4 ESP input: can't pullup in esp4_input\n"));
453 			IPSEC_STAT_INCREMENT(ipsecstat.in_inval);
454 			goto bad;
455 		}
456 		ip = mtod(m, struct ip *);
457 	}
458 
459 	/*
460 	 * pre-compute and cache intermediate key
461 	 */
462 	if (esp_schedule(algo, sav) != 0) {
463 		IPSEC_STAT_INCREMENT(ipsecstat.in_inval);
464 		goto bad;
465 	}
466 
467 	/*
468 	 * decrypt the packet.
469 	 */
470 	if (!algo->decrypt) {
471 		panic("internal error: no decrypt function");
472 	}
473 	KERNEL_DEBUG(DBG_FNC_DECRYPT | DBG_FUNC_START, 0, 0, 0, 0, 0);
474 	if ((*algo->decrypt)(m, off, sav, algo, ivlen)) {
475 		/* m is already freed */
476 		m = NULL;
477 		ipseclog((LOG_ERR, "decrypt fail in IPv4 ESP input: %s\n",
478 		    ipsec_logsastr(sav)));
479 		IPSEC_STAT_INCREMENT(ipsecstat.in_inval);
480 		KERNEL_DEBUG(DBG_FNC_DECRYPT | DBG_FUNC_END, 1, 0, 0, 0, 0);
481 		goto bad;
482 	}
483 	KERNEL_DEBUG(DBG_FNC_DECRYPT | DBG_FUNC_END, 2, 0, 0, 0, 0);
484 	IPSEC_STAT_INCREMENT(ipsecstat.in_esphist[sav->alg_enc]);
485 
486 	m->m_flags |= M_DECRYPTED;
487 
488 	if (algo->finalizedecrypt) {
489 		if ((*algo->finalizedecrypt)(sav, saved_icv, algo->icvlen)) {
490 			ipseclog((LOG_ERR, "esp4 packet decryption ICV failure: %s\n",
491 			    ipsec_logsastr(sav)));
492 			IPSEC_STAT_INCREMENT(ipsecstat.in_espauthfail);
493 			KERNEL_DEBUG(DBG_FNC_DECRYPT | DBG_FUNC_END, 1, 0, 0, 0, 0);
494 			goto bad;
495 		} else {
496 			m->m_flags |= M_AUTHIPDGM;
497 			IPSEC_STAT_INCREMENT(ipsecstat.in_espauthsucc);
498 
499 			/*
500 			 * update replay window.
501 			 */
502 			if ((sav->flags & SADB_X_EXT_OLD) == 0 && sav->replay[replay_index] != NULL) {
503 				if (ipsec_updatereplay(seq, sav, (u_int8_t)replay_index)) {
504 					IPSEC_STAT_INCREMENT(ipsecstat.in_espreplay);
505 					goto bad;
506 				}
507 			}
508 		}
509 	}
510 
511 	/*
512 	 * find the trailer of the ESP.
513 	 */
514 	m_copydata(m, m->m_pkthdr.len - sizeof(esptail), sizeof(esptail),
515 	    (caddr_t)&esptail);
516 	nxt = esptail.esp_nxt;
517 	taillen = esptail.esp_padlen + sizeof(esptail);
518 
519 	if (m->m_pkthdr.len < taillen
520 	    || m->m_pkthdr.len - taillen < hlen) { /*?*/
521 		ipseclog((LOG_WARNING,
522 		    "bad pad length in IPv4 ESP input: %s %s\n",
523 		    ipsec4_logpacketstr(ip, spi), ipsec_logsastr(sav)));
524 		IPSEC_STAT_INCREMENT(ipsecstat.in_inval);
525 		goto bad;
526 	}
527 
528 	/* strip off the trailing pad area. */
529 	m_adj(m, (int)-taillen);
530 	ip = mtod(m, struct ip *);
531 #ifdef IPLEN_FLIPPED
532 	ip->ip_len = ip->ip_len - (u_short)taillen;
533 #else
534 	ip->ip_len = htons(ntohs(ip->ip_len) - taillen);
535 #endif
536 	if (ip->ip_p == IPPROTO_UDP) {
537 		// offset includes the outer ip and udp header lengths.
538 		if (m->m_len < off) {
539 			m = m_pullup(m, off);
540 			if (!m) {
541 				ipseclog((LOG_DEBUG,
542 				    "IPv4 ESP input: invalid udp encapsulated ESP packet length \n"));
543 				IPSEC_STAT_INCREMENT(ipsecstat.in_inval);
544 				goto bad;
545 			}
546 			ip = mtod(m, struct ip *);
547 		}
548 
549 		// check the UDP encap header to detect changes in the source port, and then strip the header
550 		off -= sizeof(struct udphdr); // off no longer includes the udphdr's size
551 		// if peer is behind nat and this is the latest esp packet
552 		if ((sav->flags & SADB_X_EXT_NATT_DETECTED_PEER) != 0 &&
553 		    (sav->flags & SADB_X_EXT_OLD) == 0 &&
554 		    seq && sav->replay[replay_index] &&
555 		    seq >= sav->replay[replay_index]->lastseq) {
556 			struct udphdr *encap_uh = (__typeof__(encap_uh))(void *)((caddr_t)ip + off);
557 			if (encap_uh->uh_sport &&
558 			    ntohs(encap_uh->uh_sport) != sav->remote_ike_port) {
559 				sav->remote_ike_port = ntohs(encap_uh->uh_sport);
560 			}
561 		}
562 		ip = esp4_input_strip_udp_encap(m, off);
563 		esp = (struct esp *)(void *)(((u_int8_t *)ip) + off);
564 	}
565 
566 	/* was it transmitted over the IPsec tunnel SA? */
567 	if (ipsec4_tunnel_validate(m, (int)(off + esplen + ivlen), nxt, sav, &ifamily)) {
568 		ifaddr_t ifa;
569 		struct sockaddr_storage addr;
570 
571 		/*
572 		 * strip off all the headers that precedes ESP header.
573 		 *	IP4 xx ESP IP4' payload -> IP4' payload
574 		 *
575 		 * XXX more sanity checks
576 		 * XXX relationship with gif?
577 		 */
578 		u_int8_t tos, otos;
579 		u_int8_t inner_ip_proto = 0;
580 		int sum;
581 
582 		tos = ip->ip_tos;
583 		m_adj(m, (int)(off + esplen + ivlen));
584 		if (ifamily == AF_INET) {
585 			struct sockaddr_in *ipaddr;
586 
587 			if (m->m_len < sizeof(*ip)) {
588 				m = m_pullup(m, sizeof(*ip));
589 				if (!m) {
590 					IPSEC_STAT_INCREMENT(ipsecstat.in_inval);
591 					goto bad;
592 				}
593 			}
594 			ip = mtod(m, struct ip *);
595 			/* ECN consideration. */
596 
597 			otos = ip->ip_tos;
598 			if (ip_ecn_egress(ip4_ipsec_ecn, &tos, &ip->ip_tos) == 0) {
599 				IPSEC_STAT_INCREMENT(ipsecstat.in_inval);
600 				goto bad;
601 			}
602 
603 			if (otos != ip->ip_tos) {
604 				sum = ~ntohs(ip->ip_sum) & 0xffff;
605 				sum += (~otos & 0xffff) + ip->ip_tos;
606 				sum = (sum >> 16) + (sum & 0xffff);
607 				sum += (sum >> 16); /* add carry */
608 				ip->ip_sum = htons(~sum & 0xffff);
609 			}
610 
611 			if (!key_checktunnelsanity(sav, AF_INET,
612 			    (caddr_t)&ip->ip_src, (caddr_t)&ip->ip_dst)) {
613 				ipseclog((LOG_ERR, "ipsec tunnel address mismatch "
614 				    "in ESP input: %s %s\n",
615 				    ipsec4_logpacketstr(ip, spi), ipsec_logsastr(sav)));
616 				IPSEC_STAT_INCREMENT(ipsecstat.in_inval);
617 				goto bad;
618 			}
619 
620 			inner_ip_proto = ip->ip_p;
621 
622 			bzero(&addr, sizeof(addr));
623 			ipaddr = (__typeof__(ipaddr)) & addr;
624 			ipaddr->sin_family = AF_INET;
625 			ipaddr->sin_len = sizeof(*ipaddr);
626 			ipaddr->sin_addr = ip->ip_dst;
627 		} else if (ifamily == AF_INET6) {
628 			struct sockaddr_in6 *ip6addr;
629 
630 			/*
631 			 * m_pullup is prohibited in KAME IPv6 input processing
632 			 * but there's no other way!
633 			 */
634 			if (m->m_len < sizeof(*ip6)) {
635 				m = m_pullup(m, sizeof(*ip6));
636 				if (!m) {
637 					IPSEC_STAT_INCREMENT(ipsecstat.in_inval);
638 					goto bad;
639 				}
640 			}
641 
642 			/*
643 			 * Expect 32-bit aligned data pointer on strict-align
644 			 * platforms.
645 			 */
646 			MBUF_STRICT_DATA_ALIGNMENT_CHECK_32(m);
647 
648 			ip6 = mtod(m, struct ip6_hdr *);
649 
650 			/* ECN consideration. */
651 			if (ip64_ecn_egress(ip4_ipsec_ecn, &tos, &ip6->ip6_flow) == 0) {
652 				IPSEC_STAT_INCREMENT(ipsecstat.in_inval);
653 				goto bad;
654 			}
655 
656 			if (!key_checktunnelsanity(sav, AF_INET6,
657 			    (caddr_t)&ip6->ip6_src, (caddr_t)&ip6->ip6_dst)) {
658 				ipseclog((LOG_ERR, "ipsec tunnel address mismatch "
659 				    "in ESP input: %s %s\n",
660 				    ipsec6_logpacketstr(ip6, spi), ipsec_logsastr(sav)));
661 				IPSEC_STAT_INCREMENT(ipsecstat.in_inval);
662 				goto bad;
663 			}
664 
665 			inner_ip_proto = ip6->ip6_nxt;
666 
667 			bzero(&addr, sizeof(addr));
668 			ip6addr = (__typeof__(ip6addr)) & addr;
669 			ip6addr->sin6_family = AF_INET6;
670 			ip6addr->sin6_len = sizeof(*ip6addr);
671 			ip6addr->sin6_addr = ip6->ip6_dst;
672 		} else {
673 			ipseclog((LOG_ERR, "ipsec tunnel unsupported address family "
674 			    "in ESP input\n"));
675 			goto bad;
676 		}
677 
678 		key_sa_recordxfer(sav, m->m_pkthdr.len);
679 		if (ipsec_incr_history_count(m, IPPROTO_ESP, spi) != 0 ||
680 		    ipsec_incr_history_count(m, IPPROTO_IPV4, 0) != 0) {
681 			IPSEC_STAT_INCREMENT(ipsecstat.in_nomem);
682 			goto bad;
683 		}
684 
685 		// update the receiving interface address based on the inner address
686 		ifa = ifa_ifwithaddr((struct sockaddr *)&addr);
687 		if (ifa) {
688 			m->m_pkthdr.rcvif = ifa->ifa_ifp;
689 			ifa_remref(ifa);
690 		}
691 
692 		/* Clear the csum flags, they can't be valid for the inner headers */
693 		m->m_pkthdr.csum_flags = 0;
694 
695 		// Input via IPsec interface
696 		lck_mtx_lock(sadb_mutex);
697 		ifnet_t ipsec_if = sav->sah->ipsec_if;
698 		if (ipsec_if != NULL) {
699 			// If an interface is found, add a reference count before dropping the lock
700 			ifnet_reference(ipsec_if);
701 		}
702 		lck_mtx_unlock(sadb_mutex);
703 
704 		if ((m->m_pkthdr.pkt_flags & PKTF_WAKE_PKT) == PKTF_WAKE_PKT) {
705 			if (m->m_pkthdr.rcvif != NULL) {
706 				if_ports_used_match_mbuf(m->m_pkthdr.rcvif, ifamily, m);
707 			} else {
708 				ipseclog((LOG_ERR, "no input interface for ipsec wake packet\n"));
709 			}
710 		}
711 
712 		if (ipsec_if != NULL) {
713 			esp_input_log(m, sav, spi, seq);
714 
715 			// Return mbuf
716 			if (interface != NULL &&
717 			    interface == ipsec_if) {
718 				out_m = m;
719 				ifnet_release(ipsec_if);
720 				goto done;
721 			}
722 
723 			errno_t inject_error = ipsec_inject_inbound_packet(ipsec_if, m);
724 			ifnet_release(ipsec_if);
725 
726 			if (inject_error == 0) {
727 				m = NULL;
728 				goto done;
729 			} else {
730 				goto bad;
731 			}
732 		}
733 
734 		if (proto_input(ifamily == AF_INET ? PF_INET : PF_INET6, m) != 0) {
735 			goto bad;
736 		}
737 
738 		nxt = IPPROTO_DONE;
739 		KERNEL_DEBUG(DBG_FNC_ESPIN | DBG_FUNC_END, 2, 0, 0, 0, 0);
740 	} else {
741 		/*
742 		 * strip off ESP header and IV.
743 		 * even in m_pulldown case, we need to strip off ESP so that
744 		 * we can always compute checksum for AH correctly.
745 		 */
746 		size_t stripsiz;
747 
748 		stripsiz = esplen + ivlen;
749 
750 		ip = mtod(m, struct ip *);
751 		ovbcopy((caddr_t)ip, (caddr_t)(((u_char *)ip) + stripsiz), off);
752 		m->m_data += stripsiz;
753 		m->m_len -= stripsiz;
754 		m->m_pkthdr.len -= stripsiz;
755 
756 		ip = mtod(m, struct ip *);
757 #ifdef IPLEN_FLIPPED
758 		ip->ip_len = ip->ip_len - (u_short)stripsiz;
759 #else
760 		ip->ip_len = htons(ntohs(ip->ip_len) - stripsiz);
761 #endif
762 		ip->ip_p = (u_int8_t)nxt;
763 
764 		key_sa_recordxfer(sav, m->m_pkthdr.len);
765 		if (ipsec_incr_history_count(m, IPPROTO_ESP, spi) != 0) {
766 			IPSEC_STAT_INCREMENT(ipsecstat.in_nomem);
767 			goto bad;
768 		}
769 
770 		/*
771 		 * Set the csum valid flag, if we authenticated the
772 		 * packet, the payload shouldn't be corrupt unless
773 		 * it was corrupted before being signed on the other
774 		 * side.
775 		 */
776 		if (nxt == IPPROTO_TCP || nxt == IPPROTO_UDP) {
777 			m->m_pkthdr.csum_flags = CSUM_DATA_VALID | CSUM_PSEUDO_HDR;
778 			m->m_pkthdr.csum_data = 0xFFFF;
779 			_CASSERT(offsetof(struct pkthdr, csum_data) == offsetof(struct pkthdr, csum_rx_val));
780 		}
781 
782 		if (nxt != IPPROTO_DONE) {
783 			if ((ip_protox[nxt]->pr_flags & PR_LASTHDR) != 0 &&
784 			    ipsec4_in_reject(m, NULL)) {
785 				IPSEC_STAT_INCREMENT(ipsecstat.in_polvio);
786 				goto bad;
787 			}
788 			KERNEL_DEBUG(DBG_FNC_ESPIN | DBG_FUNC_END, 3, 0, 0, 0, 0);
789 
790 			/* translate encapsulated UDP port ? */
791 			if ((sav->flags & SADB_X_EXT_NATT_MULTIPLEUSERS) != 0) {
792 				struct udphdr   *udp;
793 
794 				if (nxt != IPPROTO_UDP) {       /* not UPD packet - drop it */
795 					IPSEC_STAT_INCREMENT(ipsecstat.in_inval);
796 					goto bad;
797 				}
798 
799 				if (m->m_len < off + sizeof(struct udphdr)) {
800 					m = m_pullup(m, off + sizeof(struct udphdr));
801 					if (!m) {
802 						ipseclog((LOG_DEBUG,
803 						    "IPv4 ESP input: can't pullup UDP header in esp4_input\n"));
804 						IPSEC_STAT_INCREMENT(ipsecstat.in_inval);
805 						goto bad;
806 					}
807 					ip = mtod(m, struct ip *);
808 				}
809 				udp = (struct udphdr *)(void *)(((u_int8_t *)ip) + off);
810 
811 				lck_mtx_lock(sadb_mutex);
812 				if (sav->natt_encapsulated_src_port == 0) {
813 					sav->natt_encapsulated_src_port = udp->uh_sport;
814 				} else if (sav->natt_encapsulated_src_port != udp->uh_sport) {  /* something wrong */
815 					IPSEC_STAT_INCREMENT(ipsecstat.in_inval);
816 					lck_mtx_unlock(sadb_mutex);
817 					goto bad;
818 				}
819 				lck_mtx_unlock(sadb_mutex);
820 				udp->uh_sport = htons(sav->remote_ike_port);
821 				udp->uh_sum = 0;
822 			}
823 
824 			DTRACE_IP6(receive, struct mbuf *, m, struct inpcb *, NULL,
825 			    struct ip *, ip, struct ifnet *, m->m_pkthdr.rcvif,
826 			    struct ip *, ip, struct ip6_hdr *, NULL);
827 
828 			// Input via IPsec interface legacy path
829 			lck_mtx_lock(sadb_mutex);
830 			ifnet_t ipsec_if = sav->sah->ipsec_if;
831 			if (ipsec_if != NULL) {
832 				// If an interface is found, add a reference count before dropping the lock
833 				ifnet_reference(ipsec_if);
834 			}
835 			lck_mtx_unlock(sadb_mutex);
836 			if (ipsec_if != NULL) {
837 				int mlen;
838 				if ((mlen = m_length2(m, NULL)) < hlen) {
839 					ipseclog((LOG_DEBUG,
840 					    "IPv4 ESP input: decrypted packet too short %d < %u\n",
841 					    mlen, hlen));
842 					IPSEC_STAT_INCREMENT(ipsecstat.in_inval);
843 					ifnet_release(ipsec_if);
844 					goto bad;
845 				}
846 				ip->ip_len = htons(ip->ip_len + hlen);
847 				ip->ip_off = htons(ip->ip_off);
848 				ip->ip_sum = 0;
849 				ip->ip_sum = ip_cksum_hdr_in(m, hlen);
850 
851 				esp_input_log(m, sav, spi, seq);
852 
853 				if ((m->m_pkthdr.pkt_flags & PKTF_WAKE_PKT) == PKTF_WAKE_PKT) {
854 					if_ports_used_match_mbuf(ipsec_if, PF_INET, m);
855 				}
856 
857 				// Return mbuf
858 				if (interface != NULL &&
859 				    interface == ipsec_if) {
860 					out_m = m;
861 					ifnet_release(ipsec_if);
862 					goto done;
863 				}
864 
865 				errno_t inject_error = ipsec_inject_inbound_packet(ipsec_if, m);
866 				ifnet_release(ipsec_if);
867 
868 				if (inject_error == 0) {
869 					m = NULL;
870 					goto done;
871 				} else {
872 					goto bad;
873 				}
874 			}
875 
876 			if ((m->m_pkthdr.pkt_flags & PKTF_WAKE_PKT) == PKTF_WAKE_PKT) {
877 				if_ports_used_match_mbuf(m->m_pkthdr.rcvif, PF_INET, m);
878 				if (m->m_pkthdr.rcvif == NULL) {
879 					ipseclog((LOG_ERR, "no input interface for ipsec wake packet\n"));
880 				}
881 			}
882 
883 			ip_proto_dispatch_in(m, off, (u_int8_t)nxt, 0);
884 		} else {
885 			m_freem(m);
886 		}
887 		m = NULL;
888 	}
889 
890 done:
891 	if (sav) {
892 		KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
893 		    printf("DP esp4_input call free SA:0x%llx\n",
894 		    (uint64_t)VM_KERNEL_ADDRPERM(sav)));
895 		key_freesav(sav, KEY_SADB_UNLOCKED);
896 	}
897 	IPSEC_STAT_INCREMENT(ipsecstat.in_success);
898 	return out_m;
899 bad:
900 	if (sav) {
901 		KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
902 		    printf("DP esp4_input call free SA:0x%llx\n",
903 		    (uint64_t)VM_KERNEL_ADDRPERM(sav)));
904 		key_freesav(sav, KEY_SADB_UNLOCKED);
905 	}
906 	if (m) {
907 		m_freem(m);
908 	}
909 	KERNEL_DEBUG(DBG_FNC_ESPIN | DBG_FUNC_END, 4, 0, 0, 0, 0);
910 	return out_m;
911 }
912 
913 int
esp6_input(struct mbuf ** mp,int * offp,int proto)914 esp6_input(struct mbuf **mp, int *offp, int proto)
915 {
916 	return esp6_input_extended(mp, offp, proto, NULL);
917 }
918 
919 int
esp6_input_extended(struct mbuf ** mp,int * offp,int proto,ifnet_t interface)920 esp6_input_extended(struct mbuf **mp, int *offp, int proto, ifnet_t interface)
921 {
922 	struct mbuf *m = *mp;
923 	int off = *offp;
924 	struct ip *ip;
925 	struct ip6_hdr *ip6;
926 	struct esp *esp;
927 	struct esptail esptail;
928 	u_int32_t spi;
929 	u_int32_t seq;
930 	u_int32_t replay_index = 0;
931 	struct secasvar *sav = NULL;
932 	u_int16_t nxt;
933 	const struct esp_algorithm *algo;
934 	int ivlen;
935 	size_t esplen;
936 	u_int16_t taillen;
937 	sa_family_t ifamily;
938 
939 	/* sanity check for alignment. */
940 	if (off % 4 != 0 || m->m_pkthdr.len % 4 != 0) {
941 		ipseclog((LOG_ERR, "IPv6 ESP input: packet alignment problem "
942 		    "(off=%d, pktlen=%d)\n", off, m->m_pkthdr.len));
943 		IPSEC_STAT_INCREMENT(ipsec6stat.in_inval);
944 		goto bad;
945 	}
946 
947 #ifndef PULLDOWN_TEST
948 	IP6_EXTHDR_CHECK(m, off, ESPMAXLEN, {return IPPROTO_DONE;});
949 	esp = (struct esp *)(void *)(mtod(m, caddr_t) + off);
950 #else
951 	IP6_EXTHDR_GET(esp, struct esp *, m, off, ESPMAXLEN);
952 	if (esp == NULL) {
953 		IPSEC_STAT_INCREMENT(ipsec6stat.in_inval);
954 		return IPPROTO_DONE;
955 	}
956 #endif
957 	m->m_pkthdr.csum_flags &= ~CSUM_RX_FLAGS;
958 
959 	/* Expect 32-bit data aligned pointer on strict-align platforms */
960 	MBUF_STRICT_DATA_ALIGNMENT_CHECK_32(m);
961 
962 	ip6 = mtod(m, struct ip6_hdr *);
963 	if (__improbable(ntohs(ip6->ip6_plen) == 0)) {
964 		ipseclog((LOG_ERR, "IPv6 ESP input: "
965 		    "ESP with IPv6 jumbogram is not supported.\n"));
966 		IPSEC_STAT_INCREMENT(ipsec6stat.in_inval);
967 		goto bad;
968 	}
969 
970 	if (__improbable(proto != IPPROTO_ESP &&
971 	    !(proto == IPPROTO_UDP &&
972 	    off >= (sizeof(struct udphdr) + sizeof(struct ip6_hdr))))) {
973 		ipseclog((LOG_DEBUG, "IPv6 ESP input: invalid protocol type\n"));
974 		IPSEC_STAT_INCREMENT(ipsec6stat.in_inval);
975 		goto bad;
976 	}
977 
978 	/* find the sassoc. */
979 	spi = esp->esp_spi;
980 
981 	if ((sav = key_allocsa_extended(AF_INET6,
982 	    (caddr_t)&ip6->ip6_src, (caddr_t)&ip6->ip6_dst,
983 	    interface != NULL ? interface->if_index : IFSCOPE_UNKNOWN,
984 	    IPPROTO_ESP, spi, interface)) == 0) {
985 		ipseclog((LOG_WARNING,
986 		    "IPv6 ESP input: no key association found for spi %u (0x%08x) seq %u"
987 		    " src %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x"
988 		    " dst %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x if %s\n",
989 		    (u_int32_t)ntohl(spi), (u_int32_t)ntohl(spi), ntohl(((struct newesp *)esp)->esp_seq),
990 		    ntohs(ip6->ip6_src.__u6_addr.__u6_addr16[0]), ntohs(ip6->ip6_src.__u6_addr.__u6_addr16[1]),
991 		    ntohs(ip6->ip6_src.__u6_addr.__u6_addr16[2]), ntohs(ip6->ip6_src.__u6_addr.__u6_addr16[3]),
992 		    ntohs(ip6->ip6_src.__u6_addr.__u6_addr16[4]), ntohs(ip6->ip6_src.__u6_addr.__u6_addr16[5]),
993 		    ntohs(ip6->ip6_src.__u6_addr.__u6_addr16[6]), ntohs(ip6->ip6_src.__u6_addr.__u6_addr16[7]),
994 		    ntohs(ip6->ip6_dst.__u6_addr.__u6_addr16[0]), ntohs(ip6->ip6_dst.__u6_addr.__u6_addr16[1]),
995 		    ntohs(ip6->ip6_dst.__u6_addr.__u6_addr16[2]), ntohs(ip6->ip6_dst.__u6_addr.__u6_addr16[3]),
996 		    ntohs(ip6->ip6_dst.__u6_addr.__u6_addr16[4]), ntohs(ip6->ip6_dst.__u6_addr.__u6_addr16[5]),
997 		    ntohs(ip6->ip6_dst.__u6_addr.__u6_addr16[6]), ntohs(ip6->ip6_dst.__u6_addr.__u6_addr16[7]),
998 		    ((interface != NULL) ? if_name(interface) : "NONE")));
999 		IPSEC_STAT_INCREMENT(ipsec6stat.in_nosa);
1000 		goto bad;
1001 	}
1002 	KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
1003 	    printf("DP esp6_input called to allocate SA:0x%llx\n",
1004 	    (uint64_t)VM_KERNEL_ADDRPERM(sav)));
1005 
1006 	if (sav->state != SADB_SASTATE_MATURE
1007 	    && sav->state != SADB_SASTATE_DYING) {
1008 		ipseclog((LOG_DEBUG,
1009 		    "IPv6 ESP input: non-mature/dying SA found for spi %u (0x%08x)\n",
1010 		    (u_int32_t)ntohl(spi), (u_int32_t)ntohl(spi)));
1011 		IPSEC_STAT_INCREMENT(ipsec6stat.in_badspi);
1012 		goto bad;
1013 	}
1014 
1015 	algo = esp_algorithm_lookup(sav->alg_enc);
1016 	if (!algo) {
1017 		ipseclog((LOG_DEBUG, "IPv6 ESP input: "
1018 		    "unsupported encryption algorithm for spi %u (0x%08x)\n",
1019 		    (u_int32_t)ntohl(spi), (u_int32_t)ntohl(spi)));
1020 		IPSEC_STAT_INCREMENT(ipsec6stat.in_badspi);
1021 		goto bad;
1022 	}
1023 
1024 	/* check if we have proper ivlen information */
1025 	ivlen = sav->ivlen;
1026 	if (__improbable(ivlen < 0)) {
1027 		ipseclog((LOG_ERR, "improper ivlen in IPv6 ESP input: %s %s\n",
1028 		    ipsec6_logpacketstr(ip6, spi), ipsec_logsastr(sav)));
1029 		IPSEC_STAT_INCREMENT(ipsec6stat.in_badspi);
1030 		goto bad;
1031 	}
1032 
1033 	seq = ntohl(((struct newesp *)esp)->esp_seq);
1034 
1035 	if ((sav->flags2 & SADB_X_EXT_SA2_SEQ_PER_TRAFFIC_CLASS) ==
1036 	    SADB_X_EXT_SA2_SEQ_PER_TRAFFIC_CLASS) {
1037 		replay_index = seq >> PER_TC_REPLAY_WINDOW_SN_SHIFT;
1038 	}
1039 
1040 	if (!((sav->flags & SADB_X_EXT_OLD) == 0 &&
1041 	    sav->replay[replay_index] != NULL &&
1042 	    ((sav->alg_auth && sav->key_auth) || algo->finalizedecrypt))) {
1043 		goto noreplaycheck;
1044 	}
1045 
1046 	if ((sav->alg_auth == SADB_X_AALG_NULL || sav->alg_auth == SADB_AALG_NONE) &&
1047 	    !algo->finalizedecrypt) {
1048 		goto noreplaycheck;
1049 	}
1050 
1051 	/*
1052 	 * check for sequence number.
1053 	 */
1054 	if (ipsec_chkreplay(seq, sav, (u_int8_t)replay_index)) {
1055 		; /*okey*/
1056 	} else {
1057 		IPSEC_STAT_INCREMENT(ipsec6stat.in_espreplay);
1058 		ipseclog((LOG_WARNING,
1059 		    "replay packet in IPv6 ESP input: seq(%u) idx(%u) %s %s\n",
1060 		    seq, (u_int8_t)replay_index, ipsec6_logpacketstr(ip6, spi), ipsec_logsastr(sav)));
1061 		goto bad;
1062 	}
1063 
1064 	/* Save ICV from packet for verification later */
1065 	size_t siz = 0;
1066 	unsigned char saved_icv[AH_MAXSUMSIZE] __attribute__((aligned(4)));
1067 	if (algo->finalizedecrypt) {
1068 		siz = algo->icvlen;
1069 		VERIFY(siz <= UINT16_MAX);
1070 		if (m->m_pkthdr.len < off + ESPMAXLEN + siz) {
1071 			ipseclog((LOG_DEBUG,
1072 			    "invalid ESP packet length %u, missing ICV\n",
1073 			    m->m_pkthdr.len));
1074 			IPSEC_STAT_INCREMENT(ipsec6stat.in_inval);
1075 			goto bad;
1076 		}
1077 		m_copydata(m, m->m_pkthdr.len - (int)siz, (int)siz, (caddr_t) saved_icv);
1078 	} else {
1079 		/* check ICV immediately */
1080 		u_char sum0[AH_MAXSUMSIZE] __attribute__((aligned(4)));
1081 		u_char sum[AH_MAXSUMSIZE] __attribute__((aligned(4)));
1082 		const struct ah_algorithm *sumalgo;
1083 
1084 		sumalgo = ah_algorithm_lookup(sav->alg_auth);
1085 		if (!sumalgo) {
1086 			goto noreplaycheck;
1087 		}
1088 		siz = (((*sumalgo->sumsiz)(sav) + 3) & ~(4 - 1));
1089 		if (m->m_pkthdr.len < off + ESPMAXLEN + siz) {
1090 			ipseclog((LOG_DEBUG,
1091 			    "invalid ESP packet length %u, missing ICV\n",
1092 			    m->m_pkthdr.len));
1093 			IPSEC_STAT_INCREMENT(ipsec6stat.in_inval);
1094 			goto bad;
1095 		}
1096 		if (__improbable(AH_MAXSUMSIZE < siz)) {
1097 			ipseclog((LOG_DEBUG,
1098 			    "internal error: AH_MAXSUMSIZE must be larger than %u\n",
1099 			    (u_int32_t)siz));
1100 			IPSEC_STAT_INCREMENT(ipsec6stat.in_inval);
1101 			goto bad;
1102 		}
1103 
1104 		m_copydata(m, m->m_pkthdr.len - (int)siz, (int)siz, (caddr_t) &sum0[0]);
1105 
1106 		if (esp_auth(m, off, m->m_pkthdr.len - off - siz, sav, sum)) {
1107 			ipseclog((LOG_WARNING, "auth fail in IPv6 ESP input: %s %s\n",
1108 			    ipsec6_logpacketstr(ip6, spi), ipsec_logsastr(sav)));
1109 			IPSEC_STAT_INCREMENT(ipsec6stat.in_espauthfail);
1110 			goto bad;
1111 		}
1112 
1113 		if (cc_cmp_safe(siz, sum0, sum)) {
1114 			ipseclog((LOG_WARNING, "auth fail in IPv6 ESP input: %s %s\n",
1115 			    ipsec6_logpacketstr(ip6, spi), ipsec_logsastr(sav)));
1116 			IPSEC_STAT_INCREMENT(ipsec6stat.in_espauthfail);
1117 			goto bad;
1118 		}
1119 
1120 		m->m_flags |= M_AUTHIPDGM;
1121 		IPSEC_STAT_INCREMENT(ipsec6stat.in_espauthsucc);
1122 
1123 		/*
1124 		 * update replay window.
1125 		 */
1126 		if ((sav->flags & SADB_X_EXT_OLD) == 0 && sav->replay[replay_index] != NULL) {
1127 			if (ipsec_updatereplay(seq, sav, (u_int8_t)replay_index)) {
1128 				IPSEC_STAT_INCREMENT(ipsec6stat.in_espreplay);
1129 				goto bad;
1130 			}
1131 		}
1132 	}
1133 
1134 	/* strip off the authentication data */
1135 	m_adj(m, (int)-siz);
1136 	ip6 = mtod(m, struct ip6_hdr *);
1137 	ip6->ip6_plen = htons(ntohs(ip6->ip6_plen) - (u_int16_t)siz);
1138 
1139 noreplaycheck:
1140 
1141 	/* process main esp header. */
1142 	if (sav->flags & SADB_X_EXT_OLD) {
1143 		/* RFC 1827 */
1144 		esplen = sizeof(struct esp);
1145 	} else {
1146 		/* RFC 2406 */
1147 		if (sav->flags & SADB_X_EXT_DERIV) {
1148 			esplen = sizeof(struct esp);
1149 		} else {
1150 			esplen = sizeof(struct newesp);
1151 		}
1152 	}
1153 
1154 	if (m->m_pkthdr.len < off + esplen + ivlen + sizeof(esptail)) {
1155 		ipseclog((LOG_WARNING,
1156 		    "IPv6 ESP input: packet too short\n"));
1157 		IPSEC_STAT_INCREMENT(ipsec6stat.in_inval);
1158 		goto bad;
1159 	}
1160 
1161 #ifndef PULLDOWN_TEST
1162 	IP6_EXTHDR_CHECK(m, off, (int)(esplen + ivlen), goto bad);  /*XXX*/
1163 #else
1164 	IP6_EXTHDR_GET(esp, struct esp *, m, off, esplen + ivlen);
1165 	if (esp == NULL) {
1166 		IPSEC_STAT_INCREMENT(ipsec6stat.in_inval);
1167 		m = NULL;
1168 		goto bad;
1169 	}
1170 #endif
1171 	ip6 = mtod(m, struct ip6_hdr *);        /*set it again just in case*/
1172 
1173 	/*
1174 	 * pre-compute and cache intermediate key
1175 	 */
1176 	if (esp_schedule(algo, sav) != 0) {
1177 		IPSEC_STAT_INCREMENT(ipsec6stat.in_inval);
1178 		goto bad;
1179 	}
1180 
1181 	/*
1182 	 * decrypt the packet.
1183 	 */
1184 	if (!algo->decrypt) {
1185 		panic("internal error: no decrypt function");
1186 	}
1187 	KERNEL_DEBUG(DBG_FNC_DECRYPT | DBG_FUNC_START, 0, 0, 0, 0, 0);
1188 	if ((*algo->decrypt)(m, off, sav, algo, ivlen)) {
1189 		/* m is already freed */
1190 		m = NULL;
1191 		ipseclog((LOG_ERR, "decrypt fail in IPv6 ESP input: %s\n",
1192 		    ipsec_logsastr(sav)));
1193 		IPSEC_STAT_INCREMENT(ipsec6stat.in_inval);
1194 		KERNEL_DEBUG(DBG_FNC_DECRYPT | DBG_FUNC_END, 1, 0, 0, 0, 0);
1195 		goto bad;
1196 	}
1197 	KERNEL_DEBUG(DBG_FNC_DECRYPT | DBG_FUNC_END, 2, 0, 0, 0, 0);
1198 	IPSEC_STAT_INCREMENT(ipsec6stat.in_esphist[sav->alg_enc]);
1199 
1200 	m->m_flags |= M_DECRYPTED;
1201 
1202 	if (algo->finalizedecrypt) {
1203 		if ((*algo->finalizedecrypt)(sav, saved_icv, algo->icvlen)) {
1204 			ipseclog((LOG_ERR, "esp6 packet decryption ICV failure: %s\n",
1205 			    ipsec_logsastr(sav)));
1206 			IPSEC_STAT_INCREMENT(ipsec6stat.in_espauthfail);
1207 			KERNEL_DEBUG(DBG_FNC_DECRYPT | DBG_FUNC_END, 1, 0, 0, 0, 0);
1208 			goto bad;
1209 		} else {
1210 			m->m_flags |= M_AUTHIPDGM;
1211 			IPSEC_STAT_INCREMENT(ipsec6stat.in_espauthsucc);
1212 
1213 			/*
1214 			 * update replay window.
1215 			 */
1216 			if ((sav->flags & SADB_X_EXT_OLD) == 0 && sav->replay[replay_index] != NULL) {
1217 				if (ipsec_updatereplay(seq, sav, (u_int8_t)replay_index)) {
1218 					IPSEC_STAT_INCREMENT(ipsec6stat.in_espreplay);
1219 					goto bad;
1220 				}
1221 			}
1222 		}
1223 	}
1224 
1225 	/*
1226 	 * find the trailer of the ESP.
1227 	 */
1228 	m_copydata(m, m->m_pkthdr.len - sizeof(esptail), sizeof(esptail),
1229 	    (caddr_t)&esptail);
1230 	nxt = esptail.esp_nxt;
1231 	taillen = esptail.esp_padlen + sizeof(esptail);
1232 
1233 	if (m->m_pkthdr.len < taillen
1234 	    || m->m_pkthdr.len - taillen < sizeof(struct ip6_hdr)) {    /*?*/
1235 		ipseclog((LOG_WARNING,
1236 		    "bad pad length in IPv6 ESP input: %s %s\n",
1237 		    ipsec6_logpacketstr(ip6, spi), ipsec_logsastr(sav)));
1238 		IPSEC_STAT_INCREMENT(ipsec6stat.in_inval);
1239 		goto bad;
1240 	}
1241 
1242 	/* strip off the trailing pad area. */
1243 	m_adj(m, -taillen);
1244 	ip6 = mtod(m, struct ip6_hdr *);
1245 	ip6->ip6_plen = htons(ntohs(ip6->ip6_plen) - taillen);
1246 
1247 	if (proto == IPPROTO_UDP) {
1248 		// offset includes the outer ip and udp header lengths.
1249 		if (m->m_len < off) {
1250 			m = m_pullup(m, off);
1251 			if (!m) {
1252 				ipseclog((LOG_DEBUG,
1253 				    "IPv6 ESP input: invalid udp encapsulated ESP packet length\n"));
1254 				IPSEC_STAT_INCREMENT(ipsec6stat.in_inval);
1255 				goto bad;
1256 			}
1257 			ip6 = mtod(m, struct ip6_hdr *);
1258 		}
1259 
1260 		// check the UDP encap header to detect changes in the source port, and then strip the header
1261 		off -= sizeof(struct udphdr); // off no longer includes the udphdr's size
1262 		// if peer is behind nat and this is the latest esp packet
1263 		if ((sav->flags & SADB_X_EXT_NATT_DETECTED_PEER) != 0 &&
1264 		    (sav->flags & SADB_X_EXT_OLD) == 0 &&
1265 		    seq && sav->replay[replay_index] &&
1266 		    seq >= sav->replay[replay_index]->lastseq) {
1267 			struct udphdr *encap_uh = (__typeof__(encap_uh))(void *)((caddr_t)ip6 + off);
1268 			if (encap_uh->uh_sport &&
1269 			    ntohs(encap_uh->uh_sport) != sav->remote_ike_port) {
1270 				sav->remote_ike_port = ntohs(encap_uh->uh_sport);
1271 			}
1272 		}
1273 		ip6 = esp6_input_strip_udp_encap(m, off);
1274 		esp = (struct esp *)(void *)(((u_int8_t *)ip6) + off);
1275 	}
1276 
1277 
1278 	/* was it transmitted over the IPsec tunnel SA? */
1279 	if (ipsec6_tunnel_validate(m, (int)(off + esplen + ivlen), nxt, sav, &ifamily)) {
1280 		ifaddr_t ifa;
1281 		struct sockaddr_storage addr;
1282 		u_int8_t inner_ip_proto = 0;
1283 
1284 		/*
1285 		 * strip off all the headers that precedes ESP header.
1286 		 *	IP6 xx ESP IP6' payload -> IP6' payload
1287 		 *
1288 		 * XXX more sanity checks
1289 		 * XXX relationship with gif?
1290 		 */
1291 		u_int32_t flowinfo;     /*net endian*/
1292 		flowinfo = ip6->ip6_flow;
1293 		m_adj(m, (int)(off + esplen + ivlen));
1294 		if (ifamily == AF_INET6) {
1295 			struct sockaddr_in6 *ip6addr;
1296 
1297 			if (m->m_len < sizeof(*ip6)) {
1298 #ifndef PULLDOWN_TEST
1299 				/*
1300 				 * m_pullup is prohibited in KAME IPv6 input processing
1301 				 * but there's no other way!
1302 				 */
1303 #else
1304 				/* okay to pullup in m_pulldown style */
1305 #endif
1306 				m = m_pullup(m, sizeof(*ip6));
1307 				if (!m) {
1308 					IPSEC_STAT_INCREMENT(ipsec6stat.in_inval);
1309 					goto bad;
1310 				}
1311 			}
1312 			ip6 = mtod(m, struct ip6_hdr *);
1313 			/* ECN consideration. */
1314 			if (ip6_ecn_egress(ip6_ipsec_ecn, &flowinfo, &ip6->ip6_flow) == 0) {
1315 				IPSEC_STAT_INCREMENT(ipsec6stat.in_inval);
1316 				goto bad;
1317 			}
1318 			if (!key_checktunnelsanity(sav, AF_INET6,
1319 			    (caddr_t)&ip6->ip6_src, (caddr_t)&ip6->ip6_dst)) {
1320 				ipseclog((LOG_ERR, "ipsec tunnel address mismatch "
1321 				    "in IPv6 ESP input: %s %s\n",
1322 				    ipsec6_logpacketstr(ip6, spi),
1323 				    ipsec_logsastr(sav)));
1324 				IPSEC_STAT_INCREMENT(ipsec6stat.in_inval);
1325 				goto bad;
1326 			}
1327 
1328 			inner_ip_proto = ip6->ip6_nxt;
1329 
1330 			bzero(&addr, sizeof(addr));
1331 			ip6addr = (__typeof__(ip6addr)) & addr;
1332 			ip6addr->sin6_family = AF_INET6;
1333 			ip6addr->sin6_len = sizeof(*ip6addr);
1334 			ip6addr->sin6_addr = ip6->ip6_dst;
1335 		} else if (ifamily == AF_INET) {
1336 			struct sockaddr_in *ipaddr;
1337 
1338 			if (m->m_len < sizeof(*ip)) {
1339 				m = m_pullup(m, sizeof(*ip));
1340 				if (!m) {
1341 					IPSEC_STAT_INCREMENT(ipsecstat.in_inval);
1342 					goto bad;
1343 				}
1344 			}
1345 
1346 			u_int8_t otos;
1347 			int sum;
1348 
1349 			ip = mtod(m, struct ip *);
1350 			otos = ip->ip_tos;
1351 			/* ECN consideration. */
1352 			if (ip46_ecn_egress(ip6_ipsec_ecn, &flowinfo, &ip->ip_tos) == 0) {
1353 				IPSEC_STAT_INCREMENT(ipsecstat.in_inval);
1354 				goto bad;
1355 			}
1356 
1357 			if (otos != ip->ip_tos) {
1358 				sum = ~ntohs(ip->ip_sum) & 0xffff;
1359 				sum += (~otos & 0xffff) + ip->ip_tos;
1360 				sum = (sum >> 16) + (sum & 0xffff);
1361 				sum += (sum >> 16); /* add carry */
1362 				ip->ip_sum = htons(~sum & 0xffff);
1363 			}
1364 
1365 			if (!key_checktunnelsanity(sav, AF_INET,
1366 			    (caddr_t)&ip->ip_src, (caddr_t)&ip->ip_dst)) {
1367 				ipseclog((LOG_ERR, "ipsec tunnel address mismatch "
1368 				    "in ESP input: %s %s\n",
1369 				    ipsec4_logpacketstr(ip, spi), ipsec_logsastr(sav)));
1370 				IPSEC_STAT_INCREMENT(ipsecstat.in_inval);
1371 				goto bad;
1372 			}
1373 
1374 			inner_ip_proto = ip->ip_p;
1375 
1376 			bzero(&addr, sizeof(addr));
1377 			ipaddr = (__typeof__(ipaddr)) & addr;
1378 			ipaddr->sin_family = AF_INET;
1379 			ipaddr->sin_len = sizeof(*ipaddr);
1380 			ipaddr->sin_addr = ip->ip_dst;
1381 		}
1382 
1383 		key_sa_recordxfer(sav, m->m_pkthdr.len);
1384 		if (ipsec_incr_history_count(m, IPPROTO_ESP, spi) != 0 ||
1385 		    ipsec_incr_history_count(m, IPPROTO_IPV6, 0) != 0) {
1386 			IPSEC_STAT_INCREMENT(ipsec6stat.in_nomem);
1387 			goto bad;
1388 		}
1389 
1390 		// update the receiving interface address based on the inner address
1391 		ifa = ifa_ifwithaddr((struct sockaddr *)&addr);
1392 		if (ifa) {
1393 			m->m_pkthdr.rcvif = ifa->ifa_ifp;
1394 			ifa_remref(ifa);
1395 		}
1396 
1397 		// Input via IPsec interface
1398 		lck_mtx_lock(sadb_mutex);
1399 		ifnet_t ipsec_if = sav->sah->ipsec_if;
1400 		if (ipsec_if != NULL) {
1401 			// If an interface is found, add a reference count before dropping the lock
1402 			ifnet_reference(ipsec_if);
1403 		}
1404 		lck_mtx_unlock(sadb_mutex);
1405 
1406 		if ((m->m_pkthdr.pkt_flags & PKTF_WAKE_PKT) == PKTF_WAKE_PKT) {
1407 			if_ports_used_match_mbuf(m->m_pkthdr.rcvif, ifamily, m);
1408 			if (m->m_pkthdr.rcvif == NULL) {
1409 				ipseclog((LOG_ERR, "no input interface for ipsec wake packet\n"));
1410 			}
1411 		}
1412 
1413 		if (ipsec_if != NULL) {
1414 			esp_input_log(m, sav, spi, seq);
1415 
1416 			// Return mbuf
1417 			if (interface != NULL &&
1418 			    interface == ipsec_if) {
1419 				ifnet_release(ipsec_if);
1420 				goto done;
1421 			}
1422 
1423 			errno_t inject_error = ipsec_inject_inbound_packet(ipsec_if, m);
1424 			ifnet_release(ipsec_if);
1425 
1426 			if (inject_error == 0) {
1427 				m = NULL;
1428 				nxt = IPPROTO_DONE;
1429 				goto done;
1430 			} else {
1431 				goto bad;
1432 			}
1433 		}
1434 
1435 		if (proto_input(ifamily == AF_INET ? PF_INET : PF_INET6, m) != 0) {
1436 			goto bad;
1437 		}
1438 		nxt = IPPROTO_DONE;
1439 	} else {
1440 		/*
1441 		 * strip off ESP header and IV.
1442 		 * even in m_pulldown case, we need to strip off ESP so that
1443 		 * we can always compute checksum for AH correctly.
1444 		 */
1445 		u_int16_t stripsiz;
1446 		char *prvnxtp;
1447 
1448 		/*
1449 		 * Set the next header field of the previous header correctly.
1450 		 */
1451 		prvnxtp = ip6_get_prevhdr(m, off); /* XXX */
1452 		*prvnxtp = (u_int8_t)nxt;
1453 
1454 		VERIFY(esplen + ivlen <= UINT16_MAX);
1455 		stripsiz = (u_int16_t)(esplen + ivlen);
1456 
1457 		ip6 = mtod(m, struct ip6_hdr *);
1458 		if (m->m_len >= stripsiz + off) {
1459 			ovbcopy((caddr_t)ip6, ((caddr_t)ip6) + stripsiz, off);
1460 			m->m_data += stripsiz;
1461 			m->m_len -= stripsiz;
1462 			m->m_pkthdr.len -= stripsiz;
1463 		} else {
1464 			/*
1465 			 * this comes with no copy if the boundary is on
1466 			 * cluster
1467 			 */
1468 			struct mbuf *n;
1469 
1470 			n = m_split(m, off, M_DONTWAIT);
1471 			if (n == NULL) {
1472 				/* m is retained by m_split */
1473 				goto bad;
1474 			}
1475 			m_adj(n, stripsiz);
1476 			/* m_cat does not update m_pkthdr.len */
1477 			m->m_pkthdr.len += n->m_pkthdr.len;
1478 			m_cat(m, n);
1479 		}
1480 
1481 #ifndef PULLDOWN_TEST
1482 		/*
1483 		 * KAME requires that the packet to be contiguous on the
1484 		 * mbuf.  We need to make that sure.
1485 		 * this kind of code should be avoided.
1486 		 * XXX other conditions to avoid running this part?
1487 		 */
1488 		if (m->m_len != m->m_pkthdr.len) {
1489 			struct mbuf *n = NULL;
1490 			int maxlen;
1491 
1492 			MGETHDR(n, M_DONTWAIT, MT_HEADER);      /* MAC-OK */
1493 			maxlen = MHLEN;
1494 			if (n) {
1495 				M_COPY_PKTHDR(n, m);
1496 			}
1497 			if (n && m->m_pkthdr.len > maxlen) {
1498 				MCLGET(n, M_DONTWAIT);
1499 				maxlen = MCLBYTES;
1500 				if ((n->m_flags & M_EXT) == 0) {
1501 					m_free(n);
1502 					n = NULL;
1503 				}
1504 			}
1505 			if (!n) {
1506 				printf("esp6_input: mbuf allocation failed\n");
1507 				goto bad;
1508 			}
1509 
1510 			if (m->m_pkthdr.len <= maxlen) {
1511 				m_copydata(m, 0, m->m_pkthdr.len, mtod(n, caddr_t));
1512 				n->m_len = m->m_pkthdr.len;
1513 				n->m_pkthdr.len = m->m_pkthdr.len;
1514 				n->m_next = NULL;
1515 				m_freem(m);
1516 			} else {
1517 				m_copydata(m, 0, maxlen, mtod(n, caddr_t));
1518 				n->m_len = maxlen;
1519 				n->m_pkthdr.len = m->m_pkthdr.len;
1520 				n->m_next = m;
1521 				m_adj(m, maxlen);
1522 				m->m_flags &= ~M_PKTHDR;
1523 			}
1524 			m = n;
1525 		}
1526 #endif
1527 		ip6 = mtod(m, struct ip6_hdr *);
1528 		ip6->ip6_plen = htons(ntohs(ip6->ip6_plen) - stripsiz);
1529 
1530 		key_sa_recordxfer(sav, m->m_pkthdr.len);
1531 		if (ipsec_incr_history_count(m, IPPROTO_ESP, spi) != 0) {
1532 			IPSEC_STAT_INCREMENT(ipsec6stat.in_nomem);
1533 			goto bad;
1534 		}
1535 
1536 		/*
1537 		 * Set the csum valid flag, if we authenticated the
1538 		 * packet, the payload shouldn't be corrupt unless
1539 		 * it was corrupted before being signed on the other
1540 		 * side.
1541 		 */
1542 		if (nxt == IPPROTO_TCP || nxt == IPPROTO_UDP) {
1543 			m->m_pkthdr.csum_flags = CSUM_DATA_VALID | CSUM_PSEUDO_HDR;
1544 			m->m_pkthdr.csum_data = 0xFFFF;
1545 			_CASSERT(offsetof(struct pkthdr, csum_data) == offsetof(struct pkthdr, csum_rx_val));
1546 		}
1547 
1548 		// Input via IPsec interface
1549 		lck_mtx_lock(sadb_mutex);
1550 		ifnet_t ipsec_if = sav->sah->ipsec_if;
1551 		if (ipsec_if != NULL) {
1552 			// If an interface is found, add a reference count before dropping the lock
1553 			ifnet_reference(ipsec_if);
1554 		}
1555 		lck_mtx_unlock(sadb_mutex);
1556 		if (ipsec_if != NULL) {
1557 			esp_input_log(m, sav, spi, seq);
1558 
1559 			if ((m->m_pkthdr.pkt_flags & PKTF_WAKE_PKT) == PKTF_WAKE_PKT) {
1560 				if_ports_used_match_mbuf(ipsec_if, PF_INET6, m);
1561 			}
1562 
1563 			// Return mbuf
1564 			if (interface != NULL &&
1565 			    interface == ipsec_if) {
1566 				ifnet_release(ipsec_if);
1567 				goto done;
1568 			}
1569 
1570 			errno_t inject_error = ipsec_inject_inbound_packet(ipsec_if, m);
1571 			ifnet_release(ipsec_if);
1572 
1573 			if (inject_error == 0) {
1574 				m = NULL;
1575 				nxt = IPPROTO_DONE;
1576 				goto done;
1577 			} else {
1578 				goto bad;
1579 			}
1580 		} else {
1581 			if ((m->m_pkthdr.pkt_flags & PKTF_WAKE_PKT) == PKTF_WAKE_PKT) {
1582 				if_ports_used_match_mbuf(m->m_pkthdr.rcvif, PF_INET, m);
1583 				if (m->m_pkthdr.rcvif == NULL) {
1584 					ipseclog((LOG_ERR, "no input interface for ipsec wake packet\n"));
1585 				}
1586 			}
1587 		}
1588 	}
1589 
1590 done:
1591 	*offp = off;
1592 	*mp = m;
1593 	if (sav) {
1594 		KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
1595 		    printf("DP esp6_input call free SA:0x%llx\n",
1596 		    (uint64_t)VM_KERNEL_ADDRPERM(sav)));
1597 		key_freesav(sav, KEY_SADB_UNLOCKED);
1598 	}
1599 	IPSEC_STAT_INCREMENT(ipsec6stat.in_success);
1600 	return nxt;
1601 
1602 bad:
1603 	if (sav) {
1604 		KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
1605 		    printf("DP esp6_input call free SA:0x%llx\n",
1606 		    (uint64_t)VM_KERNEL_ADDRPERM(sav)));
1607 		key_freesav(sav, KEY_SADB_UNLOCKED);
1608 	}
1609 	if (m) {
1610 		m_freem(m);
1611 	}
1612 	if (interface != NULL) {
1613 		*mp = NULL;
1614 	}
1615 	return IPPROTO_DONE;
1616 }
1617 
1618 void
esp6_ctlinput(int cmd,struct sockaddr * sa,void * d,__unused struct ifnet * ifp)1619 esp6_ctlinput(int cmd, struct sockaddr *sa, void *d, __unused struct ifnet *ifp)
1620 {
1621 	const struct newesp *espp;
1622 	struct newesp esp;
1623 	struct ip6ctlparam *ip6cp = NULL, ip6cp1;
1624 	struct secasvar *sav;
1625 	struct ip6_hdr *ip6;
1626 	struct mbuf *m;
1627 	int off = 0;
1628 	struct sockaddr_in6 *sa6_src, *sa6_dst;
1629 
1630 	if (sa->sa_family != AF_INET6 ||
1631 	    sa->sa_len != sizeof(struct sockaddr_in6)) {
1632 		return;
1633 	}
1634 	if ((unsigned)cmd >= PRC_NCMDS) {
1635 		return;
1636 	}
1637 
1638 	/* if the parameter is from icmp6, decode it. */
1639 	if (d != NULL) {
1640 		ip6cp = (struct ip6ctlparam *)d;
1641 		m = ip6cp->ip6c_m;
1642 		ip6 = ip6cp->ip6c_ip6;
1643 		off = ip6cp->ip6c_off;
1644 	} else {
1645 		m = NULL;
1646 		ip6 = NULL;
1647 	}
1648 
1649 	if (ip6) {
1650 		/*
1651 		 * Notify the error to all possible sockets via pfctlinput2.
1652 		 * Since the upper layer information (such as protocol type,
1653 		 * source and destination ports) is embedded in the encrypted
1654 		 * data and might have been cut, we can't directly call
1655 		 * an upper layer ctlinput function. However, the pcbnotify
1656 		 * function will consider source and destination addresses
1657 		 * as well as the flow info value, and may be able to find
1658 		 * some PCB that should be notified.
1659 		 * Although pfctlinput2 will call esp6_ctlinput(), there is
1660 		 * no possibility of an infinite loop of function calls,
1661 		 * because we don't pass the inner IPv6 header.
1662 		 */
1663 		bzero(&ip6cp1, sizeof(ip6cp1));
1664 		ip6cp1.ip6c_src = ip6cp->ip6c_src;
1665 		pfctlinput2(cmd, sa, (void *)&ip6cp1);
1666 
1667 		/*
1668 		 * Then go to special cases that need ESP header information.
1669 		 * XXX: We assume that when ip6 is non NULL,
1670 		 * M and OFF are valid.
1671 		 */
1672 
1673 		/* check if we can safely examine src and dst ports */
1674 		if (m->m_pkthdr.len < off + sizeof(esp)) {
1675 			return;
1676 		}
1677 
1678 		if (m->m_len < off + sizeof(esp)) {
1679 			/*
1680 			 * this should be rare case,
1681 			 * so we compromise on this copy...
1682 			 */
1683 			m_copydata(m, off, sizeof(esp), (caddr_t)&esp);
1684 			espp = &esp;
1685 		} else {
1686 			espp = (struct newesp*)(void *)(mtod(m, caddr_t) + off);
1687 		}
1688 
1689 		if (cmd == PRC_MSGSIZE) {
1690 			int valid = 0;
1691 
1692 			/*
1693 			 * Check to see if we have a valid SA corresponding to
1694 			 * the address in the ICMP message payload.
1695 			 */
1696 			sa6_src = ip6cp->ip6c_src;
1697 			sa6_dst = (struct sockaddr_in6 *)(void *)sa;
1698 			sav = key_allocsa(AF_INET6,
1699 			    (caddr_t)&sa6_src->sin6_addr,
1700 			    (caddr_t)&sa6_dst->sin6_addr,
1701 			    sa6_dst->sin6_scope_id,
1702 			    IPPROTO_ESP, espp->esp_spi);
1703 			if (sav) {
1704 				if (sav->state == SADB_SASTATE_MATURE ||
1705 				    sav->state == SADB_SASTATE_DYING) {
1706 					valid++;
1707 				}
1708 				key_freesav(sav, KEY_SADB_UNLOCKED);
1709 			}
1710 
1711 			/* XXX Further validation? */
1712 
1713 			/*
1714 			 * Depending on the value of "valid" and routing table
1715 			 * size (mtudisc_{hi,lo}wat), we will:
1716 			 * - recalcurate the new MTU and create the
1717 			 *   corresponding routing entry, or
1718 			 * - ignore the MTU change notification.
1719 			 */
1720 			icmp6_mtudisc_update((struct ip6ctlparam *)d, valid);
1721 		}
1722 	} else {
1723 		/* we normally notify any pcb here */
1724 	}
1725 }
1726 
1727 int
esp_kpipe_input(ifnet_t interface,kern_packet_t sph,kern_packet_t dph)1728 esp_kpipe_input(ifnet_t interface, kern_packet_t sph, kern_packet_t dph)
1729 {
1730 	struct newesp *esp = NULL;
1731 	struct esptail *esptail = NULL;
1732 	struct secasvar *sav = NULL;
1733 	struct ipsecstat *stat = NULL;
1734 	const struct esp_algorithm *e_algo = NULL;
1735 	const struct ah_algorithm *a_algo = NULL;
1736 	caddr_t src_ip = NULL, dst_ip = NULL;
1737 	uint8_t *sbaddr = NULL, *dbaddr = NULL;
1738 	uint8_t *src_payload = NULL, *dst_payload = NULL;
1739 	uint8_t *iv = NULL;
1740 	size_t iphlen = 0;
1741 	size_t auth_size = 0;
1742 	size_t esphlen = 0;
1743 	u_int32_t replay_index = 0;
1744 	int af = 0, ivlen = 0;
1745 	int err = 0;
1746 	uint32_t slim = 0, slen = 0;
1747 	uint32_t dlim = 0;
1748 	uint8_t dscp = 0, nxt_proto = 0;
1749 
1750 	KERNEL_DEBUG(DBG_FNC_ESPIN | DBG_FUNC_START, 0, 0, 0, 0, 0);
1751 
1752 	MD_BUFLET_ADDR(SK_PTR_ADDR_KPKT(sph), sbaddr);
1753 	kern_buflet_t sbuf = __packet_get_next_buflet(sph, NULL);
1754 	VERIFY(sbuf != NULL);
1755 	slen = __buflet_get_data_length(sbuf);
1756 	slim = __buflet_get_data_limit(sbuf);
1757 	slim -= __buflet_get_data_offset(sbuf);
1758 
1759 	MD_BUFLET_ADDR(SK_PTR_ADDR_KPKT(dph), dbaddr);
1760 	kern_buflet_t dbuf = __packet_get_next_buflet(dph, NULL);
1761 	VERIFY(dbuf != NULL);
1762 	dlim = __buflet_get_data_limit(dbuf);
1763 	dlim -= __buflet_get_data_offset(dbuf);
1764 
1765 	struct ip *ip_hdr = (struct ip *)(void *)sbaddr;
1766 	ASSERT(IP_HDR_ALIGNED_P(ip_hdr));
1767 
1768 	u_int ip_vers = IP_VHL_V(ip_hdr->ip_vhl);
1769 	switch (ip_vers) {
1770 	case IPVERSION: {
1771 #ifdef _IP_VHL
1772 		iphlen = IP_VHL_HL(ip_hdr->ip_vhl) << 2;
1773 #else /* _IP_VHL */
1774 		iphlen = ip_hdr->ip_hl << 2;
1775 #endif /* _IP_VHL */
1776 		nxt_proto = ip_hdr->ip_p;
1777 		dscp = ip_hdr->ip_tos >> IPTOS_DSCP_SHIFT;
1778 		src_ip = (caddr_t)&ip_hdr->ip_src;
1779 		dst_ip = (caddr_t)&ip_hdr->ip_dst;
1780 		stat = &ipsecstat;
1781 		af = AF_INET;
1782 		break;
1783 	}
1784 	case 6: {
1785 		struct ip6_hdr *ip6 = (struct ip6_hdr *)sbaddr;
1786 		iphlen = sizeof(struct ip6_hdr);
1787 		nxt_proto = ip6->ip6_nxt;
1788 		dscp = (ntohl(ip6->ip6_flow) & IP6FLOW_DSCP_MASK) >> IP6FLOW_DSCP_SHIFT;
1789 		src_ip = (caddr_t)&ip6->ip6_src;
1790 		dst_ip = (caddr_t)&ip6->ip6_dst;
1791 		stat = &ipsec6stat;
1792 		af = AF_INET6;
1793 		if (__improbable(ip6->ip6_plen == 0)) {
1794 			esp_packet_log_err("esp kpipe input, jumbogram not supported");
1795 			IPSEC_STAT_INCREMENT(ipsec6stat.in_inval);
1796 			goto bad;
1797 		}
1798 
1799 		break;
1800 	}
1801 	default: {
1802 		esp_log_info("esp kpipe input, ipversion %u, SPI=%x",
1803 		    ip_vers, ntohl(sav->spi));
1804 		err = EINVAL;
1805 		goto bad;
1806 	}
1807 	}
1808 
1809 	if (__improbable(dlim < slen)) {
1810 		esp_packet_log_err("esp kpipe input, output buffer is short(%u), "
1811 		    "compared to input buffer(%u) SPI=%x\n", dlim, slen, ntohl(sav->spi));
1812 		IPSEC_STAT_INCREMENT(stat->in_inval);
1813 		err = EINVAL;
1814 		goto bad;
1815 	}
1816 
1817 	if (__improbable(nxt_proto != IPPROTO_ESP)) {
1818 		esp_packet_log_err("esp kpipe input, invalid nxt proto %u", nxt_proto);
1819 		IPSEC_STAT_INCREMENT(stat->in_inval);
1820 		err = EINVAL;
1821 		goto bad;
1822 	}
1823 
1824 	if (__improbable(slen < (iphlen + sizeof(struct newesp)))) {
1825 		esp_packet_log_err("esp kpipe input, slen too short %u", slen);
1826 		IPSEC_STAT_INCREMENT(stat->in_inval);
1827 		err = EINVAL;
1828 		goto bad;
1829 	}
1830 
1831 	esp = (struct newesp *)(void *)(sbaddr + iphlen);
1832 
1833 	sav = key_allocsa_extended(af, src_ip, dst_ip,
1834 	    interface != NULL ? interface->if_index: IFSCOPE_UNKNOWN,
1835 	    IPPROTO_ESP, esp->esp_spi, interface);
1836 	if (__improbable(sav == NULL)) {
1837 		if (ipsec_debug) {
1838 			char src_buf[MAX_IPv6_STR_LEN] = {};
1839 			char dst_buf[MAX_IPv6_STR_LEN] = {};
1840 			inet_ntop(af, src_ip, src_buf, sizeof(src_buf));
1841 			inet_ntop(af, dst_ip, dst_buf, sizeof(src_buf));
1842 			esp_packet_log_err("esp kpipe input, no SA found for SPI=%x, "
1843 			    "packet %s<->%s", ntohl(esp->esp_spi), src_buf, dst_buf);
1844 		}
1845 		IPSEC_STAT_INCREMENT(stat->in_nosa);
1846 		err = ENOENT;
1847 		goto bad;
1848 	}
1849 
1850 	if (__improbable(sav->sah == NULL)) {
1851 		esp_log_err("esp kpipe input, sah is NULL\n");
1852 		IPSEC_STAT_INCREMENT(stat->in_nosa);
1853 		err = ENOENT;
1854 		goto bad;
1855 	}
1856 	if (__improbable(sav->sah->saidx.mode != IPSEC_MODE_TRANSPORT)) {
1857 		esp_log_err("ipsec tunnel mode not supported "
1858 		    "in kpipe mode, SPI=%x\n", ntohl(sav->spi));
1859 		IPSEC_STAT_INCREMENT(stat->in_nosa);
1860 		err = EINVAL;
1861 		goto bad;
1862 	}
1863 	if (__improbable((sav->flags & (SADB_X_EXT_OLD | SADB_X_EXT_DERIV |
1864 	    SADB_X_EXT_NATT | SADB_X_EXT_NATT_MULTIPLEUSERS |
1865 	    SADB_X_EXT_CYCSEQ | SADB_X_EXT_PMASK)) != 0)) {
1866 		esp_log_err("sadb flag %x not supported in "
1867 		    "kpipe mode, SPI=%x\n", sav->flags, ntohl(sav->spi));
1868 		IPSEC_STAT_INCREMENT(stat->in_nosa);
1869 		err = EINVAL;
1870 		goto bad;
1871 	}
1872 	if (__improbable(sav->state != SADB_SASTATE_MATURE &&
1873 	    sav->state != SADB_SASTATE_DYING)) {
1874 		esp_log_info("esp kpipe input, invalid SA state %u, SPI=%x",
1875 		    sav->state, ntohl(sav->spi));
1876 		IPSEC_STAT_INCREMENT(stat->in_inval);
1877 		err = EINVAL;
1878 		goto bad;
1879 	}
1880 
1881 	if ((sav->flags2 & SADB_X_EXT_SA2_SEQ_PER_TRAFFIC_CLASS) ==
1882 	    SADB_X_EXT_SA2_SEQ_PER_TRAFFIC_CLASS) {
1883 		replay_index = ntohl(esp->esp_seq) >> PER_TC_REPLAY_WINDOW_SN_SHIFT;
1884 	}
1885 
1886 	if (__improbable(sav->replay[replay_index] == NULL)) {
1887 		esp_log_err("esp kpipe input, missing replay window, SPI=%x\n",
1888 		    ntohl(sav->spi));
1889 		IPSEC_STAT_INCREMENT(stat->in_inval);
1890 		err = EINVAL;
1891 		goto bad;
1892 	}
1893 
1894 	/*
1895 	 * check for sequence number
1896 	 */
1897 	if (__improbable(!ipsec_chkreplay(ntohl(esp->esp_seq), sav,
1898 	    (uint8_t)replay_index))) {
1899 		esp_packet_log_err("esp kpipe input, replay packet, "
1900 		    "seq(%u), idx(%u), SPI=%x\n", ntohl(esp->esp_seq),
1901 		    replay_index, ntohl(sav->spi));
1902 		IPSEC_STAT_INCREMENT(stat->in_espreplay);
1903 		err = EINVAL;
1904 		goto bad;
1905 	}
1906 
1907 	e_algo = esp_algorithm_lookup(sav->alg_enc);
1908 	if (__improbable(e_algo == NULL)) {
1909 		esp_log_info("esp kpipe input, unsupported algorithm(%d) for, SPI=%x",
1910 		    sav->alg_enc, ntohl(sav->spi));
1911 		IPSEC_STAT_INCREMENT(stat->in_inval);
1912 		err = EINVAL;
1913 		goto bad;
1914 	}
1915 
1916 	if ((sav->flags & SADB_X_EXT_IIV) == 0) {
1917 		ivlen = sav->ivlen;
1918 		if (__improbable(ivlen < 0)) {
1919 			panic("esp kpipe input: invalid ivlen(%d) SPI=%x",
1920 			    ivlen, ntohl(sav->spi));
1921 			/* NOTREACHED */
1922 			__builtin_unreachable();
1923 		}
1924 
1925 		iv = sbaddr + iphlen + sizeof(struct newesp);
1926 	}
1927 
1928 	esphlen = sizeof(struct newesp) + ivlen;
1929 
1930 	if (sav->alg_auth != SADB_X_AALG_NULL &&
1931 	    sav->alg_auth != SADB_AALG_NONE) {
1932 		a_algo = ah_algorithm_lookup(sav->alg_auth);
1933 		if (a_algo != NULL && sav->key_auth != NULL) {
1934 			auth_size = (((*a_algo->sumsiz)(sav) + 3) & ~(4 - 1));
1935 			VERIFY(auth_size < AH_MAXSUMSIZE);
1936 
1937 			if (__improbable(slen < iphlen + esphlen + auth_size)) {
1938 				esp_packet_log_err("esp kpipe input, input buffer "
1939 				    "does not contain auth, SPI=%x\n", ntohl(sav->spi));
1940 				IPSEC_STAT_INCREMENT(stat->in_espauthfail);
1941 				err = EBADMSG;
1942 				goto bad;
1943 			}
1944 
1945 			/*
1946 			 * Use destination buffer to store authentication
1947 			 * tag for comparison.
1948 			 */
1949 			uint8_t *auth_buf = dbaddr + dlim - auth_size;
1950 			if (__improbable((err = esp_auth_data(sav, (uint8_t *)esp,
1951 			    slen - iphlen - auth_size, auth_buf, auth_size)) != 0)) {
1952 				esp_packet_log_err("esp kpipe input, esp auth "
1953 				    "data failed, SPI=%x\n", ntohl(sav->spi));
1954 				IPSEC_STAT_INCREMENT(stat->in_espauthfail);
1955 				err = EBADMSG;
1956 				goto bad;
1957 			}
1958 
1959 			if (__improbable(cc_cmp_safe(auth_size, auth_buf,
1960 			    sbaddr + slen - auth_size) != 0)) {
1961 				esp_packet_log_err("esp kpipe input, auth compare "
1962 				    "failed, SPI=%x\n", ntohl(sav->spi));
1963 				IPSEC_STAT_INCREMENT(stat->in_espauthfail);
1964 				err = EBADMSG;
1965 				goto bad;
1966 			}
1967 
1968 			IPSEC_STAT_INCREMENT(stat->in_espauthsucc);
1969 		}
1970 	} else if (e_algo->finalizedecrypt) {
1971 		auth_size = e_algo->icvlen;
1972 	}
1973 
1974 	if (__improbable(slen <= (iphlen + esphlen + sizeof(struct esptail) +
1975 	    auth_size))) {
1976 		esp_packet_log_err("esp kpipe input, input buffer is short(%u), "
1977 		    "to contain ivlen and esptail SPI=%x\n", slen, ntohl(sav->spi));
1978 		IPSEC_STAT_INCREMENT(stat->in_inval);
1979 		err = EBADMSG;
1980 		goto bad;
1981 	}
1982 
1983 	/*
1984 	 * pre-compute and cache intermediate key
1985 	 */
1986 	if (__improbable((err = esp_schedule(e_algo, sav)) != 0)) {
1987 		esp_log_info("esp schedule failed %d, SPI=%x\n", err, ntohl(sav->spi));
1988 		IPSEC_STAT_INCREMENT(ipsec6stat.in_inval);
1989 		goto bad;
1990 	}
1991 
1992 	VERIFY(e_algo->decrypt_pkt);
1993 	KERNEL_DEBUG(DBG_FNC_DECRYPT | DBG_FUNC_START, 0, 0, 0, 0, 0);
1994 	src_payload = sbaddr + iphlen + esphlen;
1995 	dst_payload = dbaddr + iphlen;
1996 	uint16_t encrypted_payload_len = (uint16_t)(slen - iphlen - esphlen - auth_size);
1997 	if (__improbable((err = (*e_algo->decrypt_pkt)(sav, src_payload,
1998 	    encrypted_payload_len, esp, iv, ivlen, dst_payload,
1999 	    encrypted_payload_len)) != 0)) {
2000 		esp_packet_log_err("esp kpipe input: decryption failed, SPI=%x\n",
2001 		    ntohl(sav->spi));
2002 		IPSEC_STAT_INCREMENT(stat->in_inval);
2003 		KERNEL_DEBUG(DBG_FNC_DECRYPT | DBG_FUNC_END, 1, 0, 0, 0, 0);
2004 		goto bad;
2005 	}
2006 	KERNEL_DEBUG(DBG_FNC_DECRYPT | DBG_FUNC_END, 2, 0, 0, 0, 0);
2007 	IPSEC_STAT_INCREMENT(stat->in_esphist[sav->alg_enc]);
2008 
2009 	if (e_algo->finalizedecrypt) {
2010 		if (__improbable((err = (*e_algo->finalizedecrypt)(sav,
2011 		    sbaddr + slen - auth_size, e_algo->icvlen)) != 0)) {
2012 			esp_packet_log_err("esp kpipe input: ICV failed, SPI=%x\n",
2013 			    ntohl(sav->spi));
2014 			IPSEC_STAT_INCREMENT(stat->in_espauthfail);
2015 			KERNEL_DEBUG(DBG_FNC_DECRYPT | DBG_FUNC_END, 3, 0, 0, 0, 0);
2016 			goto bad;
2017 		}
2018 
2019 		IPSEC_STAT_INCREMENT(stat->in_espauthsucc);
2020 		KERNEL_DEBUG(DBG_FNC_DECRYPT | DBG_FUNC_END, 4, 0, 0, 0, 0);
2021 	}
2022 
2023 	if (__improbable(ipsec_updatereplay(ntohl(esp->esp_seq), sav,
2024 	    (uint8_t)replay_index))) {
2025 		esp_packet_log_err("esp kpipe input: update replay failed, SPI=%x\n",
2026 		    ntohl(sav->spi));
2027 		IPSEC_STAT_INCREMENT(stat->in_espreplay);
2028 		goto bad;
2029 	}
2030 
2031 	esptail = (struct esptail *)(dst_payload + encrypted_payload_len -
2032 	    sizeof(struct esptail));
2033 	nxt_proto = esptail->esp_nxt;
2034 
2035 	size_t taillen = sizeof(struct esptail) + esptail->esp_padlen;
2036 	if (__improbable(encrypted_payload_len <= taillen)) {
2037 		esp_packet_log_err("esp kpipe input: encrypted payload len %u, "
2038 		    "is invalid, taillen %zu, SPI=%x\n",
2039 		    encrypted_payload_len, taillen, ntohl(sav->spi));
2040 		IPSEC_STAT_INCREMENT(stat->in_inval);
2041 		goto bad;
2042 	}
2043 
2044 	uint16_t decrypted_payload_len = encrypted_payload_len - (uint16_t)taillen;
2045 
2046 	switch (ip_vers) {
2047 	case IPVERSION: {
2048 		struct ip *ip = (struct ip *)(void *)dbaddr;
2049 		ASSERT(IP_HDR_ALIGNED_P(ip));
2050 		ip->ip_p = nxt_proto;
2051 		ip->ip_len = htons((uint16_t)(iphlen + decrypted_payload_len));
2052 		ip->ip_sum = 0; // Recalculate checksum
2053 		ip->ip_sum = in_cksum_hdr_opt(ip);
2054 		break;
2055 	}
2056 	case 6: {
2057 		struct ip6_hdr *ip6 = (struct ip6_hdr *)dbaddr;
2058 		ip6->ip6_plen = htons((uint16_t)decrypted_payload_len);
2059 		ip6->ip6_nxt = nxt_proto;
2060 		break;
2061 	}
2062 	}
2063 
2064 	if (nxt_proto == IPPROTO_TCP || nxt_proto == IPPROTO_UDP) {
2065 		__packet_set_inet_checksum(dph,
2066 		    PACKET_CSUM_DATA_VALID | PACKET_CSUM_PSEUDO_HDR, 0,
2067 		    0xFFFF, FALSE);
2068 	}
2069 
2070 	__buflet_set_data_length(dbuf, (uint16_t)(iphlen + decrypted_payload_len));
2071 
2072 	key_sa_recordxfer(sav, iphlen + decrypted_payload_len);
2073 	IPSEC_STAT_INCREMENT(stat->in_success);
2074 	key_freesav(sav, KEY_SADB_UNLOCKED);
2075 	KERNEL_DEBUG(DBG_FNC_ESPIN | DBG_FUNC_END, 1, 0, 0, 0, 0);
2076 
2077 	return 0;
2078 bad:
2079 	if (sav != NULL) {
2080 		key_freesav(sav, KEY_SADB_UNLOCKED);
2081 		sav = NULL;
2082 	}
2083 
2084 	KERNEL_DEBUG(DBG_FNC_ESPIN | DBG_FUNC_END, 2, err, 0, 0, 0);
2085 	return err;
2086 }
2087