1 /*
2 * Copyright (c) 2008-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/ipsec.c,v 1.3.2.7 2001/07/19 06:37:23 kris Exp $ */
30 /* $KAME: ipsec.c,v 1.103 2001/05/24 07:14:18 sakane 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 /*
62 * IPsec controller part.
63 */
64
65 #include <sys/param.h>
66 #include <sys/systm.h>
67 #include <sys/malloc.h>
68 #include <sys/mbuf.h>
69 #include <sys/mcache.h>
70 #include <sys/domain.h>
71 #include <sys/protosw.h>
72 #include <sys/socket.h>
73 #include <sys/socketvar.h>
74 #include <sys/errno.h>
75 #include <sys/time.h>
76 #include <sys/kernel.h>
77 #include <sys/syslog.h>
78 #include <sys/sysctl.h>
79 #include <sys/priv.h>
80 #include <kern/locks.h>
81 #include <sys/kauth.h>
82 #include <sys/bitstring.h>
83
84 #include <libkern/OSAtomic.h>
85 #include <libkern/sysctl.h>
86
87 #include <net/if.h>
88 #include <net/route.h>
89 #include <net/if_ipsec.h>
90 #include <net/if_ports_used.h>
91
92 #include <netinet/in.h>
93 #include <netinet/in_systm.h>
94 #include <netinet/ip.h>
95 #include <netinet/ip_var.h>
96 #include <netinet/in_var.h>
97 #include <netinet/udp.h>
98 #include <netinet/udp_var.h>
99 #include <netinet/ip_ecn.h>
100 #include <netinet6/ip6_ecn.h>
101 #include <netinet/tcp.h>
102 #include <netinet/udp.h>
103
104 #include <netinet/ip6.h>
105 #include <netinet6/ip6_var.h>
106 #include <netinet/in_pcb.h>
107 #include <netinet/icmp6.h>
108
109 #include <netinet6/ipsec.h>
110 #include <netinet6/ipsec6.h>
111 #include <netinet6/ah.h>
112 #include <netinet6/ah6.h>
113 #if IPSEC_ESP
114 #include <netinet6/esp.h>
115 #include <netinet6/esp6.h>
116 #endif
117 #include <netkey/key.h>
118 #include <netkey/keydb.h>
119 #include <netkey/key_debug.h>
120 #include <net/nat464_utils.h>
121 #include <net/net_osdep.h>
122
123 #include <os/log_private.h>
124
125 #include <kern/assert.h>
126 #if SKYWALK
127 #include <skywalk/os_skywalk_private.h>
128 #endif // SKYWALK
129
130 #include <net/sockaddr_utils.h>
131
132 #if IPSEC_DEBUG
133 int ipsec_debug = 1;
134 #else
135 int ipsec_debug = 0;
136 #endif
137
138 #include <sys/kdebug.h>
139 #define DBG_LAYER_BEG NETDBG_CODE(DBG_NETIPSEC, 1)
140 #define DBG_LAYER_END NETDBG_CODE(DBG_NETIPSEC, 3)
141 #define DBG_FNC_GETPOL_SOCK NETDBG_CODE(DBG_NETIPSEC, (1 << 8))
142 #define DBG_FNC_GETPOL_ADDR NETDBG_CODE(DBG_NETIPSEC, (2 << 8))
143 #define DBG_FNC_IPSEC_OUT NETDBG_CODE(DBG_NETIPSEC, (3 << 8))
144
145 struct ipsecstat ipsecstat;
146 int ip4_ah_cleartos = 1;
147 int ip4_ah_offsetmask = 0; /* maybe IP_DF? */
148 int ip4_ipsec_dfbit = 0; /* DF bit on encap. 0: clear 1: set 2: copy */
149 int ip4_esp_trans_deflev = IPSEC_LEVEL_USE;
150 int ip4_esp_net_deflev = IPSEC_LEVEL_USE;
151 int ip4_ah_trans_deflev = IPSEC_LEVEL_USE;
152 int ip4_ah_net_deflev = IPSEC_LEVEL_USE;
153 struct secpolicy ip4_def_policy;
154 int ip4_ipsec_ecn = ECN_COMPATIBILITY; /* ECN ignore(-1)/compatibility(0)/normal(1) */
155 int ip4_esp_randpad = -1;
156 int esp_udp_encap_port = 0;
157 static int sysctl_def_policy SYSCTL_HANDLER_ARGS;
158 extern int natt_keepalive_interval;
159 extern u_int64_t natt_now;
160
161 struct ipsec_tag;
162
163 SYSCTL_DECL(_net_inet_ipsec);
164 SYSCTL_DECL(_net_inet6_ipsec6);
165 /* net.inet.ipsec */
166 SYSCTL_STRUCT(_net_inet_ipsec, IPSECCTL_STATS,
167 stats, CTLFLAG_RD | CTLFLAG_LOCKED, &ipsecstat, ipsecstat, "");
168 SYSCTL_PROC(_net_inet_ipsec, IPSECCTL_DEF_POLICY, def_policy, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
169 &ip4_def_policy.policy, 0, &sysctl_def_policy, "I", "");
170 SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_ESP_TRANSLEV, esp_trans_deflev,
171 CTLFLAG_RW | CTLFLAG_LOCKED, &ip4_esp_trans_deflev, 0, "");
172 SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_ESP_NETLEV, esp_net_deflev,
173 CTLFLAG_RW | CTLFLAG_LOCKED, &ip4_esp_net_deflev, 0, "");
174 SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_AH_TRANSLEV, ah_trans_deflev,
175 CTLFLAG_RW | CTLFLAG_LOCKED, &ip4_ah_trans_deflev, 0, "");
176 SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_AH_NETLEV, ah_net_deflev,
177 CTLFLAG_RW | CTLFLAG_LOCKED, &ip4_ah_net_deflev, 0, "");
178 SYSCTL_INT(_net_inet_ipsec, IPSECCTL_AH_CLEARTOS,
179 ah_cleartos, CTLFLAG_RW | CTLFLAG_LOCKED, &ip4_ah_cleartos, 0, "");
180 SYSCTL_INT(_net_inet_ipsec, IPSECCTL_AH_OFFSETMASK,
181 ah_offsetmask, CTLFLAG_RW | CTLFLAG_LOCKED, &ip4_ah_offsetmask, 0, "");
182 SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DFBIT,
183 dfbit, CTLFLAG_RW | CTLFLAG_LOCKED, &ip4_ipsec_dfbit, 0, "");
184 SYSCTL_INT(_net_inet_ipsec, IPSECCTL_ECN,
185 ecn, CTLFLAG_RW | CTLFLAG_LOCKED, &ip4_ipsec_ecn, 0, "");
186 SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEBUG,
187 debug, CTLFLAG_RW | CTLFLAG_LOCKED, &ipsec_debug, 0, "");
188 SYSCTL_INT(_net_inet_ipsec, IPSECCTL_ESP_RANDPAD,
189 esp_randpad, CTLFLAG_RW | CTLFLAG_LOCKED, &ip4_esp_randpad, 0, "");
190
191 /* for performance, we bypass ipsec until a security policy is set */
192 int ipsec_bypass = 1;
193 SYSCTL_INT(_net_inet_ipsec, OID_AUTO, bypass, CTLFLAG_RD | CTLFLAG_LOCKED, &ipsec_bypass, 0, "");
194
195 /*
196 * NAT Traversal requires a UDP port for encapsulation,
197 * esp_udp_encap_port controls which port is used. Racoon
198 * must set this port to the port racoon is using locally
199 * for nat traversal.
200 */
201 SYSCTL_INT(_net_inet_ipsec, OID_AUTO, esp_port,
202 CTLFLAG_RW | CTLFLAG_LOCKED, &esp_udp_encap_port, 0, "");
203
204 struct ipsecstat ipsec6stat;
205 int ip6_esp_trans_deflev = IPSEC_LEVEL_USE;
206 int ip6_esp_net_deflev = IPSEC_LEVEL_USE;
207 int ip6_ah_trans_deflev = IPSEC_LEVEL_USE;
208 int ip6_ah_net_deflev = IPSEC_LEVEL_USE;
209 struct secpolicy ip6_def_policy;
210 int ip6_ipsec_ecn = ECN_COMPATIBILITY; /* ECN ignore(-1)/compatibility(0)/normal(1) */
211 int ip6_esp_randpad = -1;
212
213 /* net.inet6.ipsec6 */
214 SYSCTL_STRUCT(_net_inet6_ipsec6, IPSECCTL_STATS,
215 stats, CTLFLAG_RD | CTLFLAG_LOCKED, &ipsec6stat, ipsecstat, "");
216 SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_POLICY,
217 def_policy, CTLFLAG_RW | CTLFLAG_LOCKED, &ip6_def_policy.policy, 0, "");
218 SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_ESP_TRANSLEV, esp_trans_deflev,
219 CTLFLAG_RW | CTLFLAG_LOCKED, &ip6_esp_trans_deflev, 0, "");
220 SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_ESP_NETLEV, esp_net_deflev,
221 CTLFLAG_RW | CTLFLAG_LOCKED, &ip6_esp_net_deflev, 0, "");
222 SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_AH_TRANSLEV, ah_trans_deflev,
223 CTLFLAG_RW | CTLFLAG_LOCKED, &ip6_ah_trans_deflev, 0, "");
224 SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_AH_NETLEV, ah_net_deflev,
225 CTLFLAG_RW | CTLFLAG_LOCKED, &ip6_ah_net_deflev, 0, "");
226 SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_ECN,
227 ecn, CTLFLAG_RW | CTLFLAG_LOCKED, &ip6_ipsec_ecn, 0, "");
228 SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEBUG,
229 debug, CTLFLAG_RW | CTLFLAG_LOCKED, &ipsec_debug, 0, "");
230 SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_ESP_RANDPAD,
231 esp_randpad, CTLFLAG_RW | CTLFLAG_LOCKED, &ip6_esp_randpad, 0, "");
232
233 SYSCTL_DECL(_net_link_generic_system);
234
235 static int ipsec_setspidx_interface(struct secpolicyindex *, u_int8_t, struct mbuf *,
236 int, int, int);
237 static int ipsec_setspidx_mbuf(struct secpolicyindex *, u_int8_t, u_int,
238 struct mbuf *, int);
239 static int ipsec4_setspidx_inpcb(struct mbuf *, struct inpcb *pcb);
240 static int ipsec6_setspidx_in6pcb(struct mbuf *, struct in6pcb *pcb);
241 static int ipsec_setspidx(struct mbuf *, struct secpolicyindex *, int, int);
242 static void ipsec4_get_ulp(struct mbuf *m, struct secpolicyindex *, int);
243 static int ipsec4_setspidx_ipaddr(struct mbuf *, struct secpolicyindex *);
244 static void ipsec6_get_ulp(struct mbuf *m, struct secpolicyindex *, int);
245 static int ipsec6_setspidx_ipaddr(struct mbuf *, struct secpolicyindex *);
246 static struct inpcbpolicy *ipsec_newpcbpolicy(void);
247 static void ipsec_delpcbpolicy(struct inpcbpolicy *);
248 static struct secpolicy *ipsec_deepcopy_policy(struct secpolicy *src);
249 static int ipsec_set_policy(struct secpolicy **pcb_sp,
250 int optname, caddr_t __sized_by(len)request, size_t len, int priv);
251 static void vshiftl(unsigned char *__sized_by(wsize)bitmap, int nbit, size_t wsize);
252 static int ipsec_in_reject(struct secpolicy *, struct mbuf *);
253 static int ipsec64_encapsulate(struct mbuf *, struct secasvar *, uint32_t);
254 static int ipsec6_update_routecache_and_output(struct ipsec_output_state *state, struct secasvar *sav);
255 static int ipsec46_encapsulate(struct ipsec_output_state *state, struct secasvar *sav);
256 static struct ipsec_tag *ipsec_addaux(struct mbuf *);
257 static struct ipsec_tag *ipsec_findaux(struct mbuf *);
258 static void ipsec_optaux(struct mbuf *, struct ipsec_tag *);
259 int ipsec_send_natt_keepalive(struct secasvar *sav);
260 bool ipsec_fill_offload_frame(ifnet_t ifp, struct secasvar *sav, struct ifnet_keepalive_offload_frame *frame, size_t frame_data_offset);
261
262 extern bool IOPMCopySleepWakeUUIDKey(char *, size_t);
263
264 static int
265 sysctl_def_policy SYSCTL_HANDLER_ARGS
266 {
267 int new_policy = ip4_def_policy.policy;
268 int error = sysctl_handle_int(oidp, &new_policy, 0, req);
269
270 #pragma unused(arg1, arg2)
271 if (error == 0) {
272 if (new_policy != IPSEC_POLICY_NONE &&
273 new_policy != IPSEC_POLICY_DISCARD) {
274 return EINVAL;
275 }
276 ip4_def_policy.policy = new_policy;
277
278 /* Turn off the bypass if the default security policy changes */
279 if (ipsec_bypass != 0 && ip4_def_policy.policy != IPSEC_POLICY_NONE) {
280 ipsec_bypass = 0;
281 }
282 }
283
284 return error;
285 }
286
287 /*
288 * For OUTBOUND packet having a socket. Searching SPD for packet,
289 * and return a pointer to SP.
290 * OUT: NULL: no apropreate SP found, the following value is set to error.
291 * 0 : bypass
292 * EACCES : discard packet.
293 * ENOENT : ipsec_acquire() in progress, maybe.
294 * others : error occurred.
295 * others: a pointer to SP
296 *
297 * NOTE: IPv6 mapped adddress concern is implemented here.
298 */
299 struct secpolicy *
ipsec4_getpolicybysock(struct mbuf * m,u_int8_t dir,struct socket * so,int * error)300 ipsec4_getpolicybysock(struct mbuf *m,
301 u_int8_t dir,
302 struct socket *so,
303 int *error)
304 {
305 struct inpcbpolicy *pcbsp = NULL;
306 struct secpolicy *currsp = NULL; /* policy on socket */
307 struct secpolicy *kernsp = NULL; /* policy on kernel */
308
309 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
310 /* sanity check */
311 if (m == NULL || so == NULL || error == NULL) {
312 panic("ipsec4_getpolicybysock: NULL pointer was passed.");
313 }
314
315 if (so->so_pcb == NULL) {
316 printf("ipsec4_getpolicybysock: so->so_pcb == NULL\n");
317 return ipsec4_getpolicybyaddr(m, dir, 0, error);
318 }
319
320 switch (SOCK_DOM(so)) {
321 case PF_INET:
322 pcbsp = sotoinpcb(so)->inp_sp;
323 break;
324 case PF_INET6:
325 pcbsp = sotoin6pcb(so)->in6p_sp;
326 break;
327 }
328
329 if (!pcbsp) {
330 /* Socket has not specified an IPSEC policy */
331 return ipsec4_getpolicybyaddr(m, dir, 0, error);
332 }
333
334 KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK | DBG_FUNC_START, 0, 0, 0, 0, 0);
335
336 switch (SOCK_DOM(so)) {
337 case PF_INET:
338 /* set spidx in pcb */
339 *error = ipsec4_setspidx_inpcb(m, sotoinpcb(so));
340 break;
341 case PF_INET6:
342 /* set spidx in pcb */
343 *error = ipsec6_setspidx_in6pcb(m, sotoin6pcb(so));
344 break;
345 default:
346 panic("ipsec4_getpolicybysock: unsupported address family");
347 }
348 if (*error) {
349 KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK | DBG_FUNC_END, 1, *error, 0, 0, 0);
350 return NULL;
351 }
352
353 /* sanity check */
354 if (pcbsp == NULL) {
355 panic("ipsec4_getpolicybysock: pcbsp is NULL.");
356 }
357
358 switch (dir) {
359 case IPSEC_DIR_INBOUND:
360 currsp = pcbsp->sp_in;
361 break;
362 case IPSEC_DIR_OUTBOUND:
363 currsp = pcbsp->sp_out;
364 break;
365 default:
366 panic("ipsec4_getpolicybysock: illegal direction.");
367 }
368
369 /* sanity check */
370 if (currsp == NULL) {
371 panic("ipsec4_getpolicybysock: currsp is NULL.");
372 }
373
374 /* when privilieged socket */
375 if (pcbsp->priv) {
376 switch (currsp->policy) {
377 case IPSEC_POLICY_BYPASS:
378 lck_mtx_lock(sadb_mutex);
379 currsp->refcnt++;
380 lck_mtx_unlock(sadb_mutex);
381 *error = 0;
382 KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK | DBG_FUNC_END, 2, *error, 0, 0, 0);
383 return currsp;
384
385 case IPSEC_POLICY_ENTRUST:
386 /* look for a policy in SPD */
387 kernsp = key_allocsp(&currsp->spidx, dir);
388
389 /* SP found */
390 if (kernsp != NULL) {
391 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
392 printf("DP ipsec4_getpolicybysock called "
393 "to allocate SP:0x%llx\n",
394 (uint64_t)VM_KERNEL_ADDRPERM(kernsp)));
395 *error = 0;
396 KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK | DBG_FUNC_END, 3, *error, 0, 0, 0);
397 return kernsp;
398 }
399
400 /* no SP found */
401 lck_mtx_lock(sadb_mutex);
402 if (ip4_def_policy.policy != IPSEC_POLICY_DISCARD
403 && ip4_def_policy.policy != IPSEC_POLICY_NONE) {
404 ipseclog((LOG_INFO,
405 "fixed system default policy: %d->%d\n",
406 ip4_def_policy.policy, IPSEC_POLICY_NONE));
407 ip4_def_policy.policy = IPSEC_POLICY_NONE;
408 }
409 ip4_def_policy.refcnt++;
410 lck_mtx_unlock(sadb_mutex);
411 *error = 0;
412 KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK | DBG_FUNC_END, 4, *error, 0, 0, 0);
413 return &ip4_def_policy;
414
415 case IPSEC_POLICY_IPSEC:
416 lck_mtx_lock(sadb_mutex);
417 currsp->refcnt++;
418 lck_mtx_unlock(sadb_mutex);
419 *error = 0;
420 KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK | DBG_FUNC_END, 5, *error, 0, 0, 0);
421 return currsp;
422
423 default:
424 ipseclog((LOG_ERR, "ipsec4_getpolicybysock: "
425 "Invalid policy for PCB %d\n", currsp->policy));
426 *error = EINVAL;
427 KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK | DBG_FUNC_END, 6, *error, 0, 0, 0);
428 return NULL;
429 }
430 /* NOTREACHED */
431 }
432
433 /* when non-privilieged socket */
434 /* look for a policy in SPD */
435 kernsp = key_allocsp(&currsp->spidx, dir);
436
437 /* SP found */
438 if (kernsp != NULL) {
439 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
440 printf("DP ipsec4_getpolicybysock called "
441 "to allocate SP:0x%llx\n",
442 (uint64_t)VM_KERNEL_ADDRPERM(kernsp)));
443 *error = 0;
444 KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK | DBG_FUNC_END, 7, *error, 0, 0, 0);
445 return kernsp;
446 }
447
448 /* no SP found */
449 switch (currsp->policy) {
450 case IPSEC_POLICY_BYPASS:
451 ipseclog((LOG_ERR, "ipsec4_getpolicybysock: "
452 "Illegal policy for non-priviliged defined %d\n",
453 currsp->policy));
454 *error = EINVAL;
455 KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK | DBG_FUNC_END, 8, *error, 0, 0, 0);
456 return NULL;
457
458 case IPSEC_POLICY_ENTRUST:
459 lck_mtx_lock(sadb_mutex);
460 if (ip4_def_policy.policy != IPSEC_POLICY_DISCARD
461 && ip4_def_policy.policy != IPSEC_POLICY_NONE) {
462 ipseclog((LOG_INFO,
463 "fixed system default policy: %d->%d\n",
464 ip4_def_policy.policy, IPSEC_POLICY_NONE));
465 ip4_def_policy.policy = IPSEC_POLICY_NONE;
466 }
467 ip4_def_policy.refcnt++;
468 lck_mtx_unlock(sadb_mutex);
469 *error = 0;
470 KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK | DBG_FUNC_END, 9, *error, 0, 0, 0);
471 return &ip4_def_policy;
472
473 case IPSEC_POLICY_IPSEC:
474 lck_mtx_lock(sadb_mutex);
475 currsp->refcnt++;
476 lck_mtx_unlock(sadb_mutex);
477 *error = 0;
478 KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK | DBG_FUNC_END, 10, *error, 0, 0, 0);
479 return currsp;
480
481 default:
482 ipseclog((LOG_ERR, "ipsec4_getpolicybysock: "
483 "Invalid policy for PCB %d\n", currsp->policy));
484 *error = EINVAL;
485 KERNEL_DEBUG(DBG_FNC_GETPOL_SOCK | DBG_FUNC_END, 11, *error, 0, 0, 0);
486 return NULL;
487 }
488 /* NOTREACHED */
489 }
490
491 /*
492 * For FORWADING packet or OUTBOUND without a socket. Searching SPD for packet,
493 * and return a pointer to SP.
494 * OUT: positive: a pointer to the entry for security policy leaf matched.
495 * NULL: no apropreate SP found, the following value is set to error.
496 * 0 : bypass
497 * EACCES : discard packet.
498 * ENOENT : ipsec_acquire() in progress, maybe.
499 * others : error occurred.
500 */
501 struct secpolicy *
ipsec4_getpolicybyaddr(struct mbuf * m,u_int8_t dir,int flag,int * error)502 ipsec4_getpolicybyaddr(struct mbuf *m,
503 u_int8_t dir,
504 int flag,
505 int *error)
506 {
507 struct secpolicy *sp = NULL;
508
509 if (ipsec_bypass != 0) {
510 return 0;
511 }
512
513 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
514
515 /* sanity check */
516 if (m == NULL || error == NULL) {
517 panic("ipsec4_getpolicybyaddr: NULL pointer was passed.");
518 }
519 {
520 struct secpolicyindex spidx;
521
522 KERNEL_DEBUG(DBG_FNC_GETPOL_ADDR | DBG_FUNC_START, 0, 0, 0, 0, 0);
523 bzero(&spidx, sizeof(spidx));
524
525 /* make a index to look for a policy */
526 *error = ipsec_setspidx_mbuf(&spidx, dir, AF_INET, m,
527 (flag & IP_FORWARDING) ? 0 : 1);
528
529 if (*error != 0) {
530 KERNEL_DEBUG(DBG_FNC_GETPOL_ADDR | DBG_FUNC_END, 1, *error, 0, 0, 0);
531 return NULL;
532 }
533
534 sp = key_allocsp(&spidx, dir);
535 }
536
537 /* SP found */
538 if (sp != NULL) {
539 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
540 printf("DP ipsec4_getpolicybyaddr called "
541 "to allocate SP:0x%llx\n",
542 (uint64_t)VM_KERNEL_ADDRPERM(sp)));
543 *error = 0;
544 KERNEL_DEBUG(DBG_FNC_GETPOL_ADDR | DBG_FUNC_END, 2, *error, 0, 0, 0);
545 return sp;
546 }
547
548 /* no SP found */
549 lck_mtx_lock(sadb_mutex);
550 if (ip4_def_policy.policy != IPSEC_POLICY_DISCARD
551 && ip4_def_policy.policy != IPSEC_POLICY_NONE) {
552 ipseclog((LOG_INFO, "fixed system default policy:%d->%d\n",
553 ip4_def_policy.policy,
554 IPSEC_POLICY_NONE));
555 ip4_def_policy.policy = IPSEC_POLICY_NONE;
556 }
557 ip4_def_policy.refcnt++;
558 lck_mtx_unlock(sadb_mutex);
559 *error = 0;
560 KERNEL_DEBUG(DBG_FNC_GETPOL_ADDR | DBG_FUNC_END, 3, *error, 0, 0, 0);
561 return &ip4_def_policy;
562 }
563
564 /* Match with bound interface rather than src addr.
565 * Unlike getpolicybyaddr, do not set the default policy.
566 * Return 0 if should continue processing, or -1 if packet
567 * should be dropped.
568 */
569 int
ipsec4_getpolicybyinterface(struct mbuf * m,u_int8_t dir,int * flags,struct ip_out_args * ipoa,struct secpolicy ** sp)570 ipsec4_getpolicybyinterface(struct mbuf *m,
571 u_int8_t dir,
572 int *flags,
573 struct ip_out_args *ipoa,
574 struct secpolicy **sp)
575 {
576 struct secpolicyindex spidx;
577 int error = 0;
578
579 if (ipsec_bypass != 0) {
580 return 0;
581 }
582
583 /* Sanity check */
584 if (m == NULL || ipoa == NULL || sp == NULL) {
585 panic("ipsec4_getpolicybyinterface: NULL pointer was passed.");
586 }
587
588 if (ipoa->ipoa_boundif == IFSCOPE_NONE) {
589 return 0;
590 }
591
592 KERNEL_DEBUG(DBG_FNC_GETPOL_ADDR | DBG_FUNC_START, 0, 0, 0, 0, 0);
593 bzero(&spidx, sizeof(spidx));
594
595 /* make a index to look for a policy */
596 error = ipsec_setspidx_interface(&spidx, dir, m, (*flags & IP_FORWARDING) ? 0 : 1,
597 ipoa->ipoa_boundif, 4);
598
599 if (error != 0) {
600 KERNEL_DEBUG(DBG_FNC_GETPOL_ADDR | DBG_FUNC_END, 1, error, 0, 0, 0);
601 return 0;
602 }
603
604 *sp = key_allocsp(&spidx, dir);
605
606 /* Return SP, whether NULL or not */
607 if (*sp != NULL && (*sp)->policy == IPSEC_POLICY_IPSEC) {
608 if ((*sp)->ipsec_if == NULL) {
609 /* Invalid to capture on an interface without redirect */
610 key_freesp(*sp, KEY_SADB_UNLOCKED);
611 *sp = NULL;
612 return -1;
613 } else if ((*sp)->disabled) {
614 /* Disabled policies go in the clear */
615 key_freesp(*sp, KEY_SADB_UNLOCKED);
616 *sp = NULL;
617 *flags |= IP_NOIPSEC; /* Avoid later IPsec check */
618 } else {
619 /* If policy is enabled, redirect to ipsec interface */
620 ipoa->ipoa_boundif = (*sp)->ipsec_if->if_index;
621 }
622 }
623
624 KERNEL_DEBUG(DBG_FNC_GETPOL_ADDR | DBG_FUNC_END, 2, error, 0, 0, 0);
625
626 return 0;
627 }
628
629
630 /*
631 * For OUTBOUND packet having a socket. Searching SPD for packet,
632 * and return a pointer to SP.
633 * OUT: NULL: no apropreate SP found, the following value is set to error.
634 * 0 : bypass
635 * EACCES : discard packet.
636 * ENOENT : ipsec_acquire() in progress, maybe.
637 * others : error occurred.
638 * others: a pointer to SP
639 */
640 struct secpolicy *
ipsec6_getpolicybysock(struct mbuf * m,u_int8_t dir,struct socket * so,int * error)641 ipsec6_getpolicybysock(struct mbuf *m,
642 u_int8_t dir,
643 struct socket *so,
644 int *error)
645 {
646 struct inpcbpolicy *pcbsp = NULL;
647 struct secpolicy *currsp = NULL; /* policy on socket */
648 struct secpolicy *kernsp = NULL; /* policy on kernel */
649
650 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
651
652 /* sanity check */
653 if (m == NULL || so == NULL || error == NULL) {
654 panic("ipsec6_getpolicybysock: NULL pointer was passed.");
655 }
656
657 #if DIAGNOSTIC
658 if (SOCK_DOM(so) != PF_INET6) {
659 panic("ipsec6_getpolicybysock: socket domain != inet6");
660 }
661 #endif
662
663 pcbsp = sotoin6pcb(so)->in6p_sp;
664
665 if (!pcbsp) {
666 return ipsec6_getpolicybyaddr(m, dir, 0, error);
667 }
668
669 /* set spidx in pcb */
670 ipsec6_setspidx_in6pcb(m, sotoin6pcb(so));
671
672 /* sanity check */
673 if (pcbsp == NULL) {
674 panic("ipsec6_getpolicybysock: pcbsp is NULL.");
675 }
676
677 switch (dir) {
678 case IPSEC_DIR_INBOUND:
679 currsp = pcbsp->sp_in;
680 break;
681 case IPSEC_DIR_OUTBOUND:
682 currsp = pcbsp->sp_out;
683 break;
684 default:
685 panic("ipsec6_getpolicybysock: illegal direction.");
686 }
687
688 /* sanity check */
689 if (currsp == NULL) {
690 panic("ipsec6_getpolicybysock: currsp is NULL.");
691 }
692
693 /* when privilieged socket */
694 if (pcbsp->priv) {
695 switch (currsp->policy) {
696 case IPSEC_POLICY_BYPASS:
697 lck_mtx_lock(sadb_mutex);
698 currsp->refcnt++;
699 lck_mtx_unlock(sadb_mutex);
700 *error = 0;
701 return currsp;
702
703 case IPSEC_POLICY_ENTRUST:
704 /* look for a policy in SPD */
705 kernsp = key_allocsp(&currsp->spidx, dir);
706
707 /* SP found */
708 if (kernsp != NULL) {
709 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
710 printf("DP ipsec6_getpolicybysock called "
711 "to allocate SP:0x%llx\n",
712 (uint64_t)VM_KERNEL_ADDRPERM(kernsp)));
713 *error = 0;
714 return kernsp;
715 }
716
717 /* no SP found */
718 lck_mtx_lock(sadb_mutex);
719 if (ip6_def_policy.policy != IPSEC_POLICY_DISCARD
720 && ip6_def_policy.policy != IPSEC_POLICY_NONE) {
721 ipseclog((LOG_INFO,
722 "fixed system default policy: %d->%d\n",
723 ip6_def_policy.policy, IPSEC_POLICY_NONE));
724 ip6_def_policy.policy = IPSEC_POLICY_NONE;
725 }
726 ip6_def_policy.refcnt++;
727 lck_mtx_unlock(sadb_mutex);
728 *error = 0;
729 return &ip6_def_policy;
730
731 case IPSEC_POLICY_IPSEC:
732 lck_mtx_lock(sadb_mutex);
733 currsp->refcnt++;
734 lck_mtx_unlock(sadb_mutex);
735 *error = 0;
736 return currsp;
737
738 default:
739 ipseclog((LOG_ERR, "ipsec6_getpolicybysock: "
740 "Invalid policy for PCB %d\n", currsp->policy));
741 *error = EINVAL;
742 return NULL;
743 }
744 /* NOTREACHED */
745 }
746
747 /* when non-privilieged socket */
748 /* look for a policy in SPD */
749 kernsp = key_allocsp(&currsp->spidx, dir);
750
751 /* SP found */
752 if (kernsp != NULL) {
753 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
754 printf("DP ipsec6_getpolicybysock called "
755 "to allocate SP:0x%llx\n",
756 (uint64_t)VM_KERNEL_ADDRPERM(kernsp)));
757 *error = 0;
758 return kernsp;
759 }
760
761 /* no SP found */
762 switch (currsp->policy) {
763 case IPSEC_POLICY_BYPASS:
764 ipseclog((LOG_ERR, "ipsec6_getpolicybysock: "
765 "Illegal policy for non-priviliged defined %d\n",
766 currsp->policy));
767 *error = EINVAL;
768 return NULL;
769
770 case IPSEC_POLICY_ENTRUST:
771 lck_mtx_lock(sadb_mutex);
772 if (ip6_def_policy.policy != IPSEC_POLICY_DISCARD
773 && ip6_def_policy.policy != IPSEC_POLICY_NONE) {
774 ipseclog((LOG_INFO,
775 "fixed system default policy: %d->%d\n",
776 ip6_def_policy.policy, IPSEC_POLICY_NONE));
777 ip6_def_policy.policy = IPSEC_POLICY_NONE;
778 }
779 ip6_def_policy.refcnt++;
780 lck_mtx_unlock(sadb_mutex);
781 *error = 0;
782 return &ip6_def_policy;
783
784 case IPSEC_POLICY_IPSEC:
785 lck_mtx_lock(sadb_mutex);
786 currsp->refcnt++;
787 lck_mtx_unlock(sadb_mutex);
788 *error = 0;
789 return currsp;
790
791 default:
792 ipseclog((LOG_ERR,
793 "ipsec6_policybysock: Invalid policy for PCB %d\n",
794 currsp->policy));
795 *error = EINVAL;
796 return NULL;
797 }
798 /* NOTREACHED */
799 }
800
801 /*
802 * For FORWADING packet or OUTBOUND without a socket. Searching SPD for packet,
803 * and return a pointer to SP.
804 * `flag' means that packet is to be forwarded whether or not.
805 * flag = 1: forwad
806 * OUT: positive: a pointer to the entry for security policy leaf matched.
807 * NULL: no apropreate SP found, the following value is set to error.
808 * 0 : bypass
809 * EACCES : discard packet.
810 * ENOENT : ipsec_acquire() in progress, maybe.
811 * others : error occurred.
812 */
813 #ifndef IP_FORWARDING
814 #define IP_FORWARDING 1
815 #endif
816
817 struct secpolicy *
ipsec6_getpolicybyaddr(struct mbuf * m,u_int8_t dir,int flag,int * error)818 ipsec6_getpolicybyaddr(struct mbuf *m,
819 u_int8_t dir,
820 int flag,
821 int *error)
822 {
823 struct secpolicy *sp = NULL;
824
825 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
826
827 /* sanity check */
828 if (m == NULL || error == NULL) {
829 panic("ipsec6_getpolicybyaddr: NULL pointer was passed.");
830 }
831
832 {
833 struct secpolicyindex spidx;
834
835 bzero(&spidx, sizeof(spidx));
836
837 /* make a index to look for a policy */
838 *error = ipsec_setspidx_mbuf(&spidx, dir, AF_INET6, m,
839 (flag & IP_FORWARDING) ? 0 : 1);
840
841 if (*error != 0) {
842 return NULL;
843 }
844
845 sp = key_allocsp(&spidx, dir);
846 }
847
848 /* SP found */
849 if (sp != NULL) {
850 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
851 printf("DP ipsec6_getpolicybyaddr called "
852 "to allocate SP:0x%llx\n",
853 (uint64_t)VM_KERNEL_ADDRPERM(sp)));
854 *error = 0;
855 return sp;
856 }
857
858 /* no SP found */
859 lck_mtx_lock(sadb_mutex);
860 if (ip6_def_policy.policy != IPSEC_POLICY_DISCARD
861 && ip6_def_policy.policy != IPSEC_POLICY_NONE) {
862 ipseclog((LOG_INFO, "fixed system default policy: %d->%d\n",
863 ip6_def_policy.policy, IPSEC_POLICY_NONE));
864 ip6_def_policy.policy = IPSEC_POLICY_NONE;
865 }
866 ip6_def_policy.refcnt++;
867 lck_mtx_unlock(sadb_mutex);
868 *error = 0;
869 return &ip6_def_policy;
870 }
871
872 /* Match with bound interface rather than src addr.
873 * Unlike getpolicybyaddr, do not set the default policy.
874 * Return 0 if should continue processing, or -1 if packet
875 * should be dropped.
876 */
877 int
ipsec6_getpolicybyinterface(struct mbuf * m,u_int8_t dir,int flag,struct ip6_out_args * ip6oap,int * noipsec,struct secpolicy ** sp)878 ipsec6_getpolicybyinterface(struct mbuf *m,
879 u_int8_t dir,
880 int flag,
881 struct ip6_out_args *ip6oap,
882 int *noipsec,
883 struct secpolicy **sp)
884 {
885 struct secpolicyindex spidx;
886 int error = 0;
887
888 if (ipsec_bypass != 0) {
889 return 0;
890 }
891
892 /* Sanity check */
893 if (m == NULL || sp == NULL || noipsec == NULL || ip6oap == NULL) {
894 panic("ipsec6_getpolicybyinterface: NULL pointer was passed.");
895 }
896
897 *noipsec = 0;
898
899 if (ip6oap->ip6oa_boundif == IFSCOPE_NONE) {
900 return 0;
901 }
902
903 KERNEL_DEBUG(DBG_FNC_GETPOL_ADDR | DBG_FUNC_START, 0, 0, 0, 0, 0);
904 bzero(&spidx, sizeof(spidx));
905
906 /* make a index to look for a policy */
907 error = ipsec_setspidx_interface(&spidx, dir, m, (flag & IP_FORWARDING) ? 0 : 1,
908 ip6oap->ip6oa_boundif, 6);
909
910 if (error != 0) {
911 KERNEL_DEBUG(DBG_FNC_GETPOL_ADDR | DBG_FUNC_END, 1, error, 0, 0, 0);
912 return 0;
913 }
914
915 *sp = key_allocsp(&spidx, dir);
916
917 /* Return SP, whether NULL or not */
918 if (*sp != NULL && (*sp)->policy == IPSEC_POLICY_IPSEC) {
919 if ((*sp)->ipsec_if == NULL) {
920 /* Invalid to capture on an interface without redirect */
921 key_freesp(*sp, KEY_SADB_UNLOCKED);
922 *sp = NULL;
923 return -1;
924 } else if ((*sp)->disabled) {
925 /* Disabled policies go in the clear */
926 key_freesp(*sp, KEY_SADB_UNLOCKED);
927 *sp = NULL;
928 *noipsec = 1; /* Avoid later IPsec check */
929 } else {
930 /* If policy is enabled, redirect to ipsec interface */
931 ip6oap->ip6oa_boundif = (*sp)->ipsec_if->if_index;
932 }
933 }
934
935 KERNEL_DEBUG(DBG_FNC_GETPOL_ADDR | DBG_FUNC_END, 2, *error, 0, 0, 0);
936
937 return 0;
938 }
939
940 /*
941 * set IP address into spidx from mbuf.
942 * When Forwarding packet and ICMP echo reply, this function is used.
943 *
944 * IN: get the followings from mbuf.
945 * protocol family, src, dst, next protocol
946 * OUT:
947 * 0: success.
948 * other: failure, and set errno.
949 */
950 static int
ipsec_setspidx_mbuf(struct secpolicyindex * spidx,u_int8_t dir,__unused u_int family,struct mbuf * m,int needport)951 ipsec_setspidx_mbuf(
952 struct secpolicyindex *spidx,
953 u_int8_t dir,
954 __unused u_int family,
955 struct mbuf *m,
956 int needport)
957 {
958 int error;
959
960 /* sanity check */
961 if (spidx == NULL || m == NULL) {
962 panic("ipsec_setspidx_mbuf: NULL pointer was passed.");
963 }
964
965 bzero(spidx, sizeof(*spidx));
966
967 error = ipsec_setspidx(m, spidx, needport, 0);
968 if (error) {
969 goto bad;
970 }
971 spidx->dir = dir;
972
973 return 0;
974
975 bad:
976 /* XXX initialize */
977 bzero(spidx, sizeof(*spidx));
978 return EINVAL;
979 }
980
981 static int
ipsec_setspidx_interface(struct secpolicyindex * spidx,u_int8_t dir,struct mbuf * m,int needport,int ifindex,int ip_version)982 ipsec_setspidx_interface(
983 struct secpolicyindex *spidx,
984 u_int8_t dir,
985 struct mbuf *m,
986 int needport,
987 int ifindex,
988 int ip_version)
989 {
990 int error;
991
992 /* sanity check */
993 if (spidx == NULL || m == NULL) {
994 panic("ipsec_setspidx_interface: NULL pointer was passed.");
995 }
996
997 bzero(spidx, sizeof(*spidx));
998
999 error = ipsec_setspidx(m, spidx, needport, ip_version);
1000 if (error) {
1001 goto bad;
1002 }
1003 spidx->dir = dir;
1004
1005 if (ifindex != 0) {
1006 ifnet_head_lock_shared();
1007 spidx->internal_if = ifindex2ifnet[ifindex];
1008 ifnet_head_done();
1009 } else {
1010 spidx->internal_if = NULL;
1011 }
1012
1013 return 0;
1014
1015 bad:
1016 return EINVAL;
1017 }
1018
1019 static int
ipsec4_setspidx_inpcb(struct mbuf * m,struct inpcb * pcb)1020 ipsec4_setspidx_inpcb(struct mbuf *m, struct inpcb *pcb)
1021 {
1022 struct secpolicyindex *spidx;
1023 int error;
1024
1025 if (ipsec_bypass != 0) {
1026 return 0;
1027 }
1028
1029 /* sanity check */
1030 if (pcb == NULL) {
1031 panic("ipsec4_setspidx_inpcb: no PCB found.");
1032 }
1033 if (pcb->inp_sp == NULL) {
1034 panic("ipsec4_setspidx_inpcb: no inp_sp found.");
1035 }
1036 if (pcb->inp_sp->sp_out == NULL || pcb->inp_sp->sp_in == NULL) {
1037 panic("ipsec4_setspidx_inpcb: no sp_in/out found.");
1038 }
1039
1040 bzero(&pcb->inp_sp->sp_in->spidx, sizeof(*spidx));
1041 bzero(&pcb->inp_sp->sp_out->spidx, sizeof(*spidx));
1042
1043 spidx = &pcb->inp_sp->sp_in->spidx;
1044 error = ipsec_setspidx(m, spidx, 1, 0);
1045 if (error) {
1046 goto bad;
1047 }
1048 spidx->dir = IPSEC_DIR_INBOUND;
1049
1050 spidx = &pcb->inp_sp->sp_out->spidx;
1051 error = ipsec_setspidx(m, spidx, 1, 0);
1052 if (error) {
1053 goto bad;
1054 }
1055 spidx->dir = IPSEC_DIR_OUTBOUND;
1056
1057 return 0;
1058
1059 bad:
1060 bzero(&pcb->inp_sp->sp_in->spidx, sizeof(*spidx));
1061 bzero(&pcb->inp_sp->sp_out->spidx, sizeof(*spidx));
1062 return error;
1063 }
1064
1065 static int
ipsec6_setspidx_in6pcb(struct mbuf * m,struct in6pcb * pcb)1066 ipsec6_setspidx_in6pcb(struct mbuf *m, struct in6pcb *pcb)
1067 {
1068 struct secpolicyindex *spidx;
1069 int error;
1070
1071 /* sanity check */
1072 if (pcb == NULL) {
1073 panic("ipsec6_setspidx_in6pcb: no PCB found.");
1074 }
1075 if (pcb->in6p_sp == NULL) {
1076 panic("ipsec6_setspidx_in6pcb: no in6p_sp found.");
1077 }
1078 if (pcb->in6p_sp->sp_out == NULL || pcb->in6p_sp->sp_in == NULL) {
1079 panic("ipsec6_setspidx_in6pcb: no sp_in/out found.");
1080 }
1081
1082 bzero(&pcb->in6p_sp->sp_in->spidx, sizeof(*spidx));
1083 bzero(&pcb->in6p_sp->sp_out->spidx, sizeof(*spidx));
1084
1085 spidx = &pcb->in6p_sp->sp_in->spidx;
1086 error = ipsec_setspidx(m, spidx, 1, 0);
1087 if (error) {
1088 goto bad;
1089 }
1090 spidx->dir = IPSEC_DIR_INBOUND;
1091
1092 spidx = &pcb->in6p_sp->sp_out->spidx;
1093 error = ipsec_setspidx(m, spidx, 1, 0);
1094 if (error) {
1095 goto bad;
1096 }
1097 spidx->dir = IPSEC_DIR_OUTBOUND;
1098
1099 return 0;
1100
1101 bad:
1102 bzero(&pcb->in6p_sp->sp_in->spidx, sizeof(*spidx));
1103 bzero(&pcb->in6p_sp->sp_out->spidx, sizeof(*spidx));
1104 return error;
1105 }
1106
1107 /*
1108 * configure security policy index (src/dst/proto/sport/dport)
1109 * by looking at the content of mbuf.
1110 * the caller is responsible for error recovery (like clearing up spidx).
1111 */
1112 static int
ipsec_setspidx(struct mbuf * m,struct secpolicyindex * spidx,int needport,int force_ip_version)1113 ipsec_setspidx(struct mbuf *m,
1114 struct secpolicyindex *spidx,
1115 int needport,
1116 int force_ip_version)
1117 {
1118 struct ip *ip = NULL;
1119 struct ip ipbuf;
1120 u_int v;
1121 struct mbuf *n;
1122 int len;
1123 int error;
1124
1125 if (m == NULL) {
1126 panic("ipsec_setspidx: m == 0 passed.");
1127 }
1128
1129 /*
1130 * validate m->m_pkthdr.len. we see incorrect length if we
1131 * mistakenly call this function with inconsistent mbuf chain
1132 * (like 4.4BSD tcp/udp processing). XXX should we panic here?
1133 */
1134 len = 0;
1135 for (n = m; n; n = n->m_next) {
1136 len += n->m_len;
1137 }
1138 if (m->m_pkthdr.len != len) {
1139 KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
1140 printf("ipsec_setspidx: "
1141 "total of m_len(%d) != pkthdr.len(%d), "
1142 "ignored.\n",
1143 len, m->m_pkthdr.len));
1144 return EINVAL;
1145 }
1146
1147 if (m->m_pkthdr.len < sizeof(struct ip)) {
1148 KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
1149 printf("ipsec_setspidx: "
1150 "pkthdr.len(%d) < sizeof(struct ip), ignored.\n",
1151 m->m_pkthdr.len));
1152 return EINVAL;
1153 }
1154
1155 if (m->m_len >= sizeof(*ip)) {
1156 ip = mtod(m, struct ip *);
1157 } else {
1158 m_copydata(m, 0, sizeof(ipbuf), (caddr_t)&ipbuf);
1159 ip = &ipbuf;
1160 }
1161
1162 if (force_ip_version) {
1163 v = force_ip_version;
1164 } else {
1165 #ifdef _IP_VHL
1166 v = _IP_VHL_V(ip->ip_vhl);
1167 #else
1168 v = ip->ip_v;
1169 #endif
1170 }
1171 switch (v) {
1172 case 4:
1173 error = ipsec4_setspidx_ipaddr(m, spidx);
1174 if (error) {
1175 return error;
1176 }
1177 ipsec4_get_ulp(m, spidx, needport);
1178 return 0;
1179 case 6:
1180 if (m->m_pkthdr.len < sizeof(struct ip6_hdr)) {
1181 KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
1182 printf("ipsec_setspidx: "
1183 "pkthdr.len(%d) < sizeof(struct ip6_hdr), "
1184 "ignored.\n", m->m_pkthdr.len));
1185 return EINVAL;
1186 }
1187 error = ipsec6_setspidx_ipaddr(m, spidx);
1188 if (error) {
1189 return error;
1190 }
1191 ipsec6_get_ulp(m, spidx, needport);
1192 return 0;
1193 default:
1194 KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
1195 printf("ipsec_setspidx: "
1196 "unknown IP version %u, ignored.\n", v));
1197 return EINVAL;
1198 }
1199 }
1200
1201 static void
ipsec4_get_ulp(struct mbuf * m,struct secpolicyindex * spidx,int needport)1202 ipsec4_get_ulp(struct mbuf *m, struct secpolicyindex *spidx, int needport)
1203 {
1204 struct ip ip;
1205 struct ip6_ext ip6e;
1206 u_int8_t nxt;
1207 int off;
1208 struct tcphdr th;
1209 struct udphdr uh;
1210
1211 /* sanity check */
1212 if (m == NULL) {
1213 panic("ipsec4_get_ulp: NULL pointer was passed.");
1214 }
1215 if (m->m_pkthdr.len < sizeof(ip)) {
1216 panic("ipsec4_get_ulp: too short");
1217 }
1218
1219 /* set default */
1220 spidx->ul_proto = IPSEC_ULPROTO_ANY;
1221 SIN(&spidx->src)->sin_port = IPSEC_PORT_ANY;
1222 SIN(&spidx->dst)->sin_port = IPSEC_PORT_ANY;
1223
1224 m_copydata(m, 0, sizeof(ip), (caddr_t)&ip);
1225 /* ip_input() flips it into host endian XXX need more checking */
1226 if (ip.ip_off & (IP_MF | IP_OFFMASK)) {
1227 return;
1228 }
1229
1230 nxt = ip.ip_p;
1231 #ifdef _IP_VHL
1232 off = _IP_VHL_HL(ip->ip_vhl) << 2;
1233 #else
1234 off = ip.ip_hl << 2;
1235 #endif
1236 while (off < m->m_pkthdr.len) {
1237 switch (nxt) {
1238 case IPPROTO_TCP:
1239 spidx->ul_proto = nxt;
1240 if (!needport) {
1241 return;
1242 }
1243 if (off + sizeof(struct tcphdr) > m->m_pkthdr.len) {
1244 return;
1245 }
1246 m_copydata(m, off, sizeof(th), (caddr_t)&th);
1247 SIN(&spidx->src)->sin_port = th.th_sport;
1248 SIN(&spidx->dst)->sin_port = th.th_dport;
1249 return;
1250 case IPPROTO_UDP:
1251 spidx->ul_proto = nxt;
1252 if (!needport) {
1253 return;
1254 }
1255 if (off + sizeof(struct udphdr) > m->m_pkthdr.len) {
1256 return;
1257 }
1258 m_copydata(m, off, sizeof(uh), (caddr_t)&uh);
1259 SIN(&spidx->src)->sin_port = uh.uh_sport;
1260 SIN(&spidx->dst)->sin_port = uh.uh_dport;
1261 return;
1262 case IPPROTO_AH:
1263 if (off + sizeof(ip6e) > m->m_pkthdr.len) {
1264 return;
1265 }
1266 m_copydata(m, off, sizeof(ip6e), (caddr_t)&ip6e);
1267 off += (ip6e.ip6e_len + 2) << 2;
1268 nxt = ip6e.ip6e_nxt;
1269 break;
1270 case IPPROTO_ICMP:
1271 default:
1272 /* XXX intermediate headers??? */
1273 spidx->ul_proto = nxt;
1274 return;
1275 }
1276 }
1277 }
1278
1279 /* assumes that m is sane */
1280 static int
ipsec4_setspidx_ipaddr(struct mbuf * m,struct secpolicyindex * spidx)1281 ipsec4_setspidx_ipaddr(struct mbuf *m, struct secpolicyindex *spidx)
1282 {
1283 struct ip *ip = NULL;
1284 struct ip ipbuf;
1285 struct sockaddr_in *sin;
1286
1287 if (m->m_len >= sizeof(*ip)) {
1288 ip = mtod(m, struct ip *);
1289 } else {
1290 m_copydata(m, 0, sizeof(ipbuf), (caddr_t)&ipbuf);
1291 ip = &ipbuf;
1292 }
1293
1294 sin = SIN(&spidx->src);
1295 SOCKADDR_ZERO(sin, sizeof(*sin));
1296 sin->sin_family = AF_INET;
1297 sin->sin_len = sizeof(struct sockaddr_in);
1298 bcopy(&ip->ip_src, &sin->sin_addr, sizeof(ip->ip_src));
1299 spidx->prefs = sizeof(struct in_addr) << 3;
1300
1301 sin = SIN(&spidx->dst);
1302 SOCKADDR_ZERO(sin, sizeof(*sin));
1303 sin->sin_family = AF_INET;
1304 sin->sin_len = sizeof(struct sockaddr_in);
1305 bcopy(&ip->ip_dst, &sin->sin_addr, sizeof(ip->ip_dst));
1306 spidx->prefd = sizeof(struct in_addr) << 3;
1307
1308 return 0;
1309 }
1310
1311 static void
ipsec6_get_ulp(struct mbuf * m,struct secpolicyindex * spidx,int needport)1312 ipsec6_get_ulp(struct mbuf *m,
1313 struct secpolicyindex *spidx,
1314 int needport)
1315 {
1316 int off, nxt;
1317 struct tcphdr th;
1318 struct udphdr uh;
1319
1320 /* sanity check */
1321 if (m == NULL) {
1322 panic("ipsec6_get_ulp: NULL pointer was passed.");
1323 }
1324
1325 KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
1326 printf("ipsec6_get_ulp:\n"); kdebug_mbuf(m));
1327
1328 /* set default */
1329 spidx->ul_proto = IPSEC_ULPROTO_ANY;
1330 SIN6(&spidx->src)->sin6_port = IPSEC_PORT_ANY;
1331 SIN6(&spidx->dst)->sin6_port = IPSEC_PORT_ANY;
1332
1333 nxt = -1;
1334 off = ip6_lasthdr(m, 0, IPPROTO_IPV6, &nxt);
1335 if (off < 0 || m->m_pkthdr.len < off) {
1336 return;
1337 }
1338
1339 VERIFY(nxt <= UINT8_MAX);
1340 switch (nxt) {
1341 case IPPROTO_TCP:
1342 spidx->ul_proto = (u_int8_t)nxt;
1343 if (!needport) {
1344 break;
1345 }
1346 if (off + sizeof(struct tcphdr) > m->m_pkthdr.len) {
1347 break;
1348 }
1349 m_copydata(m, off, sizeof(th), (caddr_t)&th);
1350 SIN6(&spidx->src)->sin6_port = th.th_sport;
1351 SIN6(&spidx->dst)->sin6_port = th.th_dport;
1352 break;
1353 case IPPROTO_UDP:
1354 spidx->ul_proto = (u_int8_t)nxt;
1355 if (!needport) {
1356 break;
1357 }
1358 if (off + sizeof(struct udphdr) > m->m_pkthdr.len) {
1359 break;
1360 }
1361 m_copydata(m, off, sizeof(uh), (caddr_t)&uh);
1362 SIN6(&spidx->src)->sin6_port = uh.uh_sport;
1363 SIN6(&spidx->dst)->sin6_port = uh.uh_dport;
1364 break;
1365 case IPPROTO_ICMPV6:
1366 default:
1367 /* XXX intermediate headers??? */
1368 spidx->ul_proto = (u_int8_t)nxt;
1369 break;
1370 }
1371 }
1372
1373 /* assumes that m is sane */
1374 static int
ipsec6_setspidx_ipaddr(struct mbuf * m,struct secpolicyindex * spidx)1375 ipsec6_setspidx_ipaddr(struct mbuf *m,
1376 struct secpolicyindex *spidx)
1377 {
1378 struct ip6_hdr *ip6 = NULL;
1379 struct ip6_hdr ip6buf;
1380 struct sockaddr_in6 *sin6;
1381
1382 if (m->m_len >= sizeof(*ip6)) {
1383 ip6 = mtod(m, struct ip6_hdr *);
1384 } else {
1385 m_copydata(m, 0, sizeof(ip6buf), (caddr_t)&ip6buf);
1386 ip6 = &ip6buf;
1387 }
1388
1389 sin6 = SIN6(&spidx->src);
1390 SOCKADDR_ZERO(sin6, sizeof(*sin6));
1391 sin6->sin6_family = AF_INET6;
1392 sin6->sin6_len = sizeof(struct sockaddr_in6);
1393 bcopy(&ip6->ip6_src, &sin6->sin6_addr, sizeof(ip6->ip6_src));
1394 if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src)) {
1395 if (m->m_pkthdr.pkt_flags & PKTF_IFAINFO) {
1396 ip6_getsrcifaddr_info(m, &sin6->sin6_scope_id, NULL);
1397 } else if (m->m_pkthdr.pkt_ext_flags & PKTF_EXT_OUTPUT_SCOPE) {
1398 sin6->sin6_scope_id = ip6_output_getsrcifscope(m);
1399 }
1400 in6_verify_ifscope(&ip6->ip6_src, sin6->sin6_scope_id);
1401 if (in6_embedded_scope) {
1402 sin6->sin6_addr.s6_addr16[1] = 0;
1403 sin6->sin6_scope_id = ntohs(ip6->ip6_src.s6_addr16[1]);
1404 }
1405 }
1406 spidx->prefs = sizeof(struct in6_addr) << 3;
1407
1408 sin6 = SIN6(&spidx->dst);
1409 SOCKADDR_ZERO(sin6, sizeof(*sin6));
1410 sin6->sin6_family = AF_INET6;
1411 sin6->sin6_len = sizeof(struct sockaddr_in6);
1412 bcopy(&ip6->ip6_dst, &sin6->sin6_addr, sizeof(ip6->ip6_dst));
1413 if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst)) {
1414 if (m->m_pkthdr.pkt_flags & PKTF_IFAINFO) {
1415 ip6_getdstifaddr_info(m, &sin6->sin6_scope_id, NULL);
1416 } else if (m->m_pkthdr.pkt_ext_flags & PKTF_EXT_OUTPUT_SCOPE) {
1417 sin6->sin6_scope_id = ip6_output_getdstifscope(m);
1418 }
1419 in6_verify_ifscope(&ip6->ip6_dst, sin6->sin6_scope_id);
1420 if (in6_embedded_scope) {
1421 sin6->sin6_addr.s6_addr16[1] = 0;
1422 sin6->sin6_scope_id = ntohs(ip6->ip6_dst.s6_addr16[1]);
1423 }
1424 }
1425 spidx->prefd = sizeof(struct in6_addr) << 3;
1426
1427 return 0;
1428 }
1429
1430 static struct inpcbpolicy *
ipsec_newpcbpolicy(void)1431 ipsec_newpcbpolicy(void)
1432 {
1433 struct inpcbpolicy *p;
1434
1435 p = kalloc_type(struct inpcbpolicy, Z_WAITOK | Z_ZERO);
1436 return p;
1437 }
1438
1439 static void
ipsec_delpcbpolicy(struct inpcbpolicy * p)1440 ipsec_delpcbpolicy(struct inpcbpolicy *p)
1441 {
1442 kfree_type(struct inpcbpolicy, p);
1443 }
1444
1445 /* initialize policy in PCB */
1446 int
ipsec_init_policy(struct socket * so,struct inpcbpolicy ** pcb_sp)1447 ipsec_init_policy(struct socket *so,
1448 struct inpcbpolicy **pcb_sp)
1449 {
1450 struct inpcbpolicy *new;
1451
1452 /* sanity check. */
1453 if (so == NULL || pcb_sp == NULL) {
1454 panic("ipsec_init_policy: NULL pointer was passed.");
1455 }
1456
1457 new = ipsec_newpcbpolicy();
1458 if (new == NULL) {
1459 ipseclog((LOG_DEBUG, "ipsec_init_policy: No more memory.\n"));
1460 return ENOBUFS;
1461 }
1462
1463 #ifdef __APPLE__
1464 if (kauth_cred_issuser(so->so_cred))
1465 #else
1466 if (so->so_cred != 0 && !suser(so->so_cred->pc_ucred, NULL))
1467 #endif
1468 { new->priv = 1;} else {
1469 new->priv = 0;
1470 }
1471
1472 if ((new->sp_in = key_newsp()) == NULL) {
1473 ipsec_delpcbpolicy(new);
1474 return ENOBUFS;
1475 }
1476 new->sp_in->state = IPSEC_SPSTATE_ALIVE;
1477 new->sp_in->policy = IPSEC_POLICY_ENTRUST;
1478
1479 if ((new->sp_out = key_newsp()) == NULL) {
1480 key_freesp(new->sp_in, KEY_SADB_UNLOCKED);
1481 ipsec_delpcbpolicy(new);
1482 return ENOBUFS;
1483 }
1484 new->sp_out->state = IPSEC_SPSTATE_ALIVE;
1485 new->sp_out->policy = IPSEC_POLICY_ENTRUST;
1486
1487 *pcb_sp = new;
1488
1489 return 0;
1490 }
1491
1492 /* copy old ipsec policy into new */
1493 int
ipsec_copy_policy(struct inpcbpolicy * old,struct inpcbpolicy * new)1494 ipsec_copy_policy(struct inpcbpolicy *old,
1495 struct inpcbpolicy *new)
1496 {
1497 struct secpolicy *sp;
1498
1499 if (ipsec_bypass != 0) {
1500 return 0;
1501 }
1502
1503 sp = ipsec_deepcopy_policy(old->sp_in);
1504 if (sp) {
1505 key_freesp(new->sp_in, KEY_SADB_UNLOCKED);
1506 new->sp_in = sp;
1507 } else {
1508 return ENOBUFS;
1509 }
1510
1511 sp = ipsec_deepcopy_policy(old->sp_out);
1512 if (sp) {
1513 key_freesp(new->sp_out, KEY_SADB_UNLOCKED);
1514 new->sp_out = sp;
1515 } else {
1516 return ENOBUFS;
1517 }
1518
1519 new->priv = old->priv;
1520
1521 return 0;
1522 }
1523
1524 /* deep-copy a policy in PCB */
1525 static struct secpolicy *
ipsec_deepcopy_policy(struct secpolicy * src)1526 ipsec_deepcopy_policy(struct secpolicy *src)
1527 {
1528 struct ipsecrequest *__single newchain = NULL;
1529 struct ipsecrequest *p;
1530 struct ipsecrequest **q;
1531 struct secpolicy *dst;
1532
1533 if (src == NULL) {
1534 return NULL;
1535 }
1536 dst = key_newsp();
1537 if (dst == NULL) {
1538 return NULL;
1539 }
1540
1541 /*
1542 * deep-copy IPsec request chain. This is required since struct
1543 * ipsecrequest is not reference counted.
1544 */
1545 q = &newchain;
1546 for (p = src->req; p; p = p->next) {
1547 *q = kalloc_type(struct ipsecrequest, Z_WAITOK_ZERO_NOFAIL);
1548
1549 (*q)->saidx.proto = p->saidx.proto;
1550 (*q)->saidx.mode = p->saidx.mode;
1551 (*q)->level = p->level;
1552 (*q)->saidx.reqid = p->saidx.reqid;
1553
1554 bcopy(&p->saidx.src, &(*q)->saidx.src, sizeof((*q)->saidx.src));
1555 bcopy(&p->saidx.dst, &(*q)->saidx.dst, sizeof((*q)->saidx.dst));
1556
1557 (*q)->sp = dst;
1558
1559 q = &((*q)->next);
1560 }
1561
1562 dst->req = newchain;
1563 dst->state = src->state;
1564 dst->policy = src->policy;
1565 /* do not touch the refcnt fields */
1566
1567 return dst;
1568 }
1569
1570 /* set policy and ipsec request if present. */
1571 static int
ipsec_set_policy(struct secpolicy ** pcb_sp,__unused int optname,caddr_t __sized_by (len)request,size_t len,int priv)1572 ipsec_set_policy(struct secpolicy **pcb_sp,
1573 __unused int optname,
1574 caddr_t __sized_by(len)request,
1575 size_t len,
1576 int priv)
1577 {
1578 struct sadb_x_policy *xpl;
1579 struct secpolicy *newsp = NULL;
1580 int error;
1581
1582 /* sanity check. */
1583 if (pcb_sp == NULL || *pcb_sp == NULL || request == NULL) {
1584 return EINVAL;
1585 }
1586 if (len < sizeof(*xpl)) {
1587 return EINVAL;
1588 }
1589 xpl = (struct sadb_x_policy *)(void *)request;
1590
1591 KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
1592 printf("ipsec_set_policy: passed policy\n");
1593 kdebug_sadb_x_policy((struct sadb_ext *)xpl));
1594
1595 /* check policy type */
1596 /* ipsec_set_policy() accepts IPSEC, ENTRUST and BYPASS. */
1597 if (xpl->sadb_x_policy_type == IPSEC_POLICY_DISCARD
1598 || xpl->sadb_x_policy_type == IPSEC_POLICY_NONE) {
1599 return EINVAL;
1600 }
1601
1602 /* check privileged socket */
1603 if (priv == 0 && xpl->sadb_x_policy_type == IPSEC_POLICY_BYPASS) {
1604 return EACCES;
1605 }
1606
1607 /* allocation new SP entry */
1608 if ((newsp = key_msg2sp(xpl, len, &error)) == NULL) {
1609 return error;
1610 }
1611
1612 newsp->state = IPSEC_SPSTATE_ALIVE;
1613
1614 /* clear old SP and set new SP */
1615 key_freesp(*pcb_sp, KEY_SADB_UNLOCKED);
1616 *pcb_sp = newsp;
1617 KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
1618 printf("ipsec_set_policy: new policy\n");
1619 kdebug_secpolicy(newsp));
1620
1621 return 0;
1622 }
1623
1624 int
ipsec4_set_policy(struct inpcb * inp,int optname,caddr_t __sized_by (len)request,size_t len,int priv)1625 ipsec4_set_policy(struct inpcb *inp,
1626 int optname,
1627 caddr_t __sized_by(len)request,
1628 size_t len,
1629 int priv)
1630 {
1631 struct sadb_x_policy *xpl;
1632 struct secpolicy **pcb_sp;
1633 int error = 0;
1634 struct sadb_x_policy xpl_aligned_buf;
1635 u_int8_t *xpl_unaligned;
1636
1637 /* sanity check. */
1638 if (inp == NULL || request == NULL) {
1639 return EINVAL;
1640 }
1641 if (len < sizeof(*xpl)) {
1642 return EINVAL;
1643 }
1644 xpl = (struct sadb_x_policy *)(void *)request;
1645
1646 /* This is a new mbuf allocated by soopt_getm() */
1647 if (IPSEC_IS_P2ALIGNED(xpl)) {
1648 xpl_unaligned = NULL;
1649 } else {
1650 xpl_unaligned = (__typeof__(xpl_unaligned))xpl;
1651 memcpy(&xpl_aligned_buf, xpl, sizeof(xpl_aligned_buf));
1652 xpl = (__typeof__(xpl)) & xpl_aligned_buf;
1653 }
1654
1655 if (inp->inp_sp == NULL) {
1656 error = ipsec_init_policy(inp->inp_socket, &inp->inp_sp);
1657 if (error) {
1658 return error;
1659 }
1660 }
1661
1662 /* select direction */
1663 switch (xpl->sadb_x_policy_dir) {
1664 case IPSEC_DIR_INBOUND:
1665 pcb_sp = &inp->inp_sp->sp_in;
1666 break;
1667 case IPSEC_DIR_OUTBOUND:
1668 pcb_sp = &inp->inp_sp->sp_out;
1669 break;
1670 default:
1671 ipseclog((LOG_ERR, "ipsec4_set_policy: invalid direction=%u\n",
1672 xpl->sadb_x_policy_dir));
1673 return EINVAL;
1674 }
1675
1676 /* turn bypass off */
1677 if (ipsec_bypass != 0) {
1678 ipsec_bypass = 0;
1679 }
1680
1681 return ipsec_set_policy(pcb_sp, optname, request, len, priv);
1682 }
1683
1684 /* delete policy in PCB */
1685 int
ipsec4_delete_pcbpolicy(struct inpcb * inp)1686 ipsec4_delete_pcbpolicy(struct inpcb *inp)
1687 {
1688 /* sanity check. */
1689 if (inp == NULL) {
1690 panic("ipsec4_delete_pcbpolicy: NULL pointer was passed.");
1691 }
1692
1693 if (inp->inp_sp == NULL) {
1694 return 0;
1695 }
1696
1697 if (inp->inp_sp->sp_in != NULL) {
1698 key_freesp(inp->inp_sp->sp_in, KEY_SADB_UNLOCKED);
1699 inp->inp_sp->sp_in = NULL;
1700 }
1701
1702 if (inp->inp_sp->sp_out != NULL) {
1703 key_freesp(inp->inp_sp->sp_out, KEY_SADB_UNLOCKED);
1704 inp->inp_sp->sp_out = NULL;
1705 }
1706
1707 ipsec_delpcbpolicy(inp->inp_sp);
1708 inp->inp_sp = NULL;
1709
1710 return 0;
1711 }
1712
1713 int
ipsec6_set_policy(struct in6pcb * in6p,int optname,caddr_t __sized_by (len)request,size_t len,int priv)1714 ipsec6_set_policy(struct in6pcb *in6p,
1715 int optname,
1716 caddr_t __sized_by(len)request,
1717 size_t len,
1718 int priv)
1719 {
1720 struct sadb_x_policy *xpl;
1721 struct secpolicy **pcb_sp;
1722 int error = 0;
1723 struct sadb_x_policy xpl_aligned_buf;
1724 u_int8_t *xpl_unaligned;
1725
1726 /* sanity check. */
1727 if (in6p == NULL || request == NULL) {
1728 return EINVAL;
1729 }
1730 if (len < sizeof(*xpl)) {
1731 return EINVAL;
1732 }
1733 xpl = (struct sadb_x_policy *)(void *)request;
1734
1735 /* This is a new mbuf allocated by soopt_getm() */
1736 if (IPSEC_IS_P2ALIGNED(xpl)) {
1737 xpl_unaligned = NULL;
1738 } else {
1739 xpl_unaligned = (__typeof__(xpl_unaligned))xpl;
1740 memcpy(&xpl_aligned_buf, xpl, sizeof(xpl_aligned_buf));
1741 xpl = (__typeof__(xpl)) & xpl_aligned_buf;
1742 }
1743
1744 if (in6p->in6p_sp == NULL) {
1745 error = ipsec_init_policy(in6p->inp_socket, &in6p->in6p_sp);
1746 if (error) {
1747 return error;
1748 }
1749 }
1750
1751 /* select direction */
1752 switch (xpl->sadb_x_policy_dir) {
1753 case IPSEC_DIR_INBOUND:
1754 pcb_sp = &in6p->in6p_sp->sp_in;
1755 break;
1756 case IPSEC_DIR_OUTBOUND:
1757 pcb_sp = &in6p->in6p_sp->sp_out;
1758 break;
1759 default:
1760 ipseclog((LOG_ERR, "ipsec6_set_policy: invalid direction=%u\n",
1761 xpl->sadb_x_policy_dir));
1762 return EINVAL;
1763 }
1764
1765 return ipsec_set_policy(pcb_sp, optname, request, len, priv);
1766 }
1767
1768 int
ipsec6_delete_pcbpolicy(struct in6pcb * in6p)1769 ipsec6_delete_pcbpolicy(struct in6pcb *in6p)
1770 {
1771 /* sanity check. */
1772 if (in6p == NULL) {
1773 panic("ipsec6_delete_pcbpolicy: NULL pointer was passed.");
1774 }
1775
1776 if (in6p->in6p_sp == NULL) {
1777 return 0;
1778 }
1779
1780 if (in6p->in6p_sp->sp_in != NULL) {
1781 key_freesp(in6p->in6p_sp->sp_in, KEY_SADB_UNLOCKED);
1782 in6p->in6p_sp->sp_in = NULL;
1783 }
1784
1785 if (in6p->in6p_sp->sp_out != NULL) {
1786 key_freesp(in6p->in6p_sp->sp_out, KEY_SADB_UNLOCKED);
1787 in6p->in6p_sp->sp_out = NULL;
1788 }
1789
1790 ipsec_delpcbpolicy(in6p->in6p_sp);
1791 in6p->in6p_sp = NULL;
1792
1793 return 0;
1794 }
1795
1796 /*
1797 * return current level.
1798 * Either IPSEC_LEVEL_USE or IPSEC_LEVEL_REQUIRE are always returned.
1799 */
1800 u_int
ipsec_get_reqlevel(struct ipsecrequest * isr)1801 ipsec_get_reqlevel(struct ipsecrequest *isr)
1802 {
1803 u_int level = 0;
1804 u_int esp_trans_deflev = 0, esp_net_deflev = 0, ah_trans_deflev = 0, ah_net_deflev = 0;
1805
1806 /* sanity check */
1807 if (isr == NULL || isr->sp == NULL) {
1808 panic("ipsec_get_reqlevel: NULL pointer is passed.");
1809 }
1810 if (SA(&isr->sp->spidx.src)->sa_family
1811 != SA(&isr->sp->spidx.dst)->sa_family) {
1812 panic("ipsec_get_reqlevel: family mismatched.");
1813 }
1814
1815 /* XXX note that we have ipseclog() expanded here - code sync issue */
1816 #define IPSEC_CHECK_DEFAULT(lev) \
1817 (((lev) != IPSEC_LEVEL_USE && (lev) != IPSEC_LEVEL_REQUIRE \
1818 && (lev) != IPSEC_LEVEL_UNIQUE) \
1819 ? (ipsec_debug \
1820 ? log(LOG_INFO, "fixed system default level " #lev ":%d->%d\n",\
1821 (lev), IPSEC_LEVEL_REQUIRE) \
1822 : (void)0), \
1823 (lev) = IPSEC_LEVEL_REQUIRE, \
1824 (lev) \
1825 : (lev))
1826
1827 /* set default level */
1828 switch (SA(&isr->sp->spidx.src)->sa_family) {
1829 case AF_INET:
1830 esp_trans_deflev = IPSEC_CHECK_DEFAULT(ip4_esp_trans_deflev);
1831 esp_net_deflev = IPSEC_CHECK_DEFAULT(ip4_esp_net_deflev);
1832 ah_trans_deflev = IPSEC_CHECK_DEFAULT(ip4_ah_trans_deflev);
1833 ah_net_deflev = IPSEC_CHECK_DEFAULT(ip4_ah_net_deflev);
1834 break;
1835 case AF_INET6:
1836 esp_trans_deflev = IPSEC_CHECK_DEFAULT(ip6_esp_trans_deflev);
1837 esp_net_deflev = IPSEC_CHECK_DEFAULT(ip6_esp_net_deflev);
1838 ah_trans_deflev = IPSEC_CHECK_DEFAULT(ip6_ah_trans_deflev);
1839 ah_net_deflev = IPSEC_CHECK_DEFAULT(ip6_ah_net_deflev);
1840 break;
1841 default:
1842 panic("key_get_reqlevel: Unknown family. %d",
1843 SA(&isr->sp->spidx.src)->sa_family);
1844 }
1845
1846 #undef IPSEC_CHECK_DEFAULT
1847
1848 /* set level */
1849 switch (isr->level) {
1850 case IPSEC_LEVEL_DEFAULT:
1851 switch (isr->saidx.proto) {
1852 case IPPROTO_ESP:
1853 if (isr->saidx.mode == IPSEC_MODE_TUNNEL) {
1854 level = esp_net_deflev;
1855 } else {
1856 level = esp_trans_deflev;
1857 }
1858 break;
1859 case IPPROTO_AH:
1860 if (isr->saidx.mode == IPSEC_MODE_TUNNEL) {
1861 level = ah_net_deflev;
1862 } else {
1863 level = ah_trans_deflev;
1864 }
1865 break;
1866 case IPPROTO_IPCOMP:
1867 ipseclog((LOG_ERR, "ipsec_get_reqlevel: "
1868 "still got IPCOMP - exiting\n"));
1869 break;
1870 default:
1871 panic("ipsec_get_reqlevel: "
1872 "Illegal protocol defined %u\n",
1873 isr->saidx.proto);
1874 }
1875 break;
1876
1877 case IPSEC_LEVEL_USE:
1878 case IPSEC_LEVEL_REQUIRE:
1879 level = isr->level;
1880 break;
1881 case IPSEC_LEVEL_UNIQUE:
1882 level = IPSEC_LEVEL_REQUIRE;
1883 break;
1884
1885 default:
1886 panic("ipsec_get_reqlevel: Illegal IPsec level %u",
1887 isr->level);
1888 }
1889
1890 return level;
1891 }
1892
1893 /*
1894 * Check AH/ESP integrity.
1895 * OUT:
1896 * 0: valid
1897 * 1: invalid
1898 */
1899 static int
ipsec_in_reject(struct secpolicy * sp,struct mbuf * m)1900 ipsec_in_reject(struct secpolicy *sp, struct mbuf *m)
1901 {
1902 struct ipsecrequest *isr;
1903 u_int level;
1904 int need_auth, need_conf, need_icv;
1905
1906 KEYDEBUG(KEYDEBUG_IPSEC_DATA,
1907 printf("ipsec_in_reject: using SP\n");
1908 kdebug_secpolicy(sp));
1909
1910 /* check policy */
1911 switch (sp->policy) {
1912 case IPSEC_POLICY_DISCARD:
1913 case IPSEC_POLICY_GENERATE:
1914 return 1;
1915 case IPSEC_POLICY_BYPASS:
1916 case IPSEC_POLICY_NONE:
1917 return 0;
1918
1919 case IPSEC_POLICY_IPSEC:
1920 break;
1921
1922 case IPSEC_POLICY_ENTRUST:
1923 default:
1924 panic("ipsec_hdrsiz: Invalid policy found. %d", sp->policy);
1925 }
1926
1927 need_auth = 0;
1928 need_conf = 0;
1929 need_icv = 0;
1930
1931 /* XXX should compare policy against ipsec header history */
1932
1933 for (isr = sp->req; isr != NULL; isr = isr->next) {
1934 /* get current level */
1935 level = ipsec_get_reqlevel(isr);
1936
1937 switch (isr->saidx.proto) {
1938 case IPPROTO_ESP:
1939 if (level == IPSEC_LEVEL_REQUIRE) {
1940 need_conf++;
1941
1942 #if 0
1943 /* this won't work with multiple input threads - isr->sav would change
1944 * with every packet and is not necessarily related to the current packet
1945 * being processed. If ESP processing is required - the esp code should
1946 * make sure that the integrity check is present and correct. I don't see
1947 * why it would be necessary to check for the presence of the integrity
1948 * check value here. I think this is just wrong.
1949 * isr->sav has been removed.
1950 * %%%%%% this needs to be re-worked at some point but I think the code below can
1951 * be ignored for now.
1952 */
1953 if (isr->sav != NULL
1954 && isr->sav->flags == SADB_X_EXT_NONE
1955 && isr->sav->alg_auth != SADB_AALG_NONE) {
1956 need_icv++;
1957 }
1958 #endif
1959 }
1960 break;
1961 case IPPROTO_AH:
1962 if (level == IPSEC_LEVEL_REQUIRE) {
1963 need_auth++;
1964 need_icv++;
1965 }
1966 break;
1967 case IPPROTO_IPCOMP:
1968 /*
1969 * we don't really care, as IPcomp document says that
1970 * we shouldn't compress small packets, IPComp policy
1971 * should always be treated as being in "use" level.
1972 */
1973 break;
1974 }
1975 }
1976
1977 KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
1978 printf("ipsec_in_reject: auth:%d conf:%d icv:%d m_flags:%x\n",
1979 need_auth, need_conf, need_icv, m->m_flags));
1980
1981 if ((need_conf && !(m->m_flags & M_DECRYPTED))
1982 || (!need_auth && need_icv && !(m->m_flags & M_AUTHIPDGM))
1983 || (need_auth && !(m->m_flags & M_AUTHIPHDR))) {
1984 return 1;
1985 }
1986
1987 return 0;
1988 }
1989
1990 /*
1991 * Check AH/ESP integrity.
1992 * This function is called from tcp_input(), udp_input(),
1993 * and {ah,esp}4_input for tunnel mode
1994 */
1995 int
ipsec4_in_reject_so(struct mbuf * m,struct socket * so)1996 ipsec4_in_reject_so(struct mbuf *m, struct socket *so)
1997 {
1998 struct secpolicy *sp = NULL;
1999 int error;
2000 int result;
2001
2002 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
2003 /* sanity check */
2004 if (m == NULL) {
2005 return 0; /* XXX should be panic ? */
2006 }
2007 /* get SP for this packet.
2008 * When we are called from ip_forward(), we call
2009 * ipsec4_getpolicybyaddr() with IP_FORWARDING flag.
2010 */
2011 if (so == NULL) {
2012 sp = ipsec4_getpolicybyaddr(m, IPSEC_DIR_INBOUND, IP_FORWARDING, &error);
2013 } else {
2014 sp = ipsec4_getpolicybyaddr(m, IPSEC_DIR_INBOUND, 0, &error);
2015 }
2016
2017 if (sp == NULL) {
2018 return 0; /* XXX should be panic ?
2019 * -> No, there may be error. */
2020 }
2021 result = ipsec_in_reject(sp, m);
2022 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
2023 printf("DP ipsec4_in_reject_so call free SP:0x%llx\n",
2024 (uint64_t)VM_KERNEL_ADDRPERM(sp)));
2025 key_freesp(sp, KEY_SADB_UNLOCKED);
2026
2027 return result;
2028 }
2029
2030 int
ipsec4_in_reject(struct mbuf * m,struct inpcb * inp)2031 ipsec4_in_reject(struct mbuf *m, struct inpcb *inp)
2032 {
2033 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
2034 if (inp == NULL) {
2035 return ipsec4_in_reject_so(m, NULL);
2036 }
2037 if (inp->inp_socket) {
2038 return ipsec4_in_reject_so(m, inp->inp_socket);
2039 } else {
2040 panic("ipsec4_in_reject: invalid inpcb/socket");
2041 }
2042
2043 /* NOTREACHED */
2044 return 0;
2045 }
2046
2047 /*
2048 * Check AH/ESP integrity.
2049 * This function is called from tcp6_input(), udp6_input(),
2050 * and {ah,esp}6_input for tunnel mode
2051 */
2052 int
ipsec6_in_reject_so(struct mbuf * m,struct socket * so)2053 ipsec6_in_reject_so(struct mbuf *m, struct socket *so)
2054 {
2055 struct secpolicy *sp = NULL;
2056 int error;
2057 int result;
2058
2059 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
2060 /* sanity check */
2061 if (m == NULL) {
2062 return 0; /* XXX should be panic ? */
2063 }
2064 /* get SP for this packet.
2065 * When we are called from ip_forward(), we call
2066 * ipsec6_getpolicybyaddr() with IP_FORWARDING flag.
2067 */
2068 if (so == NULL) {
2069 sp = ipsec6_getpolicybyaddr(m, IPSEC_DIR_INBOUND, IP_FORWARDING, &error);
2070 } else {
2071 sp = ipsec6_getpolicybyaddr(m, IPSEC_DIR_INBOUND, 0, &error);
2072 }
2073
2074 if (sp == NULL) {
2075 return 0; /* XXX should be panic ? */
2076 }
2077 result = ipsec_in_reject(sp, m);
2078 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
2079 printf("DP ipsec6_in_reject_so call free SP:0x%llx\n",
2080 (uint64_t)VM_KERNEL_ADDRPERM(sp)));
2081 key_freesp(sp, KEY_SADB_UNLOCKED);
2082
2083 return result;
2084 }
2085
2086 int
ipsec6_in_reject(struct mbuf * m,struct in6pcb * in6p)2087 ipsec6_in_reject(struct mbuf *m, struct in6pcb *in6p)
2088 {
2089 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
2090 if (in6p == NULL) {
2091 return ipsec6_in_reject_so(m, NULL);
2092 }
2093 if (in6p->in6p_socket) {
2094 return ipsec6_in_reject_so(m, in6p->in6p_socket);
2095 } else {
2096 panic("ipsec6_in_reject: invalid in6p/socket");
2097 }
2098
2099 /* NOTREACHED */
2100 return 0;
2101 }
2102
2103 /*
2104 * compute the byte size to be occupied by IPsec header.
2105 * in case it is tunneled, it includes the size of outer IP header.
2106 * NOTE: SP passed is free in this function.
2107 */
2108 size_t
ipsec_hdrsiz(struct secpolicy * sp)2109 ipsec_hdrsiz(struct secpolicy *sp)
2110 {
2111 struct ipsecrequest *isr;
2112 size_t siz, clen;
2113
2114 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
2115 KEYDEBUG(KEYDEBUG_IPSEC_DATA,
2116 printf("ipsec_hdrsiz: using SP\n");
2117 kdebug_secpolicy(sp));
2118
2119 /* check policy */
2120 switch (sp->policy) {
2121 case IPSEC_POLICY_DISCARD:
2122 case IPSEC_POLICY_GENERATE:
2123 case IPSEC_POLICY_BYPASS:
2124 case IPSEC_POLICY_NONE:
2125 return 0;
2126
2127 case IPSEC_POLICY_IPSEC:
2128 break;
2129
2130 case IPSEC_POLICY_ENTRUST:
2131 default:
2132 panic("ipsec_hdrsiz: Invalid policy found. %d", sp->policy);
2133 }
2134
2135 siz = 0;
2136
2137 for (isr = sp->req; isr != NULL; isr = isr->next) {
2138 clen = 0;
2139
2140 switch (isr->saidx.proto) {
2141 case IPPROTO_ESP:
2142 #if IPSEC_ESP
2143 clen = esp_hdrsiz(isr);
2144 #else
2145 clen = 0; /*XXX*/
2146 #endif
2147 break;
2148 case IPPROTO_AH:
2149 clen = ah_hdrsiz(isr);
2150 break;
2151 default:
2152 ipseclog((LOG_ERR, "ipsec_hdrsiz: "
2153 "unknown protocol %u\n",
2154 isr->saidx.proto));
2155 break;
2156 }
2157
2158 if (isr->saidx.mode == IPSEC_MODE_TUNNEL) {
2159 switch (SA(&isr->saidx.dst)->sa_family) {
2160 case AF_INET:
2161 clen += sizeof(struct ip);
2162 break;
2163 case AF_INET6:
2164 clen += sizeof(struct ip6_hdr);
2165 break;
2166 default:
2167 ipseclog((LOG_ERR, "ipsec_hdrsiz: "
2168 "unknown AF %d in IPsec tunnel SA\n",
2169 SA(&isr->saidx.dst)->sa_family));
2170 break;
2171 }
2172 }
2173 siz += clen;
2174 }
2175
2176 return siz;
2177 }
2178
2179 /* This function is called from ip_forward() and ipsec4_hdrsize_tcp(). */
2180 size_t
ipsec4_hdrsiz(struct mbuf * m,u_int8_t dir,struct inpcb * inp)2181 ipsec4_hdrsiz(struct mbuf *m, u_int8_t dir, struct inpcb *inp)
2182 {
2183 struct secpolicy *sp = NULL;
2184 int error;
2185 size_t size;
2186
2187 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
2188 /* sanity check */
2189 if (m == NULL) {
2190 return 0; /* XXX should be panic ? */
2191 }
2192 if (inp != NULL && inp->inp_socket == NULL) {
2193 panic("ipsec4_hdrsize: why is socket NULL but there is PCB.");
2194 }
2195
2196 /* get SP for this packet.
2197 * When we are called from ip_forward(), we call
2198 * ipsec4_getpolicybyaddr() with IP_FORWARDING flag.
2199 */
2200 if (inp == NULL) {
2201 sp = ipsec4_getpolicybyaddr(m, dir, IP_FORWARDING, &error);
2202 } else {
2203 sp = ipsec4_getpolicybyaddr(m, dir, 0, &error);
2204 }
2205
2206 if (sp == NULL) {
2207 return 0; /* XXX should be panic ? */
2208 }
2209 size = ipsec_hdrsiz(sp);
2210 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
2211 printf("DP ipsec4_hdrsiz call free SP:0x%llx\n",
2212 (uint64_t)VM_KERNEL_ADDRPERM(sp)));
2213 KEYDEBUG(KEYDEBUG_IPSEC_DATA,
2214 printf("ipsec4_hdrsiz: size:%lu.\n", (u_int32_t)size));
2215 key_freesp(sp, KEY_SADB_UNLOCKED);
2216
2217 return size;
2218 }
2219
2220 /* This function is called from ipsec6_hdrsize_tcp(),
2221 * and maybe from ip6_forward.()
2222 */
2223 size_t
ipsec6_hdrsiz(struct mbuf * m,u_int8_t dir,struct in6pcb * in6p)2224 ipsec6_hdrsiz(struct mbuf *m, u_int8_t dir, struct in6pcb *in6p)
2225 {
2226 struct secpolicy *sp = NULL;
2227 int error;
2228 size_t size;
2229
2230 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
2231 /* sanity check */
2232 if (m == NULL) {
2233 return 0; /* XXX shoud be panic ? */
2234 }
2235 if (in6p != NULL && in6p->in6p_socket == NULL) {
2236 panic("ipsec6_hdrsize: why is socket NULL but there is PCB.");
2237 }
2238
2239 /* get SP for this packet */
2240 /* XXX Is it right to call with IP_FORWARDING. */
2241 if (in6p == NULL) {
2242 sp = ipsec6_getpolicybyaddr(m, dir, IP_FORWARDING, &error);
2243 } else {
2244 sp = ipsec6_getpolicybyaddr(m, dir, 0, &error);
2245 }
2246
2247 if (sp == NULL) {
2248 return 0;
2249 }
2250 size = ipsec_hdrsiz(sp);
2251 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
2252 printf("DP ipsec6_hdrsiz call free SP:0x%llx\n",
2253 (uint64_t)VM_KERNEL_ADDRPERM(sp)));
2254 KEYDEBUG(KEYDEBUG_IPSEC_DATA,
2255 printf("ipsec6_hdrsiz: size:%lu.\n", (u_int32_t)size));
2256 key_freesp(sp, KEY_SADB_UNLOCKED);
2257
2258 return size;
2259 }
2260
2261 /*
2262 * encapsulate for ipsec tunnel.
2263 * ip->ip_src must be fixed later on.
2264 */
2265 int
ipsec4_encapsulate(struct mbuf * m,struct secasvar * sav)2266 ipsec4_encapsulate(struct mbuf *m, struct secasvar *sav)
2267 {
2268 struct ip *oip;
2269 struct ip *ip;
2270 size_t plen;
2271 u_int32_t hlen;
2272
2273 /* can't tunnel between different AFs */
2274 if (SA(&sav->sah->saidx.src)->sa_family != SA(&sav->sah->saidx.dst)->sa_family
2275 || SA(&sav->sah->saidx.src)->sa_family != AF_INET) {
2276 m_freem(m);
2277 return EINVAL;
2278 }
2279
2280 if (m->m_len < sizeof(*ip)) {
2281 panic("ipsec4_encapsulate: assumption failed (first mbuf length)");
2282 }
2283
2284 ip = mtod(m, struct ip *);
2285 #ifdef _IP_VHL
2286 hlen = _IP_VHL_HL(ip->ip_vhl) << 2;
2287 #else
2288 hlen = ip->ip_hl << 2;
2289 #endif
2290
2291 if (m->m_len != hlen) {
2292 panic("ipsec4_encapsulate: assumption failed (first mbuf length)");
2293 }
2294
2295 /* generate header checksum */
2296 ip->ip_sum = 0;
2297 #ifdef _IP_VHL
2298 ip->ip_sum = in_cksum(m, hlen);
2299 #else
2300 ip->ip_sum = in_cksum(m, hlen);
2301 #endif
2302
2303 plen = m->m_pkthdr.len;
2304
2305 /*
2306 * grow the mbuf to accomodate the new IPv4 header.
2307 * NOTE: IPv4 options will never be copied.
2308 */
2309 if (M_LEADINGSPACE(m->m_next) < hlen) {
2310 struct mbuf *n;
2311 MGET(n, M_DONTWAIT, MT_DATA);
2312 if (!n) {
2313 m_freem(m);
2314 return ENOBUFS;
2315 }
2316 n->m_len = hlen;
2317 n->m_next = m->m_next;
2318 m->m_next = n;
2319 m->m_pkthdr.len += hlen;
2320 oip = mtod(n, struct ip *);
2321 } else {
2322 m->m_next->m_len += hlen;
2323 m->m_next->m_data -= hlen;
2324 m->m_pkthdr.len += hlen;
2325 oip = mtod(m->m_next, struct ip *);
2326 }
2327 ip = mtod(m, struct ip *);
2328 ovbcopy((caddr_t)ip, (caddr_t)oip, hlen);
2329 m->m_len = sizeof(struct ip);
2330 m->m_pkthdr.len -= (hlen - sizeof(struct ip));
2331
2332 /* construct new IPv4 header. see RFC 2401 5.1.2.1 */
2333 /* ECN consideration. */
2334 ip_ecn_ingress(ip4_ipsec_ecn, &ip->ip_tos, &oip->ip_tos);
2335 #ifdef _IP_VHL
2336 ip->ip_vhl = IP_MAKE_VHL(IPVERSION, sizeof(struct ip) >> 2);
2337 #else
2338 ip->ip_hl = sizeof(struct ip) >> 2;
2339 #endif
2340 ip->ip_off &= htons(~IP_OFFMASK);
2341 ip->ip_off &= htons(~IP_MF);
2342 switch (ip4_ipsec_dfbit) {
2343 case 0: /* clear DF bit */
2344 ip->ip_off &= htons(~IP_DF);
2345 break;
2346 case 1: /* set DF bit */
2347 ip->ip_off |= htons(IP_DF);
2348 break;
2349 default: /* copy DF bit */
2350 break;
2351 }
2352 ip->ip_p = IPPROTO_IPIP;
2353 if (plen + sizeof(struct ip) < IP_MAXPACKET) {
2354 ip->ip_len = htons((u_int16_t)(plen + sizeof(struct ip)));
2355 } else {
2356 ipseclog((LOG_ERR, "IPv4 ipsec: size exceeds limit: "
2357 "leave ip_len as is (invalid packet)\n"));
2358 }
2359 if (rfc6864 && IP_OFF_IS_ATOMIC(ntohs(ip->ip_off))) {
2360 ip->ip_id = 0;
2361 } else {
2362 ip->ip_id = ip_randomid((uint64_t)m);
2363 }
2364 bcopy(&SIN(&sav->sah->saidx.src)->sin_addr,
2365 &ip->ip_src, sizeof(ip->ip_src));
2366 bcopy(&SIN(&sav->sah->saidx.dst)->sin_addr,
2367 &ip->ip_dst, sizeof(ip->ip_dst));
2368 ip->ip_ttl = IPDEFTTL;
2369
2370 /* XXX Should ip_src be updated later ? */
2371
2372 return 0;
2373 }
2374
2375
2376 int
ipsec6_encapsulate(struct mbuf * m,struct secasvar * sav)2377 ipsec6_encapsulate(struct mbuf *m, struct secasvar *sav)
2378 {
2379 struct ip6_hdr *oip6;
2380 struct ip6_hdr *ip6;
2381 size_t plen;
2382
2383 /* can't tunnel between different AFs */
2384 if (SA(&sav->sah->saidx.src)->sa_family != SA(&sav->sah->saidx.dst)->sa_family
2385 || SA(&sav->sah->saidx.src)->sa_family != AF_INET6) {
2386 m_freem(m);
2387 return EINVAL;
2388 }
2389
2390 plen = m->m_pkthdr.len;
2391
2392 /*
2393 * grow the mbuf to accomodate the new IPv6 header.
2394 */
2395 if (m->m_len != sizeof(struct ip6_hdr)) {
2396 panic("ipsec6_encapsulate: assumption failed (first mbuf length)");
2397 }
2398 if (M_LEADINGSPACE(m->m_next) < sizeof(struct ip6_hdr)) {
2399 struct mbuf *n;
2400 MGET(n, M_DONTWAIT, MT_DATA);
2401 if (!n) {
2402 m_freem(m);
2403 return ENOBUFS;
2404 }
2405 n->m_len = sizeof(struct ip6_hdr);
2406 n->m_next = m->m_next;
2407 m->m_next = n;
2408 m->m_pkthdr.len += sizeof(struct ip6_hdr);
2409 oip6 = mtod(n, struct ip6_hdr *);
2410 } else {
2411 m->m_next->m_len += sizeof(struct ip6_hdr);
2412 m->m_next->m_data -= sizeof(struct ip6_hdr);
2413 m->m_pkthdr.len += sizeof(struct ip6_hdr);
2414 oip6 = mtod(m->m_next, struct ip6_hdr *);
2415 }
2416 ip6 = mtod(m, struct ip6_hdr *);
2417 ovbcopy((caddr_t)ip6, (caddr_t)oip6, sizeof(struct ip6_hdr));
2418
2419 /* Fake link-local scope-class addresses */
2420 if (in6_embedded_scope && IN6_IS_SCOPE_LINKLOCAL(&oip6->ip6_src)) {
2421 oip6->ip6_src.s6_addr16[1] = 0;
2422 }
2423 if (in6_embedded_scope && IN6_IS_SCOPE_LINKLOCAL(&oip6->ip6_dst)) {
2424 oip6->ip6_dst.s6_addr16[1] = 0;
2425 }
2426
2427 /* construct new IPv6 header. see RFC 2401 5.1.2.2 */
2428 /* ECN consideration. */
2429 ip6_ecn_ingress(ip6_ipsec_ecn, &ip6->ip6_flow, &oip6->ip6_flow);
2430 if (plen < IPV6_MAXPACKET - sizeof(struct ip6_hdr)) {
2431 ip6->ip6_plen = htons((u_int16_t)plen);
2432 } else {
2433 /* ip6->ip6_plen will be updated in ip6_output() */
2434 }
2435 ip6->ip6_nxt = IPPROTO_IPV6;
2436 bcopy(&SIN6(&sav->sah->saidx.src)->sin6_addr,
2437 &ip6->ip6_src, sizeof(ip6->ip6_src));
2438 bcopy(&SIN6(&sav->sah->saidx.dst)->sin6_addr,
2439 &ip6->ip6_dst, sizeof(ip6->ip6_dst));
2440 ip6->ip6_hlim = IPV6_DEFHLIM;
2441
2442 if (in6_embedded_scope && IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst)) {
2443 ip6->ip6_src.s6_addr16[1] = htons((u_int16_t)sav->sah->outgoing_if);
2444 ip6->ip6_dst.s6_addr16[1] = htons((u_int16_t)sav->sah->outgoing_if);
2445 }
2446
2447 /* XXX Should ip6_src be updated later ? */
2448
2449 return 0;
2450 }
2451
2452 static int
ipsec64_encapsulate(struct mbuf * m,struct secasvar * sav,u_int32_t dscp_mapping)2453 ipsec64_encapsulate(struct mbuf *m, struct secasvar *sav, u_int32_t dscp_mapping)
2454 {
2455 struct ip6_hdr *ip6, *ip6i;
2456 struct ip *ip;
2457 size_t plen;
2458
2459 /* tunneling over IPv4 */
2460 if (SA(&sav->sah->saidx.src)->sa_family != SA(&sav->sah->saidx.dst)->sa_family
2461 || SA(&sav->sah->saidx.src)->sa_family != AF_INET) {
2462 m_freem(m);
2463 return EINVAL;
2464 }
2465
2466 plen = m->m_pkthdr.len;
2467 ip6 = mtod(m, struct ip6_hdr *);
2468 /*
2469 * grow the mbuf to accomodate the new IPv4 header.
2470 */
2471 if (m->m_len != sizeof(struct ip6_hdr)) {
2472 panic("ipsec6_encapsulate: assumption failed (first mbuf length)");
2473 }
2474 if (M_LEADINGSPACE(m->m_next) < sizeof(struct ip6_hdr)) {
2475 struct mbuf *n;
2476 MGET(n, M_DONTWAIT, MT_DATA);
2477 if (!n) {
2478 m_freem(m);
2479 return ENOBUFS;
2480 }
2481 n->m_len = sizeof(struct ip6_hdr);
2482 n->m_next = m->m_next;
2483 m->m_next = n;
2484 m->m_pkthdr.len += sizeof(struct ip);
2485 ip6i = mtod(n, struct ip6_hdr *);
2486 } else {
2487 m->m_next->m_len += sizeof(struct ip6_hdr);
2488 m->m_next->m_data -= sizeof(struct ip6_hdr);
2489 m->m_pkthdr.len += sizeof(struct ip);
2490 ip6i = mtod(m->m_next, struct ip6_hdr *);
2491 }
2492
2493 bcopy(ip6, ip6i, sizeof(struct ip6_hdr));
2494 ip = mtod(m, struct ip *);
2495 m->m_len = sizeof(struct ip);
2496 /*
2497 * Fill in some of the IPv4 fields - we don't need all of them
2498 * because the rest will be filled in by ip_output
2499 */
2500 ip->ip_v = IPVERSION;
2501 ip->ip_hl = sizeof(struct ip) >> 2;
2502 ip->ip_id = 0;
2503 ip->ip_sum = 0;
2504 ip->ip_tos = 0;
2505 ip->ip_off = 0;
2506 ip->ip_ttl = IPDEFTTL;
2507 ip->ip_p = IPPROTO_IPV6;
2508
2509 /* construct new IPv4 header. see RFC 2401 5.1.2.1 */
2510 /* ECN consideration. */
2511 if (dscp_mapping == IPSEC_DSCP_MAPPING_COPY) {
2512 // Copy DSCP bits from inner IP to outer IP packet.
2513 ip64_ecn_ingress(ip4_ipsec_ecn, &ip->ip_tos, &ip6i->ip6_flow);
2514 } else if (dscp_mapping == IPSEC_DSCP_MAPPING_LEGACY) {
2515 // Copy DSCP bits in legacy style.
2516 ip64_ecn_ingress(ip4_ipsec_ecn, &ip->ip_tos, &ip6->ip6_flow);
2517 }
2518
2519 if (plen + sizeof(struct ip) < IP_MAXPACKET) {
2520 ip->ip_len = htons((u_int16_t)(plen + sizeof(struct ip)));
2521 } else {
2522 ip->ip_len = htons((u_int16_t)plen);
2523 ipseclog((LOG_ERR, "IPv4 ipsec: size exceeds limit: "
2524 "leave ip_len as is (invalid packet)\n"));
2525 }
2526 bcopy(&SIN(&sav->sah->saidx.src)->sin_addr,
2527 &ip->ip_src, sizeof(ip->ip_src));
2528 bcopy(&SIN(&sav->sah->saidx.dst)->sin_addr,
2529 &ip->ip_dst, sizeof(ip->ip_dst));
2530
2531 return 0;
2532 }
2533
2534 int
ipsec6_update_routecache_and_output(struct ipsec_output_state * state,struct secasvar * sav)2535 ipsec6_update_routecache_and_output(
2536 struct ipsec_output_state *state,
2537 struct secasvar *sav)
2538 {
2539 struct sockaddr_in6* dst6;
2540 struct route_in6 *ro6;
2541 struct ip6_hdr *ip6;
2542 errno_t error = 0;
2543
2544 int plen;
2545 struct ip6_out_args ip6oa;
2546 struct route_in6 ro6_new;
2547 struct flowadv *adv = NULL;
2548
2549 if (!state->m) {
2550 return EINVAL;
2551 }
2552 ip6 = mtod(state->m, struct ip6_hdr *);
2553
2554 // grab sadb_mutex, before updating sah's route cache
2555 lck_mtx_lock(sadb_mutex);
2556 ro6 = &sav->sah->sa_route;
2557 dst6 = SIN6(&ro6->ro_dst);
2558 if (ro6->ro_rt) {
2559 RT_LOCK(ro6->ro_rt);
2560 }
2561 if (ROUTE_UNUSABLE(ro6) ||
2562 !IN6_ARE_ADDR_EQUAL(&dst6->sin6_addr, &ip6->ip6_dst)) {
2563 if (ro6->ro_rt != NULL) {
2564 RT_UNLOCK(ro6->ro_rt);
2565 }
2566 ROUTE_RELEASE(ro6);
2567 }
2568 if (ro6->ro_rt == 0) {
2569 SOCKADDR_ZERO(dst6, sizeof(*dst6));
2570 dst6->sin6_family = AF_INET6;
2571 dst6->sin6_len = sizeof(*dst6);
2572 dst6->sin6_addr = ip6->ip6_dst;
2573 rtalloc_scoped((struct route *)ro6, sav->sah->outgoing_if);
2574 if (ro6->ro_rt) {
2575 RT_LOCK(ro6->ro_rt);
2576 }
2577 }
2578 if (ro6->ro_rt == 0) {
2579 ip6stat.ip6s_noroute++;
2580 IPSEC_STAT_INCREMENT(ipsec6stat.out_noroute);
2581 error = EHOSTUNREACH;
2582 // release sadb_mutex, after updating sah's route cache
2583 lck_mtx_unlock(sadb_mutex);
2584 return error;
2585 }
2586
2587 /*
2588 * adjust state->dst if tunnel endpoint is offlink
2589 *
2590 * XXX: caching rt_gateway value in the state is
2591 * not really good, since it may point elsewhere
2592 * when the gateway gets modified to a larger
2593 * sockaddr via rt_setgate(). This is currently
2594 * addressed by SA_SIZE roundup in that routine.
2595 */
2596 if (ro6->ro_rt->rt_flags & RTF_GATEWAY) {
2597 dst6 = SIN6(ro6->ro_rt->rt_gateway);
2598 }
2599 RT_UNLOCK(ro6->ro_rt);
2600 ROUTE_RELEASE(&state->ro);
2601 route_copyout((struct route *)&state->ro, (struct route *)ro6, sizeof(struct route_in6));
2602 state->dst = SA(dst6);
2603 state->tunneled = 6;
2604 // release sadb_mutex, after updating sah's route cache
2605 lck_mtx_unlock(sadb_mutex);
2606
2607 state->m = ipsec6_splithdr(state->m);
2608 if (!state->m) {
2609 IPSEC_STAT_INCREMENT(ipsec6stat.out_nomem);
2610 error = ENOMEM;
2611 return error;
2612 }
2613
2614 ip6 = mtod(state->m, struct ip6_hdr *);
2615 switch (sav->sah->saidx.proto) {
2616 case IPPROTO_ESP:
2617 #if IPSEC_ESP
2618 error = esp6_output(state->m, &ip6->ip6_nxt, state->m->m_next, sav);
2619 #else
2620 m_freem(state->m);
2621 error = EINVAL;
2622 #endif
2623 break;
2624 case IPPROTO_AH:
2625 error = ah6_output(state->m, &ip6->ip6_nxt, state->m->m_next, sav);
2626 break;
2627 default:
2628 ipseclog((LOG_ERR, "%s: unknown ipsec protocol %d\n", __FUNCTION__, sav->sah->saidx.proto));
2629 m_freem(state->m);
2630 IPSEC_STAT_INCREMENT(ipsec6stat.out_inval);
2631 error = EINVAL;
2632 break;
2633 }
2634 if (error) {
2635 // If error, packet already freed by above output routines
2636 state->m = NULL;
2637 return error;
2638 }
2639
2640 plen = state->m->m_pkthdr.len - sizeof(struct ip6_hdr);
2641 if (plen > IPV6_MAXPACKET) {
2642 ipseclog((LOG_ERR, "%s: IPsec with IPv6 jumbogram is not supported\n", __FUNCTION__));
2643 IPSEC_STAT_INCREMENT(ipsec6stat.out_inval);
2644 error = EINVAL;/*XXX*/
2645 return error;
2646 }
2647 ip6 = mtod(state->m, struct ip6_hdr *);
2648 ip6->ip6_plen = htons((u_int16_t)plen);
2649
2650 ipsec_set_pkthdr_for_interface(sav->sah->ipsec_if, state->m, AF_INET6,
2651 sav->flowid);
2652 ipsec_set_ip6oa_for_interface(sav->sah->ipsec_if, &ip6oa);
2653
2654 /* Increment statistics */
2655 ifnet_stat_increment_out(sav->sah->ipsec_if, 1, (u_int32_t)mbuf_pkthdr_len(state->m), 0);
2656
2657 /* Send to ip6_output */
2658 bzero(&ro6_new, sizeof(ro6_new));
2659 bzero(&ip6oa, sizeof(ip6oa));
2660 ip6oa.ip6oa_flowadv.code = 0;
2661 ip6oa.ip6oa_flags = IP6OAF_SELECT_SRCIF | IP6OAF_BOUND_SRCADDR;
2662 if (state->outgoing_if) {
2663 ip6oa.ip6oa_boundif = state->outgoing_if;
2664 ip6oa.ip6oa_flags |= IP6OAF_BOUND_IF;
2665 ip6_output_setsrcifscope(state->m, state->outgoing_if, NULL);
2666 ip6_output_setdstifscope(state->m, state->outgoing_if, NULL);
2667 }
2668
2669 adv = &ip6oa.ip6oa_flowadv;
2670 (void) ip6_output(state->m, NULL, &ro6_new, IPV6_OUTARGS, NULL, NULL, &ip6oa);
2671 state->m = NULL;
2672
2673 if (adv->code == FADV_FLOW_CONTROLLED || adv->code == FADV_SUSPENDED) {
2674 error = ENOBUFS;
2675 ifnet_disable_output(sav->sah->ipsec_if);
2676 return error;
2677 }
2678
2679 return 0;
2680 }
2681
2682 int
ipsec46_encapsulate(struct ipsec_output_state * state,struct secasvar * sav)2683 ipsec46_encapsulate(struct ipsec_output_state *state, struct secasvar *sav)
2684 {
2685 struct mbuf *m;
2686 struct ip6_hdr *ip6;
2687 struct ip *oip;
2688 struct ip *ip;
2689 size_t plen;
2690 u_int32_t hlen;
2691
2692 m = state->m;
2693 if (!m) {
2694 return EINVAL;
2695 }
2696
2697 /* can't tunnel between different AFs */
2698 if (SA(&sav->sah->saidx.src)->sa_family != SA(&sav->sah->saidx.dst)->sa_family
2699 || SA(&sav->sah->saidx.src)->sa_family != AF_INET6) {
2700 m_freem(m);
2701 return EINVAL;
2702 }
2703
2704 if (m->m_len < sizeof(*ip)) {
2705 panic("ipsec46_encapsulate: assumption failed (first mbuf length)");
2706 return EINVAL;
2707 }
2708
2709 ip = mtod(m, struct ip *);
2710 #ifdef _IP_VHL
2711 hlen = _IP_VHL_HL(ip->ip_vhl) << 2;
2712 #else
2713 hlen = ip->ip_hl << 2;
2714 #endif
2715
2716 if (m->m_len != hlen) {
2717 panic("ipsec46_encapsulate: assumption failed (first mbuf length)");
2718 return EINVAL;
2719 }
2720
2721 /* generate header checksum */
2722 ip->ip_sum = 0;
2723 #ifdef _IP_VHL
2724 ip->ip_sum = in_cksum(m, hlen);
2725 #else
2726 ip->ip_sum = in_cksum(m, hlen);
2727 #endif
2728
2729 plen = m->m_pkthdr.len; // save original IPv4 packet len, this will be ipv6 payload len
2730
2731 /*
2732 * First move the IPv4 header to the second mbuf in the chain
2733 */
2734 if (M_LEADINGSPACE(m->m_next) < hlen) {
2735 struct mbuf *n;
2736 MGET(n, M_DONTWAIT, MT_DATA);
2737 if (!n) {
2738 m_freem(m);
2739 return ENOBUFS;
2740 }
2741 n->m_len = hlen;
2742 n->m_next = m->m_next;
2743 m->m_next = n;
2744 m->m_pkthdr.len += sizeof(struct ip6_hdr);
2745 oip = mtod(n, struct ip *);
2746 } else {
2747 m->m_next->m_len += hlen;
2748 m->m_next->m_data -= hlen;
2749 m->m_pkthdr.len += sizeof(struct ip6_hdr);
2750 oip = mtod(m->m_next, struct ip *);
2751 }
2752 ip = mtod(m, struct ip *);
2753 ovbcopy((caddr_t)ip, (caddr_t)oip, hlen);
2754
2755 /*
2756 * Grow the first mbuf to accomodate the new IPv6 header.
2757 */
2758 if (M_LEADINGSPACE(m) < sizeof(struct ip6_hdr) - hlen) {
2759 struct mbuf *n;
2760 MGETHDR(n, M_DONTWAIT, MT_HEADER);
2761 if (!n) {
2762 m_freem(m);
2763 return ENOBUFS;
2764 }
2765 M_COPY_PKTHDR(n, m);
2766 MH_ALIGN(n, sizeof(struct ip6_hdr));
2767 n->m_len = sizeof(struct ip6_hdr);
2768 n->m_next = m->m_next;
2769 m->m_next = NULL;
2770 m_freem(m);
2771 state->m = n;
2772 m = state->m;
2773 } else {
2774 m->m_len += (sizeof(struct ip6_hdr) - hlen);
2775 m->m_data -= (sizeof(struct ip6_hdr) - hlen);
2776 }
2777 ip6 = mtod(m, struct ip6_hdr *);
2778 ip6->ip6_flow = 0;
2779 ip6->ip6_vfc &= ~IPV6_VERSION_MASK;
2780 ip6->ip6_vfc |= IPV6_VERSION;
2781
2782 /* construct new IPv6 header. see RFC 2401 5.1.2.2 */
2783 /* ECN consideration. */
2784 if (state->dscp_mapping == IPSEC_DSCP_MAPPING_COPY) {
2785 // Copy DSCP bits from inner IP to outer IP packet.
2786 ip46_ecn_ingress(ip6_ipsec_ecn, &ip6->ip6_flow, &oip->ip_tos);
2787 } else if (state->dscp_mapping == IPSEC_DSCP_MAPPING_LEGACY) {
2788 // Copy DSCP bits in legacy style.
2789 ip46_ecn_ingress(ip6_ipsec_ecn, &ip6->ip6_flow, &ip->ip_tos);
2790 }
2791 if (plen < IPV6_MAXPACKET - sizeof(struct ip6_hdr)) {
2792 ip6->ip6_plen = htons((u_int16_t)plen);
2793 } else {
2794 /* ip6->ip6_plen will be updated in ip6_output() */
2795 }
2796
2797 ip6->ip6_nxt = IPPROTO_IPV4;
2798 ip6->ip6_hlim = IPV6_DEFHLIM;
2799
2800 bcopy(&SIN6(&sav->sah->saidx.src)->sin6_addr,
2801 &ip6->ip6_src, sizeof(ip6->ip6_src));
2802 bcopy(&SIN6(&sav->sah->saidx.dst)->sin6_addr,
2803 &ip6->ip6_dst, sizeof(ip6->ip6_dst));
2804
2805 if (in6_embedded_scope && IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst)) {
2806 ip6->ip6_src.s6_addr16[1] = htons((u_int16_t)sav->sah->outgoing_if);
2807 ip6->ip6_dst.s6_addr16[1] = htons((u_int16_t)sav->sah->outgoing_if);
2808 }
2809
2810 return 0;
2811 }
2812
2813 /*
2814 * Check the variable replay window.
2815 * ipsec_chkreplay() performs replay check before ICV verification.
2816 * ipsec_updatereplay() updates replay bitmap. This must be called after
2817 * ICV verification (it also performs replay check, which is usually done
2818 * beforehand).
2819 * 0 (zero) is returned if packet disallowed, 1 if packet permitted.
2820 *
2821 * based on RFC 2401.
2822 */
2823 int
ipsec_chkreplay(u_int32_t seq,struct secasvar * sav,u_int8_t replay_index)2824 ipsec_chkreplay(u_int32_t seq, struct secasvar *sav, u_int8_t replay_index)
2825 {
2826 const struct secreplay *replay;
2827 u_int32_t diff;
2828 size_t fr;
2829 size_t wsizeb; /* constant: bits of window size */
2830 size_t frlast; /* constant: last frame */
2831
2832
2833 /* sanity check */
2834 if (sav == NULL) {
2835 panic("ipsec_chkreplay: NULL pointer was passed.");
2836 }
2837
2838 lck_mtx_lock(sadb_mutex);
2839 replay = sav->replay[replay_index];
2840
2841 if (replay->wsize == 0) {
2842 lck_mtx_unlock(sadb_mutex);
2843 return 1; /* no need to check replay. */
2844 }
2845
2846 /* constant */
2847 frlast = replay->wsize - 1;
2848 wsizeb = replay->wsize << 3;
2849
2850 /* sequence number of 0 is invalid */
2851 if (seq == 0) {
2852 lck_mtx_unlock(sadb_mutex);
2853 return 0;
2854 }
2855
2856 /* first time is always okay */
2857 if (replay->count == 0) {
2858 lck_mtx_unlock(sadb_mutex);
2859 return 1;
2860 }
2861
2862 if (seq > replay->lastseq) {
2863 /* larger sequences are okay */
2864 lck_mtx_unlock(sadb_mutex);
2865 return 1;
2866 } else {
2867 /* seq is equal or less than lastseq. */
2868 diff = replay->lastseq - seq;
2869
2870 /* over range to check, i.e. too old or wrapped */
2871 if (diff >= wsizeb) {
2872 lck_mtx_unlock(sadb_mutex);
2873 return 0;
2874 }
2875
2876 fr = frlast - diff / 8;
2877
2878 /* this packet already seen ? */
2879 if ((replay->bitmap)[fr] & (1 << (diff % 8))) {
2880 lck_mtx_unlock(sadb_mutex);
2881 return 0;
2882 }
2883
2884 /* out of order but good */
2885 lck_mtx_unlock(sadb_mutex);
2886 return 1;
2887 }
2888 }
2889
2890 /*
2891 * check replay counter whether to update or not.
2892 * OUT: 0: OK
2893 * 1: NG
2894 */
2895 int
ipsec_updatereplay(u_int32_t seq,struct secasvar * sav,u_int8_t replay_index)2896 ipsec_updatereplay(u_int32_t seq, struct secasvar *sav, u_int8_t replay_index)
2897 {
2898 struct secreplay *replay;
2899 u_int32_t diff;
2900 size_t fr;
2901 size_t wsizeb; /* constant: bits of window size */
2902 size_t frlast; /* constant: last frame */
2903
2904 /* sanity check */
2905 if (sav == NULL) {
2906 panic("ipsec_chkreplay: NULL pointer was passed.");
2907 }
2908
2909 lck_mtx_lock(sadb_mutex);
2910 replay = sav->replay[replay_index];
2911
2912 if (replay->wsize == 0) {
2913 goto ok; /* no need to check replay. */
2914 }
2915 /* constant */
2916 frlast = replay->wsize - 1;
2917 wsizeb = replay->wsize << 3;
2918
2919 /* sequence number of 0 is invalid */
2920 if (seq == 0) {
2921 lck_mtx_unlock(sadb_mutex);
2922 return 1;
2923 }
2924
2925 /* first time */
2926 if (replay->count == 0) {
2927 replay->lastseq = seq;
2928 bzero(replay->bitmap, replay->wsize);
2929 (replay->bitmap)[frlast] = 1;
2930 goto ok;
2931 }
2932
2933 if (seq > replay->lastseq) {
2934 /* seq is larger than lastseq. */
2935 diff = seq - replay->lastseq;
2936
2937 /* new larger sequence number */
2938 if (diff < wsizeb) {
2939 /* In window */
2940 /* set bit for this packet */
2941 vshiftl((unsigned char *) replay->bitmap, diff, replay->wsize);
2942 (replay->bitmap)[frlast] |= 1;
2943 } else {
2944 /* this packet has a "way larger" */
2945 bzero(replay->bitmap, replay->wsize);
2946 (replay->bitmap)[frlast] = 1;
2947 }
2948 replay->lastseq = seq;
2949
2950 /* larger is good */
2951 } else {
2952 /* seq is equal or less than lastseq. */
2953 diff = replay->lastseq - seq;
2954
2955 /* over range to check, i.e. too old or wrapped */
2956 if (diff >= wsizeb) {
2957 lck_mtx_unlock(sadb_mutex);
2958 return 1;
2959 }
2960
2961 fr = frlast - diff / 8;
2962
2963 /* this packet already seen ? */
2964 if ((replay->bitmap)[fr] & (1 << (diff % 8))) {
2965 lck_mtx_unlock(sadb_mutex);
2966 return 1;
2967 }
2968
2969 /* mark as seen */
2970 (replay->bitmap)[fr] |= (1 << (diff % 8));
2971
2972 /* out of order but good */
2973 }
2974
2975 ok:
2976 {
2977 u_int32_t max_count = ~0;
2978 if ((sav->flags2 & SADB_X_EXT_SA2_SEQ_PER_TRAFFIC_CLASS) ==
2979 SADB_X_EXT_SA2_SEQ_PER_TRAFFIC_CLASS) {
2980 max_count = PER_TC_REPLAY_WINDOW_RANGE;
2981 }
2982
2983 if (replay->count == max_count) {
2984 /* set overflow flag */
2985 replay->overflow++;
2986
2987 /* don't increment, no more packets accepted */
2988 if ((sav->flags & SADB_X_EXT_CYCSEQ) == 0) {
2989 lck_mtx_unlock(sadb_mutex);
2990 return 1;
2991 }
2992
2993 ipseclog((LOG_WARNING, "replay counter made %d cycle. %s\n",
2994 replay->overflow, ipsec_logsastr(sav)));
2995 }
2996 }
2997
2998 replay->count++;
2999
3000 lck_mtx_unlock(sadb_mutex);
3001 return 0;
3002 }
3003
3004 /*
3005 * shift variable length buffer to left.
3006 * IN: bitmap: pointer to the buffer
3007 * nbit: the number of to shift.
3008 * wsize: buffer size (bytes).
3009 */
3010 static void
vshiftl(unsigned char * __sized_by (wsize)bitmap,int nbit,size_t wsize)3011 vshiftl(unsigned char *__sized_by(wsize)bitmap, int nbit, size_t wsize)
3012 {
3013 size_t i;
3014 int s, j;
3015 unsigned char over;
3016
3017 for (j = 0; j < nbit; j += 8) {
3018 s = (nbit - j < 8) ? (nbit - j): 8;
3019 bitmap[0] <<= s;
3020 for (i = 1; i < wsize; i++) {
3021 over = (bitmap[i] >> (8 - s));
3022 bitmap[i] <<= s;
3023 bitmap[i - 1] |= over;
3024 }
3025 }
3026
3027 return;
3028 }
3029
3030 const char *
ipsec4_logpacketstr(struct ip * ip,u_int32_t spi)3031 ipsec4_logpacketstr(struct ip *ip, u_int32_t spi)
3032 {
3033 static char buf[256] __attribute__((aligned(4)));
3034 char *p;
3035 u_int8_t *s, *d;
3036
3037 s = (u_int8_t *)(&ip->ip_src);
3038 d = (u_int8_t *)(&ip->ip_dst);
3039
3040 p = buf;
3041 snprintf(buf, sizeof(buf), "packet(SPI=%u ", (u_int32_t)ntohl(spi));
3042 while (p && *p) {
3043 p++;
3044 }
3045 snprintf(p, sizeof(buf) - (p - buf), "src=%u.%u.%u.%u",
3046 s[0], s[1], s[2], s[3]);
3047 while (p && *p) {
3048 p++;
3049 }
3050 snprintf(p, sizeof(buf) - (p - buf), " dst=%u.%u.%u.%u",
3051 d[0], d[1], d[2], d[3]);
3052 while (p && *p) {
3053 p++;
3054 }
3055 snprintf(p, sizeof(buf) - (p - buf), ")");
3056
3057 return __unsafe_null_terminated_from_indexable(buf);
3058 }
3059
3060 const char *
ipsec6_logpacketstr(struct ip6_hdr * ip6,u_int32_t spi)3061 ipsec6_logpacketstr(struct ip6_hdr *ip6, u_int32_t spi)
3062 {
3063 static char buf[256] __attribute__((aligned(4)));
3064 char *p;
3065
3066 p = buf;
3067 snprintf(buf, sizeof(buf), "packet(SPI=%u ", (u_int32_t)ntohl(spi));
3068 while (p && *p) {
3069 p++;
3070 }
3071 snprintf(p, sizeof(buf) - (p - buf), "src=%s",
3072 ip6_sprintf(&ip6->ip6_src));
3073 while (p && *p) {
3074 p++;
3075 }
3076 snprintf(p, sizeof(buf) - (p - buf), " dst=%s",
3077 ip6_sprintf(&ip6->ip6_dst));
3078 while (p && *p) {
3079 p++;
3080 }
3081 snprintf(p, sizeof(buf) - (p - buf), ")");
3082
3083 return __unsafe_null_terminated_from_indexable(buf);
3084 }
3085
3086 const char *
ipsec_logsastr(struct secasvar * sav)3087 ipsec_logsastr(struct secasvar *sav)
3088 {
3089 static char buf[256] __attribute__((aligned(4)));
3090 char *p;
3091 struct secasindex *saidx = &sav->sah->saidx;
3092
3093 /* validity check */
3094 if (SA(&sav->sah->saidx.src)->sa_family
3095 != SA(&sav->sah->saidx.dst)->sa_family) {
3096 panic("ipsec_logsastr: family mismatched.");
3097 }
3098
3099 p = buf;
3100 snprintf(buf, sizeof(buf), "SA(SPI=%u ", (u_int32_t)ntohl(sav->spi));
3101 while (p && *p) {
3102 p++;
3103 }
3104 if (SA(&saidx->src)->sa_family == AF_INET) {
3105 u_int8_t *s, *d;
3106 s = (u_int8_t *)&SIN(&saidx->src)->sin_addr;
3107 d = (u_int8_t *)&SIN(&saidx->dst)->sin_addr;
3108 snprintf(p, sizeof(buf) - (p - buf),
3109 "src=%d.%d.%d.%d dst=%d.%d.%d.%d",
3110 s[0], s[1], s[2], s[3], d[0], d[1], d[2], d[3]);
3111 } else if (SA(&saidx->src)->sa_family == AF_INET6) {
3112 snprintf(p, sizeof(buf) - (p - buf),
3113 "src=%s",
3114 ip6_sprintf(&SIN6(&saidx->src)->sin6_addr));
3115 while (p && *p) {
3116 p++;
3117 }
3118 snprintf(p, sizeof(buf) - (p - buf),
3119 " dst=%s",
3120 ip6_sprintf(&SIN6(&saidx->dst)->sin6_addr));
3121 }
3122 while (p && *p) {
3123 p++;
3124 }
3125 snprintf(p, sizeof(buf) - (p - buf), ")");
3126
3127 return __unsafe_null_terminated_from_indexable(buf);
3128 }
3129
3130 void
ipsec_dumpmbuf(struct mbuf * m)3131 ipsec_dumpmbuf(struct mbuf *m)
3132 {
3133 int totlen;
3134 int i;
3135 u_char *p;
3136
3137 totlen = 0;
3138 printf("---\n");
3139 while (m) {
3140 p = mtod(m, u_char *);
3141 for (i = 0; i < m->m_len; i++) {
3142 printf("%02x ", p[i]);
3143 totlen++;
3144 if (totlen % 16 == 0) {
3145 printf("\n");
3146 }
3147 }
3148 m = m->m_next;
3149 }
3150 if (totlen % 16 != 0) {
3151 printf("\n");
3152 }
3153 printf("---\n");
3154 }
3155
3156 #if INET
3157 /*
3158 * IPsec output logic for IPv4.
3159 */
3160 static int
ipsec4_output_internal(struct ipsec_output_state * state,struct secasvar * sav)3161 ipsec4_output_internal(struct ipsec_output_state *state, struct secasvar *sav)
3162 {
3163 struct ip *ip = NULL;
3164 int error = 0;
3165 struct sockaddr_in *dst4;
3166 struct route *ro4;
3167
3168 /* validity check */
3169 if (sav == NULL || sav->sah == NULL) {
3170 error = EINVAL;
3171 goto bad;
3172 }
3173
3174 /*
3175 * If there is no valid SA, we give up to process any
3176 * more. In such a case, the SA's status is changed
3177 * from DYING to DEAD after allocating. If a packet
3178 * send to the receiver by dead SA, the receiver can
3179 * not decode a packet because SA has been dead.
3180 */
3181 if (sav->state != SADB_SASTATE_MATURE
3182 && sav->state != SADB_SASTATE_DYING) {
3183 IPSEC_STAT_INCREMENT(ipsecstat.out_nosa);
3184 error = EINVAL;
3185 goto bad;
3186 }
3187
3188 state->outgoing_if = sav->sah->outgoing_if;
3189
3190 /*
3191 * There may be the case that SA status will be changed when
3192 * we are refering to one. So calling splsoftnet().
3193 */
3194
3195 if (sav->sah->saidx.mode == IPSEC_MODE_TUNNEL) {
3196 /*
3197 * build IPsec tunnel.
3198 */
3199 state->m = ipsec4_splithdr(state->m);
3200 if (!state->m) {
3201 error = ENOMEM;
3202 goto bad;
3203 }
3204
3205 if (SA(&sav->sah->saidx.src)->sa_family == AF_INET6) {
3206 error = ipsec46_encapsulate(state, sav);
3207 if (error) {
3208 // packet already freed by encapsulation error handling
3209 state->m = NULL;
3210 return error;
3211 }
3212
3213 error = ipsec6_update_routecache_and_output(state, sav);
3214 return error;
3215 } else if (SA(&sav->sah->saidx.src)->sa_family == AF_INET) {
3216 error = ipsec4_encapsulate(state->m, sav);
3217 if (error) {
3218 state->m = NULL;
3219 goto bad;
3220 }
3221 ip = mtod(state->m, struct ip *);
3222
3223 // grab sadb_mutex, before updating sah's route cache
3224 lck_mtx_lock(sadb_mutex);
3225 ro4 = (struct route *)&sav->sah->sa_route;
3226 dst4 = SIN(&ro4->ro_dst);
3227 if (ro4->ro_rt != NULL) {
3228 RT_LOCK(ro4->ro_rt);
3229 }
3230 if (ROUTE_UNUSABLE(ro4) ||
3231 dst4->sin_addr.s_addr != ip->ip_dst.s_addr) {
3232 if (ro4->ro_rt != NULL) {
3233 RT_UNLOCK(ro4->ro_rt);
3234 }
3235 ROUTE_RELEASE(ro4);
3236 }
3237 if (ro4->ro_rt == 0) {
3238 dst4->sin_family = AF_INET;
3239 dst4->sin_len = sizeof(*dst4);
3240 dst4->sin_addr = ip->ip_dst;
3241 rtalloc_scoped(ro4, sav->sah->outgoing_if);
3242 if (ro4->ro_rt == 0) {
3243 OSAddAtomic(1, &ipstat.ips_noroute);
3244 error = EHOSTUNREACH;
3245 // release sadb_mutex, after updating sah's route cache
3246 lck_mtx_unlock(sadb_mutex);
3247 goto bad;
3248 }
3249 RT_LOCK(ro4->ro_rt);
3250 }
3251
3252 /*
3253 * adjust state->dst if tunnel endpoint is offlink
3254 *
3255 * XXX: caching rt_gateway value in the state is
3256 * not really good, since it may point elsewhere
3257 * when the gateway gets modified to a larger
3258 * sockaddr via rt_setgate(). This is currently
3259 * addressed by SA_SIZE roundup in that routine.
3260 */
3261 if (ro4->ro_rt->rt_flags & RTF_GATEWAY) {
3262 dst4 = SIN(ro4->ro_rt->rt_gateway);
3263 }
3264 RT_UNLOCK(ro4->ro_rt);
3265 ROUTE_RELEASE(&state->ro);
3266 route_copyout((struct route *)&state->ro, ro4, sizeof(struct route));
3267 state->dst = SA(dst4);
3268 state->tunneled = 4;
3269 // release sadb_mutex, after updating sah's route cache
3270 lck_mtx_unlock(sadb_mutex);
3271 } else {
3272 ipseclog((LOG_ERR, "%s: family mismatched between inner and outer spi=%u\n",
3273 __FUNCTION__, (u_int32_t)ntohl(sav->spi)));
3274 error = EAFNOSUPPORT;
3275 goto bad;
3276 }
3277 }
3278
3279 state->m = ipsec4_splithdr(state->m);
3280 if (!state->m) {
3281 error = ENOMEM;
3282 goto bad;
3283 }
3284 switch (sav->sah->saidx.proto) {
3285 case IPPROTO_ESP:
3286 #if IPSEC_ESP
3287 if ((error = esp4_output(state->m, sav)) != 0) {
3288 state->m = NULL;
3289 goto bad;
3290 }
3291 break;
3292 #else
3293 m_freem(state->m);
3294 state->m = NULL;
3295 error = EINVAL;
3296 goto bad;
3297 #endif
3298 case IPPROTO_AH:
3299 if ((error = ah4_output(state->m, sav)) != 0) {
3300 state->m = NULL;
3301 goto bad;
3302 }
3303 break;
3304 default:
3305 ipseclog((LOG_ERR,
3306 "ipsec4_output: unknown ipsec protocol %d\n",
3307 sav->sah->saidx.proto));
3308 m_freem(state->m);
3309 state->m = NULL;
3310 error = EPROTONOSUPPORT;
3311 goto bad;
3312 }
3313
3314 if (state->m == 0) {
3315 error = ENOMEM;
3316 goto bad;
3317 }
3318
3319 #if SKYWALK
3320 state->m->m_pkthdr.pkt_flowid = sav->flowid;
3321 state->m->m_pkthdr.pkt_flags |= PKTF_FLOW_ID;
3322 #endif /* !SKYWALK */
3323
3324 return 0;
3325
3326 bad:
3327 return error;
3328 }
3329
3330 int
ipsec4_interface_kpipe_output(ifnet_t interface,kern_packet_t sph,kern_packet_t dph)3331 ipsec4_interface_kpipe_output(ifnet_t interface, kern_packet_t sph,
3332 kern_packet_t dph)
3333 {
3334 struct sockaddr_in src = {};
3335 struct sockaddr_in dst = {};
3336 struct secasvar *sav = NULL;
3337 uint8_t *sbaddr = NULL;
3338 uint8_t *dbaddr = NULL;
3339 size_t hlen = 0;
3340 uint32_t slen = 0;
3341 uint32_t dlim = 0, doff = 0, dlen = 0;
3342 int err = 0;
3343
3344 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
3345
3346 kern_buflet_t __single sbuf = __packet_get_next_buflet(sph, NULL);
3347 VERIFY(sbuf != NULL);
3348 slen = __buflet_get_data_length(sbuf);
3349 sbaddr = ipsec_kern_buflet_to_buffer(sbuf);
3350
3351 if (__improbable(slen < sizeof(struct ip))) {
3352 os_log_info(OS_LOG_DEFAULT, "ipsec4 interface kpipe output: "
3353 "source buffer shorter than ip header, %u\n", slen);
3354 err = EINVAL;
3355 goto bad;
3356 }
3357
3358 struct ip *ip = (struct ip *)(void *)sbaddr;
3359 ASSERT(IP_HDR_ALIGNED_P(ip));
3360
3361 /* Find security association matching source and destination address */
3362 src.sin_family = AF_INET;
3363 src.sin_len = sizeof(src);
3364 src.sin_addr.s_addr = ip->ip_src.s_addr;
3365
3366 dst.sin_family = AF_INET;
3367 dst.sin_len = sizeof(dst);
3368 dst.sin_addr.s_addr = ip->ip_dst.s_addr;
3369
3370 sav = key_alloc_outbound_sav_for_interface(interface, AF_INET,
3371 SA(&src), SA(&dst));
3372 if (__improbable(sav == NULL)) {
3373 os_log_info(OS_LOG_DEFAULT, "ipsec4 interface kpipe output: "
3374 "failed to find outbound sav\n");
3375 IPSEC_STAT_INCREMENT(ipsecstat.out_nosa);
3376 err = ENOENT;
3377 goto bad;
3378 }
3379
3380 if (__improbable(sav->sah == NULL)) {
3381 os_log_info(OS_LOG_DEFAULT, "ipsec4 interface kpipe output: "
3382 "sah is NULL\n");
3383 IPSEC_STAT_INCREMENT(ipsecstat.out_nosa);
3384 err = ENOENT;
3385 goto bad;
3386 }
3387
3388 if (__improbable(sav->sah->saidx.mode != IPSEC_MODE_TRANSPORT)) {
3389 os_log_info(OS_LOG_DEFAULT, "ipsec tunnel mode not supported "
3390 "in kpipe mode, SPI=%x\n", ntohl(sav->spi));
3391 IPSEC_STAT_INCREMENT(ipsecstat.out_nosa);
3392 err = EINVAL;
3393 goto bad;
3394 }
3395 if (__improbable((sav->flags & (SADB_X_EXT_OLD | SADB_X_EXT_DERIV |
3396 SADB_X_EXT_NATT | SADB_X_EXT_NATT_MULTIPLEUSERS |
3397 SADB_X_EXT_CYCSEQ | SADB_X_EXT_PMASK)) != 0)) {
3398 os_log_info(OS_LOG_DEFAULT, "sadb flag %x not supported in "
3399 "kpipe mode, SPI=%x\n", sav->flags, ntohl(sav->spi));
3400 IPSEC_STAT_INCREMENT(ipsecstat.out_nosa);
3401 err = EINVAL;
3402 goto bad;
3403 }
3404
3405 /*
3406 * If there is no valid SA, we give up to process any
3407 * more. In such a case, the SA's status is changed
3408 * from DYING to DEAD after allocating. If a packet
3409 * send to the receiver by dead SA, the receiver can
3410 * not decode a packet because SA has been dead.
3411 */
3412 if (__improbable(sav->state != SADB_SASTATE_MATURE
3413 && sav->state != SADB_SASTATE_DYING)) {
3414 IPSEC_STAT_INCREMENT(ipsecstat.out_nosa);
3415 err = EINVAL;
3416 goto bad;
3417 }
3418
3419 #ifdef _IP_VHL
3420 hlen = IP_VHL_HL(ip->ip_vhl) << 2;
3421 #else
3422 hlen = ip->ip_hl << 2;
3423 #endif
3424 /* Copy the IP header from source packet to destination packet */
3425 kern_buflet_t __single dbuf = __packet_get_next_buflet(dph, NULL);
3426 doff = __buflet_get_data_offset(dbuf);
3427 VERIFY(doff == 0);
3428 dlen = __buflet_get_data_length(dbuf);
3429 VERIFY(dlen == 0);
3430 dbaddr = ipsec_kern_buflet_to_buffer(dbuf);
3431
3432 dlim = __buflet_get_data_limit(dbuf);
3433 if (__improbable(dlim < hlen)) {
3434 os_log_info(OS_LOG_DEFAULT, "ipsec4 interface kpipe output: "
3435 "buflet size shorter than hlen %u, SPI=%x\n", dlim, ntohl(sav->spi));
3436 err = EMSGSIZE;
3437 goto bad;
3438 }
3439
3440 VERIFY(hlen <= UINT16_MAX);
3441 memcpy(dbaddr, sbaddr, hlen);
3442 __buflet_set_data_length(dbuf, (uint16_t)hlen);
3443
3444 switch (sav->sah->saidx.proto) {
3445 case IPPROTO_ESP: {
3446 if (__improbable((err = esp_kpipe_output(sav, sph, dph)) != 0)) {
3447 goto bad;
3448 }
3449 break;
3450 }
3451 case IPPROTO_AH: {
3452 os_log_info(OS_LOG_DEFAULT, "AH not supported in kpipe mode\n");
3453 err = EPROTONOSUPPORT;
3454 goto bad;
3455 }
3456 default: {
3457 os_log_info(OS_LOG_DEFAULT, "unknown ipsec protocol %d\n",
3458 sav->sah->saidx.proto);
3459 err = EPROTONOSUPPORT;
3460 goto bad;
3461 }
3462 }
3463
3464 key_freesav(sav, KEY_SADB_UNLOCKED);
3465 return 0;
3466 bad:
3467 if (sav != NULL) {
3468 key_freesav(sav, KEY_SADB_UNLOCKED);
3469 sav = NULL;
3470 }
3471
3472 return err;
3473 }
3474
3475 int
ipsec6_interface_kpipe_output(ifnet_t interface,kern_packet_t sph,kern_packet_t dph)3476 ipsec6_interface_kpipe_output(ifnet_t interface, kern_packet_t sph,
3477 kern_packet_t dph)
3478 {
3479 struct sockaddr_in6 src = {};
3480 struct sockaddr_in6 dst = {};
3481 struct secasvar *sav = NULL;
3482 uint8_t *sbaddr = NULL;
3483 uint8_t *dbaddr = NULL;
3484 uint32_t slen = 0;
3485 uint32_t dlim = 0, doff = 0, dlen = 0;
3486 int err = 0;
3487
3488 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
3489
3490 kern_buflet_t __single sbuf = __packet_get_next_buflet(sph, NULL);
3491 VERIFY(sbuf != NULL);
3492 slen = __buflet_get_data_length(sbuf);
3493 sbaddr = ipsec_kern_buflet_to_buffer(sbuf);
3494
3495 if (__improbable(slen < sizeof(struct ip6_hdr))) {
3496 os_log_info(OS_LOG_DEFAULT, "ipsec6 interface kpipe output: "
3497 "source buffer shorter than ipv6 header, %u\n", slen);
3498 err = EINVAL;
3499 goto bad;
3500 }
3501
3502 struct ip6_hdr *ip6 = (struct ip6_hdr *)sbaddr;
3503
3504 /* Find security association matching source and destination address */
3505 src.sin6_family = AF_INET6;
3506 src.sin6_len = sizeof(src);
3507 memcpy(&src.sin6_addr, &ip6->ip6_src, sizeof(src.sin6_addr));
3508
3509 dst.sin6_family = AF_INET6;
3510 dst.sin6_len = sizeof(dst);
3511 memcpy(&dst.sin6_addr, &ip6->ip6_dst, sizeof(dst.sin6_addr));
3512
3513 sav = key_alloc_outbound_sav_for_interface(interface, AF_INET6,
3514 SA(&src), SA(&dst));
3515 if (__improbable(sav == NULL)) {
3516 os_log_info(OS_LOG_DEFAULT, "ipsec6 interface kpipe output: "
3517 "failed to find outbound sav\n");
3518 IPSEC_STAT_INCREMENT(ipsecstat.out_nosa);
3519 err = ENOENT;
3520 goto bad;
3521 }
3522
3523 if (__improbable(sav->sah == NULL)) {
3524 os_log_info(OS_LOG_DEFAULT, "ipsec6 interface kpipe output: "
3525 "sah is NULL\n");
3526 IPSEC_STAT_INCREMENT(ipsecstat.out_nosa);
3527 err = ENOENT;
3528 goto bad;
3529 }
3530
3531 if (__improbable(sav->sah->saidx.mode != IPSEC_MODE_TRANSPORT)) {
3532 os_log_info(OS_LOG_DEFAULT, "ipsec tunnel mode not supported "
3533 "in kpipe mode, SPI=%x\n", ntohl(sav->spi));
3534 IPSEC_STAT_INCREMENT(ipsecstat.out_nosa);
3535 err = EINVAL;
3536 goto bad;
3537 }
3538 if (__improbable((sav->flags & (SADB_X_EXT_OLD | SADB_X_EXT_DERIV |
3539 SADB_X_EXT_NATT | SADB_X_EXT_NATT_MULTIPLEUSERS |
3540 SADB_X_EXT_CYCSEQ | SADB_X_EXT_PMASK)) != 0)) {
3541 os_log_info(OS_LOG_DEFAULT, "sadb flag %x not supported in "
3542 "kpipe mode, SPI=%x\n", sav->flags, ntohl(sav->spi));
3543 IPSEC_STAT_INCREMENT(ipsecstat.out_nosa);
3544 err = EINVAL;
3545 goto bad;
3546 }
3547
3548 /*
3549 * If there is no valid SA, we give up to process any
3550 * more. In such a case, the SA's status is changed
3551 * from DYING to DEAD after allocating. If a packet
3552 * send to the receiver by dead SA, the receiver can
3553 * not decode a packet because SA has been dead.
3554 */
3555 if (__improbable(sav->state != SADB_SASTATE_MATURE
3556 && sav->state != SADB_SASTATE_DYING)) {
3557 IPSEC_STAT_INCREMENT(ipsecstat.out_nosa);
3558 err = EINVAL;
3559 goto bad;
3560 }
3561
3562 /* Copy the IPv6 header from source packet to destination packet */
3563 kern_buflet_t __single dbuf = __packet_get_next_buflet(dph, NULL);
3564 doff = __buflet_get_data_offset(dbuf);
3565 VERIFY(doff == 0);
3566 dlen = __buflet_get_data_length(dbuf);
3567 VERIFY(dlen == 0);
3568 dbaddr = ipsec_kern_buflet_to_buffer(dbuf);
3569
3570 dlim = __buflet_get_data_limit(dbuf);
3571 if (__improbable(dlim < sizeof(struct ip6_hdr))) {
3572 os_log_info(OS_LOG_DEFAULT, "ipsec6 interface kpipe output"
3573 "buflet size shorter than hlen %u, SPI=%x\n", dlim, ntohl(sav->spi));
3574 err = EMSGSIZE;
3575 goto bad;
3576 }
3577
3578 memcpy(dbaddr, sbaddr, sizeof(struct ip6_hdr));
3579 __buflet_set_data_length(dbuf, sizeof(struct ip6_hdr));
3580
3581 switch (sav->sah->saidx.proto) {
3582 case IPPROTO_ESP: {
3583 if (__improbable((err = esp_kpipe_output(sav, sph, dph)) != 0)) {
3584 goto bad;
3585 }
3586 break;
3587 }
3588 case IPPROTO_AH: {
3589 os_log_info(OS_LOG_DEFAULT, "AH not supported in kpipe mode\n");
3590 err = EPROTONOSUPPORT;
3591 goto bad;
3592 }
3593 default: {
3594 os_log_info(OS_LOG_DEFAULT, "unknown ipsec protocol %d\n",
3595 sav->sah->saidx.proto);
3596 err = EPROTONOSUPPORT;
3597 goto bad;
3598 }
3599 }
3600
3601 key_freesav(sav, KEY_SADB_UNLOCKED);
3602 return 0;
3603 bad:
3604 if (sav != NULL) {
3605 key_freesav(sav, KEY_SADB_UNLOCKED);
3606 sav = NULL;
3607 }
3608
3609 return err;
3610 }
3611
3612 int
ipsec4_interface_output(struct ipsec_output_state * state,ifnet_t interface)3613 ipsec4_interface_output(struct ipsec_output_state *state, ifnet_t interface)
3614 {
3615 int error = 0;
3616 struct secasvar *sav = NULL;
3617
3618 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
3619
3620 if (state == NULL) {
3621 panic("state == NULL in ipsec4_output");
3622 }
3623 if (state->m == NULL) {
3624 panic("state->m == NULL in ipsec4_output");
3625 }
3626 if (state->dst == NULL) {
3627 panic("state->dst == NULL in ipsec4_output");
3628 }
3629
3630 struct ip *ip = mtod(state->m, struct ip *);
3631
3632 struct sockaddr_in src = {};
3633 src.sin_family = AF_INET;
3634 src.sin_len = sizeof(src);
3635 memcpy(&src.sin_addr, &ip->ip_src, sizeof(src.sin_addr));
3636
3637 struct sockaddr_in dst = {};
3638 dst.sin_family = AF_INET;
3639 dst.sin_len = sizeof(dst);
3640 memcpy(&dst.sin_addr, &ip->ip_dst, sizeof(dst.sin_addr));
3641
3642 sav = key_alloc_outbound_sav_for_interface(interface, AF_INET,
3643 SA(&src),
3644 SA(&dst));
3645 if (sav == NULL) {
3646 goto bad;
3647 }
3648
3649 if ((error = ipsec4_output_internal(state, sav)) != 0) {
3650 goto bad;
3651 }
3652
3653 KERNEL_DEBUG(DBG_FNC_IPSEC_OUT | DBG_FUNC_END, 0, 0, 0, 0, 0);
3654 if (sav) {
3655 key_freesav(sav, KEY_SADB_UNLOCKED);
3656 }
3657 return 0;
3658
3659 bad:
3660 if (sav) {
3661 key_freesav(sav, KEY_SADB_UNLOCKED);
3662 }
3663 m_freem(state->m);
3664 state->m = NULL;
3665 KERNEL_DEBUG(DBG_FNC_IPSEC_OUT | DBG_FUNC_END, error, 0, 0, 0, 0);
3666 return error;
3667 }
3668
3669 int
ipsec4_output(struct ipsec_output_state * state,struct secpolicy * sp,__unused int flags)3670 ipsec4_output(struct ipsec_output_state *state, struct secpolicy *sp, __unused int flags)
3671 {
3672 struct ip *ip = NULL;
3673 struct ipsecrequest *isr = NULL;
3674 struct secasindex saidx;
3675 struct secasvar *__single sav = NULL;
3676 int error = 0;
3677 struct sockaddr_in *sin;
3678
3679 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
3680
3681 if (!state) {
3682 panic("state == NULL in ipsec4_output");
3683 }
3684 if (!state->m) {
3685 panic("state->m == NULL in ipsec4_output");
3686 }
3687 if (!state->dst) {
3688 panic("state->dst == NULL in ipsec4_output");
3689 }
3690
3691 KERNEL_DEBUG(DBG_FNC_IPSEC_OUT | DBG_FUNC_START, 0, 0, 0, 0, 0);
3692
3693 KEYDEBUG(KEYDEBUG_IPSEC_DATA,
3694 printf("ipsec4_output: applied SP\n");
3695 kdebug_secpolicy(sp));
3696
3697 for (isr = sp->req; isr != NULL; isr = isr->next) {
3698 /* make SA index for search proper SA */
3699 ip = mtod(state->m, struct ip *);
3700 bcopy(&isr->saidx, &saidx, sizeof(saidx));
3701 saidx.mode = isr->saidx.mode;
3702 saidx.reqid = isr->saidx.reqid;
3703 sin = SIN(&saidx.src);
3704 if (sin->sin_len == 0) {
3705 sin->sin_len = sizeof(*sin);
3706 sin->sin_family = AF_INET;
3707 sin->sin_port = IPSEC_PORT_ANY;
3708 bcopy(&ip->ip_src, &sin->sin_addr,
3709 sizeof(sin->sin_addr));
3710 }
3711 sin = SIN(&saidx.dst);
3712 if (sin->sin_len == 0) {
3713 sin->sin_len = sizeof(*sin);
3714 sin->sin_family = AF_INET;
3715 sin->sin_port = IPSEC_PORT_ANY;
3716 /*
3717 * Get port from packet if upper layer is UDP and nat traversal
3718 * is enabled and transport mode.
3719 */
3720
3721 if ((esp_udp_encap_port & 0xFFFF) != 0 &&
3722 isr->saidx.mode == IPSEC_MODE_TRANSPORT) {
3723 if (ip->ip_p == IPPROTO_UDP) {
3724 struct udphdr *udp;
3725 u_int32_t hlen;
3726 #ifdef _IP_VHL
3727 hlen = IP_VHL_HL(ip->ip_vhl) << 2;
3728 #else
3729 hlen = ip->ip_hl << 2;
3730 #endif
3731 if (state->m->m_len < hlen + sizeof(struct udphdr)) {
3732 state->m = m_pullup(state->m, hlen + sizeof(struct udphdr));
3733 if (!state->m) {
3734 ipseclog((LOG_DEBUG, "IPv4 output: can't pullup UDP header\n"));
3735 IPSEC_STAT_INCREMENT(ipsecstat.in_inval);
3736 goto bad;
3737 }
3738 ip = mtod(state->m, struct ip *);
3739 }
3740 udp = (struct udphdr *)(void *)(((u_int8_t *)ip) + hlen);
3741 sin->sin_port = udp->uh_dport;
3742 }
3743 }
3744
3745 bcopy(&ip->ip_dst, &sin->sin_addr,
3746 sizeof(sin->sin_addr));
3747 }
3748
3749 if ((error = key_checkrequest(isr, &saidx, &sav)) != 0) {
3750 /*
3751 * IPsec processing is required, but no SA found.
3752 * I assume that key_acquire() had been called
3753 * to get/establish the SA. Here I discard
3754 * this packet because it is responsibility for
3755 * upper layer to retransmit the packet.
3756 */
3757 IPSEC_STAT_INCREMENT(ipsecstat.out_nosa);
3758 goto bad;
3759 }
3760
3761 /* validity check */
3762 if (sav == NULL) {
3763 switch (ipsec_get_reqlevel(isr)) {
3764 case IPSEC_LEVEL_USE:
3765 continue;
3766 case IPSEC_LEVEL_REQUIRE:
3767 /* must be not reached here. */
3768 panic("ipsec4_output: no SA found, but required.");
3769 }
3770 }
3771
3772 if ((error = ipsec4_output_internal(state, sav)) != 0) {
3773 goto bad;
3774 }
3775 }
3776
3777 KERNEL_DEBUG(DBG_FNC_IPSEC_OUT | DBG_FUNC_END, 0, 0, 0, 0, 0);
3778 if (sav) {
3779 key_freesav(sav, KEY_SADB_UNLOCKED);
3780 }
3781 return 0;
3782
3783 bad:
3784 if (sav) {
3785 key_freesav(sav, KEY_SADB_UNLOCKED);
3786 }
3787 m_freem(state->m);
3788 state->m = NULL;
3789 KERNEL_DEBUG(DBG_FNC_IPSEC_OUT | DBG_FUNC_END, error, 0, 0, 0, 0);
3790 return error;
3791 }
3792
3793 #endif
3794
3795 /*
3796 * IPsec output logic for IPv6, transport mode.
3797 */
3798 static int
ipsec6_output_trans_internal(struct ipsec_output_state * state,struct secasvar * sav,u_char * nexthdrp,struct mbuf * mprev)3799 ipsec6_output_trans_internal(
3800 struct ipsec_output_state *state,
3801 struct secasvar *sav,
3802 u_char *nexthdrp,
3803 struct mbuf *mprev)
3804 {
3805 struct ip6_hdr *ip6;
3806 size_t plen;
3807 int error = 0;
3808
3809 /* validity check */
3810 if (sav == NULL || sav->sah == NULL) {
3811 error = EINVAL;
3812 goto bad;
3813 }
3814
3815 /*
3816 * If there is no valid SA, we give up to process.
3817 * see same place at ipsec4_output().
3818 */
3819 if (sav->state != SADB_SASTATE_MATURE
3820 && sav->state != SADB_SASTATE_DYING) {
3821 IPSEC_STAT_INCREMENT(ipsec6stat.out_nosa);
3822 error = EINVAL;
3823 goto bad;
3824 }
3825
3826 state->outgoing_if = sav->sah->outgoing_if;
3827
3828 switch (sav->sah->saidx.proto) {
3829 case IPPROTO_ESP:
3830 #if IPSEC_ESP
3831 error = esp6_output(state->m, nexthdrp, mprev->m_next, sav);
3832 #else
3833 m_freem(state->m);
3834 error = EINVAL;
3835 #endif
3836 break;
3837 case IPPROTO_AH:
3838 error = ah6_output(state->m, nexthdrp, mprev->m_next, sav);
3839 break;
3840 default:
3841 ipseclog((LOG_ERR, "ipsec6_output_trans: "
3842 "unknown ipsec protocol %d\n", sav->sah->saidx.proto));
3843 m_freem(state->m);
3844 IPSEC_STAT_INCREMENT(ipsec6stat.out_inval);
3845 error = EPROTONOSUPPORT;
3846 break;
3847 }
3848 if (error) {
3849 state->m = NULL;
3850 goto bad;
3851 }
3852 plen = state->m->m_pkthdr.len - sizeof(struct ip6_hdr);
3853 if (plen > IPV6_MAXPACKET) {
3854 ipseclog((LOG_ERR, "ipsec6_output_trans: "
3855 "IPsec with IPv6 jumbogram is not supported\n"));
3856 IPSEC_STAT_INCREMENT(ipsec6stat.out_inval);
3857 error = EINVAL; /*XXX*/
3858 goto bad;
3859 }
3860 ip6 = mtod(state->m, struct ip6_hdr *);
3861 ip6->ip6_plen = htons((u_int16_t)plen);
3862
3863 #if SKYWALK
3864 ASSERT(state->m != NULL);
3865 state->m->m_pkthdr.pkt_flowid = sav->flowid;
3866 state->m->m_pkthdr.pkt_flags |= PKTF_FLOW_ID;
3867 #endif /* !SKYWALK */
3868 return 0;
3869 bad:
3870 return error;
3871 }
3872
3873 int
ipsec6_output_trans(struct ipsec_output_state * state,u_char * nexthdrp,struct mbuf * mprev,struct secpolicy * sp,__unused int flags,int * tun)3874 ipsec6_output_trans(
3875 struct ipsec_output_state *state,
3876 u_char *nexthdrp,
3877 struct mbuf *mprev,
3878 struct secpolicy *sp,
3879 __unused int flags,
3880 int *tun)
3881 {
3882 struct ip6_hdr *ip6;
3883 struct ipsecrequest *isr = NULL;
3884 struct secasindex saidx;
3885 int error = 0;
3886 struct sockaddr_in6 *sin6;
3887 struct secasvar *__single sav = NULL;
3888
3889 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
3890
3891 if (!state) {
3892 panic("state == NULL in ipsec6_output_trans");
3893 }
3894 if (!state->m) {
3895 panic("state->m == NULL in ipsec6_output_trans");
3896 }
3897 if (!nexthdrp) {
3898 panic("nexthdrp == NULL in ipsec6_output_trans");
3899 }
3900 if (!mprev) {
3901 panic("mprev == NULL in ipsec6_output_trans");
3902 }
3903 if (!sp) {
3904 panic("sp == NULL in ipsec6_output_trans");
3905 }
3906 if (!tun) {
3907 panic("tun == NULL in ipsec6_output_trans");
3908 }
3909
3910 KEYDEBUG(KEYDEBUG_IPSEC_DATA,
3911 printf("ipsec6_output_trans: applyed SP\n");
3912 kdebug_secpolicy(sp));
3913
3914 *tun = 0;
3915 for (isr = sp->req; isr; isr = isr->next) {
3916 if (isr->saidx.mode == IPSEC_MODE_TUNNEL) {
3917 /* the rest will be handled by ipsec6_output_tunnel() */
3918 break;
3919 }
3920
3921 /* make SA index for search proper SA */
3922 ip6 = mtod(state->m, struct ip6_hdr *);
3923 bcopy(&isr->saidx, &saidx, sizeof(saidx));
3924 saidx.mode = isr->saidx.mode;
3925 saidx.reqid = isr->saidx.reqid;
3926 sin6 = SIN6(&saidx.src);
3927 if (sin6->sin6_len == 0) {
3928 sin6->sin6_len = sizeof(*sin6);
3929 sin6->sin6_family = AF_INET6;
3930 sin6->sin6_port = IPSEC_PORT_ANY;
3931 bcopy(&ip6->ip6_src, &sin6->sin6_addr,
3932 sizeof(ip6->ip6_src));
3933 if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src)) {
3934 /* fix scope id for comparing SPD */
3935 sin6->sin6_scope_id = ip6_output_getsrcifscope(state->m);
3936 in6_verify_ifscope(&ip6->ip6_src, sin6->sin6_scope_id);
3937 if (in6_embedded_scope) {
3938 sin6->sin6_scope_id = ntohs(ip6->ip6_src.s6_addr16[1]);
3939 sin6->sin6_addr.s6_addr16[1] = 0;
3940 }
3941 }
3942 }
3943 sin6 = SIN6(&saidx.dst);
3944 if (sin6->sin6_len == 0) {
3945 sin6->sin6_len = sizeof(*sin6);
3946 sin6->sin6_family = AF_INET6;
3947 sin6->sin6_port = IPSEC_PORT_ANY;
3948 bcopy(&ip6->ip6_dst, &sin6->sin6_addr,
3949 sizeof(ip6->ip6_dst));
3950 if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst)) {
3951 /* fix scope id for comparing SPD */
3952 sin6->sin6_scope_id = ip6_output_getdstifscope(state->m);
3953 in6_verify_ifscope(&ip6->ip6_dst, sin6->sin6_scope_id);
3954 if (in6_embedded_scope) {
3955 sin6->sin6_scope_id = ntohs(ip6->ip6_dst.s6_addr16[1]);
3956 sin6->sin6_addr.s6_addr16[1] = 0;
3957 }
3958 }
3959 }
3960
3961 if (key_checkrequest(isr, &saidx, &sav) == ENOENT) {
3962 /*
3963 * IPsec processing is required, but no SA found.
3964 * I assume that key_acquire() had been called
3965 * to get/establish the SA. Here I discard
3966 * this packet because it is responsibility for
3967 * upper layer to retransmit the packet.
3968 */
3969 IPSEC_STAT_INCREMENT(ipsec6stat.out_nosa);
3970 error = ENOENT;
3971
3972 /*
3973 * Notify the fact that the packet is discarded
3974 * to ourselves. I believe this is better than
3975 * just silently discarding. ([email protected])
3976 * XXX: should we restrict the error to TCP packets?
3977 * XXX: should we directly notify sockets via
3978 * pfctlinputs?
3979 */
3980 icmp6_error(state->m, ICMP6_DST_UNREACH,
3981 ICMP6_DST_UNREACH_ADMIN, 0);
3982 state->m = NULL; /* icmp6_error freed the mbuf */
3983 goto bad;
3984 }
3985
3986 /* validity check */
3987 if (sav == NULL) {
3988 switch (ipsec_get_reqlevel(isr)) {
3989 case IPSEC_LEVEL_USE:
3990 continue;
3991 case IPSEC_LEVEL_REQUIRE:
3992 /* must be not reached here. */
3993 panic("ipsec6_output_trans: no SA found, but required.");
3994 }
3995 }
3996
3997 if ((error = ipsec6_output_trans_internal(state, sav, nexthdrp, mprev)) != 0) {
3998 goto bad;
3999 }
4000 }
4001
4002 /* if we have more to go, we need a tunnel mode processing */
4003 if (isr != NULL) {
4004 *tun = 1;
4005 }
4006
4007 if (sav) {
4008 key_freesav(sav, KEY_SADB_UNLOCKED);
4009 }
4010 return 0;
4011
4012 bad:
4013 if (sav) {
4014 key_freesav(sav, KEY_SADB_UNLOCKED);
4015 }
4016 m_freem(state->m);
4017 state->m = NULL;
4018 return error;
4019 }
4020
4021 /*
4022 * IPsec output logic for IPv6, tunnel mode.
4023 */
4024 static int
ipsec6_output_tunnel_internal(struct ipsec_output_state * state,struct secasvar * sav,int * must_be_last)4025 ipsec6_output_tunnel_internal(struct ipsec_output_state *state, struct secasvar *sav, int *must_be_last)
4026 {
4027 struct ip6_hdr *ip6;
4028 struct sockaddr_in6* dst6;
4029 struct route_in6 *ro6;
4030 size_t plen;
4031 int error = 0;
4032
4033 /* validity check */
4034 if (sav == NULL || sav->sah == NULL || sav->sah->saidx.mode != IPSEC_MODE_TUNNEL) {
4035 error = EINVAL;
4036 goto bad;
4037 }
4038
4039 /*
4040 * If there is no valid SA, we give up to process.
4041 * see same place at ipsec4_output().
4042 */
4043 if (sav->state != SADB_SASTATE_MATURE
4044 && sav->state != SADB_SASTATE_DYING) {
4045 IPSEC_STAT_INCREMENT(ipsec6stat.out_nosa);
4046 error = EINVAL;
4047 goto bad;
4048 }
4049
4050 state->outgoing_if = sav->sah->outgoing_if;
4051
4052 if (sav->sah->saidx.mode == IPSEC_MODE_TUNNEL) {
4053 /*
4054 * build IPsec tunnel.
4055 */
4056 state->m = ipsec6_splithdr(state->m);
4057 if (!state->m) {
4058 IPSEC_STAT_INCREMENT(ipsec6stat.out_nomem);
4059 error = ENOMEM;
4060 goto bad;
4061 }
4062
4063 if (SA(&sav->sah->saidx.src)->sa_family == AF_INET6) {
4064 error = ipsec6_encapsulate(state->m, sav);
4065 if (error) {
4066 state->m = 0;
4067 goto bad;
4068 }
4069 ip6 = mtod(state->m, struct ip6_hdr *);
4070 } else if (SA(&sav->sah->saidx.src)->sa_family == AF_INET) {
4071 struct ip *ip;
4072 struct sockaddr_in* dst4;
4073 struct route *ro4 = NULL;
4074 struct route ro4_copy;
4075 struct ip_out_args ipoa;
4076
4077 bzero(&ipoa, sizeof(ipoa));
4078 ipoa.ipoa_boundif = IFSCOPE_NONE;
4079 ipoa.ipoa_flags = IPOAF_SELECT_SRCIF;
4080 ipoa.ipoa_sotc = SO_TC_UNSPEC;
4081 ipoa.ipoa_netsvctype = _NET_SERVICE_TYPE_UNSPEC;
4082
4083 if (must_be_last) {
4084 *must_be_last = 1;
4085 }
4086
4087 state->tunneled = 4; /* must not process any further in ip6_output */
4088 error = ipsec64_encapsulate(state->m, sav, state->dscp_mapping);
4089 if (error) {
4090 state->m = 0;
4091 goto bad;
4092 }
4093 /* Now we have an IPv4 packet */
4094 ip = mtod(state->m, struct ip *);
4095
4096 // grab sadb_mutex, to update sah's route cache and get a local copy of it
4097 lck_mtx_lock(sadb_mutex);
4098 ro4 = (struct route *)&sav->sah->sa_route;
4099 dst4 = SIN(&ro4->ro_dst);
4100 if (ro4->ro_rt) {
4101 RT_LOCK(ro4->ro_rt);
4102 }
4103 if (ROUTE_UNUSABLE(ro4) ||
4104 dst4->sin_addr.s_addr != ip->ip_dst.s_addr) {
4105 if (ro4->ro_rt != NULL) {
4106 RT_UNLOCK(ro4->ro_rt);
4107 }
4108 ROUTE_RELEASE(ro4);
4109 }
4110 if (ro4->ro_rt == NULL) {
4111 dst4->sin_family = AF_INET;
4112 dst4->sin_len = sizeof(*dst4);
4113 dst4->sin_addr = ip->ip_dst;
4114 } else {
4115 RT_UNLOCK(ro4->ro_rt);
4116 }
4117 route_copyout(&ro4_copy, ro4, sizeof(struct route));
4118 // release sadb_mutex, after updating sah's route cache and getting a local copy
4119 lck_mtx_unlock(sadb_mutex);
4120 state->m = ipsec4_splithdr(state->m);
4121 if (!state->m) {
4122 error = ENOMEM;
4123 ROUTE_RELEASE(&ro4_copy);
4124 goto bad;
4125 }
4126 switch (sav->sah->saidx.proto) {
4127 case IPPROTO_ESP:
4128 #if IPSEC_ESP
4129 if ((error = esp4_output(state->m, sav)) != 0) {
4130 state->m = NULL;
4131 ROUTE_RELEASE(&ro4_copy);
4132 goto bad;
4133 }
4134 break;
4135
4136 #else
4137 m_freem(state->m);
4138 state->m = NULL;
4139 error = EINVAL;
4140 ROUTE_RELEASE(&ro4_copy);
4141 goto bad;
4142 #endif
4143 case IPPROTO_AH:
4144 if ((error = ah4_output(state->m, sav)) != 0) {
4145 state->m = NULL;
4146 ROUTE_RELEASE(&ro4_copy);
4147 goto bad;
4148 }
4149 break;
4150 default:
4151 ipseclog((LOG_ERR,
4152 "ipsec4_output: unknown ipsec protocol %d\n",
4153 sav->sah->saidx.proto));
4154 m_freem(state->m);
4155 state->m = NULL;
4156 error = EPROTONOSUPPORT;
4157 ROUTE_RELEASE(&ro4_copy);
4158 goto bad;
4159 }
4160
4161 if (state->m == 0) {
4162 error = ENOMEM;
4163 ROUTE_RELEASE(&ro4_copy);
4164 goto bad;
4165 }
4166 ipsec_set_pkthdr_for_interface(sav->sah->ipsec_if, state->m,
4167 AF_INET, sav->flowid);
4168 ipsec_set_ipoa_for_interface(sav->sah->ipsec_if, &ipoa);
4169
4170 ip = mtod(state->m, struct ip *);
4171 ip->ip_len = ntohs(ip->ip_len); /* flip len field before calling ip_output */
4172 error = ip_output(state->m, NULL, &ro4_copy, IP_OUTARGS, NULL, &ipoa);
4173 state->m = NULL;
4174 // grab sadb_mutex, to synchronize the sah's route cache with the local copy
4175 lck_mtx_lock(sadb_mutex);
4176 route_copyin(&ro4_copy, ro4, sizeof(struct route));
4177 lck_mtx_unlock(sadb_mutex);
4178 if (error != 0) {
4179 goto bad;
4180 }
4181 goto done;
4182 } else {
4183 ipseclog((LOG_ERR, "ipsec6_output_tunnel: "
4184 "unsupported inner family, spi=%u\n",
4185 (u_int32_t)ntohl(sav->spi)));
4186 IPSEC_STAT_INCREMENT(ipsec6stat.out_inval);
4187 error = EAFNOSUPPORT;
4188 goto bad;
4189 }
4190
4191 // grab sadb_mutex, before updating sah's route cache
4192 lck_mtx_lock(sadb_mutex);
4193 ro6 = &sav->sah->sa_route;
4194 dst6 = SIN6(&ro6->ro_dst);
4195 if (ro6->ro_rt) {
4196 RT_LOCK(ro6->ro_rt);
4197 }
4198 if (ROUTE_UNUSABLE(ro6) ||
4199 !IN6_ARE_ADDR_EQUAL(&dst6->sin6_addr, &ip6->ip6_dst)) {
4200 if (ro6->ro_rt != NULL) {
4201 RT_UNLOCK(ro6->ro_rt);
4202 }
4203 ROUTE_RELEASE(ro6);
4204 }
4205 if (ro6->ro_rt == 0) {
4206 SOCKADDR_ZERO(dst6, sizeof(*dst6));
4207 dst6->sin6_family = AF_INET6;
4208 dst6->sin6_len = sizeof(*dst6);
4209 dst6->sin6_addr = ip6->ip6_dst;
4210 rtalloc_scoped((struct route *)ro6, sav->sah->outgoing_if);
4211 if (ro6->ro_rt) {
4212 RT_LOCK(ro6->ro_rt);
4213 }
4214 }
4215 if (ro6->ro_rt == 0) {
4216 ip6stat.ip6s_noroute++;
4217 IPSEC_STAT_INCREMENT(ipsec6stat.out_noroute);
4218 error = EHOSTUNREACH;
4219 // release sadb_mutex, after updating sah's route cache
4220 lck_mtx_unlock(sadb_mutex);
4221 goto bad;
4222 }
4223
4224 /*
4225 * adjust state->dst if tunnel endpoint is offlink
4226 *
4227 * XXX: caching rt_gateway value in the state is
4228 * not really good, since it may point elsewhere
4229 * when the gateway gets modified to a larger
4230 * sockaddr via rt_setgate(). This is currently
4231 * addressed by SA_SIZE roundup in that routine.
4232 */
4233 if (ro6->ro_rt->rt_flags & RTF_GATEWAY) {
4234 dst6 = SIN6(ro6->ro_rt->rt_gateway);
4235 }
4236 RT_UNLOCK(ro6->ro_rt);
4237 ROUTE_RELEASE(&state->ro);
4238 route_copyout((struct route *)&state->ro, (struct route *)ro6, sizeof(struct route_in6));
4239 state->dst = SA(dst6);
4240 state->tunneled = 6;
4241 // release sadb_mutex, after updating sah's route cache
4242 lck_mtx_unlock(sadb_mutex);
4243 }
4244
4245 state->m = ipsec6_splithdr(state->m);
4246 if (!state->m) {
4247 IPSEC_STAT_INCREMENT(ipsec6stat.out_nomem);
4248 error = ENOMEM;
4249 goto bad;
4250 }
4251 ip6 = mtod(state->m, struct ip6_hdr *);
4252 switch (sav->sah->saidx.proto) {
4253 case IPPROTO_ESP:
4254 #if IPSEC_ESP
4255 error = esp6_output(state->m, &ip6->ip6_nxt, state->m->m_next, sav);
4256 #else
4257 m_freem(state->m);
4258 error = EINVAL;
4259 #endif
4260 break;
4261 case IPPROTO_AH:
4262 error = ah6_output(state->m, &ip6->ip6_nxt, state->m->m_next, sav);
4263 break;
4264 default:
4265 ipseclog((LOG_ERR, "ipsec6_output_tunnel: "
4266 "unknown ipsec protocol %d\n", sav->sah->saidx.proto));
4267 m_freem(state->m);
4268 IPSEC_STAT_INCREMENT(ipsec6stat.out_inval);
4269 error = EINVAL;
4270 break;
4271 }
4272 if (error) {
4273 state->m = NULL;
4274 goto bad;
4275 }
4276 plen = state->m->m_pkthdr.len - sizeof(struct ip6_hdr);
4277 if (plen > IPV6_MAXPACKET) {
4278 ipseclog((LOG_ERR, "ipsec6_output_tunnel: "
4279 "IPsec with IPv6 jumbogram is not supported\n"));
4280 IPSEC_STAT_INCREMENT(ipsec6stat.out_inval);
4281 error = EINVAL; /*XXX*/
4282 goto bad;
4283 }
4284 ip6 = mtod(state->m, struct ip6_hdr *);
4285 ip6->ip6_plen = htons((u_int16_t)plen);
4286 done:
4287 #if SKYWALK
4288 if (state->m != NULL) {
4289 state->m->m_pkthdr.pkt_flowid = sav->flowid;
4290 state->m->m_pkthdr.pkt_flags |= PKTF_FLOW_ID;
4291 }
4292 #endif /* !SKYWALK */
4293
4294 return 0;
4295
4296 bad:
4297 return error;
4298 }
4299
4300 int
ipsec6_output_tunnel(struct ipsec_output_state * state,struct secpolicy * sp,__unused int flags)4301 ipsec6_output_tunnel(
4302 struct ipsec_output_state *state,
4303 struct secpolicy *sp,
4304 __unused int flags)
4305 {
4306 struct ip6_hdr *ip6;
4307 struct ipsecrequest *isr = NULL;
4308 struct secasindex saidx;
4309 struct secasvar *__single sav = NULL;
4310 int error = 0;
4311
4312 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
4313
4314 if (!state) {
4315 panic("state == NULL in ipsec6_output_tunnel");
4316 }
4317 if (!state->m) {
4318 panic("state->m == NULL in ipsec6_output_tunnel");
4319 }
4320 if (!sp) {
4321 panic("sp == NULL in ipsec6_output_tunnel");
4322 }
4323
4324 KEYDEBUG(KEYDEBUG_IPSEC_DATA,
4325 printf("ipsec6_output_tunnel: applyed SP\n");
4326 kdebug_secpolicy(sp));
4327
4328 /*
4329 * transport mode ipsec (before the 1st tunnel mode) is already
4330 * processed by ipsec6_output_trans().
4331 */
4332 for (isr = sp->req; isr; isr = isr->next) {
4333 if (isr->saidx.mode == IPSEC_MODE_TUNNEL) {
4334 break;
4335 }
4336 }
4337
4338 for (/* already initialized */; isr; isr = isr->next) {
4339 if (isr->saidx.mode == IPSEC_MODE_TUNNEL) {
4340 /* When tunnel mode, SA peers must be specified. */
4341 bcopy(&isr->saidx, &saidx, sizeof(saidx));
4342 } else {
4343 /* make SA index to look for a proper SA */
4344 struct sockaddr_in6 *sin6;
4345
4346 bzero(&saidx, sizeof(saidx));
4347 saidx.proto = isr->saidx.proto;
4348 saidx.mode = isr->saidx.mode;
4349 saidx.reqid = isr->saidx.reqid;
4350
4351 ip6 = mtod(state->m, struct ip6_hdr *);
4352 sin6 = SIN6(&saidx.src);
4353 if (sin6->sin6_len == 0) {
4354 sin6->sin6_len = sizeof(*sin6);
4355 sin6->sin6_family = AF_INET6;
4356 sin6->sin6_port = IPSEC_PORT_ANY;
4357 bcopy(&ip6->ip6_src, &sin6->sin6_addr,
4358 sizeof(ip6->ip6_src));
4359 if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src)) {
4360 /* fix scope id for comparing SPD */
4361 sin6->sin6_scope_id = ip6_output_getsrcifscope(state->m);
4362 in6_verify_ifscope(&ip6->ip6_src, sin6->sin6_scope_id);
4363 if (in6_embedded_scope) {
4364 sin6->sin6_scope_id = ntohs(ip6->ip6_src.s6_addr16[1]);
4365 sin6->sin6_addr.s6_addr16[1] = 0;
4366 }
4367 }
4368 }
4369 sin6 = SIN6(&saidx.dst);
4370 if (sin6->sin6_len == 0) {
4371 sin6->sin6_len = sizeof(*sin6);
4372 sin6->sin6_family = AF_INET6;
4373 sin6->sin6_port = IPSEC_PORT_ANY;
4374 bcopy(&ip6->ip6_dst, &sin6->sin6_addr,
4375 sizeof(ip6->ip6_dst));
4376 if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst)) {
4377 /* fix scope id for comparing SPD */
4378 sin6->sin6_scope_id = ip6_output_getdstifscope(state->m);
4379 in6_verify_ifscope(&ip6->ip6_dst, sin6->sin6_scope_id);
4380 if (in6_embedded_scope) {
4381 sin6->sin6_scope_id = ntohs(ip6->ip6_src.s6_addr16[1]);
4382 sin6->sin6_addr.s6_addr16[1] = 0;
4383 }
4384 }
4385 }
4386 }
4387
4388 if (key_checkrequest(isr, &saidx, &sav) == ENOENT) {
4389 /*
4390 * IPsec processing is required, but no SA found.
4391 * I assume that key_acquire() had been called
4392 * to get/establish the SA. Here I discard
4393 * this packet because it is responsibility for
4394 * upper layer to retransmit the packet.
4395 */
4396 IPSEC_STAT_INCREMENT(ipsec6stat.out_nosa);
4397 error = ENOENT;
4398 goto bad;
4399 }
4400
4401 /* validity check */
4402 if (sav == NULL) {
4403 switch (ipsec_get_reqlevel(isr)) {
4404 case IPSEC_LEVEL_USE:
4405 continue;
4406 case IPSEC_LEVEL_REQUIRE:
4407 /* must be not reached here. */
4408 panic("ipsec6_output_tunnel: no SA found, but required.");
4409 }
4410 }
4411
4412 /*
4413 * If there is no valid SA, we give up to process.
4414 * see same place at ipsec4_output().
4415 */
4416 if (sav->state != SADB_SASTATE_MATURE
4417 && sav->state != SADB_SASTATE_DYING) {
4418 IPSEC_STAT_INCREMENT(ipsec6stat.out_nosa);
4419 error = EINVAL;
4420 goto bad;
4421 }
4422
4423 int must_be_last = 0;
4424
4425 if ((error = ipsec6_output_tunnel_internal(state, sav, &must_be_last)) != 0) {
4426 goto bad;
4427 }
4428
4429 if (must_be_last && isr->next) {
4430 ipseclog((LOG_ERR, "ipsec6_output_tunnel: "
4431 "IPv4 must be outer layer, spi=%u\n",
4432 (u_int32_t)ntohl(sav->spi)));
4433 error = EINVAL;
4434 goto bad;
4435 }
4436 }
4437
4438 if (sav) {
4439 key_freesav(sav, KEY_SADB_UNLOCKED);
4440 }
4441 return 0;
4442
4443 bad:
4444 if (sav) {
4445 key_freesav(sav, KEY_SADB_UNLOCKED);
4446 }
4447 if (state->m) {
4448 m_freem(state->m);
4449 }
4450 state->m = NULL;
4451 return error;
4452 }
4453
4454 int
ipsec6_interface_output(struct ipsec_output_state * state,ifnet_t interface,u_char * nexthdrp,struct mbuf * mprev)4455 ipsec6_interface_output(struct ipsec_output_state *state, ifnet_t interface, u_char *nexthdrp, struct mbuf *mprev)
4456 {
4457 int error = 0;
4458 struct secasvar *sav = NULL;
4459
4460 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
4461
4462 if (state == NULL) {
4463 panic("state == NULL in ipsec6_output");
4464 }
4465 if (state->m == NULL) {
4466 panic("state->m == NULL in ipsec6_output");
4467 }
4468 if (nexthdrp == NULL) {
4469 panic("nexthdrp == NULL in ipsec6_output");
4470 }
4471 if (mprev == NULL) {
4472 panic("mprev == NULL in ipsec6_output");
4473 }
4474
4475 struct ip6_hdr *ip6 = mtod(state->m, struct ip6_hdr *);
4476
4477 struct sockaddr_in6 src = {};
4478 src.sin6_family = AF_INET6;
4479 src.sin6_len = sizeof(src);
4480 memcpy(&src.sin6_addr, &ip6->ip6_src, sizeof(src.sin6_addr));
4481
4482 struct sockaddr_in6 dst = {};
4483 dst.sin6_family = AF_INET6;
4484 dst.sin6_len = sizeof(dst);
4485 memcpy(&dst.sin6_addr, &ip6->ip6_dst, sizeof(dst.sin6_addr));
4486
4487 sav = key_alloc_outbound_sav_for_interface(interface, AF_INET6,
4488 SA(&src),
4489 SA(&dst));
4490 if (sav == NULL) {
4491 goto bad;
4492 }
4493
4494 if (sav->sah && sav->sah->saidx.mode == IPSEC_MODE_TUNNEL) {
4495 if ((error = ipsec6_output_tunnel_internal(state, sav, NULL)) != 0) {
4496 goto bad;
4497 }
4498 } else {
4499 if ((error = ipsec6_output_trans_internal(state, sav, nexthdrp, mprev)) != 0) {
4500 goto bad;
4501 }
4502 }
4503
4504 if (sav) {
4505 key_freesav(sav, KEY_SADB_UNLOCKED);
4506 }
4507 return 0;
4508
4509 bad:
4510 if (sav) {
4511 key_freesav(sav, KEY_SADB_UNLOCKED);
4512 }
4513 m_freem(state->m);
4514 state->m = NULL;
4515 return error;
4516 }
4517
4518 #if INET
4519 /*
4520 * Chop IP header and option off from the payload.
4521 */
4522 struct mbuf *
ipsec4_splithdr(struct mbuf * m)4523 ipsec4_splithdr(struct mbuf *m)
4524 {
4525 struct mbuf *mh;
4526 struct ip *ip;
4527 int hlen;
4528
4529 if (m->m_len < sizeof(struct ip)) {
4530 panic("ipsec4_splithdr: first mbuf too short, m_len %d, pkt_len %d, m_flag %x", m->m_len, m->m_pkthdr.len, m->m_flags);
4531 }
4532 ip = mtod(m, struct ip *);
4533 #ifdef _IP_VHL
4534 hlen = _IP_VHL_HL(ip->ip_vhl) << 2;
4535 #else
4536 hlen = ip->ip_hl << 2;
4537 #endif
4538 if (m->m_len > hlen) {
4539 MGETHDR(mh, M_DONTWAIT, MT_HEADER); /* MAC-OK */
4540 if (!mh) {
4541 m_freem(m);
4542 return NULL;
4543 }
4544 M_COPY_PKTHDR(mh, m);
4545 MH_ALIGN(mh, hlen);
4546 m->m_flags &= ~M_PKTHDR;
4547 m_mchtype(m, MT_DATA);
4548 m->m_len -= hlen;
4549 m->m_data += hlen;
4550 mh->m_next = m;
4551 m = mh;
4552 m->m_len = hlen;
4553 bcopy((caddr_t)ip, mtod(m, caddr_t), hlen);
4554 } else if (m->m_len < hlen) {
4555 m = m_pullup(m, hlen);
4556 if (!m) {
4557 return NULL;
4558 }
4559 }
4560 return m;
4561 }
4562 #endif
4563
4564 struct mbuf *
ipsec6_splithdr(struct mbuf * m)4565 ipsec6_splithdr(struct mbuf *m)
4566 {
4567 struct mbuf *mh;
4568 struct ip6_hdr *ip6;
4569 int hlen;
4570
4571 if (m->m_len < sizeof(struct ip6_hdr)) {
4572 panic("ipsec6_splithdr: first mbuf too short");
4573 }
4574 ip6 = mtod(m, struct ip6_hdr *);
4575 hlen = sizeof(struct ip6_hdr);
4576 if (m->m_len > hlen) {
4577 MGETHDR(mh, M_DONTWAIT, MT_HEADER); /* MAC-OK */
4578 if (!mh) {
4579 m_freem(m);
4580 return NULL;
4581 }
4582 M_COPY_PKTHDR(mh, m);
4583 MH_ALIGN(mh, hlen);
4584 m->m_flags &= ~M_PKTHDR;
4585 m_mchtype(m, MT_DATA);
4586 m->m_len -= hlen;
4587 m->m_data += hlen;
4588 mh->m_next = m;
4589 m = mh;
4590 m->m_len = hlen;
4591 bcopy((caddr_t)ip6, mtod(m, caddr_t), hlen);
4592 } else if (m->m_len < hlen) {
4593 m = m_pullup(m, hlen);
4594 if (!m) {
4595 return NULL;
4596 }
4597 }
4598 return m;
4599 }
4600
4601 /* validate inbound IPsec tunnel packet. */
4602 int
ipsec4_tunnel_validate(struct mbuf * m,int off,u_int nxt0,struct secasvar * sav,sa_family_t * ifamily)4603 ipsec4_tunnel_validate(
4604 struct mbuf *m, /* no pullup permitted, m->m_len >= ip */
4605 int off,
4606 u_int nxt0,
4607 struct secasvar *sav,
4608 sa_family_t *ifamily)
4609 {
4610 u_int8_t nxt = nxt0 & 0xff;
4611 struct sockaddr_in *sin;
4612 struct sockaddr_in osrc, odst, i4src, i4dst;
4613 struct sockaddr_in6 i6src, i6dst;
4614 int hlen;
4615 struct secpolicy *sp;
4616 struct ip *oip;
4617
4618 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
4619
4620 /* do not decapsulate if the SA is for transport mode only */
4621 if (sav->sah->saidx.mode == IPSEC_MODE_TRANSPORT) {
4622 return 0;
4623 }
4624
4625 #if DIAGNOSTIC
4626 if (m->m_len < sizeof(struct ip)) {
4627 panic("too short mbuf on ipsec4_tunnel_validate");
4628 }
4629 #endif
4630 if (nxt != IPPROTO_IPV4 && nxt != IPPROTO_IPV6) {
4631 return 0;
4632 }
4633 if (m->m_pkthdr.len < off + sizeof(struct ip)) {
4634 return 0;
4635 }
4636
4637 oip = mtod(m, struct ip *);
4638 #ifdef _IP_VHL
4639 hlen = _IP_VHL_HL(oip->ip_vhl) << 2;
4640 #else
4641 hlen = oip->ip_hl << 2;
4642 #endif
4643 if (hlen != sizeof(struct ip)) {
4644 return 0;
4645 }
4646
4647 sin = SIN(&sav->sah->saidx.dst);
4648 if (sin->sin_family != AF_INET) {
4649 return 0;
4650 }
4651 if (bcmp(&oip->ip_dst, &sin->sin_addr, sizeof(oip->ip_dst)) != 0) {
4652 return 0;
4653 }
4654
4655 if (sav->sah->ipsec_if != NULL) {
4656 // the ipsec interface SAs don't have a policies.
4657 if (nxt == IPPROTO_IPV4) {
4658 *ifamily = AF_INET;
4659 } else if (nxt == IPPROTO_IPV6) {
4660 *ifamily = AF_INET6;
4661 } else {
4662 return 0;
4663 }
4664 return 1;
4665 }
4666
4667 /* XXX slow */
4668 SOCKADDR_ZERO(&osrc, sizeof(osrc));
4669 SOCKADDR_ZERO(&odst, sizeof(odst));
4670 osrc.sin_family = odst.sin_family = AF_INET;
4671 osrc.sin_len = odst.sin_len = sizeof(struct sockaddr_in);
4672 osrc.sin_addr = oip->ip_src;
4673 odst.sin_addr = oip->ip_dst;
4674 /*
4675 * RFC2401 5.2.1 (b): (assume that we are using tunnel mode)
4676 * - if the inner destination is multicast address, there can be
4677 * multiple permissible inner source address. implementation
4678 * may want to skip verification of inner source address against
4679 * SPD selector.
4680 * - if the inner protocol is ICMP, the packet may be an error report
4681 * from routers on the other side of the VPN cloud (R in the
4682 * following diagram). in this case, we cannot verify inner source
4683 * address against SPD selector.
4684 * me -- gw === gw -- R -- you
4685 *
4686 * we consider the first bullet to be users responsibility on SPD entry
4687 * configuration (if you need to encrypt multicast traffic, set
4688 * the source range of SPD selector to 0.0.0.0/0, or have explicit
4689 * address ranges for possible senders).
4690 * the second bullet is not taken care of (yet).
4691 *
4692 * therefore, we do not do anything special about inner source.
4693 */
4694 if (nxt == IPPROTO_IPV4) {
4695 SOCKADDR_ZERO(&i4src, sizeof(struct sockaddr_in));
4696 SOCKADDR_ZERO(&i4dst, sizeof(struct sockaddr_in));
4697 i4src.sin_family = i4dst.sin_family = *ifamily = AF_INET;
4698 i4src.sin_len = i4dst.sin_len = sizeof(struct sockaddr_in);
4699 m_copydata(m, off + offsetof(struct ip, ip_src), sizeof(i4src.sin_addr),
4700 (caddr_t)&i4src.sin_addr);
4701 m_copydata(m, off + offsetof(struct ip, ip_dst), sizeof(i4dst.sin_addr),
4702 (caddr_t)&i4dst.sin_addr);
4703 sp = key_gettunnel(SA(&osrc), SA(&odst), SA(&i4src), SA(&i4dst));
4704 } else if (nxt == IPPROTO_IPV6) {
4705 SOCKADDR_ZERO(&i6src, sizeof(struct sockaddr_in6));
4706 SOCKADDR_ZERO(&i6dst, sizeof(struct sockaddr_in6));
4707 i6src.sin6_family = i6dst.sin6_family = *ifamily = AF_INET6;
4708 i6src.sin6_len = i6dst.sin6_len = sizeof(struct sockaddr_in6);
4709 m_copydata(m, off + offsetof(struct ip6_hdr, ip6_src), sizeof(i6src.sin6_addr),
4710 (caddr_t)&i6src.sin6_addr);
4711 m_copydata(m, off + offsetof(struct ip6_hdr, ip6_dst), sizeof(i6dst.sin6_addr),
4712 (caddr_t)&i6dst.sin6_addr);
4713 sp = key_gettunnel(SA(&osrc), SA(&odst), SA(&i6src), SA(&i6dst));
4714 } else {
4715 return 0; /* unsupported family */
4716 }
4717 if (!sp) {
4718 return 0;
4719 }
4720
4721 key_freesp(sp, KEY_SADB_UNLOCKED);
4722
4723 return 1;
4724 }
4725
4726 /* validate inbound IPsec tunnel packet. */
4727 int
ipsec6_tunnel_validate(struct mbuf * m,int off,u_int nxt0,struct secasvar * sav,sa_family_t * ifamily)4728 ipsec6_tunnel_validate(
4729 struct mbuf *m, /* no pullup permitted, m->m_len >= ip */
4730 int off,
4731 u_int nxt0,
4732 struct secasvar *sav,
4733 sa_family_t *ifamily)
4734 {
4735 u_int8_t nxt = nxt0 & 0xff;
4736 struct sockaddr_in6 *sin6;
4737 struct sockaddr_in i4src, i4dst;
4738 struct sockaddr_in6 osrc, odst, i6src, i6dst;
4739 struct secpolicy *sp;
4740 struct ip6_hdr *oip6;
4741
4742 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
4743
4744 /* do not decapsulate if the SA is for transport mode only */
4745 if (sav->sah->saidx.mode == IPSEC_MODE_TRANSPORT) {
4746 return 0;
4747 }
4748
4749 #if DIAGNOSTIC
4750 if (m->m_len < sizeof(struct ip6_hdr)) {
4751 panic("too short mbuf on ipsec6_tunnel_validate");
4752 }
4753 #endif
4754 if (nxt == IPPROTO_IPV4) {
4755 if (m->m_pkthdr.len < off + sizeof(struct ip)) {
4756 ipseclog((LOG_NOTICE, "ipsec6_tunnel_validate pkthdr %d off %d ip6hdr %zu", m->m_pkthdr.len, off, sizeof(struct ip6_hdr)));
4757 return 0;
4758 }
4759 } else if (nxt == IPPROTO_IPV6) {
4760 if (m->m_pkthdr.len < off + sizeof(struct ip6_hdr)) {
4761 ipseclog((LOG_NOTICE, "ipsec6_tunnel_validate pkthdr %d off %d ip6hdr %zu", m->m_pkthdr.len, off, sizeof(struct ip6_hdr)));
4762 return 0;
4763 }
4764 } else {
4765 ipseclog((LOG_NOTICE, "ipsec6_tunnel_validate invalid nxt(%u) protocol", nxt));
4766 return 0;
4767 }
4768
4769 oip6 = mtod(m, struct ip6_hdr *);
4770 /* AF_INET should be supported, but at this moment we don't. */
4771 sin6 = SIN6(&sav->sah->saidx.dst);
4772 if (sin6->sin6_family != AF_INET6) {
4773 return 0;
4774 }
4775
4776 struct in6_addr tmp_sah_dst_addr = {};
4777 struct in6_addr *sah_dst_addr = &SIN6(&sav->sah->saidx.dst)->sin6_addr;
4778 if (in6_embedded_scope && IN6_IS_SCOPE_LINKLOCAL(sah_dst_addr)) {
4779 memcpy(&tmp_sah_dst_addr, sah_dst_addr, sizeof(tmp_sah_dst_addr));
4780 tmp_sah_dst_addr.s6_addr16[1] = htons((u_int16_t)sav->sah->outgoing_if);
4781 sah_dst_addr = &tmp_sah_dst_addr;
4782 }
4783 if (!IN6_ARE_ADDR_EQUAL(&oip6->ip6_dst, sah_dst_addr)) {
4784 return 0;
4785 }
4786
4787 if (sav->sah->ipsec_if != NULL) {
4788 // the ipsec interface SAs don't have a policies.
4789 if (nxt == IPPROTO_IPV4) {
4790 *ifamily = AF_INET;
4791 } else if (nxt == IPPROTO_IPV6) {
4792 *ifamily = AF_INET6;
4793 } else {
4794 return 0;
4795 }
4796 return 1;
4797 }
4798
4799 /* XXX slow */
4800 SOCKADDR_ZERO(&osrc, sizeof(osrc));
4801 SOCKADDR_ZERO(&odst, sizeof(odst));
4802 osrc.sin6_family = odst.sin6_family = AF_INET6;
4803 osrc.sin6_len = odst.sin6_len = sizeof(struct sockaddr_in6);
4804 osrc.sin6_addr = oip6->ip6_src;
4805 odst.sin6_addr = oip6->ip6_dst;
4806
4807 /*
4808 * regarding to inner source address validation, see a long comment
4809 * in ipsec4_tunnel_validate.
4810 */
4811
4812 if (nxt == IPPROTO_IPV4) {
4813 SOCKADDR_ZERO(&i4src, sizeof(struct sockaddr_in));
4814 SOCKADDR_ZERO(&i4dst, sizeof(struct sockaddr_in));
4815 i4src.sin_family = i4dst.sin_family = *ifamily = AF_INET;
4816 i4src.sin_len = i4dst.sin_len = sizeof(struct sockaddr_in);
4817 m_copydata(m, off + offsetof(struct ip, ip_src), sizeof(i4src.sin_addr),
4818 (caddr_t)&i4src.sin_addr);
4819 m_copydata(m, off + offsetof(struct ip, ip_dst), sizeof(i4dst.sin_addr),
4820 (caddr_t)&i4dst.sin_addr);
4821 sp = key_gettunnel(SA(&osrc), SA(&odst), SA(&i4src), SA(&i4dst));
4822 } else if (nxt == IPPROTO_IPV6) {
4823 SOCKADDR_ZERO(&i6src, sizeof(struct sockaddr_in6));
4824 SOCKADDR_ZERO(&i6dst, sizeof(struct sockaddr_in6));
4825 i6src.sin6_family = i6dst.sin6_family = *ifamily = AF_INET6;
4826 i6src.sin6_len = i6dst.sin6_len = sizeof(struct sockaddr_in6);
4827 m_copydata(m, off + offsetof(struct ip6_hdr, ip6_src), sizeof(i6src.sin6_addr),
4828 (caddr_t)&i6src.sin6_addr);
4829 m_copydata(m, off + offsetof(struct ip6_hdr, ip6_dst), sizeof(i6dst.sin6_addr),
4830 (caddr_t)&i6dst.sin6_addr);
4831 sp = key_gettunnel(SA(&osrc), SA(&odst), SA(&i6src), SA(&i6dst));
4832 } else {
4833 return 0; /* unsupported family */
4834 }
4835 /*
4836 * when there is no suitable inbound policy for the packet of the ipsec
4837 * tunnel mode, the kernel never decapsulate the tunneled packet
4838 * as the ipsec tunnel mode even when the system wide policy is "none".
4839 * then the kernel leaves the generic tunnel module to process this
4840 * packet. if there is no rule of the generic tunnel, the packet
4841 * is rejected and the statistics will be counted up.
4842 */
4843 if (!sp) {
4844 return 0;
4845 }
4846 key_freesp(sp, KEY_SADB_UNLOCKED);
4847
4848 return 1;
4849 }
4850
4851 /*
4852 * Make a mbuf chain for encryption.
4853 * If the original mbuf chain contains a mbuf with a cluster,
4854 * allocate a new cluster and copy the data to the new cluster.
4855 * XXX: this hack is inefficient, but is necessary to handle cases
4856 * of TCP retransmission...
4857 */
4858 struct mbuf *
ipsec_copypkt(struct mbuf * m)4859 ipsec_copypkt(struct mbuf *m)
4860 {
4861 struct mbuf *n, **mpp, *mnew;
4862
4863 for (n = m, mpp = &m; n; n = n->m_next) {
4864 if (n->m_flags & M_EXT) {
4865 /*
4866 * Make a copy only if there are more than one references
4867 * to the cluster.
4868 * XXX: is this approach effective?
4869 */
4870 if (
4871 m_get_ext_free(n) != NULL ||
4872 m_mclhasreference(n)
4873 ) {
4874 int remain, copied;
4875 struct mbuf *mm;
4876
4877 if (n->m_flags & M_PKTHDR) {
4878 MGETHDR(mnew, M_DONTWAIT, MT_HEADER); /* MAC-OK */
4879 if (mnew == NULL) {
4880 goto fail;
4881 }
4882 M_COPY_PKTHDR(mnew, n);
4883 } else {
4884 MGET(mnew, M_DONTWAIT, MT_DATA);
4885 if (mnew == NULL) {
4886 goto fail;
4887 }
4888 }
4889 mnew->m_len = 0;
4890 mm = mnew;
4891
4892 /*
4893 * Copy data. If we don't have enough space to
4894 * store the whole data, allocate a cluster
4895 * or additional mbufs.
4896 * XXX: we don't use m_copyback(), since the
4897 * function does not use clusters and thus is
4898 * inefficient.
4899 */
4900 remain = n->m_len;
4901 copied = 0;
4902 while (1) {
4903 int len;
4904 struct mbuf *mn;
4905
4906 if (remain <= (mm->m_flags & M_PKTHDR ? MHLEN : MLEN)) {
4907 len = remain;
4908 } else { /* allocate a cluster */
4909 MCLGET(mm, M_DONTWAIT);
4910 if (!(mm->m_flags & M_EXT)) {
4911 m_free(mm);
4912 goto fail;
4913 }
4914 len = remain < MCLBYTES ?
4915 remain : MCLBYTES;
4916 }
4917
4918 bcopy(m_mtod_current(n) + copied, m_mtod_current(mm), len);
4919
4920 copied += len;
4921 remain -= len;
4922 mm->m_len = len;
4923
4924 if (remain <= 0) { /* completed? */
4925 break;
4926 }
4927
4928 /* need another mbuf */
4929 MGETHDR(mn, M_DONTWAIT, MT_HEADER); /* XXXMAC: tags copied next time in loop? */
4930 if (mn == NULL) {
4931 goto fail;
4932 }
4933 mn->m_pkthdr.rcvif = NULL;
4934 mm->m_next = mn;
4935 mm = mn;
4936 }
4937
4938 /* adjust chain */
4939 mm->m_next = m_free(n);
4940 n = mm;
4941 *mpp = mnew;
4942 mpp = &n->m_next;
4943
4944 continue;
4945 }
4946 }
4947 *mpp = n;
4948 mpp = &n->m_next;
4949 }
4950
4951 return m;
4952 fail:
4953 m_freem(m);
4954 return NULL;
4955 }
4956
4957 /* Used to avoid processing the packet over again */
4958 #define IPSEC_HISTORY_MAX 8
4959
4960 struct ipsec_tag {
4961 struct socket *socket;
4962 u_int32_t history_count;
4963 };
4964
4965 static struct ipsec_tag *
ipsec_addaux(struct mbuf * m)4966 ipsec_addaux(
4967 struct mbuf *m)
4968 {
4969 struct m_tag *tag;
4970
4971 /* Check if the tag already exists */
4972 tag = m_tag_locate(m, KERNEL_MODULE_TAG_ID, KERNEL_TAG_TYPE_IPSEC);
4973
4974 if (tag == NULL) {
4975 struct ipsec_tag *itag;
4976
4977 /* Allocate a tag */
4978 tag = m_tag_create(KERNEL_MODULE_TAG_ID, KERNEL_TAG_TYPE_IPSEC,
4979 sizeof(struct ipsec_tag), M_DONTWAIT, m);
4980
4981 if (tag) {
4982 itag = (struct ipsec_tag*)(tag->m_tag_data);
4983 itag->socket = 0;
4984 itag->history_count = 0;
4985
4986 m_tag_prepend(m, tag);
4987 }
4988 }
4989
4990 return tag ? (struct ipsec_tag*)(tag->m_tag_data) : NULL;
4991 }
4992
4993 static struct ipsec_tag *
ipsec_findaux(struct mbuf * m)4994 ipsec_findaux(
4995 struct mbuf *m)
4996 {
4997 struct m_tag *tag;
4998
4999 tag = m_tag_locate(m, KERNEL_MODULE_TAG_ID, KERNEL_TAG_TYPE_IPSEC);
5000
5001 return tag != NULL ? (struct ipsec_tag*)(tag->m_tag_data) : NULL;
5002 }
5003
5004 void
ipsec_delaux(struct mbuf * m)5005 ipsec_delaux(
5006 struct mbuf *m)
5007 {
5008 struct m_tag *tag;
5009
5010 tag = m_tag_locate(m, KERNEL_MODULE_TAG_ID, KERNEL_TAG_TYPE_IPSEC);
5011
5012 if (tag != NULL) {
5013 m_tag_delete(m, tag);
5014 }
5015 }
5016
5017 /* if the aux buffer is unnecessary, nuke it. */
5018 static void
ipsec_optaux(struct mbuf * m,struct ipsec_tag * itag)5019 ipsec_optaux(
5020 struct mbuf *m,
5021 struct ipsec_tag *itag)
5022 {
5023 if (itag != NULL && itag->socket == NULL && itag->history_count == 0) {
5024 ipsec_delaux(m);
5025 }
5026 }
5027
5028 int
ipsec_setsocket(struct mbuf * m,struct socket * so)5029 ipsec_setsocket(struct mbuf *m, struct socket *so)
5030 {
5031 struct ipsec_tag *tag;
5032
5033 /* if so == NULL, don't insist on getting the aux mbuf */
5034 if (so != NULL) {
5035 tag = ipsec_addaux(m);
5036 if (!tag) {
5037 return ENOBUFS;
5038 }
5039 } else {
5040 tag = ipsec_findaux(m);
5041 }
5042 if (tag != NULL) {
5043 tag->socket = so;
5044 ipsec_optaux(m, tag);
5045 }
5046 return 0;
5047 }
5048
5049 struct socket *
ipsec_getsocket(struct mbuf * m)5050 ipsec_getsocket(struct mbuf *m)
5051 {
5052 struct ipsec_tag *itag;
5053
5054 itag = ipsec_findaux(m);
5055 if (itag) {
5056 return itag->socket;
5057 } else {
5058 return NULL;
5059 }
5060 }
5061
5062 int
ipsec_incr_history_count(struct mbuf * m,__unused int proto,__unused u_int32_t spi)5063 ipsec_incr_history_count(
5064 struct mbuf *m,
5065 __unused int proto,
5066 __unused u_int32_t spi)
5067 {
5068 struct ipsec_tag *itag;
5069
5070 itag = ipsec_addaux(m);
5071 if (itag == NULL) {
5072 return ENOBUFS;
5073 }
5074 if (itag->history_count == IPSEC_HISTORY_MAX) {
5075 return ENOSPC; /* XXX */
5076 }
5077 itag->history_count++;
5078
5079 return 0;
5080 }
5081
5082 u_int32_t
ipsec_get_history_count(struct mbuf * m)5083 ipsec_get_history_count(
5084 struct mbuf *m)
5085 {
5086 struct ipsec_tag *itag;
5087
5088 itag = ipsec_findaux(m);
5089 if (itag == NULL) {
5090 return 0;
5091 }
5092 return itag->history_count;
5093 }
5094
5095 struct ipsec_tag_container {
5096 struct m_tag ipsec_m_tag;
5097 struct ipsec_tag ipsec_tag;
5098 };
5099
5100 static struct m_tag *
m_tag_kalloc_ipsec(u_int32_t id,u_int16_t type,uint16_t len,int wait)5101 m_tag_kalloc_ipsec(u_int32_t id, u_int16_t type, uint16_t len, int wait)
5102 {
5103 struct ipsec_tag_container *tag_container;
5104 struct m_tag *tag = NULL;
5105
5106 assert3u(id, ==, KERNEL_MODULE_TAG_ID);
5107 assert3u(type, ==, KERNEL_TAG_TYPE_IPSEC);
5108 assert3u(len, ==, sizeof(struct ipsec_tag));
5109
5110 if (len != sizeof(struct ipsec_tag)) {
5111 return NULL;
5112 }
5113
5114 tag_container = kalloc_type(struct ipsec_tag_container, wait | M_ZERO);
5115 if (tag_container != NULL) {
5116 tag = &tag_container->ipsec_m_tag;
5117
5118 assert3p(tag, ==, tag_container);
5119
5120 M_TAG_INIT(tag, id, type, len, &tag_container->ipsec_tag, NULL);
5121 }
5122
5123 return tag;
5124 }
5125
5126 static void
m_tag_kfree_ipsec(struct m_tag * tag)5127 m_tag_kfree_ipsec(struct m_tag *tag)
5128 {
5129 struct ipsec_tag_container *__single tag_container = (struct ipsec_tag_container *)tag;
5130
5131 assert3u(tag->m_tag_len, ==, sizeof(struct ipsec_tag));
5132
5133 kfree_type(struct ipsec_tag_container, tag_container);
5134 }
5135
5136 void
ipsec_register_m_tag(void)5137 ipsec_register_m_tag(void)
5138 {
5139 int error;
5140
5141 error = m_register_internal_tag_type(KERNEL_TAG_TYPE_IPSEC, sizeof(struct ipsec_tag),
5142 m_tag_kalloc_ipsec, m_tag_kfree_ipsec);
5143
5144 assert3u(error, ==, 0);
5145 }
5146
5147 __private_extern__ boolean_t
ipsec_send_natt_keepalive(struct secasvar * sav)5148 ipsec_send_natt_keepalive(
5149 struct secasvar *sav)
5150 {
5151 struct mbuf *m = NULL;
5152 int error = 0;
5153 int keepalive_interval = natt_keepalive_interval;
5154
5155 LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
5156 lck_mtx_lock(sadb_mutex);
5157
5158 if (((esp_udp_encap_port & 0xFFFF) == 0 && sav->natt_encapsulated_src_port == 0) || sav->remote_ike_port == 0) {
5159 lck_mtx_unlock(sadb_mutex);
5160 return FALSE;
5161 }
5162
5163 if (sav->natt_interval != 0) {
5164 keepalive_interval = (int)sav->natt_interval;
5165 }
5166
5167 // natt timestamp may have changed... reverify
5168 if ((natt_now - sav->natt_last_activity) < keepalive_interval) {
5169 lck_mtx_unlock(sadb_mutex);
5170 return FALSE;
5171 }
5172
5173 if (sav->flags & SADB_X_EXT_ESP_KEEPALIVE) {
5174 lck_mtx_unlock(sadb_mutex);
5175 return FALSE; // don't send these from the kernel
5176 }
5177
5178 lck_mtx_unlock(sadb_mutex);
5179
5180 m = m_gethdr(M_NOWAIT, MT_DATA);
5181 if (m == NULL) {
5182 return FALSE;
5183 }
5184
5185 lck_mtx_lock(sadb_mutex);
5186 if (sav->sah->saidx.dst.ss_family == AF_INET) {
5187 struct ip_out_args ipoa = {};
5188 struct route ro = {};
5189
5190 ipoa.ipoa_boundif = IFSCOPE_NONE;
5191 ipoa.ipoa_flags = IPOAF_SELECT_SRCIF;
5192 ipoa.ipoa_sotc = SO_TC_UNSPEC;
5193 ipoa.ipoa_netsvctype = _NET_SERVICE_TYPE_UNSPEC;
5194
5195 struct ip *ip = (__typeof__(ip))(void *)m_mtod_current(m);
5196
5197 /*
5198 * Type 2: a UDP packet complete with IP header.
5199 * We must do this because UDP output requires
5200 * an inpcb which we don't have. UDP packet
5201 * contains one byte payload. The byte is set
5202 * to 0xFF.
5203 */
5204 struct udphdr *uh = (__typeof__(uh))(void *)(m_mtod_current(m) + sizeof(*ip));
5205 m->m_len = sizeof(struct udpiphdr) + 1;
5206 bzero(m_mtod_current(m), m->m_len);
5207 m->m_pkthdr.len = m->m_len;
5208
5209 ip->ip_len = (u_short)m->m_len;
5210 ip->ip_ttl = (u_char)ip_defttl;
5211 ip->ip_p = IPPROTO_UDP;
5212 if (sav->sah->dir != IPSEC_DIR_INBOUND) {
5213 ip->ip_src = SIN(&sav->sah->saidx.src)->sin_addr;
5214 ip->ip_dst = SIN(&sav->sah->saidx.dst)->sin_addr;
5215 } else {
5216 ip->ip_src = SIN(&sav->sah->saidx.dst)->sin_addr;
5217 ip->ip_dst = SIN(&sav->sah->saidx.src)->sin_addr;
5218 }
5219 if (sav->natt_encapsulated_src_port != 0) {
5220 uh->uh_sport = (u_short)sav->natt_encapsulated_src_port;
5221 } else {
5222 uh->uh_sport = htons((u_short)esp_udp_encap_port);
5223 }
5224 uh->uh_sport = htons((u_short)esp_udp_encap_port);
5225 uh->uh_dport = htons(sav->remote_ike_port);
5226 uh->uh_ulen = htons(1 + sizeof(*uh));
5227 uh->uh_sum = 0;
5228 *(u_int8_t*)(m_mtod_current(m) + sizeof(*ip) + sizeof(*uh)) = 0xFF;
5229
5230 if (ROUTE_UNUSABLE(&sav->sah->sa_route) ||
5231 rt_key(sav->sah->sa_route.ro_rt)->sa_family != AF_INET) {
5232 ROUTE_RELEASE(&sav->sah->sa_route);
5233 }
5234
5235 route_copyout(&ro, (struct route *)&sav->sah->sa_route, sizeof(struct route));
5236 lck_mtx_unlock(sadb_mutex);
5237
5238 necp_mark_packet_as_keepalive(m, TRUE);
5239 error = ip_output(m, NULL, &ro, IP_OUTARGS | IP_NOIPSEC, NULL, &ipoa);
5240
5241 lck_mtx_lock(sadb_mutex);
5242 route_copyin(&ro, (struct route *)&sav->sah->sa_route, sizeof(struct route));
5243 } else if (sav->sah->saidx.dst.ss_family == AF_INET6) {
5244 struct ip6_out_args ip6oa = {};
5245 struct route_in6 ro6 = {};
5246
5247 ip6oa.ip6oa_flowadv.code = 0;
5248 ip6oa.ip6oa_flags = IP6OAF_SELECT_SRCIF | IP6OAF_BOUND_SRCADDR;
5249 if (sav->sah->outgoing_if) {
5250 ip6oa.ip6oa_boundif = sav->sah->outgoing_if;
5251 ip6oa.ip6oa_flags |= IP6OAF_BOUND_IF;
5252 }
5253
5254 struct ip6_hdr *ip6 = (__typeof__(ip6))m_mtod_current(m);
5255
5256 /*
5257 * Type 2: a UDP packet complete with IPv6 header.
5258 * We must do this because UDP output requires
5259 * an inpcb which we don't have. UDP packet
5260 * contains one byte payload. The byte is set
5261 * to 0xFF.
5262 */
5263 struct udphdr *uh = (__typeof__(uh))(void *)(m_mtod_current(m) + sizeof(*ip6));
5264 m->m_len = sizeof(struct udphdr) + sizeof(struct ip6_hdr) + 1;
5265 bzero(m_mtod_current(m), m->m_len);
5266 m->m_pkthdr.len = m->m_len;
5267
5268 ip6->ip6_flow = 0;
5269 ip6->ip6_vfc &= ~IPV6_VERSION_MASK;
5270 ip6->ip6_vfc |= IPV6_VERSION;
5271 ip6->ip6_nxt = IPPROTO_UDP;
5272 ip6->ip6_hlim = (u_int8_t)ip6_defhlim;
5273 ip6->ip6_plen = htons(sizeof(struct udphdr) + 1);
5274 if (sav->sah->dir != IPSEC_DIR_INBOUND) {
5275 ip6->ip6_src = SIN6(&sav->sah->saidx.src)->sin6_addr;
5276 ip6->ip6_dst = SIN6(&sav->sah->saidx.dst)->sin6_addr;
5277 ip6_output_setsrcifscope(m, SIN6(&sav->sah->saidx.src)->sin6_scope_id, NULL);
5278 ip6_output_setdstifscope(m, SIN6(&sav->sah->saidx.dst)->sin6_scope_id, NULL);
5279 } else {
5280 ip6->ip6_src = SIN6(&sav->sah->saidx.dst)->sin6_addr;
5281 ip6->ip6_dst = SIN6(&sav->sah->saidx.src)->sin6_addr;
5282 ip6_output_setdstifscope(m, SIN6(&sav->sah->saidx.src)->sin6_scope_id, NULL);
5283 ip6_output_setsrcifscope(m, SIN6(&sav->sah->saidx.dst)->sin6_scope_id, NULL);
5284 }
5285
5286 if (IN6_IS_SCOPE_EMBED(&ip6->ip6_src)) {
5287 ip6->ip6_src.s6_addr16[1] = 0;
5288 }
5289 if (IN6_IS_SCOPE_EMBED(&ip6->ip6_dst)) {
5290 ip6->ip6_dst.s6_addr16[1] = 0;
5291 }
5292
5293 if (sav->natt_encapsulated_src_port != 0) {
5294 uh->uh_sport = (u_short)sav->natt_encapsulated_src_port;
5295 } else {
5296 uh->uh_sport = htons((u_short)esp_udp_encap_port);
5297 }
5298 uh->uh_dport = htons(sav->remote_ike_port);
5299 uh->uh_ulen = htons(1 + sizeof(*uh));
5300 *(u_int8_t*)(m_mtod_current(m) + sizeof(*ip6) + sizeof(*uh)) = 0xFF;
5301 uh->uh_sum = in6_pseudo(&ip6->ip6_src, &ip6->ip6_dst, htonl(ntohs(uh->uh_ulen) + IPPROTO_UDP));
5302 m->m_pkthdr.csum_flags = (CSUM_UDPIPV6 | CSUM_ZERO_INVERT);
5303 m->m_pkthdr.csum_data = offsetof(struct udphdr, uh_sum);
5304
5305 if (ROUTE_UNUSABLE(&sav->sah->sa_route) ||
5306 rt_key(sav->sah->sa_route.ro_rt)->sa_family != AF_INET6) {
5307 ROUTE_RELEASE(&sav->sah->sa_route);
5308 }
5309
5310 route_copyout((struct route *)&ro6, (struct route *)&sav->sah->sa_route, sizeof(struct route_in6));
5311 lck_mtx_unlock(sadb_mutex);
5312
5313 necp_mark_packet_as_keepalive(m, TRUE);
5314 error = ip6_output(m, NULL, &ro6, IPV6_OUTARGS, NULL, NULL, &ip6oa);
5315
5316 lck_mtx_lock(sadb_mutex);
5317 route_copyin((struct route *)&ro6, (struct route *)&sav->sah->sa_route, sizeof(struct route_in6));
5318 } else {
5319 ipseclog((LOG_ERR, "nat keepalive: invalid address family %u\n", sav->sah->saidx.dst.ss_family));
5320 lck_mtx_unlock(sadb_mutex);
5321 m_freem(m);
5322 return FALSE;
5323 }
5324
5325 if (error == 0) {
5326 sav->natt_last_activity = natt_now;
5327 lck_mtx_unlock(sadb_mutex);
5328 return TRUE;
5329 }
5330
5331 lck_mtx_unlock(sadb_mutex);
5332 return FALSE;
5333 }
5334
5335 __private_extern__ bool
ipsec_fill_offload_frame(ifnet_t ifp,struct secasvar * sav,struct ifnet_keepalive_offload_frame * frame,size_t frame_data_offset)5336 ipsec_fill_offload_frame(ifnet_t ifp,
5337 struct secasvar *sav,
5338 struct ifnet_keepalive_offload_frame *frame,
5339 size_t frame_data_offset)
5340 {
5341 u_int8_t *data = NULL;
5342 struct udphdr *uh = NULL;
5343 size_t total_length = 0;
5344
5345 if (sav == NULL || sav->sah == NULL || frame == NULL ||
5346 (ifp != NULL && ifp->if_index != sav->sah->outgoing_if) ||
5347 !(sav->flags & SADB_X_EXT_NATT) ||
5348 !(sav->flags & SADB_X_EXT_NATT_KEEPALIVE) ||
5349 !(sav->flags & SADB_X_EXT_NATT_KEEPALIVE_OFFLOAD) ||
5350 sav->flags & SADB_X_EXT_ESP_KEEPALIVE ||
5351 ((esp_udp_encap_port & 0xFFFF) == 0 && sav->natt_encapsulated_src_port == 0) ||
5352 sav->remote_ike_port == 0 ||
5353 (natt_keepalive_interval == 0 && sav->natt_interval == 0 && sav->natt_offload_interval == 0)) {
5354 /* SA is not eligible for keepalive offload on this interface */
5355 return FALSE;
5356 }
5357
5358 u_int16_t frame_data_len = 0;
5359 sa_family_t af = sav->sah->saidx.dst.ss_family;
5360 if (af == AF_INET6 ||
5361 (af == AF_INET && IS_INTF_CLAT46(ifp))) {
5362 frame_data_len = sizeof(struct udphdr) + sizeof(struct ip6_hdr) + 1;
5363 } else if (af == AF_INET) {
5364 frame_data_len = sizeof(struct udpiphdr) + 1;
5365 } else {
5366 return FALSE;
5367 }
5368
5369 if (os_add_overflow(frame_data_offset, frame_data_len,
5370 &total_length) || total_length > IFNET_KEEPALIVE_OFFLOAD_FRAME_DATA_SIZE) {
5371 /* Not enough room in this data frame */
5372 return FALSE;
5373 }
5374
5375 data = frame->data;
5376 if (af == AF_INET6 ||
5377 (af == AF_INET && IS_INTF_CLAT46(ifp))) {
5378 struct ip6_hdr *ip6 = (struct ip6_hdr *)(void *)(data + frame_data_offset);
5379 uh = (struct udphdr *)(void *)(data + frame_data_offset + sizeof(*ip6));
5380 frame->length = (uint8_t)(frame_data_offset + frame_data_len);
5381 frame->type = IFNET_KEEPALIVE_OFFLOAD_FRAME_IPSEC;
5382 frame->ether_type = IFNET_KEEPALIVE_OFFLOAD_FRAME_ETHERTYPE_IPV6;
5383
5384 bzero(data, IFNET_KEEPALIVE_OFFLOAD_FRAME_DATA_SIZE);
5385 ip6->ip6_flow = 0;
5386 ip6->ip6_vfc &= ~IPV6_VERSION_MASK;
5387 ip6->ip6_vfc |= IPV6_VERSION;
5388 ip6->ip6_nxt = IPPROTO_UDP;
5389 ip6->ip6_hlim = (uint8_t)ip6_defhlim;
5390 ip6->ip6_plen = htons(sizeof(struct udphdr) + 1);
5391
5392 if (af == AF_INET6) {
5393 if (sav->sah->dir != IPSEC_DIR_INBOUND) {
5394 ip6->ip6_src = SIN6(&sav->sah->saidx.src)->sin6_addr;
5395 ip6->ip6_dst = SIN6(&sav->sah->saidx.dst)->sin6_addr;
5396 } else {
5397 ip6->ip6_src = SIN6(&sav->sah->saidx.dst)->sin6_addr;
5398 ip6->ip6_dst = SIN6(&sav->sah->saidx.src)->sin6_addr;
5399 }
5400 } else {
5401 /*
5402 * Retrieve the local IPv6 CLAT46 address reserved for stateless
5403 * translation.
5404 */
5405 struct in6_ifaddr *ia6_clat_src = in6ifa_ifpwithflag(ifp, IN6_IFF_CLAT46);
5406 if (ia6_clat_src == NULL) {
5407 ip6stat.ip6s_clat464_out_nov6addr_drop++;
5408 return FALSE;
5409 }
5410
5411 ip6->ip6_src = ia6_clat_src->ia_addr.sin6_addr;
5412 ifa_remref(&ia6_clat_src->ia_ifa);
5413
5414 /*
5415 * Translate IPv4 destination to IPv6 destination by using the
5416 * prefixes learned through prior PLAT discovery.
5417 */
5418 struct in_addr *ipv4_dst = NULL;
5419 if (sav->sah->dir != IPSEC_DIR_INBOUND) {
5420 ipv4_dst = &(SIN(&sav->sah->saidx.dst)->sin_addr);
5421 } else {
5422 ipv4_dst = &(SIN(&sav->sah->saidx.src)->sin_addr);
5423 }
5424
5425 if (nat464_synthesize_ipv6(ifp, ipv4_dst, &ip6->ip6_dst) != 0) {
5426 ip6stat.ip6s_clat464_out_v6synthfail_drop++;
5427 return FALSE;
5428 }
5429
5430 ip6stat.ip6s_clat464_out_success++;
5431 }
5432
5433 if (IN6_IS_SCOPE_EMBED(&ip6->ip6_src)) {
5434 ip6->ip6_src.s6_addr16[1] = 0;
5435 }
5436 if (IN6_IS_SCOPE_EMBED(&ip6->ip6_dst)) {
5437 ip6->ip6_dst.s6_addr16[1] = 0;
5438 }
5439 /* Fill out the UDP header */
5440 if (sav->natt_encapsulated_src_port != 0) {
5441 uh->uh_sport = (u_short)sav->natt_encapsulated_src_port;
5442 } else {
5443 uh->uh_sport = htons((u_short)esp_udp_encap_port);
5444 }
5445 uh->uh_dport = htons(sav->remote_ike_port);
5446 uh->uh_ulen = htons(1 + sizeof(*uh));
5447 *(u_int8_t*)(data + frame_data_offset + sizeof(*ip6) + sizeof(*uh)) = 0xFF;
5448 uh->uh_sum = inet6_cksum_buffer((const uint8_t *)ip6, IPPROTO_UDP,
5449 sizeof(*ip6), ntohs(ip6->ip6_plen), frame_data_len);
5450 } else {
5451 struct ip *ip = (struct ip *)(void *)(data + frame_data_offset);
5452 uh = (struct udphdr *)(void *)(data + frame_data_offset + sizeof(*ip));
5453
5454 frame->length = (uint8_t)(frame_data_offset + frame_data_len);
5455 frame->type = IFNET_KEEPALIVE_OFFLOAD_FRAME_IPSEC;
5456 frame->ether_type = IFNET_KEEPALIVE_OFFLOAD_FRAME_ETHERTYPE_IPV4;
5457
5458 bzero(data, IFNET_KEEPALIVE_OFFLOAD_FRAME_DATA_SIZE);
5459
5460 ip->ip_v = IPVERSION;
5461 ip->ip_hl = sizeof(struct ip) >> 2;
5462 ip->ip_off &= htons(~IP_OFFMASK);
5463 ip->ip_off &= htons(~IP_MF);
5464 switch (ip4_ipsec_dfbit) {
5465 case 0: /* clear DF bit */
5466 ip->ip_off &= htons(~IP_DF);
5467 break;
5468 case 1: /* set DF bit */
5469 ip->ip_off |= htons(IP_DF);
5470 break;
5471 default: /* copy DF bit */
5472 break;
5473 }
5474 ip->ip_len = htons(sizeof(struct udpiphdr) + 1);
5475 if (rfc6864 && IP_OFF_IS_ATOMIC(htons(ip->ip_off))) {
5476 ip->ip_id = 0;
5477 } else {
5478 ip->ip_id = ip_randomid((uint64_t)frame);
5479 }
5480 ip->ip_ttl = (u_char)ip_defttl;
5481 ip->ip_p = IPPROTO_UDP;
5482 ip->ip_sum = 0;
5483 if (sav->sah->dir != IPSEC_DIR_INBOUND) {
5484 ip->ip_src = SIN(&sav->sah->saidx.src)->sin_addr;
5485 ip->ip_dst = SIN(&sav->sah->saidx.dst)->sin_addr;
5486 } else {
5487 ip->ip_src = SIN(&sav->sah->saidx.dst)->sin_addr;
5488 ip->ip_dst = SIN(&sav->sah->saidx.src)->sin_addr;
5489 }
5490 ip->ip_sum = in_cksum_hdr_opt(ip);
5491 /* Fill out the UDP header */
5492 if (sav->natt_encapsulated_src_port != 0) {
5493 uh->uh_sport = (u_short)sav->natt_encapsulated_src_port;
5494 } else {
5495 uh->uh_sport = htons((u_short)esp_udp_encap_port);
5496 }
5497 uh->uh_dport = htons(sav->remote_ike_port);
5498 uh->uh_ulen = htons(1 + sizeof(*uh));
5499 uh->uh_sum = 0;
5500 *(u_int8_t*)(data + frame_data_offset + sizeof(*ip) + sizeof(*uh)) = 0xFF;
5501 }
5502
5503 if (sav->natt_offload_interval != 0) {
5504 frame->interval = sav->natt_offload_interval;
5505 } else if (sav->natt_interval != 0) {
5506 frame->interval = sav->natt_interval;
5507 } else {
5508 frame->interval = (u_int16_t)natt_keepalive_interval;
5509 }
5510 return TRUE;
5511 }
5512
5513 void
ipsec_get_local_ports(void)5514 ipsec_get_local_ports(void)
5515 {
5516 errno_t error;
5517 uint32_t count = 0;
5518 ifnet_t *__counted_by(count) ifp_list = NULL;
5519 uint32_t i;
5520 static uint8_t port_bitmap[bitstr_size(IP_PORTRANGE_SIZE)];
5521
5522 error = ifnet_list_get_all(IFNET_FAMILY_IPSEC, &ifp_list, &count);
5523 if (error != 0) {
5524 os_log_error(OS_LOG_DEFAULT, "%s: ifnet_list_get_all() failed %d",
5525 __func__, error);
5526 return;
5527 }
5528 for (i = 0; i < count; i++) {
5529 ifnet_t ifp = ifp_list[i];
5530
5531 /*
5532 * Skip the IPsec companion link default interface
5533 * because it will never receive any packet and
5534 * the presence of the port entry can cause a
5535 * wake packet to be mis-attributed to the wrong
5536 * interface
5537 */
5538 if (IFNET_IS_COMPANION_LINK(ifp) &&
5539 ifp->if_subfamily == IFNET_SUBFAMILY_DEFAULT) {
5540 continue;
5541 }
5542
5543 /*
5544 * Get all the TCP and UDP ports for IPv4 and IPv6
5545 */
5546 error = ifnet_get_local_ports_extended(ifp, PF_UNSPEC,
5547 IFNET_GET_LOCAL_PORTS_WILDCARDOK |
5548 IFNET_GET_LOCAL_PORTS_NOWAKEUPOK |
5549 IFNET_GET_LOCAL_PORTS_ANYTCPSTATEOK,
5550 port_bitmap);
5551 if (error != 0) {
5552 os_log_error(OS_LOG_DEFAULT, "%s: ifnet_get_local_ports_extended(%s) failed %d",
5553 __func__, if_name(ifp), error);
5554 }
5555 }
5556 ifnet_list_free_counted_by(ifp_list, count);
5557 }
5558
5559 void
ipsec_fill_ip6_sockaddr_4_6_with_ifscope(union sockaddr_in_4_6 * sin46,struct in6_addr * ip6,u_int16_t port,uint32_t ifscope)5560 ipsec_fill_ip6_sockaddr_4_6_with_ifscope(union sockaddr_in_4_6 *sin46,
5561 struct in6_addr *ip6, u_int16_t port, uint32_t ifscope)
5562 {
5563 if (sin46 == NULL) {
5564 return;
5565 }
5566
5567 struct sockaddr_in6 *sin6 = &sin46->sin6;
5568
5569 sin6->sin6_family = AF_INET6;
5570 sin6->sin6_len = sizeof(*sin6);
5571 sin6->sin6_port = port;
5572 sin6->sin6_addr = *ip6;
5573 if (IN6_IS_SCOPE_EMBED(&sin6->sin6_addr)) {
5574 sin6->sin6_scope_id = ifscope;
5575 if (in6_embedded_scope) {
5576 in6_verify_ifscope(&sin6->sin6_addr, sin6->sin6_scope_id);
5577 if (sin6->sin6_addr.s6_addr16[1] != 0) {
5578 sin6->sin6_scope_id = ntohs(sin6->sin6_addr.s6_addr16[1]);
5579 sin6->sin6_addr.s6_addr16[1] = 0;
5580 }
5581 }
5582 }
5583 }
5584
5585 void
ipsec_fill_ip6_sockaddr_4_6(union sockaddr_in_4_6 * sin46,struct in6_addr * ip6,u_int16_t port)5586 ipsec_fill_ip6_sockaddr_4_6(union sockaddr_in_4_6 *sin46,
5587 struct in6_addr *ip6, u_int16_t port)
5588 {
5589 if (sin46 == NULL) {
5590 return;
5591 }
5592
5593 struct sockaddr_in6 *sin6 = &sin46->sin6;
5594
5595 sin6->sin6_family = AF_INET6;
5596 sin6->sin6_len = sizeof(*sin6);
5597 sin6->sin6_port = port;
5598 sin6->sin6_addr = *ip6;
5599 }
5600
5601 void
ipsec_fill_ip_sockaddr_4_6(union sockaddr_in_4_6 * sin46,struct in_addr ip,u_int16_t port)5602 ipsec_fill_ip_sockaddr_4_6(union sockaddr_in_4_6 *sin46,
5603 struct in_addr ip, u_int16_t port)
5604 {
5605 if (sin46 == NULL) {
5606 return;
5607 }
5608
5609 struct sockaddr_in *sin = &sin46->sin;
5610
5611 sin->sin_family = AF_INET;
5612 sin->sin_len = sizeof(*sin);
5613 sin->sin_port = port;
5614 sin->sin_addr.s_addr = ip.s_addr;
5615 }
5616
5617 void
ipsec_init(void)5618 ipsec_init(void)
5619 {
5620 ipsec_register_control();
5621 }
5622