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
138static struct ip *
139esp4_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(from: (caddr_t)ip, to: (caddr_t)(((u_char *)ip) + stripsiz), len: 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
156static struct ip6_hdr *
157esp6_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(from: (caddr_t)ip6, to: (caddr_t)(((u_char *)ip6) + stripsiz), len: 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
174static void
175esp_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
208void
209esp4_input(struct mbuf *m, int off)
210{
211 (void)esp4_input_extended(m, off, NULL);
212}
213
214struct mbuf *
215esp4_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 src: (caddr_t)&ip->ip_src, dst: (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(num: siz, ptr1: sum0, ptr2: 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
426noreplaycheck:
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, iphlen: 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(s: &addr, n: 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(s: &addr, n: 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(interface: 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(ifp: m->m_pkthdr.rcvif, proto_family: 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(interface: ipsec_if);
720 goto done;
721 }
722
723 errno_t inject_error = ipsec_inject_inbound_packet(interface: ipsec_if, packet: m);
724 ifnet_release(interface: 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(protocol: ifamily == AF_INET ? PF_INET : PF_INET6, packet: 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(from: (caddr_t)ip, to: (caddr_t)(((u_char *)ip) + stripsiz), len: 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(interface: 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(interface: 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(ifp: 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(interface: ipsec_if);
862 goto done;
863 }
864
865 errno_t inject_error = ipsec_inject_inbound_packet(interface: ipsec_if, packet: m);
866 ifnet_release(interface: 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(ifp: 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, hlen: off, proto: (u_int8_t)nxt, ipfref: 0);
884 } else {
885 m_freem(m);
886 }
887 m = NULL;
888 }
889
890done:
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;
899bad:
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
913int
914esp6_input(struct mbuf **mp, int *offp, int proto)
915{
916 return esp6_input_extended(mp, offp, proto, NULL);
917}
918
919int
920esp6_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 src: (caddr_t)&ip6->ip6_src, dst: (caddr_t)&ip6->ip6_dst,
983 dst_ifscope: 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(num: siz, ptr1: sum0, ptr2: 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
1139noreplaycheck:
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, ip6hlen: 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(s: &addr, n: 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(s: &addr, n: 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(interface: 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(ifp: m->m_pkthdr.rcvif, proto_family: 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(interface: ipsec_if);
1420 goto done;
1421 }
1422
1423 errno_t inject_error = ipsec_inject_inbound_packet(interface: ipsec_if, packet: m);
1424 ifnet_release(interface: 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(protocol: ifamily == AF_INET ? PF_INET : PF_INET6, packet: 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(from: (caddr_t)ip6, to: ((caddr_t)ip6) + stripsiz, len: 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(interface: 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(ifp: ipsec_if, PF_INET6, m);
1561 }
1562
1563 // Return mbuf
1564 if (interface != NULL &&
1565 interface == ipsec_if) {
1566 ifnet_release(interface: ipsec_if);
1567 goto done;
1568 }
1569
1570 errno_t inject_error = ipsec_inject_inbound_packet(interface: ipsec_if, packet: m);
1571 ifnet_release(interface: 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(ifp: 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
1590done:
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
1602bad:
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
1618void
1619esp6_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(s: &ip6cp1, n: 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
1727int
1728esp_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(ph: sph, NULL);
1754 VERIFY(sbuf != NULL);
1755 slen = __buflet_get_data_length(buf: sbuf);
1756 slim = __buflet_get_data_limit(buf: sbuf);
1757 slim -= __buflet_get_data_offset(buf: sbuf);
1758
1759 MD_BUFLET_ADDR(SK_PTR_ADDR_KPKT(dph), dbaddr);
1760 kern_buflet_t dbuf = __packet_get_next_buflet(ph: dph, NULL);
1761 VERIFY(dbuf != NULL);
1762 dlim = __buflet_get_data_limit(buf: dbuf);
1763 dlim -= __buflet_get_data_offset(buf: 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(family: af, src: src_ip, dst: dst_ip,
1834 dst_ifscope: interface != NULL ? interface->if_index: IFSCOPE_UNKNOWN,
1835 IPPROTO_ESP, spi: 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(ph: dph,
2066 PACKET_CSUM_DATA_VALID | PACKET_CSUM_PSEUDO_HDR, start: 0,
2067 stuff_val: 0xFFFF, FALSE);
2068 }
2069
2070 __buflet_set_data_length(buf: dbuf, dlen: (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;
2078bad:
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