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